use gnc_account_get_all_parents and std::mismatch

This commit is contained in:
Christopher Lam 2025-01-19 22:32:57 +08:00
parent a2d7868dce
commit f6c73b15fb
2 changed files with 29 additions and 42 deletions

View File

@ -3254,12 +3254,6 @@ gnc_account_get_all_parents (const Account *account)
gchar * gchar *
gnc_account_get_full_name(const Account *account) 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 /* 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. */ * bother to check if they have a non-nullptr pointer before calling. */
if (nullptr == account) if (nullptr == account)
@ -3268,35 +3262,24 @@ gnc_account_get_full_name(const Account *account)
/* errors */ /* errors */
g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup("")); g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(""));
/* optimizations */ auto path{gnc_account_get_all_parents (account)};
priv = GET_PRIVATE(account); auto seps_size{path.empty() ? 0 : strlen (account_separator) * (path.size() - 1)};
if (!priv->parent) auto alloc_size{std::accumulate (path.begin(), path.end(), seps_size,
return g_strdup(""); [](auto sum, auto acc)
{ return sum + strlen (xaccAccountGetName (acc)); })};
auto rv = g_new (char, alloc_size + 1);
auto p = rv;
/* Figure out how much space is needed by counting the nodes up to std::for_each (path.rbegin(), path.rend(),
* the root. */ [&p, rv](auto a)
level = 0; {
for (a = account; a; a = priv->parent) if (p != rv)
{ p = stpcpy (p, account_separator);
priv = GET_PRIVATE(a); p = stpcpy (p, xaccAccountGetName (a));
level++; });
} *p = '\0';
/* Get all the pointers in the right order. The root node "entry" return rv;
* 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;
} }
const char * const char *

View File

@ -48,6 +48,7 @@
#include "qofbook.h" #include "qofbook.h"
#include "Split.h" #include "Split.h"
#include "AccountP.hpp" #include "AccountP.hpp"
#include "Account.hpp"
#include "Scrub.h" #include "Scrub.h"
#include "TransactionP.hpp" #include "TransactionP.hpp"
#include "TransLog.h" #include "TransLog.h"
@ -1653,20 +1654,23 @@ int
xaccSplitCompareAccountFullNames(const Split *sa, const Split *sb) xaccSplitCompareAccountFullNames(const Split *sa, const Split *sb)
{ {
Account *aa, *ab; Account *aa, *ab;
char *full_a, *full_b; if (sa == sb) return 0;
int retval;
if (!sa && !sb) return 0;
if (!sa) return -1; if (!sa) return -1;
if (!sb) return 1; if (!sb) return 1;
aa = sa->acc; aa = sa->acc;
ab = sb->acc; ab = sb->acc;
full_a = gnc_account_get_full_name(aa); if (aa == ab) return 0;
full_b = gnc_account_get_full_name(ab);
retval = g_utf8_collate(full_a, full_b); auto path_a = gnc_account_get_all_parents (aa);
g_free(full_a); auto path_b = gnc_account_get_all_parents (ab);
g_free(full_b); auto mismatch_pair = std::mismatch (path_a.rbegin(), path_a.rend(),
return retval; 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));
} }