diff --git a/ChangeLog b/ChangeLog index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 1af9a15f9..1b7b30c5e 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,13 @@ +Fri Aug 24 11:15:46 2001 Owen Taylor + + * glib/gstrfuncs.c docs/Changes-2.0.txt: Patch from Darin + Adler to restore Glib-1.2 handling of empty strings, + and to fix off-by-one with @max_tokens. (#57663). + Doc improvements. + + * tests/strfunc-test.c: Change tests to correspond to + new behavior of g_strsplit(). + Thu Aug 23 11:09:58 2001 Owen Taylor * glib/ghash.c (g_hash_table_foreach_remove_or_steal): diff --git a/docs/Changes-2.0.txt b/docs/Changes-2.0.txt index d9fc04177..28b888977 100644 --- a/docs/Changes-2.0.txt +++ b/docs/Changes-2.0.txt @@ -32,3 +32,11 @@ * GDate now works in UTF-8, not in the current locale. If you want to use it with the encoding of the locale, you need to convert strings using g_locale_to_utf8 first. + +* g_strsplit() has been fixed to: + + - include trailing empty tokens, rather than stripping them + - split into a maximum of @max_tokens tokens, rather than + @max_tokens + 1 + + Code depending on either of these bugs will need to be fixed. diff --git a/docs/reference/glib/tmpl/string_utils.sgml b/docs/reference/glib/tmpl/string_utils.sgml index 43a87005b..3dc908068 100644 --- a/docs/reference/glib/tmpl/string_utils.sgml +++ b/docs/reference/glib/tmpl/string_utils.sgml @@ -358,20 +358,12 @@ nesting such as g_strup (g_strcanon (str)). -Splits a string into a maximum of @max_tokens pieces, using the given -@delimiter. If @max_tokens is reached, the last piece contains the -remainder of @string. If @string is an empty string, then the resulting -string array has no elements. -@string: a string to split. -@delimiter: a string which specifies the places at which to split the string. -The delimiter is not included in any of the resulting strings, unless -max_tokens is reached. -@max_tokens: the maximum number of pieces to split @string into. If this is -less than 1, the string is split completely. -@Returns: a newly-allocated NULL-terminated array of strings. Use g_strfreev() -to free it. +@string: +@delimiter: +@max_tokens: +@Returns: diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index c79cc51bf..45dfe956b 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -1566,6 +1566,29 @@ g_strchomp (gchar *string) return string; } +/** + * g_strsplit: + * @string: a string to split. + * @delimiter: a string which specifies the places at which to split the string. + * The delimiter is not included in any of the resulting strings, unless + * max_tokens is reached. + * @max_tokens: the maximum number of pieces to split @string into. If this is + * less than 1, the string is split completely. + * + * Splits a string into a maximum of @max_tokens pieces, using the given + * @delimiter. If @max_tokens is reached, the remainder of @string is appended + * to the last token. + * + * As a special case, the result of splitting the empty string "" is an empty + * vector, not a vector containing a single string. The reason for this + * special case is that being able to represent a empty vector is typically + * more useful than consistent handling of empty elements. If you do need + * to represent empty elements, you'll need to check for the empty string + * before calling g_strsplit(). + * + * Return value: a newly-allocated %NULL-terminated array of strings. Use g_strfreev() + * to free it. + **/ gchar** g_strsplit (const gchar *string, const gchar *delimiter, @@ -1573,7 +1596,8 @@ g_strsplit (const gchar *string, { GSList *string_list = NULL, *slist; gchar **str_array, *s; - guint n = 1; + guint n = 0; + const gchar *remainder; g_return_val_if_fail (string != NULL, NULL); g_return_val_if_fail (delimiter != NULL, NULL); @@ -1581,8 +1605,11 @@ g_strsplit (const gchar *string, if (max_tokens < 1) max_tokens = G_MAXINT; + else + --max_tokens; - s = strstr (string, delimiter); + remainder = string; + s = strstr (remainder, delimiter); if (s) { gsize delimiter_len = strlen (delimiter); @@ -1592,18 +1619,22 @@ g_strsplit (const gchar *string, gsize len; gchar *new_string; - len = s - string; + len = s - remainder; new_string = g_new (gchar, len + 1); - strncpy (new_string, string, len); + strncpy (new_string, remainder, len); new_string[len] = 0; string_list = g_slist_prepend (string_list, new_string); n++; - string = s + delimiter_len; - s = strstr (string, delimiter); + remainder = s + delimiter_len; + s = strstr (remainder, delimiter); } while (--max_tokens && s); } - string_list = g_slist_prepend (string_list, g_strdup (string)); + if (*string) + { + n++; + string_list = g_slist_prepend (string_list, g_strdup (remainder)); + } str_array = g_new (gchar*, n + 1); diff --git a/tests/strfunc-test.c b/tests/strfunc-test.c index dc6ac3aac..9255233cf 100644 --- a/tests/strfunc-test.c +++ b/tests/strfunc-test.c @@ -145,7 +145,7 @@ main (int argc, TEST (NULL, strcmp (g_strrstr_len ("FooBarFooBarFoo", 14, "BarFoo"), "BarFooBarFoo") == 0); - TEST (NULL, strv_check (g_strsplit ("", ",", 0), "", NULL)); + TEST (NULL, strv_check (g_strsplit ("", ",", 0), NULL)); TEST (NULL, strv_check (g_strsplit ("x", ",", 0), "x", NULL)); TEST (NULL, strv_check (g_strsplit ("x,y", ",", 0), "x", "y", NULL)); TEST (NULL, strv_check (g_strsplit ("x,y,", ",", 0), "x", "y", "", NULL)); @@ -158,18 +158,18 @@ main (int argc, TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",", 0), "", "", "x", "", "y", "", "z", "", "", NULL)); TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",,", 0), "", "x", "y", "z", "", NULL)); - TEST (NULL, strv_check (g_strsplit ("", ",", 2), "", NULL)); + TEST (NULL, strv_check (g_strsplit ("", ",", 2), NULL)); TEST (NULL, strv_check (g_strsplit ("x", ",", 2), "x", NULL)); TEST (NULL, strv_check (g_strsplit ("x,y", ",", 2), "x", "y", NULL)); - TEST (NULL, strv_check (g_strsplit ("x,y,", ",", 2), "x", "y", "", NULL)); - TEST (NULL, strv_check (g_strsplit (",x,y", ",", 2), "", "x", "y", NULL)); - TEST (NULL, strv_check (g_strsplit (",x,y,", ",", 2), "", "x", "y,", NULL)); - TEST (NULL, strv_check (g_strsplit ("x,y,z", ",", 2), "x", "y", "z", NULL)); - TEST (NULL, strv_check (g_strsplit ("x,y,z,", ",", 2), "x", "y", "z,", NULL)); - TEST (NULL, strv_check (g_strsplit (",x,y,z", ",", 2), "", "x", "y,z", NULL)); - TEST (NULL, strv_check (g_strsplit (",x,y,z,", ",", 2), "", "x", "y,z,", NULL)); - TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",", 2), "", "", "x,,y,,z,,", NULL)); - TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",,", 2), "", "x", "y,,z,,", NULL)); + TEST (NULL, strv_check (g_strsplit ("x,y,", ",", 2), "x", "y,", NULL)); + TEST (NULL, strv_check (g_strsplit (",x,y", ",", 2), "", "x,y", NULL)); + TEST (NULL, strv_check (g_strsplit (",x,y,", ",", 2), "", "x,y,", NULL)); + TEST (NULL, strv_check (g_strsplit ("x,y,z", ",", 2), "x", "y,z", NULL)); + TEST (NULL, strv_check (g_strsplit ("x,y,z,", ",", 2), "x", "y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit (",x,y,z", ",", 2), "", "x,y,z", NULL)); + TEST (NULL, strv_check (g_strsplit (",x,y,z,", ",", 2), "", "x,y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",", 2), "", ",x,,y,,z,,", NULL)); + TEST (NULL, strv_check (g_strsplit (",,x,,y,,z,,", ",,", 2), "", "x,,y,,z,,", NULL)); g_print ("\n");