From: Matthias Clasen Date: Wed, 28 Jan 2004 00:37:46 +0000 (+0000) Subject: New function, a cross between g_strsplit() and strtok(). (#88329, Soeren X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=326c025205a0b1beebf3cfb9c07d9b510fedc108;p=dana%2Fcg-glib.git New function, a cross between g_strsplit() and strtok(). (#88329, Soeren Wed Jan 28 01:39:21 2004 Matthias Clasen * glib/gstrfuncs.h: * glib/gstrfuncs.c (g_strsplit_set): New function, a cross between g_strsplit() and strtok(). (#88329, Soeren Sandmann) * tests/strfunc-test.c (main): Add g_strsplit_set() tests. --- diff --git a/ChangeLog b/ChangeLog index 68972fb3..6a0c8e88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 68972fb3..6a0c8e88 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 68972fb3..6a0c8e88 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 68972fb3..6a0c8e88 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 68972fb3..6a0c8e88 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 68972fb3..6a0c8e88 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,11 @@ +Wed Jan 28 01:39:21 2004 Matthias Clasen + + * glib/gstrfuncs.h: + * glib/gstrfuncs.c (g_strsplit_set): New function, a cross + between g_strsplit() and strtok(). (#88329, Soeren Sandmann) + + * tests/strfunc-test.c (main): Add g_strsplit_set() tests. + Fri Jan 23 22:49:52 2004 Matthias Clasen * glib/gutils.c (g_get_any_init): Sigh, protect against diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 5cbd26d4..bbd0f04c 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +Wed Jan 28 01:39:59 2004 Matthias Clasen + + * glib/glib-sections.txt: Add g_strsplit_set. (Soeren Sandmann) + Thu Jan 22 14:51:19 2004 Owen Taylor * glib/glib-sections.txt glib/tmpl/timers.sgml: Document diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 7fb4b71a..9c9817ba 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -1008,6 +1008,7 @@ g_strescape g_strcompress g_strcanon g_strsplit +g_strsplit_set g_strfreev g_strconcat g_strjoin diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index e1662125..c4854942 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -2171,6 +2171,106 @@ g_strsplit (const gchar *string, return str_array; } +/** + * g_strsplit_set: + * @string: The string to be tokenized + * @delimiters: A nul-terminated string containing bytes that are used + * to split the string. + * @max_tokens: The maximum number of tokens to split @string into. + * If this is less than 1, the string is split completely + * + * Splits @string into a number of tokens not containing any of the characters + * in @delimiter. A token is the (possibly empty) longest string that does not + * contain any of the characters in @delimiters. If @max_tokens is reached, the + * remainder is appended to the last token. + * + * For example the result of g_strtokenize ("abc:def/ghi", ":/", -1) is a + * %NULL-terminated vector containing the three strings "abc", "def", + * and "ghi". + * + * The result if g_strtokenize (":def/ghi:", ":/", -1) is a %NULL-terminated + * vector containing the four strings "", "def", "ghi", and "". + * + * 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(). + * + * Note that this function works on bytes not characters, so it can't be used + * to delimit UTF-8 strings for anything but ASCII characters. + * + * Return value: a newly-allocated %NULL-terminated array of strings. Use + * g_strfreev() to free it. + * + * Since: 2.4 + **/ +gchar ** +g_strsplit_set (const gchar *string, + const gchar *delimiters, + gint max_tokens) +{ + gboolean delim_table[256]; + GSList *tokens, *list; + gint n_tokens; + const gchar *s; + const gchar *current; + gchar *token; + gchar **result; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiters != NULL, NULL); + + if (max_tokens < 1) + max_tokens = G_MAXINT; + + if (*string == '\0') + { + result = g_new (char *, 1); + result[0] = NULL; + return result; + } + + memset (delim_table, FALSE, sizeof (delim_table)); + for (s = delimiters; *s != '\0'; ++s) + delim_table[*(guchar *)s] = TRUE; + + tokens = NULL; + n_tokens = 0; + + s = current = string; + while (*s != '\0') + { + if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens) + { + gchar *token; + + token = g_strndup (current, s - current); + tokens = g_slist_prepend (tokens, token); + ++n_tokens; + + current = s + 1; + } + + ++s; + } + + token = g_strndup (current, s - current); + tokens = g_slist_prepend (tokens, token); + ++n_tokens; + + result = g_new (gchar *, n_tokens + 1); + + result[n_tokens] = NULL; + for (list = tokens; list != NULL; list = list->next) + result[--n_tokens] = list->data; + + g_slist_free (tokens); + + return result; +} + /** * g_strfreev: * @str_array: a %NULL-terminated array of strings to free. diff --git a/glib/gstrfuncs.h b/glib/gstrfuncs.h index 785bee6f..92810689 100644 --- a/glib/gstrfuncs.h +++ b/glib/gstrfuncs.h @@ -213,8 +213,8 @@ gpointer g_memdup (gconstpointer mem, guint byte_size); /* NULL terminated string arrays. - * g_strsplit() splits up string into max_tokens tokens at delim and - * returns a newly allocated string array. + * g_strsplit(), g_strsplit_set() split up string into max_tokens tokens + * at delim and return a newly allocated string array. * g_strjoinv() concatenates all of str_array's strings, sliding in an * optional separator, the returned string is newly allocated. * g_strfreev() frees the array itself and all of its strings. @@ -223,6 +223,9 @@ gpointer g_memdup (gconstpointer mem, gchar** g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens); +gchar ** g_strsplit_set (const gchar *string, + const gchar *delimiters, + gint max_tokens); gchar* g_strjoinv (const gchar *separator, gchar **str_array); void g_strfreev (gchar **str_array); diff --git a/tests/strfunc-test.c b/tests/strfunc-test.c index dbac5e1f..eab248f8 100644 --- a/tests/strfunc-test.c +++ b/tests/strfunc-test.c @@ -286,6 +286,7 @@ main (int argc, TEST (NULL, strcmp (g_strrstr_len ("FooBarFooBarFoo", 14, "BarFoo"), "BarFooBarFoo") == 0); + /* Test g_strsplit() */ 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)); @@ -325,6 +326,70 @@ main (int argc, 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 g_strsplit_set() */ + TEST (NULL, strv_check (g_strsplit_set ("", ",/", 0), NULL)); + TEST (NULL, strv_check (g_strsplit_set (":def/ghi:", ":/", -1), "", "def", "ghi", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("abc:def/ghi", ":/", -1), "abc", "def", "ghi", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",;,;,;,;", ",;", -1), "", "", "", "", "", "", "", "", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,abc.def", ".,", -1), "", "", "abc", "def", NULL)); + + TEST (NULL, strv_check (g_strsplit_set (",x.y", ",.", 0), "", "x", "y", NULL)); + TEST (NULL, strv_check (g_strsplit_set (".x,y,", ",.", 0), "", "x", "y", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y.z", ",.", 0), "x", "y", "z", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x.y,z,", ",.", 0), "x", "y", "z", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x.y,z", ",.", 0), "", "x", "y", "z", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z,", ",.", 0), "", "x", "y", "z", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",.x,,y,;z..", ".,;", 0), "", "", "x", "", "y", "", "z", "", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,,y,,z,,", ",,", 0), "", "", "x", "", "y", "", "z", "", "", NULL)); + + TEST (NULL, strv_check (g_strsplit_set ("x,y.z", ",.", 1), "x,y.z", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x.y,z,", ",.", 1), "x.y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z", ",.", 1), ",x,y,z", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y.z,", ",.", 1), ",x,y.z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,.y,,z,,", ",.", 1), ",,x,.y,,z,,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",.x,,y,,z,,", ",,..", 1), ",.x,,y,,z,,", NULL)); + + TEST (NULL, strv_check (g_strsplit_set ("", ",", 0), NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x", ",", 0), "x", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y", ",", 0), "x", "y", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,", ",", 0), "x", "y", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y", ",", 0), "", "x", "y", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,", ",", 0), "", "x", "y", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z", ",", 0), "x", "y", "z", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z,", ",", 0), "x", "y", "z", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z", ",", 0), "", "x", "y", "z", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z,", ",", 0), "", "x", "y", "z", "", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 0), "", "", "x", "", "y", "", "z", "", "", NULL)); + + TEST (NULL, strv_check (g_strsplit_set ("", ",", 1), NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x", ",", 1), "x", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y", ",", 1), "x,y", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,", ",", 1), "x,y,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y", ",", 1), ",x,y", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,", ",", 1), ",x,y,", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z", ",", 1), "x,y,z", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z,", ",", 1), "x,y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z", ",", 1), ",x,y,z", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z,", ",", 1), ",x,y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 1), ",,x,,y,,z,,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,,y,,z,,", ",,", 1), ",,x,,y,,z,,", NULL)); + + TEST (NULL, strv_check (g_strsplit_set ("", ",", 2), NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x", ",", 2), "x", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y", ",", 2), "x", "y", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,", ",", 2), "x", "y,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y", ",", 2), "", "x,y", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,", ",", 2), "", "x,y,", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z", ",", 2), "x", "y,z", NULL)); + TEST (NULL, strv_check (g_strsplit_set ("x,y,z,", ",", 2), "x", "y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z", ",", 2), "", "x,y,z", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",x,y,z,", ",", 2), "", "x,y,z,", NULL)); + TEST (NULL, strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 2), "", ",x,,y,,z,,", NULL)); + + TEST (NULL, strv_check (g_strsplit_set (",,x,.y,..z,,", ",.", 3), "", "", "x,.y,..z,,", NULL)); + + + #define TEST_IS(name) test_is_function (#name, call_g_ascii_##name, call_##name, g_unichar_##name); FOR_ALL_CTYPE(TEST_IS)