gnucash maint: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Wed Aug 4 18:55:01 EDT 2021
Updated via https://github.com/Gnucash/gnucash/commit/d099d39a (commit)
via https://github.com/Gnucash/gnucash/commit/fd56512c (commit)
via https://github.com/Gnucash/gnucash/commit/9062be3d (commit)
via https://github.com/Gnucash/gnucash/commit/f6766d42 (commit)
via https://github.com/Gnucash/gnucash/commit/ddc423a5 (commit)
via https://github.com/Gnucash/gnucash/commit/621704eb (commit)
via https://github.com/Gnucash/gnucash/commit/4a5b5f3b (commit)
via https://github.com/Gnucash/gnucash/commit/320df7e4 (commit)
via https://github.com/Gnucash/gnucash/commit/41329396 (commit)
via https://github.com/Gnucash/gnucash/commit/bf8fe112 (commit)
via https://github.com/Gnucash/gnucash/commit/f15402a9 (commit)
from https://github.com/Gnucash/gnucash/commit/79d6154c (commit)
commit d099d39afd36b672a55956c34d105d940b6ea9af
Merge: fd56512cf bf8fe1123
Author: John Ralls <jralls at ceridwen.us>
Date: Wed Aug 4 15:52:51 2021 -0700
Merge Simon Arlott's 'commit-root-on-load' into maint.
commit fd56512cf77ad14520d7e27f8b63c13b9b023ec6
Merge: 9062be3d4 f15402a9a
Author: John Ralls <jralls at ceridwen.us>
Date: Wed Aug 4 15:48:42 2021 -0700
Merge Simon Arlott's 'load-test-xml' into maint.
commit 9062be3d47d669bbacf2ac4475b5243ddf416e3f
Merge: f6766d42e 413293961
Author: John Ralls <jralls at ceridwen.us>
Date: Wed Aug 4 14:26:27 2021 -0700
Merge Simon Arlott's 'string-cache-fixes' into maint.
commit f6766d42ece18f11e9c6ba817325a007b50cc14c
Merge: ddc423a50 4a5b5f3bf
Author: John Ralls <jralls at ceridwen.us>
Date: Wed Aug 4 14:19:21 2021 -0700
Merge Simon Arlott's 'string-cache-no-refcount-empty' into maint.
commit ddc423a5054f535ee56bae11a54dbb8c9a38c11b
Merge: 79d6154cb 621704ebe
Author: John Ralls <jralls at ceridwen.us>
Date: Wed Aug 4 14:18:16 2021 -0700
Merge Simon Arlott's 'bug-798238' into maint.
commit 621704ebeb2d182be6784ea6602c6fbd3f3b67ce
Author: Simon Arlott <sa.me.uk>
Date: Mon Jul 12 19:23:56 2021 +0100
Bug 798238 - "New security" dialog doesn't save the "Display symbol"
When creating a new commodity the display symbol isn't saved so it defaults
to one of the other values as appropriate.
After creating the new commodity (without providing a user symbol), set
the user symbol.
diff --git a/gnucash/gnome-utils/dialog-commodity.c b/gnucash/gnome-utils/dialog-commodity.c
index b1a50e6a5..7e9f8a86b 100644
--- a/gnucash/gnome-utils/dialog-commodity.c
+++ b/gnucash/gnome-utils/dialog-commodity.c
@@ -1301,6 +1301,8 @@ gnc_ui_commodity_dialog_to_object(CommodityWindow * w)
c = gnc_commodity_new(book, fullname, name_space, mnemonic, code, fraction);
w->edit_commodity = c;
gnc_commodity_begin_edit(c);
+
+ gnc_commodity_set_user_symbol(c, user_symbol);
}
else
{
commit 4a5b5f3bf2e7616c2da600ecf25bb470e5710c0c
Author: Simon Arlott <sa.me.uk>
Date: Thu Jul 8 20:43:02 2021 +0100
Don't cache the empty string
Avoid unnecessary reference counting for uses of the empty string.
diff --git a/libgnucash/engine/qof-string-cache.cpp b/libgnucash/engine/qof-string-cache.cpp
index 68e4fe479..eb236ebd0 100644
--- a/libgnucash/engine/qof-string-cache.cpp
+++ b/libgnucash/engine/qof-string-cache.cpp
@@ -84,7 +84,7 @@ qof_string_cache_destroy (void)
void
qof_string_cache_remove(const char * key)
{
- if (key)
+ if (key && key[0] != 0)
{
GHashTable* cache = qof_get_string_cache();
gpointer value;
@@ -111,6 +111,11 @@ qof_string_cache_insert(const char * key)
{
if (key)
{
+ if (key[0] == 0)
+ {
+ return "";
+ }
+
GHashTable* cache = qof_get_string_cache();
gpointer value;
gpointer cache_key;
commit 320df7e4096e504ca002b794064aace27007d06d
Author: Simon Arlott <sa.me.uk>
Date: Thu Jul 8 20:42:03 2021 +0100
Use const return values for string cache
This is a prerequisite for being able to return "" (which is const) and
none of the returned values should ever be modified.
diff --git a/gnucash/gnome-utils/gnc-component-manager.c b/gnucash/gnome-utils/gnc-component-manager.c
index 2d909dc37..b98bcc878 100644
--- a/gnucash/gnome-utils/gnc-component-manager.c
+++ b/gnucash/gnome-utils/gnc-component-manager.c
@@ -241,9 +241,9 @@ add_event_type (ComponentEventInfo *cei, QofIdTypeConst entity_type,
mask = g_hash_table_lookup (cei->event_masks, entity_type);
if (!mask)
{
- char * key = qof_string_cache_insert ((gpointer) entity_type);
+ const char * key = qof_string_cache_insert ((gpointer) entity_type);
mask = g_new0 (QofEventId, 1);
- g_hash_table_insert (cei->event_masks, key, mask);
+ g_hash_table_insert (cei->event_masks, (gpointer)key, mask);
}
if (or_in)
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 154ff1936..8f12f0c64 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -317,9 +317,9 @@ gnc_account_init(Account* acc)
priv->parent = NULL;
priv->children = NULL;
- priv->accountName = static_cast<char*>(qof_string_cache_insert(""));
- priv->accountCode = static_cast<char*>(qof_string_cache_insert(""));
- priv->description = static_cast<char*>(qof_string_cache_insert(""));
+ priv->accountName = qof_string_cache_insert("");
+ priv->accountCode = qof_string_cache_insert("");
+ priv->description = qof_string_cache_insert("");
priv->type = ACCT_TYPE_NONE;
@@ -1265,9 +1265,9 @@ xaccCloneAccount(const Account *from, QofBook *book)
* Also let caller issue the generate_event (EVENT_CREATE) */
priv->type = from_priv->type;
- priv->accountName = static_cast<char*>(qof_string_cache_insert(from_priv->accountName));
- priv->accountCode = static_cast<char*>(qof_string_cache_insert(from_priv->accountCode));
- priv->description = static_cast<char*>(qof_string_cache_insert(from_priv->description));
+ priv->accountName = qof_string_cache_replace(priv->accountName, from_priv->accountName);
+ priv->accountCode = qof_string_cache_replace(priv->accountCode, from_priv->accountCode);
+ priv->description = qof_string_cache_replace(priv->description, from_priv->description);
qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
@@ -2327,7 +2327,7 @@ int
xaccAccountOrder (const Account *aa, const Account *ab)
{
AccountPrivate *priv_aa, *priv_ab;
- char *da, *db;
+ const char *da, *db;
char *endptr = NULL;
int ta, tb, result;
long la, lb;
@@ -3264,7 +3264,7 @@ gnc_account_get_full_name(const Account *account)
AccountPrivate *priv;
const Account *a;
char *fullname;
- gchar **names;
+ const gchar **names;
int level;
/* So much for hardening the API. Too many callers to this function don't
@@ -3291,7 +3291,7 @@ gnc_account_get_full_name(const Account *account)
/* Get all the pointers in the right order. The root node "entry"
* becomes the terminating NULL pointer for the array of strings. */
- names = (gchar **)g_malloc(level * sizeof(gchar *));
+ names = (const gchar **)g_malloc(level * sizeof(gchar *));
names[--level] = NULL;
for (a = account; level > 0; a = priv->parent)
{
@@ -3300,7 +3300,7 @@ gnc_account_get_full_name(const Account *account)
}
/* Build the full name */
- fullname = g_strjoinv(account_separator, names);
+ fullname = g_strjoinv(account_separator, (gchar **)names);
g_free(names);
return fullname;
diff --git a/libgnucash/engine/AccountP.h b/libgnucash/engine/AccountP.h
index ea147aa83..746a1c504 100644
--- a/libgnucash/engine/AccountP.h
+++ b/libgnucash/engine/AccountP.h
@@ -62,7 +62,7 @@ typedef struct AccountPrivate
* It is intended to a short, 5 to 30 character long string that
* is displayed by the GUI as the account mnemonic.
*/
- char *accountName;
+ const char *accountName;
/* The accountCode is an arbitrary string assigned by the user.
* It is intended to be reporting code that is a synonym for the
@@ -71,13 +71,13 @@ typedef struct AccountPrivate
* as 100, 200 or 600 for top-level accounts, and 101, 102.. etc.
* for detail accounts.
*/
- char *accountCode;
+ const char *accountCode;
/* The description is an arbitrary string assigned by the user.
* It is intended to be a longer, 1-5 sentence description of what
* this account is all about.
*/
- char *description;
+ const char *description;
/* The type field is the account type, picked from the enumerated
* list that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK,
diff --git a/libgnucash/engine/Split.c b/libgnucash/engine/Split.c
index 8fb6091fa..1c9cf710d 100644
--- a/libgnucash/engine/Split.c
+++ b/libgnucash/engine/Split.c
@@ -1495,7 +1495,7 @@ xaccSplitOrder (const Split *sa, const Split *sb)
{
int retval;
int comp;
- char *da, *db;
+ const char *da, *db;
gboolean action_for_num;
if (sa == sb) return 0;
diff --git a/libgnucash/engine/SplitP.h b/libgnucash/engine/SplitP.h
index 8e6f41bb6..335db9174 100644
--- a/libgnucash/engine/SplitP.h
+++ b/libgnucash/engine/SplitP.h
@@ -83,7 +83,7 @@ struct split_s
* It is intended to hold a short (zero to forty character) string
* that is displayed by the GUI along with this split.
*/
- char * memo;
+ const char *memo;
/* The action field is an arbitrary user-assigned value.
* It is meant to be a very short (one to ten character) string that
@@ -91,10 +91,10 @@ struct split_s
* Withdraw, Deposit, ATM, Check, etc. The idea is that this field
* can be used to create custom reports or graphs of data.
*/
- char * action; /* Buy, Sell, Div, etc. */
+ const char *action; /* Buy, Sell, Div, etc. */
- time64 date_reconciled; /* date split was reconciled */
- char reconciled; /* The reconciled field */
+ time64 date_reconciled; /* date split was reconciled */
+ char reconciled; /* The reconciled field */
/* gains is a flag used to track the relationship between
* capital-gains splits. Depending on its value, this flag indicates
diff --git a/libgnucash/engine/Transaction.c b/libgnucash/engine/Transaction.c
index e7c3cba0a..986eb8fc3 100644
--- a/libgnucash/engine/Transaction.c
+++ b/libgnucash/engine/Transaction.c
@@ -1699,7 +1699,8 @@ xaccTransCommitEdit (Transaction *trans)
LEAVE ("(trans=%p)", trans);
}
-#define SWAP(a, b) do { gpointer tmp = (a); (a) = (b); (b) = tmp; } while (0);
+#define SWAP_STR(a, b) do { const char *tmp = (a); (a) = (b); (b) = tmp; } while (0);
+#define SWAP(a, b) do { gpointer tmp = (a); (a) = (b); (b) = tmp; } while (0);
/* Ughhh. The Rollback function is terribly complex, and, what's worse,
* it only rolls back the basics. The TransCommit functions did a bunch
@@ -1738,8 +1739,8 @@ xaccTransRollbackEdit (Transaction *trans)
/* copy the original values back in. */
orig = trans->orig;
- SWAP(trans->num, orig->num);
- SWAP(trans->description, orig->description);
+ SWAP_STR(trans->num, orig->num);
+ SWAP_STR(trans->description, orig->description);
trans->date_entered = orig->date_entered;
trans->date_posted = orig->date_posted;
SWAP(trans->common_currency, orig->common_currency);
@@ -1766,8 +1767,8 @@ xaccTransRollbackEdit (Transaction *trans)
Split *so = onode->data;
xaccSplitRollbackEdit(s);
- SWAP(s->action, so->action);
- SWAP(s->memo, so->memo);
+ SWAP_STR(s->action, so->action);
+ SWAP_STR(s->memo, so->memo);
qof_instance_copy_kvp (QOF_INSTANCE (s), QOF_INSTANCE (so));
s->reconciled = so->reconciled;
s->amount = so->amount;
@@ -1915,7 +1916,7 @@ int
xaccTransOrder_num_action (const Transaction *ta, const char *actna,
const Transaction *tb, const char *actnb)
{
- char *da, *db;
+ const char *da, *db;
int retval;
int64_t na, nb;
diff --git a/libgnucash/engine/TransactionP.h b/libgnucash/engine/TransactionP.h
index bbeef7cb0..c42f988c1 100644
--- a/libgnucash/engine/TransactionP.h
+++ b/libgnucash/engine/TransactionP.h
@@ -82,12 +82,12 @@ struct transaction_s
* It is intended to store a short id number, typically the check number,
* deposit number, invoice number or other tracking number.
*/
- char * num;
+ const char *num;
/* The description field is an arbitrary user-assigned value.
* It is meant to be a short descriptive phrase.
*/
- char * description;
+ const char *description;
/* The common_currency field is the balancing common currency for
* all the splits in the transaction. Alternate, better(?) name:
diff --git a/libgnucash/engine/gnc-budget.c b/libgnucash/engine/gnc-budget.c
index 7865e0bfc..dc67c389a 100644
--- a/libgnucash/engine/gnc-budget.c
+++ b/libgnucash/engine/gnc-budget.c
@@ -61,10 +61,10 @@ typedef struct
typedef struct GncBudgetPrivate
{
/* The name is an arbitrary string assigned by the user. */
- gchar* name;
+ const gchar *name;
/* The description is an arbitrary string assigned by the user. */
- gchar* description;
+ const gchar *description;
/* Recurrence (period info) for the budget */
Recurrence recurrence;
diff --git a/libgnucash/engine/gnc-commodity.c b/libgnucash/engine/gnc-commodity.c
index 23d5c7f3f..2d6998def 100644
--- a/libgnucash/engine/gnc-commodity.c
+++ b/libgnucash/engine/gnc-commodity.c
@@ -70,23 +70,23 @@ typedef struct gnc_commodityPrivate
{
gnc_commodity_namespace *name_space;
- char * fullname;
- char * mnemonic;
- char * printname;
- char * cusip; /* CUSIP or other identifying code */
- int fraction;
- char * unique_name;
+ const char *fullname;
+ const char *mnemonic;
+ char *printname;
+ const char *cusip; /* CUSIP or other identifying code */
+ int fraction;
+ char *unique_name;
- gboolean quote_flag; /* user wants price quotes */
- gnc_quote_source * quote_source; /* current/old source of quotes */
- char * quote_tz;
+ gboolean quote_flag; /* user wants price quotes */
+ gnc_quote_source *quote_source; /* current/old source of quotes */
+ const char *quote_tz;
/* the number of accounts using this commodity - this field is not
* persisted */
- int usage_count;
+ int usage_count;
/* the default display_symbol, set in iso-4217-currencies at start-up */
- const char * default_symbol;
+ const char *default_symbol;
} gnc_commodityPrivate;
#define GET_PRIVATE(o) \
@@ -104,7 +104,7 @@ struct gnc_commodity_namespace_s
{
QofInstance inst;
- gchar * name;
+ const gchar *name;
gboolean iso4217;
GHashTable * cm_table;
GList * cm_list;
@@ -1997,7 +1997,7 @@ gnc_commodity_table_insert(gnc_commodity_table * table,
PINFO ("insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic,
nsp->cm_table, nsp->name);
g_hash_table_insert(nsp->cm_table,
- CACHE_INSERT(priv->mnemonic),
+ (gpointer)CACHE_INSERT(priv->mnemonic),
(gpointer)comm);
nsp->cm_list = g_list_append(nsp->cm_list, comm);
diff --git a/libgnucash/engine/gnc-pricedb-p.h b/libgnucash/engine/gnc-pricedb-p.h
index 84ea6df73..49eaefc92 100644
--- a/libgnucash/engine/gnc-pricedb-p.h
+++ b/libgnucash/engine/gnc-pricedb-p.h
@@ -40,7 +40,7 @@ struct gnc_price_s
gnc_commodity *currency;
time64 tmspec;
PriceSource source;
- char *type;
+ const char *type;
gnc_numeric value;
/* 'private' object management fields */
diff --git a/libgnucash/engine/gnc-pricedb.c b/libgnucash/engine/gnc-pricedb.c
index 3dd48eb4f..1b15a5e08 100644
--- a/libgnucash/engine/gnc-pricedb.c
+++ b/libgnucash/engine/gnc-pricedb.c
@@ -558,12 +558,8 @@ gnc_price_set_typestr(GNCPrice *p, const char* type)
if (!p) return;
if (g_strcmp0(p->type, type) != 0)
{
- gchar *tmp;
-
gnc_price_begin_edit (p);
- tmp = CACHE_INSERT((gpointer) type);
- if (p->type) CACHE_REMOVE(p->type);
- p->type = tmp;
+ CACHE_REPLACE(p->type, type);
gnc_price_set_dirty(p);
gnc_price_commit_edit (p);
}
diff --git a/libgnucash/engine/gncAddress.c b/libgnucash/engine/gncAddress.c
index 2b4e5222c..6bd871e28 100644
--- a/libgnucash/engine/gncAddress.c
+++ b/libgnucash/engine/gncAddress.c
@@ -39,17 +39,17 @@ struct _gncAddress
{
QofInstance inst;
- QofBook * book;
+ QofBook * book;
QofInstance * parent;
- gboolean dirty;
- char * name;
- char * addr1;
- char * addr2;
- char * addr3;
- char * addr4;
- char * phone;
- char * fax;
- char * email;
+ gboolean dirty;
+ const char * name;
+ const char * addr1;
+ const char * addr2;
+ const char * addr3;
+ const char * addr4;
+ const char * phone;
+ const char * fax;
+ const char * email;
};
struct _gncAddressClass
@@ -393,14 +393,10 @@ gncAddressFree (GncAddress *addr)
/* Set functions */
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (member == str) return; \
if (!g_strcmp0 (member, str)) return; \
gncAddressBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE(member, str); \
}
void gncAddressSetName (GncAddress *addr, const char *name)
diff --git a/libgnucash/engine/gncBillTerm.c b/libgnucash/engine/gncBillTerm.c
index 93c03f6a7..fb6f2bb15 100644
--- a/libgnucash/engine/gncBillTerm.c
+++ b/libgnucash/engine/gncBillTerm.c
@@ -39,8 +39,8 @@ struct _gncBillTerm
QofInstance inst;
/* 'visible' data fields directly manipulated by user */
- char * name;
- char * desc;
+ const char * name;
+ const char * desc;
GncBillTermType type;
gint due_days;
gint disc_days;
@@ -72,13 +72,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
#define _GNC_MOD_NAME GNC_ID_BILLTERM
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncBillTermBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE(member, str); \
}
AS_STRING_DEC(GncBillTermType, ENUM_TERMS_TYPE)
diff --git a/libgnucash/engine/gncCustomer.c b/libgnucash/engine/gncCustomer.c
index 7d0c47939..ddb03aee0 100644
--- a/libgnucash/engine/gncCustomer.c
+++ b/libgnucash/engine/gncCustomer.c
@@ -53,9 +53,9 @@ struct _gncCustomer
QofInstance inst;
/* The following fields are identical to 'vendor' */
- char * id;
- char * name;
- char * notes;
+ const char * id;
+ const char * name;
+ const char * notes;
GncBillTerm * terms;
GncAddress * addr;
gnc_commodity * currency;
@@ -371,13 +371,9 @@ static void gncCustomerFree (GncCustomer *cust)
/* Set Functions */
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncCustomerBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE(member, str); \
}
void gncCustomerSetID (GncCustomer *cust, const char *id)
diff --git a/libgnucash/engine/gncEmployee.c b/libgnucash/engine/gncEmployee.c
index 7515d12e2..293b52dcb 100644
--- a/libgnucash/engine/gncEmployee.c
+++ b/libgnucash/engine/gncEmployee.c
@@ -47,15 +47,15 @@ static void empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
struct _gncEmployee
{
QofInstance inst;
- char * id;
- char * username;
+ const char * id;
+ const char * username;
GncAddress * addr;
gnc_commodity * currency;
gboolean active;
gnc_numeric * balance;
- char * language;
- char * acl;
+ const char * language;
+ const char * acl;
gnc_numeric workday;
gnc_numeric rate;
@@ -481,13 +481,9 @@ static void gncEmployeeFree (GncEmployee *employee)
/* Set Functions */
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncEmployeeBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
void gncEmployeeSetID (GncEmployee *employee, const char *id)
diff --git a/libgnucash/engine/gncEntry.c b/libgnucash/engine/gncEntry.c
index d48c65845..b96754463 100644
--- a/libgnucash/engine/gncEntry.c
+++ b/libgnucash/engine/gncEntry.c
@@ -44,9 +44,9 @@ struct _gncEntry
time64 date;
time64 date_entered;
- char * desc;
- char * action;
- char * notes;
+ const char * desc;
+ const char * action;
+ const char * notes;
gnc_numeric quantity;
/* customer invoice data */
@@ -191,13 +191,9 @@ gboolean gncEntryPaymentStringToType (const char *str, GncEntryPaymentType *type
#define _GNC_MOD_NAME GNC_ID_ENTRY
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncEntryBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
static inline void mark_entry (GncEntry *entry);
diff --git a/libgnucash/engine/gncInvoice.c b/libgnucash/engine/gncInvoice.c
index 5d489cb13..6ab155f81 100644
--- a/libgnucash/engine/gncInvoice.c
+++ b/libgnucash/engine/gncInvoice.c
@@ -50,11 +50,11 @@ struct _gncInvoice
{
QofInstance inst;
- char *id;
- char *notes;
+ const char *id;
+ const char *notes;
gboolean active;
- char *billing_id;
+ const char *billing_id;
char *printname;
GncBillTerm *terms;
GList *entries;
@@ -87,13 +87,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
#define GNC_INVOICE_DOCLINK "assoc_uri" // this is the old name for the document link, kept for compatibility
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncInvoiceBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
static void mark_invoice (GncInvoice *invoice);
diff --git a/libgnucash/engine/gncJob.c b/libgnucash/engine/gncJob.c
index bb9635a01..46fb843d6 100644
--- a/libgnucash/engine/gncJob.c
+++ b/libgnucash/engine/gncJob.c
@@ -41,9 +41,9 @@
struct _gncJob
{
QofInstance inst;
- char * id;
- char * name;
- char * desc;
+ const char * id;
+ const char * name;
+ const char * desc;
GncOwner owner;
gboolean active;
};
@@ -269,13 +269,9 @@ static void gncJobFree (GncJob *job)
/* Set Functions */
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncJobBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
void gncJobSetID (GncJob *job, const char *id)
diff --git a/libgnucash/engine/gncOrder.c b/libgnucash/engine/gncOrder.c
index fbf1b3bd9..24b3901f5 100644
--- a/libgnucash/engine/gncOrder.c
+++ b/libgnucash/engine/gncOrder.c
@@ -43,16 +43,16 @@ struct _gncOrder
{
QofInstance inst;
- char * id;
- char * notes;
- gboolean active;
-
- char * reference;
- char * printname;
- GncOwner owner;
- GList * entries;
- time64 opened;
- time64 closed;
+ const char * id;
+ const char * notes;
+ gboolean active;
+
+ const char * reference;
+ char * printname;
+ GncOwner owner;
+ GList * entries;
+ time64 opened;
+ time64 closed;
};
struct _gncOrderClass
@@ -65,13 +65,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
#define _GNC_MOD_NAME GNC_ID_ORDER
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncOrderBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
static inline void mark_order (GncOrder *order);
diff --git a/libgnucash/engine/gncTaxTable.c b/libgnucash/engine/gncTaxTable.c
index 182bd0552..3cd689db5 100644
--- a/libgnucash/engine/gncTaxTable.c
+++ b/libgnucash/engine/gncTaxTable.c
@@ -37,7 +37,7 @@
struct _gncTaxTable
{
QofInstance inst;
- char * name;
+ const char * name;
GncTaxTableEntryList* entries;
time64 modtime; /* internal date of last modtime */
@@ -136,13 +136,9 @@ gncTaxIncludedStringToType (const char *str, GncTaxIncluded *type)
#define _GNC_MOD_NAME GNC_ID_TAXTABLE
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncTaxTableBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
static inline void
diff --git a/libgnucash/engine/gncVendor.c b/libgnucash/engine/gncVendor.c
index 709664314..67af18c61 100644
--- a/libgnucash/engine/gncVendor.c
+++ b/libgnucash/engine/gncVendor.c
@@ -52,9 +52,9 @@ struct _gncVendor
{
QofInstance inst;
- char * id;
- char * name;
- char * notes;
+ const char * id;
+ const char * name;
+ const char * notes;
GncBillTerm * terms;
GncAddress * addr;
gnc_commodity * currency;
@@ -512,13 +512,9 @@ static void gncVendorFree (GncVendor *vendor)
/* Set Functions */
#define SET_STR(obj, member, str) { \
- char * tmp; \
- \
if (!g_strcmp0 (member, str)) return; \
gncVendorBeginEdit (obj); \
- tmp = CACHE_INSERT (str); \
- CACHE_REMOVE (member); \
- member = tmp; \
+ CACHE_REPLACE (member, str); \
}
void gncVendorSetID (GncVendor *vendor, const char *id)
diff --git a/libgnucash/engine/kvp-frame.cpp b/libgnucash/engine/kvp-frame.cpp
index 60a46edf2..6ab5bc5a6 100644
--- a/libgnucash/engine/kvp-frame.cpp
+++ b/libgnucash/engine/kvp-frame.cpp
@@ -50,7 +50,7 @@ KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept
std::for_each(rhs.m_valuemap.begin(), rhs.m_valuemap.end(),
[this](const map_type::value_type & a)
{
- auto key = static_cast<char *>(qof_string_cache_insert(a.first));
+ auto key = qof_string_cache_insert(a.first);
auto val = new KvpValueImpl(*a.second);
this->m_valuemap.insert({key,val});
}
diff --git a/libgnucash/engine/qof-string-cache.cpp b/libgnucash/engine/qof-string-cache.cpp
index aa1b89702..68e4fe479 100644
--- a/libgnucash/engine/qof-string-cache.cpp
+++ b/libgnucash/engine/qof-string-cache.cpp
@@ -106,7 +106,7 @@ qof_string_cache_remove(const char * key)
/* If the key exists in the cache, increment the refcount. Otherwise,
* add it with a refcount of 1. */
-char *
+const char *
qof_string_cache_insert(const char * key)
{
if (key)
@@ -132,10 +132,10 @@ qof_string_cache_insert(const char * key)
return NULL;
}
-char *
+const char *
qof_string_cache_replace(char const * dst, char const * src)
{
- char * tmp {qof_string_cache_insert (src)};
+ const char * tmp {qof_string_cache_insert (src)};
qof_string_cache_remove (dst);
return tmp;
}
diff --git a/libgnucash/engine/qof-string-cache.h b/libgnucash/engine/qof-string-cache.h
index f45ff1b19..f8be51c5d 100644
--- a/libgnucash/engine/qof-string-cache.h
+++ b/libgnucash/engine/qof-string-cache.h
@@ -84,11 +84,11 @@ void qof_string_cache_remove(const char * key);
/** You can use this function with g_hash_table_insert(), for the key
(or value), as long as you use the destroy notifier above.
*/
-char * qof_string_cache_insert(const char * key);
+const char * qof_string_cache_insert(const char * key);
/** Same as CACHE_REPLACE below, but safe to call from C++.
*/
-char * qof_string_cache_replace(const char * dst, const char * src);
+const char * qof_string_cache_replace(const char * dst, const char * src);
#define CACHE_INSERT(str) qof_string_cache_insert((str))
#define CACHE_REMOVE(str) qof_string_cache_remove((str))
@@ -101,7 +101,7 @@ char * qof_string_cache_replace(const char * dst, const char * src);
* It avoids unnecessary ejection by doing INSERT before REMOVE.
*/
#define CACHE_REPLACE(dst, src) do { \
- gpointer tmp = CACHE_INSERT((src)); \
+ const char *tmp = CACHE_INSERT((src)); \
CACHE_REMOVE((dst)); \
(dst) = tmp; \
} while (0)
diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp
index c768296ea..adb1ff790 100644
--- a/libgnucash/engine/qofbook.cpp
+++ b/libgnucash/engine/qofbook.cpp
@@ -613,7 +613,7 @@ qof_book_get_collection (const QofBook *book, QofIdType entity_type)
col = qof_collection_new (entity_type);
g_hash_table_insert(
book->hash_of_collections,
- qof_string_cache_insert(entity_type), col);
+ (gpointer)qof_string_cache_insert(entity_type), col);
}
return col;
}
diff --git a/libgnucash/engine/test/test-qof-string-cache.c b/libgnucash/engine/test/test-qof-string-cache.c
index f03c01032..f43a1081b 100644
--- a/libgnucash/engine/test/test-qof-string-cache.c
+++ b/libgnucash/engine/test/test-qof-string-cache.c
@@ -55,10 +55,10 @@ test_qof_string_cache( void )
/* Strings added to the cache should always return the same string address
* as long as the refcount > 0. */
gchar str[100];
- gchar* str1_1;
- gchar* str1_2;
- gchar* str1_3;
- gchar* str1_4;
+ const gchar* str1_1;
+ const gchar* str1_2;
+ const gchar* str1_3;
+ const gchar* str1_4;
strncpy(str, "str1", sizeof(str));
str1_1 = qof_string_cache_insert(str); /* Refcount = 1 */
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index 35f411322..b54163cd0 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -305,8 +305,8 @@ setup (Fixture *fixture, gconstpointer pData)
auto accts = g_hash_table_new (g_str_hash, g_str_equal);
guint ind;
- auto root_str = static_cast<char*>(CACHE_INSERT("root"));
- g_hash_table_insert (accts, root_str, root);
+ auto root_str = CACHE_INSERT("root");
+ g_hash_table_insert (accts, (gpointer)root_str, root);
fixture->func = _utest_account_fill_functions ();
if (parms == NULL)
{
diff --git a/libgnucash/engine/test/utest-Split.cpp b/libgnucash/engine/test/utest-Split.cpp
index 660210b16..93637627c 100644
--- a/libgnucash/engine/test/utest-Split.cpp
+++ b/libgnucash/engine/test/utest-Split.cpp
@@ -79,8 +79,8 @@ setup (Fixture *fixture, gconstpointer pData)
xaccSplitSetParent (fixture->split, txn);
xaccTransCommitEdit (txn);
gnc_lot_set_account (lot, acc);
- fixture->split->action = static_cast<char*>(CACHE_INSERT ("foo"));
- fixture->split->memo = static_cast<char*>(CACHE_INSERT ("bar"));
+ fixture->split->action = CACHE_INSERT ("foo");
+ fixture->split->memo = CACHE_INSERT ("bar");
fixture->split->acc = acc;
fixture->split->lot = lot;
fixture->split->parent = txn;
diff --git a/libgnucash/engine/test/utest-Transaction.cpp b/libgnucash/engine/test/utest-Transaction.cpp
index 3cf10ebb8..beba27bab 100644
--- a/libgnucash/engine/test/utest-Transaction.cpp
+++ b/libgnucash/engine/test/utest-Transaction.cpp
@@ -137,16 +137,16 @@ setup (Fixture *fixture, gconstpointer pData)
xaccAccountSetCommodity (fixture->acc2, fixture->curr);
txn->date_posted = posted;
txn->date_entered = entered;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (100000, 1000);
split1->value = gnc_numeric_create (3200, 240);
split2->amount = gnc_numeric_create (-3200, 240);
split2->value = gnc_numeric_create (-3200, 240);
split1->acc = fixture->acc1;
split2->acc = fixture->acc2;
- txn->num = static_cast<char*>(CACHE_INSERT ("123"));
- txn->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+ txn->num = CACHE_INSERT ("123");
+ txn->description = CACHE_INSERT ("Waldo Pepper");
xaccTransBeginEdit (txn);
{
xaccTransSetCurrency (txn, fixture->curr);
@@ -722,7 +722,7 @@ test_xaccFreeTransaction (Fixture *fixture, gconstpointer pData)
/* so the "free" doesn't, leaving the structure for us to test */
g_object_ref (txn);
g_object_ref (orig);
- orig->num = static_cast<char*>(CACHE_INSERT (txn_num));
+ orig->num = CACHE_INSERT (txn_num);
txn->orig = orig;
fixture->func->xaccFreeTransaction (txn);
@@ -849,17 +849,17 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
g_assert (xaccTransEqual (txn1, clone, TRUE, FALSE, TRUE, TRUE));
g_assert_cmpint (check->hits, ==, 5);
- txn1->num = g_strdup("321");
+ txn1->num = CACHE_INSERT("321");
g_free (check->msg);
check->msg = g_strdup ("[xaccTransEqual] num differs: 321 vs 123");
g_assert (!xaccTransEqual (txn1, txn0, TRUE, FALSE, TRUE, TRUE));
g_assert_cmpint (check->hits, ==, 6);
- g_free(clone->num);
- clone->num = static_cast<char*>(CACHE_INSERT("123"));
- g_free(txn1->num);
+ g_free ((char*)clone->num);
+ clone->num = CACHE_INSERT("123");
+ CACHE_REMOVE(txn1->num);
txn1->num = g_strdup("123");
- clone->description = g_strdup("salt pork");
+ clone->description = CACHE_INSERT("salt pork");
g_free (check->msg);
check->msg = g_strdup ("[xaccTransEqual] descriptions differ: salt pork vs Waldo Pepper");
g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE));
@@ -871,8 +871,8 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
xaccTransBeginEdit (clone);
cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig);
- g_free(clone->description);
- clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+ CACHE_REMOVE(clone->description);
+ clone->description = CACHE_INSERT ("Waldo Pepper");
auto frame = qof_instance_get_slots (QOF_INSTANCE (clone));
frame->set({"qux", "quux", "corge"}, new KvpValue(654.321));
xaccTransCommitEdit (clone);
@@ -885,7 +885,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
g_assert_cmpint (check->hits, ==, 9);
xaccTransBeginEdit (clone);
cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig);
- clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+ clone->description = CACHE_INSERT ("Waldo Pepper");
frame->set({"qux", "quux", "corge"}, new KvpValue(123.456));
xaccTransCommitEdit (clone);
g_free (cleanup->msg);
@@ -975,8 +975,8 @@ test_xaccTransGetImbalanceValue (Fixture *fixture, gconstpointer pData)
g_assert (gnc_numeric_equal (xaccTransGetImbalanceValue (fixture->txn),
gnc_numeric_zero ()));
split1->acc = fixture->acc1;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (100000, 1000);
split1->value = gnc_numeric_create (3200, 240);
xaccTransBeginEdit (fixture->txn);
@@ -1001,8 +1001,8 @@ test_xaccTransGetImbalance (Fixture *fixture, gconstpointer pData)
g_assert_cmpint (g_list_length (mlist), ==, 0);
split1->acc = fixture->acc1;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (100000, 1000);
split1->value = gnc_numeric_create (3200, 240);
xaccTransBeginEdit (fixture->txn);
@@ -1043,13 +1043,13 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
g_assert (!xaccTransIsBalanced (fixture->txn));
/* Make it look like a proper trading accounts transactionm */
split1->acc = acc1;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (-10000, 100);
split1->value = gnc_numeric_create (-3200, 240);
split2->acc = acc2;
- split2->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split2->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split2->memo = CACHE_INSERT ("foo");
+ split2->action = CACHE_INSERT ("bar");
split2->amount = gnc_numeric_create (3000, 240);
split2->value = gnc_numeric_create (3200, 240);
xaccTransBeginEdit (fixture->txn);
@@ -1091,8 +1091,8 @@ test_xaccTransIsBalanced (Fixture *fixture, gconstpointer pData)
g_assert (xaccTransIsBalanced (fixture->txn));
split1->acc = fixture->acc1;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (100000, 1000);
split1->value = gnc_numeric_create (3200, 240);
xaccTransBeginEdit (fixture->txn);
@@ -1124,13 +1124,13 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
/* The setup transaction is unbalanced in a trading-accounts environment. */
g_assert (!xaccTransIsBalanced (fixture->txn));
split1->acc = acc1;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (3200, 240);
split1->value = gnc_numeric_create (3200, 240);
split2->acc = acc2;
- split2->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split2->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split2->memo = CACHE_INSERT ("foo");
+ split2->action = CACHE_INSERT ("bar");
split2->amount = gnc_numeric_create (-10000, 100);
split2->value = gnc_numeric_create (-3000, 240);
xaccTransBeginEdit (fixture->txn);
@@ -1592,8 +1592,8 @@ test_xaccTransCommitEdit (void)
xaccAccountSetCommodity (acc1, comm);
xaccAccountSetCommodity (acc2, curr);
txn->date_posted = posted;
- split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
- split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+ split1->memo = CACHE_INSERT ("foo");
+ split1->action = CACHE_INSERT ("bar");
split1->amount = gnc_numeric_create (100000, 1000);
split1->value = gnc_numeric_create (3200, 240);
/* Note, deliberately imblanced to force xaccTransScrubImbalance
@@ -1603,8 +1603,8 @@ test_xaccTransCommitEdit (void)
split2->value = gnc_numeric_create (-3000, 240);
split1->acc = acc1;
split2->acc = acc2;
- txn->num = static_cast<char*>(CACHE_INSERT ("123"));
- txn->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+ txn->num = CACHE_INSERT ("123");
+ txn->description = CACHE_INSERT ("Waldo Pepper");
xaccTransBeginEdit (txn);
{
xaccTransSetCurrency (txn, curr);
@@ -1664,8 +1664,8 @@ test_xaccTransRollbackEdit (Fixture *fixture, gconstpointer pData)
orig = txn->orig;
base_frame = orig->inst.kvp_data; /* DupeTransaction copies the kvp_frame */
g_object_ref (orig); /* Keep rollback from actually freeing it */
- txn->num = static_cast<char*>(CACHE_INSERT("321"));
- txn->description = static_cast<char*>(CACHE_INSERT("salt peanuts"));
+ txn->num = CACHE_INSERT("321");
+ txn->description = CACHE_INSERT("salt peanuts");
txn->common_currency = NULL;
txn->inst.kvp_data = NULL;
txn->date_entered = new_entered;
@@ -1757,19 +1757,19 @@ test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData)
g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, NULL, NULL), ==, 0);
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==,
qof_instance_guid_compare (txnA, txnB));
- txnB->description = static_cast<char*>(CACHE_INSERT ("Salt Peanuts"));
+ txnB->description = CACHE_INSERT ("Salt Peanuts");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), >=, 1);
txnB->date_entered += 1;
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
- txnB->num = static_cast<char*>(CACHE_INSERT ("101"));
+ txnB->num = CACHE_INSERT ("101");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1);
- txnA->num = static_cast<char*>(CACHE_INSERT ("12a"));
+ txnA->num = CACHE_INSERT ("12a");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
- txnB->num = static_cast<char*>(CACHE_INSERT ("12c"));
+ txnB->num = CACHE_INSERT ("12c");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
- txnB->num = static_cast<char*>(CACHE_INSERT ("12"));
+ txnB->num = CACHE_INSERT ("12");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1);
- txnB->num = static_cast<char*>(CACHE_INSERT ("one-oh-one"));
+ txnB->num = CACHE_INSERT ("one-oh-one");
g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
g_assert_cmpint (xaccTransOrder_num_action (txnA, "24", txnB, "42"), ==, -1);
txnB->date_posted -= 1;
commit 4132939612aff073f3d2afab77171b9c9d59881d
Author: Simon Arlott <sa.me.uk>
Date: Sun Jul 11 18:51:41 2021 +0100
Avoid leaking string cache entries for "" in Transaction and Split
When g_object_new() is used, the strings that default to "" are added to
the string cache. These are then not correctly removed when updating them
with new values when cloning a Transaction/Split.
Use CACHE_REPLACE instead of CACHE_INSERT.
diff --git a/libgnucash/engine/Split.c b/libgnucash/engine/Split.c
index 8fb6091fa..5ca91507b 100644
--- a/libgnucash/engine/Split.c
+++ b/libgnucash/engine/Split.c
@@ -564,8 +564,8 @@ xaccDupeSplit (const Split *s)
split->orig_acc = s->orig_acc;
split->lot = s->lot;
- split->memo = CACHE_INSERT(s->memo);
- split->action = CACHE_INSERT(s->action);
+ CACHE_REPLACE(split->memo, s->memo);
+ CACHE_REPLACE(split->action, s->action);
qof_instance_copy_kvp (QOF_INSTANCE (split), QOF_INSTANCE (s));
diff --git a/libgnucash/engine/Transaction.c b/libgnucash/engine/Transaction.c
index e7c3cba0a..9db75799a 100644
--- a/libgnucash/engine/Transaction.c
+++ b/libgnucash/engine/Transaction.c
@@ -602,8 +602,8 @@ dupe_trans (const Transaction *from)
to = g_object_new (GNC_TYPE_TRANSACTION, NULL);
- to->num = CACHE_INSERT (from->num);
- to->description = CACHE_INSERT (from->description);
+ CACHE_REPLACE (to->num, from->num);
+ CACHE_REPLACE (to->description, from->description);
to->splits = g_list_copy (from->splits);
for (node = to->splits; node; node = node->next)
@@ -647,8 +647,8 @@ xaccTransCloneNoKvp (const Transaction *from)
to->date_entered = from->date_entered;
to->date_posted = from->date_posted;
- to->num = CACHE_INSERT (from->num);
- to->description = CACHE_INSERT (from->description);
+ CACHE_REPLACE (to->num, from->num);
+ CACHE_REPLACE (to->description, from->description);
to->common_currency = from->common_currency;
qof_instance_copy_version(to, from);
qof_instance_copy_version_check(to, from);
commit bf8fe1123c6acad373514ba8160727cdd0501e52
Author: Simon Arlott <sa.me.uk>
Date: Sun Jul 11 15:04:43 2021 +0100
Commit root accounts after loading from XML
The root accounts start with a non-zero editlevel because BeginEdit is
called for them during loading but not committed after loading.
If the book is then closed without performing any further edits that would
require a commit, the Account book_end process does nothing because the
root account is still being edited and so none of the accounts are freed.
diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp
index c956c8db5..d5b438be7 100644
--- a/libgnucash/backend/xml/io-gncxml-v2.cpp
+++ b/libgnucash/backend/xml/io-gncxml-v2.cpp
@@ -699,6 +699,7 @@ qof_session_load_from_xml_file_v2_full (
QofBookFileType type)
{
Account* root;
+ Account* template_root;
sixtp_gdv2* gd;
sixtp* top_parser;
sixtp* main_parser;
@@ -851,12 +852,18 @@ qof_session_load_from_xml_file_v2_full (
/* commit all groups, this completes the BeginEdit started when the
* account_end_handler finished reading the account.
*/
+ template_root = gnc_book_get_template_root (book);
gnc_account_foreach_descendant (root,
(AccountCb) xaccAccountCommitEdit,
NULL);
- gnc_account_foreach_descendant (gnc_book_get_template_root (book),
+ gnc_account_foreach_descendant (template_root,
(AccountCb) xaccAccountCommitEdit,
NULL);
+ /* if these exist in the XML file then they will be uncommitted */
+ if (qof_instance_get_editlevel(root) != 0)
+ xaccAccountCommitEdit(root);
+ if (qof_instance_get_editlevel(template_root) != 0)
+ xaccAccountCommitEdit(template_root);
/* start logging again */
xaccLogEnable ();
diff --git a/libgnucash/backend/xml/test/test-load-xml2.cpp b/libgnucash/backend/xml/test/test-load-xml2.cpp
index 945470078..455d20216 100644
--- a/libgnucash/backend/xml/test/test-load-xml2.cpp
+++ b/libgnucash/backend/xml/test/test-load-xml2.cpp
@@ -108,6 +108,9 @@ test_load_file (const char* filename)
do_test (gnc_account_get_book (root) == book,
"book and root account don't match");
+ do_test (qof_instance_get_editlevel(root) == 0,
+ "root account editlevel is not 0");
+
do_test_args (qof_session_get_error (session) == ERR_BACKEND_NO_ERR,
"session load xml2", __FILE__, __LINE__,
"qof error=%d for file [%s]",
commit f15402a9a603f0cb8e70f8ff89a5235e8be494f5
Author: Simon Arlott <sa.me.uk>
Date: Sun Jul 11 14:53:57 2021 +0100
Load test data from XML properly
If qof_session_new() is called without a book then qof_session_load()
won't do anything.
Set up a book for it to use.
diff --git a/libgnucash/backend/xml/test/test-load-xml2.cpp b/libgnucash/backend/xml/test/test-load-xml2.cpp
index 945470078..8eaf19749 100644
--- a/libgnucash/backend/xml/test/test-load-xml2.cpp
+++ b/libgnucash/backend/xml/test/test-load-xml2.cpp
@@ -92,7 +92,8 @@ test_load_file (const char* filename)
g_log_set_handler (logdomain, loglevel,
(GLogFunc)test_checked_handler, &check);
- auto session = qof_session_new (nullptr);
+ auto book = qof_book_new();
+ auto session = qof_session_new (book);
remove_locks (filename);
@@ -102,7 +103,6 @@ test_load_file (const char* filename)
ignore_lock ? SESSION_READ_ONLY : SESSION_NORMAL_OPEN);
qof_session_load (session, NULL);
- auto book = qof_session_get_book (session);
auto root = gnc_book_get_root_account (book);
do_test (gnc_account_get_book (root) == book,
@@ -115,6 +115,7 @@ test_load_file (const char* filename)
/* Uncomment the line below to generate corrected files */
/* qof_session_save( session, NULL ); */
qof_session_end (session);
+ qof_book_destroy (book);
}
int
Summary of changes:
gnucash/gnome-utils/dialog-commodity.c | 2 +
gnucash/gnome-utils/gnc-component-manager.c | 4 +-
libgnucash/backend/xml/io-gncxml-v2.cpp | 9 ++-
libgnucash/backend/xml/test/test-load-xml2.cpp | 8 ++-
libgnucash/engine/Account.cpp | 20 +++----
libgnucash/engine/AccountP.h | 6 +-
libgnucash/engine/Split.c | 6 +-
libgnucash/engine/SplitP.h | 8 +--
libgnucash/engine/Transaction.c | 21 +++----
libgnucash/engine/TransactionP.h | 4 +-
libgnucash/engine/gnc-budget.c | 4 +-
libgnucash/engine/gnc-commodity.c | 26 ++++-----
libgnucash/engine/gnc-pricedb-p.h | 2 +-
libgnucash/engine/gnc-pricedb.c | 6 +-
libgnucash/engine/gncAddress.c | 26 ++++-----
libgnucash/engine/gncBillTerm.c | 10 +---
libgnucash/engine/gncCustomer.c | 12 ++--
libgnucash/engine/gncEmployee.c | 14 ++---
libgnucash/engine/gncEntry.c | 12 ++--
libgnucash/engine/gncInvoice.c | 12 ++--
libgnucash/engine/gncJob.c | 12 ++--
libgnucash/engine/gncOrder.c | 26 ++++-----
libgnucash/engine/gncTaxTable.c | 8 +--
libgnucash/engine/gncVendor.c | 12 ++--
libgnucash/engine/kvp-frame.cpp | 2 +-
libgnucash/engine/qof-string-cache.cpp | 13 +++--
libgnucash/engine/qof-string-cache.h | 6 +-
libgnucash/engine/qofbook.cpp | 2 +-
libgnucash/engine/test/test-qof-string-cache.c | 8 +--
libgnucash/engine/test/utest-Account.cpp | 4 +-
libgnucash/engine/test/utest-Split.cpp | 4 +-
libgnucash/engine/test/utest-Transaction.cpp | 78 +++++++++++++-------------
32 files changed, 181 insertions(+), 206 deletions(-)
More information about the gnucash-changes
mailing list