Re: Some new GString functions - constructors

2005-12-21 Thread Paul LeoNerd Evans
On Tue, Dec 20, 2005 at 07:09:35PM -0500, Owen Taylor wrote:
 Isn't a lot of code; if it was a common operation, then sure
 I'd get annoyed writing it over and over again. But unless you are
 using GString as your string type (which I think is wrong), it 
 strikes me as quite rare.

Yes; that's fair enough.

I mentioned all the functions I created in my code, just to see what the
general thoughts from the list were. I did specifically remark that the
split functions in particular would be a point of discussion. I'm quite
prepared to accept that they don't really belong in GLib.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
As promised earlier, here's a patch with some new functions for GString.
I'll split them up with related changes, so this is just the first of a
sequence.

There's 3 functions added here, g_string_clone, g_string_new_lenz, and
g_string_slice. Each is a constructor, to return a new GString object.


* g_string_clone() is a convenient wrapper to take a copy of an
  existing GString;

g_string_clone(s)  ==   g_string_new(s-str)

  Except it returns NULL if s == NULL.

* g_string_new_lenz() is similar to g_string_new_len(), only it appends
  a terminating nul byte to the string buffer, making it safe to
  printf() or use as a normal gchar* string.

* g_string_slice() returns a new GString containing just a portion of
  the given string.


I wasn't quite sure how to implement these, in terms of writing new
code, or just calling one of the other functions. And also I'm rather
new to the documentation system, so I hope I've done those right.
Comments / suggestions / corrections would be most appreciated.


---

Some other ideas



I have planned at least two other patches.

The first to add two new constructors that I find quite useful in my
code:

GString* g_string_new_sprintf(const gchar *fmt, ...);

GString* g_string_new_vsprintf(const gchar *fmt, va_list args);

These are a little more convenient than the g_string_new() /
g_string_sprintf() pair, especially if the contructed string is being
return'd from a function.

The other has some other useful functions:

gboolean g_string_caseequal(GString *s1, GString *s2);

gint g_string_indexof(GString *str, gchar c);

void g_string_destroy(GString *str);

The latter is a function which would simply wrap 
  g_string_free(str, TRUE);
but whose type makes it usable as a GDestroyNotify callback.

I also have some slightly more special-purpose functions which I find
useful, but I'm not sure of their place in such a general-purpose
library as GLib. These are:

GString* g_string_pull_token(GString *str);
// Deletes a token from the beginning of str, and returns it

GString* g_string_pull_line(GString *str);
// Deletes a line from the beginning of str, and returns it

Finally, I have some which I find useful for dealing with lists of
strings. A trivial 

  typedef GList GStringList;

and some functions

  GStringList* g_string_split(GString *str, gchar c);

  GString* g_string_list_fold(GStringList *list, const char *sep);

  void g_string_list_free(GStringList *list, gboolean free_str, gboolean 
free_data);


I'd be interested to hear opinions on these ideas; especially the later
ones. It's quite possible that these are too special-purpose to warrant
inclusion in GLib. Though I have found them quite useful in my programs,
so I though I'd at least suggest inclusion, and see what the general
opinion is.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/
Index: docs/reference/glib/glib-sections.txt
===
RCS file: /cvs/gnome/glib/docs/reference/glib/glib-sections.txt,v
retrieving revision 1.134
diff -u -r1.134 glib-sections.txt
--- docs/reference/glib/glib-sections.txt   19 Dec 2005 21:22:29 -  
1.134
+++ docs/reference/glib/glib-sections.txt   20 Dec 2005 22:14:52 -
@@ -1794,8 +1794,11 @@
 FILEstrings/FILE
 GString
 g_string_new
+g_string_clone
 g_string_new_len
+g_string_new_lenz
 g_string_sized_new
+g_string_slice
 g_string_assign
 g_string_sprintf
 g_string_sprintfa
Index: docs/reference/glib/tmpl/strings.sgml
===
RCS file: /cvs/gnome/glib/docs/reference/glib/tmpl/strings.sgml,v
retrieving revision 1.28
diff -u -r1.28 strings.sgml
--- docs/reference/glib/tmpl/strings.sgml   20 Dec 2005 04:44:25 -  
1.28
+++ docs/reference/glib/tmpl/strings.sgml   20 Dec 2005 22:14:52 -
@@ -46,6 +46,15 @@
 @Returns: the new #GString.
 
 
