gnucash maint: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Thu Aug 12 05:40:10 EDT 2021
Updated via https://github.com/Gnucash/gnucash/commit/5ced0d93 (commit)
via https://github.com/Gnucash/gnucash/commit/40d886fa (commit)
via https://github.com/Gnucash/gnucash/commit/4c37f6d4 (commit)
via https://github.com/Gnucash/gnucash/commit/e8454992 (commit)
from https://github.com/Gnucash/gnucash/commit/fa666e73 (commit)
commit 5ced0d932a942526ef962f0748614c52cade1ac7
Merge: fa666e736 40d886fa9
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Thu Aug 12 17:39:45 2021 +0800
Merge branch 'maint-account-cpp' into maint #1107
commit 40d886fa9d54d556efbd6f150fd82a5a92d48fd1
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Wed Aug 11 09:28:26 2021 +0800
gnc_account_list_name_violations elements must be freed
diff --git a/gnucash/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c
index 2e374bdea..62d40ddcd 100644
--- a/gnucash/gnome-utils/dialog-preferences.c
+++ b/gnucash/gnome-utils/dialog-preferences.c
@@ -132,7 +132,7 @@ static gchar *gnc_account_separator_is_valid (const gchar *separator,
message = gnc_account_name_violations_errmsg (*normalized_separator,
conflict_accts);
- g_list_free (conflict_accts);
+ g_list_free_full (conflict_accts, g_free);
return message;
}
diff --git a/gnucash/gnome-utils/gnc-file.c b/gnucash/gnome-utils/gnc-file.c
index d76698e59..677125c1e 100644
--- a/gnucash/gnome-utils/gnc-file.c
+++ b/gnucash/gnome-utils/gnc-file.c
@@ -1101,6 +1101,7 @@ RESTART:
invalid_account_names );
gnc_warning_dialog(parent, "%s", message);
g_free ( message );
+ g_list_free_full (invalid_account_names, g_free);
}
// Fix account color slots being set to 'Not Set', should run once on a book
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index 910d96fdf..72f525a03 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -283,8 +283,8 @@ gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invali
* @param book Pointer to the book with accounts to verify
* @param separator The separator character to verify against
*
- * @return A GList of invalid account names. Should be freed with g_list_free
- * if no longer needed.
+ * @return A GList of invalid account names. Should be freed with
+ * g_list_free_full (value, g_free) when no longer needed.
*/
GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator);
commit 4c37f6d4ef1de455dd24839ab4a126c6f71c6c70
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Wed Aug 11 09:28:22 2021 +0800
[account.cpp] gnc_g_list_stringjoin instead of repeated allocations
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 78755e38d..ba0942758 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -227,26 +227,12 @@ gnc_set_account_separator (const gchar *separator)
gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invalid_account_names)
{
- GList *node;
gchar *message = NULL;
- gchar *account_list = NULL;
if ( !invalid_account_names )
return NULL;
- for ( node = invalid_account_names; node; node = g_list_next(node))
- {
- if ( !account_list )
- account_list = static_cast<gchar *>(node->data);
- else
- {
- gchar *tmp_list = NULL;
-
- tmp_list = g_strconcat (account_list, "\n", node->data, nullptr);
- g_free ( account_list );
- account_list = tmp_list;
- }
- }
+ auto account_list {gnc_g_list_stringjoin (invalid_account_names, "\n")};
/* Translators: The first %s will be the account separator character,
the second %s is a list of account names.
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index b54163cd0..8deea5fcf 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -29,6 +29,7 @@ extern "C"
#include <gnc-event.h>
#include <gnc-date.h>
/* Add specific headers for this class */
+#include "gnc-glib-utils.h"
#include "../Account.h"
#include "../AccountP.h"
#include "../Split.h"
@@ -429,24 +430,12 @@ test_gnc_account_name_violations_errmsg ()
{
GList *badnames = NULL, *nonames = NULL, *node = NULL;
auto separator = ":";
- char *account_list = NULL;
/* FUT wants to free the strings, so we alloc them */
badnames = g_list_prepend (badnames, g_strdup ("Foo:bar"));
badnames = g_list_prepend (badnames, g_strdup ("baz"));
badnames = g_list_prepend (badnames, g_strdup ("waldo:pepper"));
auto message = gnc_account_name_violations_errmsg (separator, nonames);
- for (node = badnames; node; node = g_list_next (node))
- {
- if (!account_list)
- account_list = g_strdup (static_cast<char*>(node->data));
- else
- {
- auto tmp_list = g_strconcat ( account_list, "\n",
- static_cast<char*>(node->data), NULL);
- g_free (account_list);
- account_list = tmp_list;
- }
- }
+ auto account_list = gnc_g_list_stringjoin (badnames, "\n");
message = gnc_account_name_violations_errmsg (separator, nonames);
g_assert (message == NULL);
auto validation_message = g_strdup_printf (
@@ -455,6 +444,7 @@ test_gnc_account_name_violations_errmsg ()
"Either change the account names or choose another separator "
"character.\n\nBelow you will find the list of invalid account names:\n"
"%s", separator, account_list);
+ g_free (account_list);
message = gnc_account_name_violations_errmsg (separator, badnames);
g_assert_cmpstr ( message, == , validation_message);
g_free (validation_message);
commit e84549926bbeaf6f19428f1aeac1b96eeb860b6e
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Tue Aug 10 12:55:47 2021 +0800
[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/
diff --git a/libgnucash/core-utils/gnc-glib-utils.c b/libgnucash/core-utils/gnc-glib-utils.c
index b45292151..c15e1dd8d 100644
--- a/libgnucash/core-utils/gnc-glib-utils.c
+++ b/libgnucash/core-utils/gnc-glib-utils.c
@@ -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;
+}
diff --git a/libgnucash/core-utils/gnc-glib-utils.h b/libgnucash/core-utils/gnc-glib-utils.h
index 7f1d1dd2e..97e36c53d 100644
--- a/libgnucash/core-utils/gnc-glib-utils.h
+++ b/libgnucash/core-utils/gnc-glib-utils.h
@@ -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. */
diff --git a/libgnucash/core-utils/test/test-gnc-glib-utils.c b/libgnucash/core-utils/test/test-gnc-glib-utils.c
index 390d6b0fa..e4423baaa 100644
--- a/libgnucash/core-utils/test/test-gnc-glib-utils.c
+++ b/libgnucash/core-utils/test/test-gnc-glib-utils.c
@@ -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();
}
Summary of changes:
gnucash/gnome-utils/dialog-preferences.c | 2 +-
gnucash/gnome-utils/gnc-file.c | 1 +
libgnucash/core-utils/gnc-glib-utils.c | 32 +++++++++++++
libgnucash/core-utils/gnc-glib-utils.h | 16 +++++++
libgnucash/core-utils/test/test-gnc-glib-utils.c | 57 ++++++++++++++++++++++++
libgnucash/engine/Account.cpp | 16 +------
libgnucash/engine/Account.h | 4 +-
libgnucash/engine/test/utest-Account.cpp | 16 ++-----
8 files changed, 113 insertions(+), 31 deletions(-)
More information about the gnucash-changes
mailing list