gnucash maint: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Fri Aug 6 07:31:01 EDT 2021


Updated	 via  https://github.com/Gnucash/gnucash/commit/bedc85af (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0420ae6a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/67bd5135 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/17953441 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5698b67b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/09e2e761 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/bebc366e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e6c33a39 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d2db4301 (commit)
	from  https://github.com/Gnucash/gnucash/commit/f0926d66 (commit)



commit bedc85afa3671b7e7a0ee2f657a89f54794371d4
Merge: f0926d66c 0420ae6a6
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 19:30:01 2021 +0800

    Merge branch 'maint-leaks' into maint #1101


commit 0420ae6a6607f32ba348dafbf57af93db9782561
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 08:01:06 2021 +0800

    [account.cpp] refactor gnc_account_list_name_violations

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index c66657b23..78755e38d 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -262,34 +262,29 @@ gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invali
     return message;
 }
 
-GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)
+struct ViolationData
 {
-    Account *root_account = gnc_book_get_root_account(book);
-    GList   *accounts, *node;
-    GList   *invalid_list = NULL;
-
-    g_return_val_if_fail (separator != NULL, NULL);
-
-    if (root_account == NULL)
-        return NULL;
-
-    accounts = gnc_account_get_descendants (root_account);
-    for (node = accounts; node; node = g_list_next(node))
-    {
-        Account *acct      = (Account*)node->data;
-        gchar   *acct_name = g_strdup ( xaccAccountGetName ( acct ) );
+    GList *list;
+    const gchar *separator;
+};
 
-        if ( g_strstr_len ( acct_name, -1, separator ) )
-            invalid_list = g_list_prepend ( invalid_list, (gpointer) acct_name );
-        else
-            g_free ( acct_name );
-    }
-    if (accounts != NULL)
-    {
-        g_list_free(accounts);
-    }
+static void
+check_acct_name (Account *acct, gpointer user_data)
+{
+    auto cb {static_cast<ViolationData*>(user_data)};
+    auto name {xaccAccountGetName (acct)};
+    if (g_strstr_len (name, -1, cb->separator))
+        cb->list = g_list_prepend (cb->list, g_strdup (name));
+}
 