+!-- # FUNCTION g_string_clone # --
+para
+
+/para
+
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
+
+
 !-- # FUNCTION g_string_new_len # --
 para
 Creates a new #GString with @len bytes of the @init buffer.  Because a length 
is
@@ -57,6 +66,16 @@
 @Returns: a new #GString.
 
 
+!-- # FUNCTION g_string_new_lenz # --
+para
+
+/para
+
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
+
+
 !-- # FUNCTION g_string_sized_new # --
 para
 Creates a new #GString, with enough space for @dfl_size bytes.
@@ -68,6 +87,17 @@
 @Returns: the new #GString.
 
 
+!-- # FUNCTION g_string_slice # --
+para
+
+/para
+
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
[EMAIL PROTECTED]: 
+
+
 !-- # FUNCTION g_string_assign # --
 para
 Copies the bytes from a string into a #GString, destroying any previous
@@ -91,6 +121,7 @@
 /para
 
 @Deprecated: This function has been renamed to g_string_printf().
+!-- # Unused Parameters # --
 

Re: Some new GString functions - constructors

2005-12-20 Thread Emmanuele Bassi
Hi,

On Tue, 2005-12-20 at 22:36 +, Paul LeoNerd Evans wrote:
 As promised earlier, here's a patch with some new functions for GString.
 I'll split them up with related changes, so this is just the first of a
 sequence.

Can you please open a bug inside http://bugzilla.gnome.org and attach
the patch there? Tracking patches on Bugzilla makes things easier than
on a mailing list.

 * g_string_clone()

 * g_string_new_lenz()

 * g_string_slice()

Apart from g_string_new_lenz() which I don't understand, the _clone()
and _slice() functions looks intersting.

 Some other ideas
 

 gint g_string_indexof(GString *str, gchar c);

This would be useful with Unicode support, or with a gunichar variant.

 void g_string_destroy(GString *str);

This is *most* useful.

 I also have some slightly more special-purpose functions which I find
 useful, but I'm not sure of their place in such a general-purpose
 library as GLib. These are:
 
 GString* g_string_pull_token(GString *str);
 // Deletes a token from the beginning of str, and returns it
 
 GString* g_string_pull_line(GString *str);
 // Deletes a line from the beginning of str, and returns it

Also, a

gchar ** g_string_tokenize (GString *str,
const gchar *token,
gsizelenght);

Could be interesting, instead of creating a new StringList type, since,
if you want a list of GString, you can always iterate on the returned
strings vector.

Ciao,
 Emmanuele.

-- 
Emmanuele Bassi - [EMAIL PROTECTED]
Log: http://log.emmanuelebassi.net

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Tue, Dec 20, 2005 at 02:43:43PM -0800, Alan M. Evans wrote:
 GStrings are already guaranteed to have a nul terminating byte, aren't
 they?

Ah; yes, in fact, they are. I had thought they weren't, in the case of
calling g_string_new_len(), because I tried it one time and found a bug.
I'd just presumed that it wasn't nul-terminated, so went and added the
_lenz() constructor instead.

On reading the gstring.c file, I note actually yes, this constructor
should nul-terminate the string. I guess my _lenz() constructor is rather
useless now then.

Sorry about that...

I guess that means the g_string_slice() constructor could actually be
written quite easily by wrapping g_string_new_len() instead.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Wed, Dec 21, 2005 at 12:00:52AM +0100, Emmanuele Bassi wrote:
 Can you please open a bug inside http://bugzilla.gnome.org and attach
 the patch there? Tracking patches on Bugzilla makes things easier than
 on a mailing list.

Shall do.

 Apart from g_string_new_lenz() which I don't understand, the _clone()
 and _slice() functions looks intersting.

Sorry about that one. See other mail... I'd added _lenz() on account of a
misunderstanding of how g_string_new_len() works - I thought it didn't
guarantee nul-termination, but it does. I'll resubmit another patch, and
add to bugzilla, without that function.

  gint g_string_indexof(GString *str, gchar c);
 
 This would be useful with Unicode support, or with a gunichar variant.

