mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
[gnc-glib-utils] gnc_g_list_stringjoin to join a GList of strings
It traverses the GList twice (once to calculate the length) but allocates only once. Includes snippet from https://www.joelonsoftware.com/2001/12/11/back-to-basics/
This commit is contained in:
parent
b1c1272f35
commit
e84549926b
@ -327,3 +327,35 @@ void gnc_gpid_kill(GPid pid)
|
||||
}
|
||||
#endif /* G_OS_WIN32 */
|
||||
}
|
||||
|
||||
static inline char*
|
||||
gnc_strcat (char* dest, const char* src)
|
||||
{
|
||||
while (*dest) dest++;
|
||||
while ((*dest++ = *src++));
|
||||
return --dest;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep)
|
||||
{
|
||||
gint seplen = sep ? strlen(sep) : 0;
|
||||
gint length = -seplen;
|
||||
gchar *retval, *p;
|
||||
|
||||
if (!list_of_strings)
|
||||
return NULL;
|
||||
|
||||
for (GList *n = list_of_strings; n; n = n->next)
|
||||
length += strlen ((gchar*)n->data) + seplen;
|
||||
|
||||
p = retval = (gchar*) g_malloc0 (length * sizeof (gchar) + 1);
|
||||
for (GList *n = list_of_strings; n; n = n->next)
|
||||
{
|
||||
p = gnc_strcat (p, (gchar*)n->data);
|
||||
if (n->next && sep)
|
||||
p = gnc_strcat (p, sep);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -183,6 +183,22 @@ void gnc_scm_log_debug(const gchar *msg);
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return a string joining a GList whose elements are gchar*
|
||||
* strings. Returns NULL if an empty GList* is passed through. The
|
||||
* optional sep string will be used as separator. Must be g_freed when
|
||||
* not needed anymore.
|
||||
*
|
||||
* @param list_of_strings A GList of chars*
|
||||
*
|
||||
* @param sep a separator or NULL
|
||||
*
|
||||
* @return A newly allocated string that has to be g_free'd by the
|
||||
* caller.
|
||||
**/
|
||||
gchar * gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep);
|
||||
|
||||
/** Kill a process. On UNIX send a SIGKILL, on Windows call TerminateProcess.
|
||||
*
|
||||
* @param pid The process ID. */
|
||||
|
@ -53,6 +53,62 @@ test_gnc_utf8_strip_invalid_and_controls (gconstpointer data)
|
||||
g_free (msg1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_g_list_stringjoin (gconstpointer data)
|
||||
{
|
||||
GList *test = NULL;
|
||||
gchar *ret;
|
||||
|
||||
ret = gnc_g_list_stringjoin (NULL, NULL);
|
||||
g_assert (ret == NULL);
|
||||
|
||||
ret = gnc_g_list_stringjoin (NULL, ":");
|
||||
g_assert (ret == NULL);
|
||||
|
||||
test = g_list_prepend (test, "one");
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, NULL);
|
||||
g_assert_cmpstr (ret, ==, "one");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, "");
|
||||
g_assert_cmpstr (ret, ==, "one");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, ":");
|
||||
g_assert_cmpstr (ret, ==, "one");
|
||||
g_free (ret);
|
||||
|
||||
test = g_list_prepend (test, "two");
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, NULL);
|
||||
g_assert_cmpstr (ret, ==, "twoone");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, "");
|
||||
g_assert_cmpstr (ret, ==, "twoone");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, ":");
|
||||
g_assert_cmpstr (ret, ==, "two:one");
|
||||
g_free (ret);
|
||||
|
||||
test = g_list_prepend (test, "three");
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, NULL);
|
||||
g_assert_cmpstr (ret, ==, "threetwoone");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, "");
|
||||
g_assert_cmpstr (ret, ==, "threetwoone");
|
||||
g_free (ret);
|
||||
|
||||
ret = gnc_g_list_stringjoin (test, ":");
|
||||
g_assert_cmpstr (ret, ==, "three:two:one");
|
||||
g_free (ret);
|
||||
|
||||
g_list_free (test);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
@ -62,6 +118,7 @@ main (int argc, char *argv[])
|
||||
g_test_init (&argc, &argv, NULL); // initialize test program
|
||||
g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls invalid utf8", (gconstpointer)invalid_utf8, test_gnc_utf8_strip_invalid_and_controls);
|
||||
g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls control chars", (gconstpointer)controls, test_gnc_utf8_strip_invalid_and_controls);
|
||||
g_test_add_data_func ("/core-utils/gnc_g_list_stringjoin", NULL, test_g_list_stringjoin);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user