-    return invalid_list;
+GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)
+{
+    g_return_val_if_fail (separator != NULL, nullptr);
+    if (!book) return nullptr;
+    ViolationData cb = { nullptr, separator };
+    gnc_account_foreach_descendant (gnc_book_get_root_account (book),
+                                    (AccountCb)check_acct_name, &cb);
+    return cb.list;
 }
 
 /********************************************************************\

commit 67bd513514b1490a9521b520e812a5d3f243185b
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 00:23:02 2021 +0800

    [account.cpp] rewrite gnc_account_foreach_descendant_until in C++

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index d3a64f5a8..c66657b23 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3153,28 +3153,24 @@ gnc_account_foreach_descendant_until (const Account *acc,
                                       AccountCb2 thunk,
                                       gpointer user_data)
 {
-    const AccountPrivate *priv;
-    GList *node;
-    Account *child;
-    gpointer result;
+    gpointer result {nullptr};
 
-    g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
-    g_return_val_if_fail(thunk, NULL);
+    g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr);
+    g_return_val_if_fail (thunk, nullptr);
 
-    priv = GET_PRIVATE(acc);
-    for (node = priv->children; node; node = node->next)
+    auto priv{GET_PRIVATE(acc)};
+
+    for (auto node = priv->children; node; node = node->next)
     {
-        child = static_cast<Account*>(node->data);
-        result = thunk(child, user_data);
-        if (result)
-            return(result);
-
-        result = gnc_account_foreach_descendant_until(child, thunk, user_data);
-        if (result)
-            return(result);
+        auto child = static_cast<Account*>(node->data);
+        result = thunk (child, user_data);
+        if (result) break;
+
+        result = gnc_account_foreach_descendant_until (child, thunk, user_data);
+        if (result) break;
     }
 
-    return NULL;
+    return result;
 }
 
 

commit 17953441cba7ee73b2e794c9e46affd5a2955a27
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 00:22:49 2021 +0800

    [account.cpp] refactor gnc_account_foreach_descendant

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 5dd157041..d3a64f5a8 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2695,7 +2695,6 @@ static void
 account_foreach_descendant (const Account *acc, AccountCb thunk,
                             void* user_data, bool sort)
 {
-    gpointer result = nullptr;
     GList *children;
 
     g_return_if_fail (GNC_IS_ACCOUNT(acc));
@@ -3146,20 +3145,7 @@ gnc_account_foreach_descendant (const Account *acc,
                                 AccountCb thunk,
                                 gpointer user_data)
 {
-    const AccountPrivate *priv;
-    GList *node;
-    Account *child;
-
-    g_return_if_fail(GNC_IS_ACCOUNT(acc));
-    g_return_if_fail(thunk);
-
-    priv = GET_PRIVATE(acc);
-    for (node = priv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        thunk(child, user_data);
-        gnc_account_foreach_descendant(child, thunk, user_data);
-    }
+    account_foreach_descendant (acc, thunk, user_data, FALSE);
 }
 
 gpointer

commit 5698b67bf563ec6ed6f0016a9edbd65af932ed50
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:08:21 2021 +0800

    [account.cpp] refactor gnc_account_lookup_by_code

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 9ac2a8b78..5dd157041 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2985,37 +2985,17 @@ gnc_account_lookup_by_name (const Account *parent, const char * name)
     return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_name, (char*)name);
 }
 
+static gpointer
+is_acct_code (Account *account, gpointer user_data)
+{
+    auto name {static_cast<gchar*>(user_data)};
+    return (g_strcmp0 (name, xaccAccountGetCode (account)) ? nullptr : account);
+}
+
 Account *
 gnc_account_lookup_by_code (const Account *parent, const char * code)
 {
-    AccountPrivate *cpriv, *ppriv;
-    Account *child, *result;
-    GList *node;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
-    g_return_val_if_fail(code, NULL);
-
-    /* first, look for accounts hanging off the current node */
-    ppriv = GET_PRIVATE(parent);
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        cpriv = GET_PRIVATE(child);
-        if (g_strcmp0(cpriv->accountCode, code) == 0)
-            return child;
-    }
-
-    /* if we are still here, then we haven't found the account yet.
-     * Recursively search each of the child accounts next */
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        result = gnc_account_lookup_by_code (child, code);
-        if (result)
-            return result;
-    }
-
-    return NULL;
+    return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_code, (char*)code);
 }
 
 static gpointer

commit 09e2e7613c47943c9f333445d75484d9744a6376
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:08:11 2021 +0800

    [account.cpp] refactor gnc_account_lookup_by_name

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 215de9751..9ac2a8b78 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2972,37 +2972,17 @@ gnc_account_get_descendants_sorted (const Account *account)
     return g_list_reverse (list);
 }
 
+static gpointer
+is_acct_name (Account *account, gpointer user_data)
+{
+    auto name {static_cast<gchar*>(user_data)};
+    return (g_strcmp0 (name, xaccAccountGetName (account)) ? nullptr : account);
+}
+
 Account *
 gnc_account_lookup_by_name (const Account *parent, const char * name)
 {
-    AccountPrivate *cpriv, *ppriv;
-    Account *child, *result;
-    GList *node;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
-    g_return_val_if_fail(name, NULL);
-
-    /* first, look for accounts hanging off the current node */
-    ppriv = GET_PRIVATE(parent);
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        cpriv = GET_PRIVATE(child);
-        if (g_strcmp0(cpriv->accountName, name) == 0)
-            return child;
-    }
-
-    /* if we are still here, then we haven't found the account yet.
-     * Recursively search each of the child accounts next */
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        result = gnc_account_lookup_by_name (child, name);
-        if (result)
-            return result;
-    }
-
-    return NULL;
+    return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_name, (char*)name);
 }
 
 Account *

commit bebc366e88344b5e226538d79908244900e19878
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:07:18 2021 +0800

    [account.cpp] refactor gnc_account_n_descendants

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index b74ca5242..215de9751 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2894,20 +2894,18 @@ gnc_account_nth_child (const Account *parent, gint num)
     return static_cast<Account*>(g_list_nth_data(GET_PRIVATE(parent)->children, num));
 }
 
