Re: Some new GString functions - constructors
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
Re: Some new GString functions - constructors
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
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
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
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
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
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
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
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
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]
(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
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
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]
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