Hmm A tricky question. In this simple case of looking for a gchar,
it's just scanning for a byte. As soon as we bring in Unicode, the
question is asked what encoding is it..? I guess we mean UTF-8 here? Is
it accepted that all Unicode strings are UTF-8 encoded?

I can have a go at a Unicode-aware _indexof(), sure... but currently I
just wrap g_strchr() for that case, so I'd need to know how to handle it
in UTF-8.

snip

 Also, a
 
   gchar ** g_string_tokenize (GString *str,
 const gchar *token,
 gsizelenght);
 
 Could be interesting, instead of creating a new StringList type, since,
 if you want a list of GString, you can always iterate on the returned
 strings vector.

Hmm.. That one seems a little messy to me. GString in, GString out. Or
gchar* in, gchar* out. If it takes in a GString*, but returns a gchar**,
that's sort of a mix of types. I don't know how anyone else feels about
that, but it doesn't quite feel right to me.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Alan M. Evans
On Tue, 2005-12-20 at 14:36, Paul LeoNerd Evans wrote:

   typedef GList GStringList;

Not entirely certain I like this. See below.

   GStringList* g_string_split(GString *str, gchar c);

Seems to me this should return a gchar** a-la g_strsplit(). Whether or
not this is more useful may depend on how you use it -- I use string
arrays frequently, rarely use GLists of strings. But at least the naming
would be more consistent.

My opinion: GLib could use more support functions for string arrays.


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Alan M. Evans
On Tue, 2005-12-20 at 15:18, Alan M. Evans wrote:
 On Tue, 2005-12-20 at 14:36, Paul LeoNerd Evans wrote:
 
typedef GList GStringList;
 
 Not entirely certain I like this. See below.
 
GStringList* g_string_split(GString *str, gchar c);
 
 Seems to me this should return a gchar** a-la g_strsplit().

I take that back. I can always use g_strsplit() on the GString contents.
On further consideration, I suppose that your GList contains GStrings,
not gchar pointers. Still not certain that g_string_split() is the best
name. And not certain that GList is the best container for the returned
data. Do you really not mind 24 bytes of overhead for every returned
token? (12 bytes for GList + 12 bytes for GString)

 My opinion: GLib could use more support functions for string arrays.

I do not take this back.


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Owen Taylor
At a high-level, I think there is a question of what GString is - 
should there be GString versions of everything you want to do 
with a char *?

My opinion is no ... a GString is the equivalent of a Java 
StringBuffer .. it is a useful way to build and work with strings,
but it isn't *a string*. That's a char *.

It would be for example, wrong to pass a GString as an argument
to a function that takes a string as an input parameter.

That implies to me, for example:

 GList *g_string_split(GString *str, gchar c);

Is wrong ... we already have g_strsplit():

(Sidenote: g_strsplit() takes a char * delimiter. This has 
the big benefit of handling UTF-8 and ascii equally well.)

Regards,
Owen


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Tue, Dec 20, 2005 at 03:26:45PM -0800, Alan M. Evans wrote:
  Not entirely certain I like this. See below.
  
 GStringList* g_string_split(GString *str, gchar c);
  
  Seems to me this should return a gchar** a-la g_strsplit().
 
 I take that back. I can always use g_strsplit() on the GString contents.
 On further consideration, I suppose that your GList contains GStrings,
 not gchar pointers. Still not certain that g_string_split() is the best
 name. And not certain that GList is the best container for the returned
 data. Do you really not mind 24 bytes of overhead for every returned
 token? (12 bytes for GList + 12 bytes for GString)

Yes; I realised this would be quite a contentious issue; I wanted to
throw it open for debate.

My gut feeling, as I said in the other thread, is that a raw gchar**
doesn't really feel right. We're dealing with a GString nice shiney
wrapped type here...

Though I do take your point of the overhead of a GList.

Any number of possible ways to do this now strike me:

  GPtrArray* g_string_split_array();
  
  GString** g_string_split_strv();  // returns NULL-terminated array
  