+static void
+count_acct (Account *account, gpointer user_data)
+{
+    auto count {static_cast<int*>(user_data)};
+    ++*count;
+}
+
 gint
 gnc_account_n_descendants (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *node;
-    gint count = 0;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
-
-    priv = GET_PRIVATE(account);
-    for (node = priv->children; node; node = g_list_next(node))
-    {
-        count += gnc_account_n_descendants(static_cast<Account*>(node->data)) + 1;
-    }
+    int count {0};
+    account_foreach_descendant (account, count_acct, &count, FALSE);
     return count;
 }
 

commit e6c33a39bc7ead9ea0d687efd4439f1c2913ff22
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:04:55 2021 +0800

    [account.cpp] refactor gnc_account_get_descendants{_sorted}

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 85a3ce909..b74ca5242 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2951,52 +2951,27 @@ gnc_account_get_tree_depth (const Account *account)
     return depth + 1;
 }
 
+static void
+collect_acct (Account *account, gpointer user_data)
+{
+    auto listptr{static_cast<GList**>(user_data)};
+    *listptr = g_list_prepend (*listptr, account);
+}
+
 GList *
 gnc_account_get_descendants (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *child, *descendants;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
-
-    priv = GET_PRIVATE(account);
-    if (!priv->children)
-        return NULL;
-
-    descendants = NULL;
-    for (child = priv->children; child; child = g_list_next(child))
-    {
-        descendants = g_list_append(descendants, child->data);
-        descendants = g_list_concat(descendants,
-                gnc_account_get_descendants(static_cast<Account const *>(child->data)));
-    }
-    return descendants;
+    GList* list = nullptr;
+    account_foreach_descendant (account, collect_acct, &list, FALSE);
+    return g_list_reverse (list);
 }
 
 GList *
 gnc_account_get_descendants_sorted (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *child, *children, *descendants;
-
-    /* errors */
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
-
-    /* optimizations */
-    priv = GET_PRIVATE(account);
-    if (!priv->children)
-        return NULL;
-
-    descendants = NULL;
-    children = g_list_sort(g_list_copy(priv->children), (GCompareFunc)xaccAccountOrder);
-    for (child = children; child; child = g_list_next(child))
-    {
-        descendants = g_list_append(descendants, child->data);
-        descendants = g_list_concat(descendants,
-                gnc_account_get_descendants_sorted(static_cast<Account const *>(child->data)));
-    }
-    g_list_free(children);
-    return descendants;
+    GList* list = nullptr;
+    account_foreach_descendant (account, collect_acct, &list, TRUE);
+    return g_list_reverse (list);
 }
 
 Account *

commit d2db43019c0be28f95233aaa7a5e97f80a1f96f8
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:02:12 2021 +0800

    [account.cpp] internal function account_foreach_descendant
    
    fast and efficient

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 8f12f0c64..85a3ce909 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2691,6 +2691,36 @@ DxaccAccountSetCurrency (Account * acc, gnc_commodity * currency)
 /********************************************************************\
 \********************************************************************/
 
+static void
+account_foreach_descendant (const Account *acc, AccountCb thunk,
+                            void* user_data, bool sort)
+{
+    gpointer result = nullptr;
+    GList *children;
+
+    g_return_if_fail (GNC_IS_ACCOUNT(acc));
+    g_return_if_fail (thunk);
+
+    auto priv{GET_PRIVATE(acc)};
+    if (sort)
+    {
+        children = g_list_copy (priv->children);
+        children = g_list_sort (children, (GCompareFunc)xaccAccountOrder);
+    }
+    else
+        children = priv->children;
+
+    for (auto node = children; node; node = node->next)
+    {
+        auto child = static_cast<Account*>(node->data);
+        thunk (child, user_data);
+        account_foreach_descendant (child, thunk, user_data, sort);
+    }
+
+    if (sort)
+        g_list_free (children);
+}
+
 void
 gnc_account_append_child (Account *new_parent, Account *child)
 {



Summary of changes:
 libgnucash/engine/Account.cpp | 258 ++++++++++++++++--------------------------
 1 file changed, 99 insertions(+), 159 deletions(-)



More information about the gnucash-changes mailing list