gnucash stable: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Sun Jan 19 19:50:15 EST 2025


Updated	 via  https://github.com/Gnucash/gnucash/commit/f6c73b15 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a2d7868d (commit)
	from  https://github.com/Gnucash/gnucash/commit/7a17d329 (commit)



commit f6c73b15fb6896b91bbbf1845cee41d7077ee5b3
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Jan 19 22:32:57 2025 +0800

    use gnc_account_get_all_parents and std::mismatch

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 241bdcf9d7..c3bc18f7fc 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3254,12 +3254,6 @@ gnc_account_get_all_parents (const Account *account)
 gchar *
 gnc_account_get_full_name(const Account *account)
 {
-    AccountPrivate *priv;
-    const Account *a;
-    char *fullname;
-    const gchar **names;
-    int level;
-
     /* So much for hardening the API. Too many callers to this function don't
      * bother to check if they have a non-nullptr pointer before calling. */
     if (nullptr == account)
@@ -3268,35 +3262,24 @@ gnc_account_get_full_name(const Account *account)
     /* errors */
     g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(""));
 
-    /* optimizations */
-    priv = GET_PRIVATE(account);
-    if (!priv->parent)
-        return g_strdup("");
+    auto path{gnc_account_get_all_parents (account)};
+    auto seps_size{path.empty() ? 0 : strlen (account_separator) * (path.size() - 1)};
+    auto alloc_size{std::accumulate (path.begin(), path.end(), seps_size,
+                                     [](auto sum, auto acc)
+                                     { return sum + strlen (xaccAccountGetName (acc)); })};
+    auto rv = g_new (char, alloc_size + 1);
+    auto p = rv;
+
+    std::for_each (path.rbegin(), path.rend(),
+                   [&p, rv](auto a)
+                   {
+                       if (p != rv)
+                           p = stpcpy (p, account_separator);
+                       p = stpcpy (p, xaccAccountGetName (a));
+                   });
+    *p = '\0';
 
-    /* Figure out how much space is needed by counting the nodes up to
-     * the root. */
-    level = 0;
-    for (a = account; a; a = priv->parent)
-    {
-        priv = GET_PRIVATE(a);
-        level++;
-    }
-
-    /* Get all the pointers in the right order. The root node "entry"
-     * becomes the terminating nullptr pointer for the array of strings. */
-    names = (const gchar **)g_malloc(level * sizeof(gchar *));
-    names[--level] = nullptr;
-    for (a = account; level > 0; a = priv->parent)
-    {
-        priv = GET_PRIVATE(a);
-        names[--level] = priv->accountName;
-    }
-
-    /* Build the full name */
-    fullname = g_strjoinv(account_separator, (gchar **)names);
-    g_free(names);
-
-    return fullname;
+    return rv;
 }
 
 const char *
diff --git a/libgnucash/engine/Split.cpp b/libgnucash/engine/Split.cpp
index d1b5c37365..64d982214e 100644
--- a/libgnucash/engine/Split.cpp
+++ b/libgnucash/engine/Split.cpp
@@ -48,6 +48,7 @@
 #include "qofbook.h"
 #include "Split.h"
 #include "AccountP.hpp"
+#include "Account.hpp"
 #include "Scrub.h"
 #include "TransactionP.hpp"
 #include "TransLog.h"
@@ -1653,20 +1654,23 @@ int
 xaccSplitCompareAccountFullNames(const Split *sa, const Split *sb)
 {
     Account *aa, *ab;
-    char *full_a, *full_b;
-    int retval;
-    if (!sa && !sb) return 0;
+    if (sa == sb) return 0;
     if (!sa) return -1;
     if (!sb) return 1;
 
     aa = sa->acc;
     ab = sb->acc;
-    full_a = gnc_account_get_full_name(aa);
-    full_b = gnc_account_get_full_name(ab);
-    retval = g_utf8_collate(full_a, full_b);
-    g_free(full_a);
-    g_free(full_b);
-    return retval;
+    if (aa == ab) return 0;
+
+    auto path_a = gnc_account_get_all_parents (aa);
+    auto path_b = gnc_account_get_all_parents (ab);
+    auto mismatch_pair = std::mismatch (path_a.rbegin(), path_a.rend(),
+                                        path_b.rbegin(), path_b.rend());
+
+    return mismatch_pair.first == path_a.rend() ? -1
+        : mismatch_pair.second == path_b.rend() ? 1
+        : g_utf8_collate (xaccAccountGetName (*mismatch_pair.first),
+                          xaccAccountGetName (*mismatch_pair.second));
 }
 
 

commit a2d7868dce592e59b3bd20939ac0bb143134673d
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Jan 19 22:32:27 2025 +0800

    [Account.hpp] gnc_account_get_all_parents returns reversed path vector

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index afcb769799..241bdcf9d7 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3242,6 +3242,15 @@ xaccAccountGetName (const Account *acc)
     return GET_PRIVATE(acc)->accountName;
 }
 
+std::vector<const Account*>
+gnc_account_get_all_parents (const Account *account)
+{
+    std::vector<const Account*> rv;
+    for (auto a = account; !gnc_account_is_root (a); a = gnc_account_get_parent (a))
+        rv.push_back (a);
+    return rv;
+}
+
 gchar *
 gnc_account_get_full_name(const Account *account)
 {
diff --git a/libgnucash/engine/Account.hpp b/libgnucash/engine/Account.hpp
index 89649acfc4..598cd0a5df 100644
--- a/libgnucash/engine/Account.hpp
+++ b/libgnucash/engine/Account.hpp
@@ -61,6 +61,8 @@ void gnc_account_foreach_split_until_date (const Account *acc, time64 end_date,
  *  @result Split* or nullptr if not found */
 Split* gnc_account_find_split (const Account*, std::function<bool(const Split*)>, bool);
 
+std::vector<const Account*> gnc_account_get_all_parents (const Account *account);
+
 #endif /* GNC_COMMODITY_HPP */
 /** @} */
 /** @} */



Summary of changes:
 libgnucash/engine/Account.cpp | 62 +++++++++++++++++++------------------------
 libgnucash/engine/Account.hpp |  2 ++
 libgnucash/engine/Split.cpp   | 22 ++++++++-------
 3 files changed, 42 insertions(+), 44 deletions(-)



More information about the gnucash-changes mailing list