Or, we could at this juncture try something new and funky.

Suppose instead we could do this:

  GString str;
  g_string_init(str);
  g_string_append_len(...);

I.e. keep the GString struct itself as a real variable, rather than just
throwing pointers to it about the place, then we could construct a

  GArray* g_string_split_array();

To return an array of GString structs themselves, rather than GString*
pointers. This would also have other benefits, like being able to
contain a plain GString struct inside a larger struct type.

Compare

  struct {
...
GString* name;
  };

  printf(My name is %s\n, me-name-str);

vs:

  struct {
...
GString name;
  };

  printf(My name is %s\n, me.name-str);


If you could use a bare GString inside a larger structure like that, it
would have immediate savings in terms of memory allocation overheads,
pointer dereference overheads, and general code neatness.

This idea would require two new functions:

  void g_string_init(GString *str);
  void g_string_fini(GString *str);

Which would do most of the work of g_string_new() and g_string_free()
respectively, apart from the initial struct allocation / final struct
free().

Thoughts on that one?

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Wed, Dec 21, 2005 at 12:33:23AM +0100, Emmanuele Bassi wrote:
 EIther way, you would have another type out: GStringList would be a
 G(S)List of GString; you would have to use:
 
   GSList *iter; /* or GList *iter; */
   for (iter = stringlist; iter != NULL; iter = iter-next)
 do_something ((GString *) iter-data);
 
 to iterate though the list, which would break the least-surprise
 principle, since you would have to use a G(S)List pointer to iterate
 through a GStringList.

Yes; PLS is broken there.

As mentioned in the other thread; I'll summarise here. I could return:

  GPtrArray*
  GString**  // NULL-terminated
  GArray*// of raw GString structs, rather than GString* pointers.

This last one has interesting ramifications.. See other thread for
detail.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Tue, Dec 20, 2005 at 06:31:01PM -0500, Owen Taylor wrote:
 At a high-level, I think there is a question of what GString is - 
 should there be GString versions of everything you want to do 
 with a char *?
 
 My opinion is no ... a GString is the equivalent of a Java 
 StringBuffer .. it is a useful way to build and work with strings,
 but it isn't *a string*. That's a char *.
 
 It would be for example, wrong to pass a GString as an argument
 to a function that takes a string as an input parameter.

Yes; I do see your point here... There is after all, no point in
defining an operation to printf() a GString, when you might as well just
use %s with s-str.

 That implies to me, for example:
 
  GList *g_string_split(GString *str, gchar c);
 
 Is wrong ... we already have g_strsplit():

Ahh.. That would miss half the point of my intention with this function.

It is true that this function takes, as input, a GString. But that
wasn't its raison d'etre. The point of this new function is its return
value. Yes, we already have g_strsplit(). This returns a NULL-terminated
array of NULL-terminated gchar* strings. My intended point of
g_string_split() would be that it would return a collection of GString*
objects. The convenience is that it wraps up the strings as GString*s.

That said, I don't see why we need a new split function, on reflection.
Maybe a:

  GString** g_string_new_strv(gchar** a);

would be useful; it would return a NULL-terminated array of new
GString*s, each one wrapping a string from the original array. Thus, to
form a GString** one could

  gchar** sv = g_strsplit(original_string-str, delim);
  GString** gsv = g_string_new_strv(sv);
  g_strfreev(sv);

So easily providing what I intended for g_string_split(), but being less
added code, and more useful.

That said, I'm still not 100% happy with a NULL-terminated GString*
array. Other threads give alternative ideas I have for these.

 (Sidenote: g_strsplit() takes a char * delimiter. This has 
 the big benefit of handling UTF-8 and ascii equally well.)

Ah yes; a most useful property.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Naked GString operations [was: Re: Some new GString functions - constructors]

2005-12-20 Thread Paul LeoNerd Evans
(Appologies for the pun in the subject; I couldn't help myself.. :) )

On Tue, Dec 20, 2005 at 03:52:28PM -0800, Alan M. Evans wrote:
void g_string_init(GString *str);
void g_string_fini(GString *str);
  
  Which would do most of the work of g_string_new() and g_string_free()
  respectively, apart from the initial struct allocation / final struct
  free().

 Mine are called g_string_init() and g_string_done(). 
snip
 By using g_string_init() instead of g_string_new() and pointers, I save
 myself four malloc() calls -- a big deal when I have thousands of these
 structs running about. And the bonus is that I can still use all the
 spiffy GString support functions.
 
 I've never dared submit my additions for fear of Owen calling my ideas
 ridiculous. (That's a joke. Owen, please don't ridicule me...)

Well... perhaps now is the time to ask the list for opinions.. I for one
would quite like to see something like this... Baring no objections to
the idea, perhaps I'll make such a change the subject of my next patch
submission. 

Arguments for:
  
  * Improvements in malloc() or other allocation space overheads

  * Improvements in nested pointer dereferencing

  * Ability to build a GArray* containing multiple GString objects

Observations:

  * Any function currently taking a GString* can't free or otherwise
modify the GString* object itself, only the data contained with it.
Such functions would not be affected by these 'naked' GStrings.

  * There are no g_string_ functions which take a GString** and attempt
to modify it.

Arguments against:

  * It does complicate the API slightly. 

  * Any code using a GString* cannot automatically know whether it was
head-allocated, or just points at a variable somewhere. Whether any
code would actually want to know, or care about such a condition, I
am not currently sure.



[PS: I'm not overly attached to _fini(), _done() seems just as nice.]

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Owen Taylor
On Tue, 2005-12-20 at 23:48 +, Paul LeoNerd Evans wrote:
 That said, I don't see why we need a new split function, on reflection.
 Maybe a:
 
   GString** g_string_new_strv(gchar** a);
 
 would be useful; it would return a NULL-terminated array of new
 GString*s, each one wrapping a string from the original array. Thus, to
 form a GString** one could
 
   gchar** sv = g_strsplit(original_string-str, delim);
   GString** gsv = g_string_new_strv(sv);
   g_strfreev(sv);
 
 So easily providing what I intended for g_string_split(), but being less
 added code, and more useful.

What I don't understand is why you want to end up with a list or array
of GString.

 gchar **names = g_strsplit(namelist, ,);
 gchar **p;
 
 for (p = names; *p; p++) {
GString *praise = g_string_new(*p);
g_string_append(praise,  is a great person);
g_printf(%s, praise-str);
g_string_free(praise);
 }

 g_strfreev(names);

Or whatever. If I *really* want a GList of GString, then:

 gchar **names = g_strsplit(namelist, ,);
 gchar **p;
 GList *l = NULL;
 
 for (p = names; *p; p++)
g_list_prepend(l, g_string_new(*p));

 g_strfreev(names);
 return g_list_reverse(l);

Isn't a lot of code; if it was a common operation, then sure
I'd get annoyed writing it over and over again. But unless you are
using GString as your string type (which I think is wrong), it 
strikes me as quite rare.

Regards,
Owen


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Some new GString functions - constructors

2005-12-20 Thread Paul LeoNerd Evans
On Wed, Dec 21, 2005 at 01:19:59AM +0100, Øyvind Kolås wrote:
 At least in my sources, and where they draw inspiration from there is
 a larger precedence for the suffix _dup, rather than _clone.

g_string_dup() also works, yes.. I'm not overly attached to the name. 

Thoughts anyone?

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Naked GString operations [was: Re: Some new GString functions - constructors]

2005-12-20 Thread Paul LeoNerd Evans
On Wed, Dec 21, 2005 at 12:07:14AM +, Paul LeoNerd Evans wrote:
 void g_string_init(GString *str);
 void g_string_fini(GString *str);

Actually, it occurs to me. If we wanted to give certain future
guarantees about GString, we could do something like the following:

  #define GSTRING_STATIC_INIT { .str = NULL; .len = 0; .allocatedlen = 0; }

  ...

  GString s = GSTRING_STATIC_INIT;

in the case of local or global variables, of only one GString (i.e. the
common case). This wouldn't work for arrays or other weird cases, but it
would avoid even the need for a call to the function to initialise it.

The downside here is that the initial representation of an empty
GString would need to be compile-time constant, if it would be used in
this manner.

Thoughts?

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: Digital signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list