gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Sat Dec 13 02:00:04 EST 2025
Updated via https://github.com/Gnucash/gnucash/commit/455ea3e7 (commit)
via https://github.com/Gnucash/gnucash/commit/e79db945 (commit)
via https://github.com/Gnucash/gnucash/commit/753e4354 (commit)
from https://github.com/Gnucash/gnucash/commit/48e1d765 (commit)
commit 455ea3e71a46d8d8baa33d4bae0ec38a5525c171
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Mon Dec 8 12:35:13 2025 +0800
[backend/xml] dom_tree_to_text returns std::optional<std::string>
diff --git a/libgnucash/backend/xml/gnc-freqspec-xml-v2.cpp b/libgnucash/backend/xml/gnc-freqspec-xml-v2.cpp
index b266adedce..2bb083ace2 100644
--- a/libgnucash/backend/xml/gnc-freqspec-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-freqspec-xml-v2.cpp
@@ -135,21 +135,18 @@ fs_uift_handler (xmlNodePtr node, gpointer data)
{
fsParseData* fspd = static_cast<decltype (fspd)> (data);
int i;
- char* nodeTxt;
- nodeTxt = dom_tree_to_text (node);
+ auto nodeTxt = dom_tree_to_text (node);
g_return_val_if_fail (nodeTxt, FALSE);
for (i = 0; uiFreqTypeStrs[i].str != NULL; i++)
{
- if (g_strcmp0 (nodeTxt, uiFreqTypeStrs[i].str) == 0)
+ if (g_strcmp0 (nodeTxt->c_str(), uiFreqTypeStrs[i].str) == 0)
{
fspd->uift = uiFreqTypeStrs[i].uift;
- g_free (nodeTxt);
return TRUE;
}
}
- g_free (nodeTxt);
return FALSE;
}
diff --git a/libgnucash/backend/xml/io-example-account.cpp b/libgnucash/backend/xml/io-example-account.cpp
index 1d89137186..3614c89479 100644
--- a/libgnucash/backend/xml/io-example-account.cpp
+++ b/libgnucash/backend/xml/io-example-account.cpp
@@ -210,7 +210,9 @@ squash_extra_whitespace (char* text)
static char*
grab_clean_string (xmlNodePtr tree)
{
- return squash_extra_whitespace (g_strstrip (dom_tree_to_text (tree)));
+ auto txt = dom_tree_to_text (tree);
+ auto str = g_strdup (txt ? txt->c_str() : "");
+ return squash_extra_whitespace (g_strstrip (str));
}
static gboolean
diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp
index 327dae7226..3265ae2929 100644
--- a/libgnucash/backend/xml/io-gncxml-v2.cpp
+++ b/libgnucash/backend/xml/io-gncxml-v2.cpp
@@ -395,7 +395,7 @@ gnc_counter_end_handler (gpointer data_for_children,
{
auto strval = dom_tree_to_text (tree);
PERR ("string_to_gint64 failed with input: %s",
- strval ? strval : "(null)");
+ strval ? strval->c_str() : "(null)");
ret = FALSE;
}
else if (g_strcmp0 (type, "transaction") == 0)
diff --git a/libgnucash/backend/xml/sixtp-dom-parsers.cpp b/libgnucash/backend/xml/sixtp-dom-parsers.cpp
index 6b9dcaaa6b..4f62bebdb2 100644
--- a/libgnucash/backend/xml/sixtp-dom-parsers.cpp
+++ b/libgnucash/backend/xml/sixtp-dom-parsers.cpp
@@ -320,19 +320,19 @@ dom_tree_to_kvp_frame_given (xmlNodePtr node, KvpFrame* frame)
if (g_strcmp0 ((char*)mark->name, "slot") == 0)
{
xmlNodePtr mark2;
- gchar* key = NULL;
+ const gchar* key = NULL;
+ std::optional<std::string> maybe_key;
KvpValue* val = NULL;
- bool must_free{false};
for (mark2 = mark->xmlChildrenNode; mark2; mark2 = mark2->next)
{
if (g_strcmp0 ((char*)mark2->name, "slot:key") == 0)
{
- key = const_cast<char*>(dom_node_to_text (mark2));
+ key = dom_node_to_text (mark2);
if (!key)
{
- key = dom_tree_to_text (mark2);
- must_free = true;
+ maybe_key = dom_tree_to_text (mark2);
+ key = maybe_key ? maybe_key->c_str() : nullptr;
}
}
else if (g_strcmp0 ((char*)mark2->name, "slot:value") == 0)
@@ -357,8 +357,6 @@ dom_tree_to_kvp_frame_given (xmlNodePtr node, KvpFrame* frame)
{
/* FIXME: should put some error here */
}
- if (must_free)
- g_free (key);
}
}
}
@@ -388,7 +386,7 @@ dom_tree_create_instance_slots (xmlNodePtr node, QofInstance* inst)
return dom_tree_to_kvp_frame_given (node, frame);
}
-gchar*
+std::optional<std::string>
dom_tree_to_text (xmlNodePtr tree)
{
/* Expect *only* text and comment sibling nodes in the given tree --
@@ -400,29 +398,29 @@ dom_tree_to_text (xmlNodePtr tree)
Ignores comment nodes and collapse text nodes into one string.
Returns NULL if expectations are unsatisfied.
*/
- gchar* result;
+ std::string rv;
gchar* temp;
- g_return_val_if_fail (tree, NULL);
+ g_return_val_if_fail (tree, std::nullopt);
/* no nodes means it's an empty string text */
if (!tree->xmlChildrenNode)
{
DEBUG ("No children");
- return g_strdup ("");
+ return "";
}
temp = (char*)xmlNodeListGetString (NULL, tree->xmlChildrenNode, TRUE);
if (!temp)
{
DEBUG ("Null string");
- return NULL;
+ return std::nullopt;
}
DEBUG ("node string [%s]", (temp == NULL ? "(null)" : temp));
- result = g_strdup (temp);
+ rv = temp;
xmlFree (temp);
- return result;
+ return rv;
}
gnc_numeric
diff --git a/libgnucash/backend/xml/sixtp-dom-parsers.h b/libgnucash/backend/xml/sixtp-dom-parsers.h
index 0538b4b68a..5f554520a0 100644
--- a/libgnucash/backend/xml/sixtp-dom-parsers.h
+++ b/libgnucash/backend/xml/sixtp-dom-parsers.h
@@ -46,7 +46,7 @@ time64 dom_tree_to_time64 (xmlNodePtr node);
gboolean dom_tree_valid_time64 (time64 ts, const xmlChar* name);
GDate* dom_tree_to_gdate (xmlNodePtr node);
gnc_numeric dom_tree_to_gnc_numeric (xmlNodePtr node);
-gchar* dom_tree_to_text (xmlNodePtr tree);
+std::optional<std::string> dom_tree_to_text (xmlNodePtr tree);
const char* dom_node_to_text (xmlNodePtr node) noexcept;
gboolean string_to_binary (const gchar* str, void** v, guint64* data_len);
gboolean dom_tree_create_instance_slots (xmlNodePtr node, QofInstance* inst);
@@ -85,11 +85,7 @@ apply_xmlnode_text (F&& f, xmlNodePtr node, T default_val = T{})
return f(txt);
if (auto txt = dom_tree_to_text(node))
- {
- auto rv = f(txt);
- g_free(txt);
- return rv;
- }
+ return f(txt->c_str());
return default_val;
}
diff --git a/libgnucash/backend/xml/test/test-dom-converters1.cpp b/libgnucash/backend/xml/test/test-dom-converters1.cpp
index 62fdfaa33b..55be6622ca 100644
--- a/libgnucash/backend/xml/test/test-dom-converters1.cpp
+++ b/libgnucash/backend/xml/test/test-dom-converters1.cpp
@@ -90,7 +90,6 @@ test_dom_tree_to_text (void)
for (i = 0; i < 20; i++)
{
gchar* test_string1;
- gchar* test_string2;
xmlNodePtr test_node;
test_node = xmlNewNode (NULL, BAD_CAST "test-node");
@@ -98,7 +97,7 @@ test_dom_tree_to_text (void)
xmlNodeAddContent (test_node, BAD_CAST test_string1);
- test_string2 = dom_tree_to_text (test_node);
+ auto test_string2 = dom_tree_to_text (test_node);
if (!test_string2)
{
@@ -106,7 +105,7 @@ test_dom_tree_to_text (void)
"null return from dom_tree_to_text");
xmlElemDump (stdout, NULL, test_node);
}
- else if (g_strcmp0 (test_string1, test_string2) == 0)
+ else if (g_strcmp0 (test_string1, test_string2->c_str()) == 0)
{
success_args ("dom_tree_to_text", __FILE__, __LINE__, "with string %s",
test_string1);
@@ -119,7 +118,6 @@ test_dom_tree_to_text (void)
xmlFreeNode (test_node);
g_free (test_string1);
- if (test_string2) g_free (test_string2);
}
}
diff --git a/libgnucash/backend/xml/test/test-file-stuff.cpp b/libgnucash/backend/xml/test/test-file-stuff.cpp
index 21ffb93f10..5d50a8f7b9 100644
--- a/libgnucash/backend/xml/test/test-file-stuff.cpp
+++ b/libgnucash/backend/xml/test/test-file-stuff.cpp
@@ -142,26 +142,22 @@ check_dom_tree_version (xmlNodePtr node, const char* verstr)
gboolean
equals_node_val_vs_string (xmlNodePtr node, const gchar* str)
{
- gchar* cmp1;
-
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (str, FALSE);
- cmp1 = dom_tree_to_text (node);
+ auto cmp1 = dom_tree_to_text (node);
if (!cmp1)
{
return FALSE;
}
- else if (g_strcmp0 (cmp1, str) == 0)
+ else if (g_strcmp0 (cmp1->c_str(), str) == 0)
{
- g_free (cmp1);
return TRUE;
}
else
{
- printf ("Differing types: node:`%s' vs string:`%s'\n", cmp1, str);
- g_free (cmp1);
+ printf ("Differing types: node:`%s' vs string:`%s'\n", cmp1->c_str(), str);
return FALSE;
}
}
@@ -169,21 +165,17 @@ equals_node_val_vs_string (xmlNodePtr node, const gchar* str)
gboolean
equals_node_val_vs_int (xmlNodePtr node, gint64 val)
{
- gchar* text;
gint64 test_val;
g_return_val_if_fail (node, FALSE);
- text = dom_tree_to_text (node);
+ auto text = dom_tree_to_text (node);
- if (!string_to_gint64 (text, &test_val))
+ if (!text || !string_to_gint64 (*text, &test_val))
{
- g_free (text);
return FALSE;
}
- g_free (text);
-
return val == test_val;
}
diff --git a/libgnucash/backend/xml/test/test-string-converters.cpp b/libgnucash/backend/xml/test/test-string-converters.cpp
index 4dcd104d8d..3f045ae4d2 100644
--- a/libgnucash/backend/xml/test/test-string-converters.cpp
+++ b/libgnucash/backend/xml/test/test-string-converters.cpp
@@ -54,13 +54,12 @@ test_string_converters (void)
{
const char* mark = test_strings[i];
xmlNodePtr test_node = text_to_dom_tree ("test-string", mark);
- char* backout = dom_tree_to_text (test_node);
+ auto backout = dom_tree_to_text (test_node);
do_test_args (
- g_strcmp0 (backout, mark) == 0,
+ g_strcmp0 (backout->c_str(), mark) == 0,
"string converting", __FILE__, __LINE__, "with string %s", mark);
- g_free (backout);
xmlFreeNode (test_node);
}
}
@@ -72,12 +71,11 @@ test_bad_string (void)
const char* sanitized = "foo?bar";
xmlNodePtr test_node = text_to_dom_tree ("test-string", badstr);
- char* backout = dom_tree_to_text (test_node);
- do_test_args (g_strcmp0 (backout, sanitized) == 0,
+ auto backout = dom_tree_to_text (test_node);
+ do_test_args (g_strcmp0 (backout->c_str(), sanitized) == 0,
"string sanitizing", __FILE__, __LINE__,
"with string %s", badstr);
- g_free (backout);
xmlFreeNode (test_node);
}
diff --git a/libgnucash/backend/xml/test/test-xml-account.cpp b/libgnucash/backend/xml/test/test-xml-account.cpp
index bc5d541fe5..5c6917ec71 100644
--- a/libgnucash/backend/xml/test/test-xml-account.cpp
+++ b/libgnucash/backend/xml/test/test-xml-account.cpp
@@ -88,29 +88,22 @@ node_and_account_equal (xmlNodePtr node, Account* act)
}
else if (g_strcmp0 ((char*)mark->name, "act:type") == 0)
{
- gchar* txt;
GNCAccountType type;
- txt = dom_tree_to_text (mark);
+ auto txt = dom_tree_to_text (mark);
if (!txt)
{
return g_strdup ("couldn't get type string");
}
- else if (!xaccAccountStringToType (txt, &type))
+ else if (!xaccAccountStringToType (txt->c_str(), &type))
{
- g_free (txt);
return g_strdup ("couldn't convert type string to int");
}
else if (type != xaccAccountGetType (act))
{
- g_free (txt);
return g_strdup ("types differ");
}
- else
- {
- g_free (txt);
- }
}
else if (g_strcmp0 ((char*)mark->name, "act:commodity") == 0)
{
diff --git a/libgnucash/backend/xml/test/test-xml-commodity.cpp b/libgnucash/backend/xml/test/test-xml-commodity.cpp
index 58683a75ea..ccbe55ecdd 100644
--- a/libgnucash/backend/xml/test/test-xml-commodity.cpp
+++ b/libgnucash/backend/xml/test/test-xml-commodity.cpp
@@ -105,30 +105,23 @@ node_and_commodity_equal (xmlNodePtr node, const gnc_commodity* com)
}
else if (g_strcmp0 ((char*)mark->name, "cmdty:fraction") == 0)
{
- gchar* txt;
gint64 type;
- txt = dom_tree_to_text (mark);
+ auto txt = dom_tree_to_text (mark);
if (!txt)
{
return "couldn't get fraction string";
}
- else if (!string_to_gint64 (txt, &type))
+ else if (!string_to_gint64 (*txt, &type))
{
- g_free (txt);
return "couldn't convert fraction string to int";
}
else if (type != gnc_commodity_get_fraction (com))
{
- g_free (txt);
return "fractions differ";
}
- else
- {
- g_free (txt);
- }
}
else if (g_strcmp0 ((char*)mark->name, "cmdty:slots") == 0)
{
diff --git a/libgnucash/backend/xml/test/test-xml-transaction.cpp b/libgnucash/backend/xml/test/test-xml-transaction.cpp
index 74815f9835..c9d6a991c5 100644
--- a/libgnucash/backend/xml/test/test-xml-transaction.cpp
+++ b/libgnucash/backend/xml/test/test-xml-transaction.cpp
@@ -116,25 +116,21 @@ equals_node_val_vs_split_internal (xmlNodePtr node, Split* spl)
}
else if (g_strcmp0 ((char*)mark->name, "split:memo") == 0)
{
- char* memo = dom_tree_to_text (mark);
+ auto memo = dom_tree_to_text (mark);
- if (g_strcmp0 (memo, xaccSplitGetMemo (spl)) != 0)
+ if (g_strcmp0 (memo->c_str(), xaccSplitGetMemo (spl)) != 0)
{
- g_free (memo);
return "memos differ";
}
- g_free (memo);
}
else if (g_strcmp0 ((char*)mark->name, "split:reconciled-state") == 0)
{
- char* rs = dom_tree_to_text (mark);
+ auto rs = dom_tree_to_text (mark);
- if (rs[0] != xaccSplitGetReconcile (spl))
+ if (!rs || rs->front() != xaccSplitGetReconcile (spl))
{
- g_free (rs);
return "states differ";
}
- g_free (rs);
}
else if (g_strcmp0 ((char*)mark->name, "split:value") == 0)
{
commit e79db945b2ea6fd2e107cafd7ba502fd82db4cd7
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Tue Dec 9 17:16:42 2025 +0800
[backend/xml] use apply_xmlnode_text
diff --git a/libgnucash/backend/xml/gnc-account-xml-v2.cpp b/libgnucash/backend/xml/gnc-account-xml-v2.cpp
index 620150a068..11e04dbec9 100644
--- a/libgnucash/backend/xml/gnc-account-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-account-xml-v2.cpp
@@ -171,32 +171,12 @@ struct account_pdata
QofBook* book;
};
-static inline gboolean
-set_string (xmlNodePtr node, Account* act,
- void (*func) (Account* act, const gchar* txt))
-{
- if (auto txt = dom_node_to_text (node))
- {
- func (act,txt);
- return TRUE;
- }
-
- gchar* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (act, txt);
-
- g_free (txt);
-
- return TRUE;
-}
-
static gboolean
account_name_handler (xmlNodePtr node, gpointer act_pdata)
{
struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
- return set_string (node, pdata->account, xaccAccountSetName);
+ return apply_xmlnode_text (xaccAccountSetName, pdata->account, node);
}
static gboolean
@@ -390,7 +370,7 @@ account_code_handler (xmlNodePtr node, gpointer act_pdata)
{
struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
- return set_string (node, pdata->account, xaccAccountSetCode);
+ return apply_xmlnode_text (xaccAccountSetCode, pdata->account, node);
}
static gboolean
@@ -398,7 +378,7 @@ account_description_handler (xmlNodePtr node, gpointer act_pdata)
{
struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
- return set_string (node, pdata->account, xaccAccountSetDescription);
+ return apply_xmlnode_text (xaccAccountSetDescription, pdata->account, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-address-xml-v2.cpp b/libgnucash/backend/xml/gnc-address-xml-v2.cpp
index bf53fa3c20..9cbaa673af 100644
--- a/libgnucash/backend/xml/gnc-address-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-address-xml-v2.cpp
@@ -96,26 +96,13 @@ struct address_pdata
GncAddress* address;
};
-static gboolean
-set_string (xmlNodePtr node, GncAddress* addr,
- void (*func) (GncAddress* addr, const char* txt))
-{
- gchar* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (addr, txt);
-
- g_free (txt);
-
- return TRUE;
-}
static gboolean
address_name_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetName);
+ return apply_xmlnode_text (gncAddressSetName, pdata->address, node);
}
static gboolean
@@ -123,7 +110,7 @@ address_addr1_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetAddr1);
+ return apply_xmlnode_text (gncAddressSetAddr1, pdata->address, node);
}
static gboolean
@@ -131,7 +118,7 @@ address_addr2_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetAddr2);
+ return apply_xmlnode_text (gncAddressSetAddr2, pdata->address, node);
}
static gboolean
@@ -139,7 +126,7 @@ address_addr3_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetAddr3);
+ return apply_xmlnode_text (gncAddressSetAddr3, pdata->address, node);
}
static gboolean
@@ -147,7 +134,7 @@ address_addr4_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetAddr4);
+ return apply_xmlnode_text (gncAddressSetAddr4, pdata->address, node);
}
static gboolean
@@ -155,7 +142,7 @@ address_phone_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetPhone);
+ return apply_xmlnode_text (gncAddressSetPhone, pdata->address, node);
}
static gboolean
@@ -163,7 +150,7 @@ address_fax_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetFax);
+ return apply_xmlnode_text (gncAddressSetFax, pdata->address, node);
}
static gboolean
@@ -171,7 +158,7 @@ address_email_handler (xmlNodePtr node, gpointer addr_pdata)
{
struct address_pdata* pdata = static_cast<decltype (pdata)> (addr_pdata);
- return set_string (node, pdata->address, gncAddressSetEmail);
+ return apply_xmlnode_text (gncAddressSetEmail, pdata->address, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-bill-term-xml-v2.cpp b/libgnucash/backend/xml/gnc-bill-term-xml-v2.cpp
index 9de99ed97c..bfa7bf7676 100644
--- a/libgnucash/backend/xml/gnc-bill-term-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-bill-term-xml-v2.cpp
@@ -275,17 +275,6 @@ set_parent_child (xmlNodePtr node, struct billterm_pdata* pdata,
return TRUE;
}
-static gboolean
-set_string (xmlNodePtr node, GncBillTerm* term,
- void (*func) (GncBillTerm*, const char*))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
- func (term, txt);
- g_free (txt);
- return TRUE;
-}
-
static gboolean
billterm_guid_handler (xmlNodePtr node, gpointer billterm_pdata)
{
@@ -313,14 +302,14 @@ static gboolean
billterm_name_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata* pdata = static_cast<decltype (pdata)> (billterm_pdata);
- return set_string (node, pdata->term, gncBillTermSetName);
+ return apply_xmlnode_text (gncBillTermSetName, pdata->term, node);
}
static gboolean
billterm_desc_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata* pdata = static_cast<decltype (pdata)> (billterm_pdata);
- return set_string (node, pdata->term, gncBillTermSetDescription);
+ return apply_xmlnode_text (gncBillTermSetDescription, pdata->term, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-budget-xml-v2.cpp b/libgnucash/backend/xml/gnc-budget-xml-v2.cpp
index 0215bf5ac9..2c1e970c18 100644
--- a/libgnucash/backend/xml/gnc-budget-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-budget-xml-v2.cpp
@@ -85,17 +85,6 @@ gnc_budget_dom_tree_create (GncBudget* bgt)
}
/***********************************************************************/
-static inline gboolean
-set_string (xmlNodePtr node, GncBudget* bgt,
- void (*func) (GncBudget* bgt, const gchar* txt))
-{
- gchar* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (bgt, txt);
- g_free (txt);
- return TRUE;
-}
static gboolean
budget_id_handler (xmlNodePtr node, gpointer bgt)
@@ -109,13 +98,13 @@ budget_id_handler (xmlNodePtr node, gpointer bgt)
static gboolean
budget_name_handler (xmlNodePtr node, gpointer bgt)
{
- return set_string (node, GNC_BUDGET (bgt), gnc_budget_set_name);
+ return apply_xmlnode_text (gnc_budget_set_name, GNC_BUDGET (bgt), node);
}
static gboolean
budget_description_handler (xmlNodePtr node, gpointer bgt)
{
- return set_string (node, GNC_BUDGET (bgt), gnc_budget_set_description);
+ return apply_xmlnode_text (gnc_budget_set_description, GNC_BUDGET (bgt), node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-commodity-xml-v2.cpp b/libgnucash/backend/xml/gnc-commodity-xml-v2.cpp
index de5c5ca896..5335e2c677 100644
--- a/libgnucash/backend/xml/gnc-commodity-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-commodity-xml-v2.cpp
@@ -171,15 +171,18 @@ set_commodity_value (xmlNodePtr node, gnc_commodity* com)
{
struct com_char_handler* mark;
+ auto call_commodity_handler = [&](gnc_commodity* com, const char* txt)
+ {
+ auto val = gnc_strstrip (txt);
+ (mark->func) (com, val.c_str());
+ };
+
for (mark = com_handlers; mark->tag; mark++)
{
if (g_strcmp0 (mark->tag, (char*)node->name) == 0)
{
- gchar* val = dom_tree_to_text (node);
- g_strstrip (val);
- (mark->func) (com, val);
- g_free (val);
- break;
+ if (apply_xmlnode_text (call_commodity_handler, com, node))
+ break;
}
}
}
diff --git a/libgnucash/backend/xml/gnc-customer-xml-v2.cpp b/libgnucash/backend/xml/gnc-customer-xml-v2.cpp
index 35c72e8532..9023269733 100644
--- a/libgnucash/backend/xml/gnc-customer-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-customer-xml-v2.cpp
@@ -145,19 +145,6 @@ struct customer_pdata
QofBook* book;
};
-static gboolean
-set_string (xmlNodePtr node, GncCustomer* cust,
- void (*func) (GncCustomer* cust, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (cust, txt);
-
- g_free (txt);
-
- return TRUE;
-}
static gboolean
set_boolean (xmlNodePtr node, GncCustomer* cust,
@@ -178,7 +165,7 @@ customer_name_handler (xmlNodePtr node, gpointer cust_pdata)
{
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
- return set_string (node, pdata->customer, gncCustomerSetName);
+ return apply_xmlnode_text (gncCustomerSetName, pdata->customer, node);
}
static gboolean
@@ -209,7 +196,7 @@ customer_id_handler (xmlNodePtr node, gpointer cust_pdata)
{
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
- return set_string (node, pdata->customer, gncCustomerSetID);
+ return apply_xmlnode_text (gncCustomerSetID, pdata->customer, node);
}
static gboolean
@@ -217,7 +204,7 @@ customer_notes_handler (xmlNodePtr node, gpointer cust_pdata)
{
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
- return set_string (node, pdata->customer, gncCustomerSetNotes);
+ return apply_xmlnode_text (gncCustomerSetNotes, pdata->customer, node);
}
static gboolean
@@ -257,20 +244,13 @@ static gboolean
customer_taxincluded_handler (xmlNodePtr node, gpointer cust_pdata)
{
struct customer_pdata* pdata = static_cast<decltype (pdata)> (cust_pdata);
- GncTaxIncluded type;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncTaxIncludedStringToType (str, &type);
- g_free (str);
-
- if (ret)
- gncCustomerSetTaxIncluded (pdata->customer, type);
-
- return ret;
+ auto set_tax_included = [](GncCustomer* cust, const char *str)
+ {
+ GncTaxIncluded type;
+ if (gncTaxIncludedStringToType (str, &type))
+ gncCustomerSetTaxIncluded (cust, type);
+ };
+ return apply_xmlnode_text (set_tax_included, pdata->customer, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-employee-xml-v2.cpp b/libgnucash/backend/xml/gnc-employee-xml-v2.cpp
index cc8bb85b16..0115ac259f 100644
--- a/libgnucash/backend/xml/gnc-employee-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-employee-xml-v2.cpp
@@ -129,26 +129,12 @@ struct employee_pdata
QofBook* book;
};
-static gboolean
-set_string (xmlNodePtr node, GncEmployee* employee,
- void (*func) (GncEmployee* employee, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (employee, txt);
-
- g_free (txt);
-
- return TRUE;
-}
-
static gboolean
employee_username_handler (xmlNodePtr node, gpointer employee_pdata)
{
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
- return set_string (node, pdata->employee, gncEmployeeSetUsername);
+ return apply_xmlnode_text (gncEmployeeSetUsername, pdata->employee, node);
}
static gboolean
@@ -181,7 +167,7 @@ employee_id_handler (xmlNodePtr node, gpointer employee_pdata)
{
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
- return set_string (node, pdata->employee, gncEmployeeSetID);
+ return apply_xmlnode_text (gncEmployeeSetID, pdata->employee, node);
}
static gboolean
@@ -189,7 +175,7 @@ employee_language_handler (xmlNodePtr node, gpointer employee_pdata)
{
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
- return set_string (node, pdata->employee, gncEmployeeSetLanguage);
+ return apply_xmlnode_text (gncEmployeeSetLanguage, pdata->employee, node);
}
static gboolean
@@ -197,7 +183,7 @@ employee_acl_handler (xmlNodePtr node, gpointer employee_pdata)
{
struct employee_pdata* pdata = static_cast<decltype (pdata)> (employee_pdata);
- return set_string (node, pdata->employee, gncEmployeeSetAcl);
+ return apply_xmlnode_text (gncEmployeeSetAcl, pdata->employee, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-entry-xml-v2.cpp b/libgnucash/backend/xml/gnc-entry-xml-v2.cpp
index 38c2c01a5b..fa61e29b97 100644
--- a/libgnucash/backend/xml/gnc-entry-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-entry-xml-v2.cpp
@@ -224,18 +224,6 @@ struct entry_pdata
Account* acc;
};
-static inline gboolean
-set_string (xmlNodePtr node, GncEntry* entry,
- void (*func) (GncEntry* entry, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (entry, txt);
- g_free (txt);
- return TRUE;
-}
-
static inline gboolean
set_time64 (xmlNodePtr node, GncEntry* entry,
void (*func) (GncEntry* entry, time64 ts))
@@ -349,7 +337,7 @@ entry_description_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- return set_string (node, pdata->entry, gncEntrySetDescription);
+ return apply_xmlnode_text (gncEntrySetDescription, pdata->entry, node);
}
static gboolean
@@ -357,7 +345,7 @@ entry_action_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- return set_string (node, pdata->entry, gncEntrySetAction);
+ return apply_xmlnode_text (gncEntrySetAction, pdata->entry, node);
}
static gboolean
@@ -365,7 +353,7 @@ entry_notes_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- return set_string (node, pdata->entry, gncEntrySetNotes);
+ return apply_xmlnode_text (gncEntrySetNotes, pdata->entry, node);
}
static gboolean
@@ -405,40 +393,30 @@ static gboolean
entry_idisctype_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- GncAmountType type;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncAmountStringToType (str, &type);
- g_free (str);
-
- if (ret)
- gncEntrySetInvDiscountType (pdata->entry, type);
-
- return ret;
+ auto entry = pdata->entry;
+ auto set_discount_type = [entry](auto str)
+ {
+ GncAmountType type;
+ if (!gncAmountStringToType (str, &type)) return false;
+ gncEntrySetInvDiscountType (entry, type);
+ return true;
+ };
+ return apply_xmlnode_text (set_discount_type, node, FALSE);
}
static gboolean
entry_idischow_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- GncDiscountHow how;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncEntryDiscountStringToHow (str, &how);
- g_free (str);
-
- if (ret)
- gncEntrySetInvDiscountHow (pdata->entry, how);
-
- return ret;
+ auto entry = pdata->entry;
+ auto set_discount_how = [entry](auto str)
+ {
+ GncDiscountHow how;
+ if (!gncEntryDiscountStringToHow (str, &how)) return false;
+ gncEntrySetInvDiscountHow (entry, how);
+ return true;
+ };
+ return apply_xmlnode_text (set_discount_how, node, FALSE);
}
static gboolean
@@ -526,20 +504,15 @@ static gboolean
entry_billpayment_handler (xmlNodePtr node, gpointer entry_pdata)
{
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
- GncEntryPaymentType type;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncEntryPaymentStringToType (str, &type);
- g_free (str);
-
- if (ret)
- gncEntrySetBillPayment (pdata->entry, type);
-
- return ret;
+ auto entry = pdata->entry;
+ auto set_billpayment = [entry](auto str)
+ {
+ GncEntryPaymentType type;
+ if (!gncEntryPaymentStringToType (str, &type)) return false;
+ gncEntrySetBillPayment (entry, type);
+ return true;
+ };
+ return apply_xmlnode_text (set_billpayment, node, FALSE);
}
/* The rest of the stuff */
diff --git a/libgnucash/backend/xml/gnc-invoice-xml-v2.cpp b/libgnucash/backend/xml/gnc-invoice-xml-v2.cpp
index b1f3bb5a82..9121a2bc72 100644
--- a/libgnucash/backend/xml/gnc-invoice-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-invoice-xml-v2.cpp
@@ -167,18 +167,6 @@ struct invoice_pdata
QofBook* book;
};
-static inline gboolean
-set_string (xmlNodePtr node, GncInvoice* invoice,
- void (*func) (GncInvoice* invoice, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (invoice, txt);
-
- g_free (txt);
- return TRUE;
-}
static inline gboolean
set_time64 (xmlNodePtr node, GncInvoice* invoice,
@@ -218,7 +206,7 @@ invoice_id_handler (xmlNodePtr node, gpointer invoice_pdata)
{
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
- return set_string (node, pdata->invoice, gncInvoiceSetID);
+ return apply_xmlnode_text (gncInvoiceSetID, pdata->invoice, node);
}
static gboolean
@@ -254,7 +242,7 @@ invoice_billing_id_handler (xmlNodePtr node, gpointer invoice_pdata)
{
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
- return set_string (node, pdata->invoice, gncInvoiceSetBillingID);
+ return apply_xmlnode_text (gncInvoiceSetBillingID, pdata->invoice, node);
}
static gboolean
@@ -262,7 +250,7 @@ invoice_notes_handler (xmlNodePtr node, gpointer invoice_pdata)
{
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
- return set_string (node, pdata->invoice, gncInvoiceSetNotes);
+ return apply_xmlnode_text (gncInvoiceSetNotes, pdata->invoice, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-job-xml-v2.cpp b/libgnucash/backend/xml/gnc-job-xml-v2.cpp
index 95aaeaa07f..040fea9c25 100644
--- a/libgnucash/backend/xml/gnc-job-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-job-xml-v2.cpp
@@ -100,26 +100,12 @@ struct job_pdata
QofBook* book;
};
-static gboolean
-set_string (xmlNodePtr node, GncJob* job,
- void (*func) (GncJob* job, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (job, txt);
-
- g_free (txt);
-
- return TRUE;
-}
-
static gboolean
job_name_handler (xmlNodePtr node, gpointer job_pdata)
{
struct job_pdata* pdata = static_cast<decltype (pdata)> (job_pdata);
- return set_string (node, pdata->job, gncJobSetName);
+ return apply_xmlnode_text (gncJobSetName, pdata->job, node);
}
static gboolean
@@ -150,7 +136,7 @@ job_id_handler (xmlNodePtr node, gpointer job_pdata)
{
struct job_pdata* pdata = static_cast<decltype (pdata)> (job_pdata);
- return set_string (node, pdata->job, gncJobSetID);
+ return apply_xmlnode_text (gncJobSetID, pdata->job, node);
}
static gboolean
@@ -158,7 +144,7 @@ job_reference_handler (xmlNodePtr node, gpointer job_pdata)
{
struct job_pdata* pdata = static_cast<decltype (pdata)> (job_pdata);
- return set_string (node, pdata->job, gncJobSetReference);
+ return apply_xmlnode_text (gncJobSetReference, pdata->job, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-order-xml-v2.cpp b/libgnucash/backend/xml/gnc-order-xml-v2.cpp
index f4d2a37ff3..96e03c8116 100644
--- a/libgnucash/backend/xml/gnc-order-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-order-xml-v2.cpp
@@ -114,19 +114,6 @@ struct order_pdata
QofBook* book;
};
-static inline gboolean
-set_string (xmlNodePtr node, GncOrder* order,
- void (*func) (GncOrder* order, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (order, txt);
-
- g_free (txt);
- return TRUE;
-}
-
static inline gboolean
set_time64 (xmlNodePtr node, GncOrder* order,
void (*func) (GncOrder* order, time64 tt))
@@ -165,7 +152,7 @@ order_id_handler (xmlNodePtr node, gpointer order_pdata)
{
struct order_pdata* pdata = static_cast<decltype (pdata)> (order_pdata);
- return set_string (node, pdata->order, gncOrderSetID);
+ return apply_xmlnode_text (gncOrderSetID, pdata->order, node);
}
static gboolean
@@ -203,7 +190,7 @@ order_notes_handler (xmlNodePtr node, gpointer order_pdata)
{
struct order_pdata* pdata = static_cast<decltype (pdata)> (order_pdata);
- return set_string (node, pdata->order, gncOrderSetNotes);
+ return apply_xmlnode_text (gncOrderSetNotes, pdata->order, node);
}
static gboolean
@@ -211,7 +198,7 @@ order_reference_handler (xmlNodePtr node, gpointer order_pdata)
{
struct order_pdata* pdata = static_cast<decltype (pdata)> (order_pdata);
- return set_string (node, pdata->order, gncOrderSetReference);
+ return apply_xmlnode_text (gncOrderSetReference, pdata->order, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-owner-xml-v2.cpp b/libgnucash/backend/xml/gnc-owner-xml-v2.cpp
index ab8d5338bf..eed8b69b67 100644
--- a/libgnucash/backend/xml/gnc-owner-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-owner-xml-v2.cpp
@@ -100,26 +100,19 @@ static gboolean
owner_type_handler (xmlNodePtr node, gpointer owner_pdata)
{
struct owner_pdata* pdata = static_cast<decltype (pdata)> (owner_pdata);
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- if (!g_strcmp0 (txt, GNC_ID_CUSTOMER))
- gncOwnerInitCustomer (pdata->owner, NULL);
- else if (!g_strcmp0 (txt, GNC_ID_JOB))
- gncOwnerInitJob (pdata->owner, NULL);
- else if (!g_strcmp0 (txt, GNC_ID_VENDOR))
- gncOwnerInitVendor (pdata->owner, NULL);
- else if (!g_strcmp0 (txt, GNC_ID_EMPLOYEE))
- gncOwnerInitEmployee (pdata->owner, NULL);
- else
+ GncOwner* owner = pdata->owner;
+ auto init_owner_type = [](GncOwner* owner, const char* txt)
{
- PWARN ("Unknown owner type: %s", txt);
- g_free (txt);
- return FALSE;
- }
-
- g_free (txt);
- return TRUE;
+ if (!g_strcmp0 (txt, GNC_ID_CUSTOMER))
+ gncOwnerInitCustomer (owner, NULL);
+ else if (!g_strcmp0 (txt, GNC_ID_JOB))
+ gncOwnerInitJob (owner, NULL);
+ else if (!g_strcmp0 (txt, GNC_ID_VENDOR))
+ gncOwnerInitVendor (owner, NULL);
+ else if (!g_strcmp0 (txt, GNC_ID_EMPLOYEE))
+ gncOwnerInitEmployee (owner, NULL);
+ };
+ return apply_xmlnode_text (init_owner_type, owner, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp b/libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp
index 12fd48e067..63d81052d2 100644
--- a/libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp
@@ -115,17 +115,13 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
}
else if (g_strcmp0 ("price:source", (char*)sub_node->name) == 0)
{
- char* text = dom_tree_to_text (sub_node);
- if (!text) return FALSE;
- gnc_price_set_source_string (p, text);
- g_free (text);
+ if (!apply_xmlnode_text (gnc_price_set_source_string, p, sub_node))
+ return FALSE;
}
else if (g_strcmp0 ("price:type", (char*)sub_node->name) == 0)
{
- char* text = dom_tree_to_text (sub_node);
- if (!text) return FALSE;
- gnc_price_set_typestr (p, text);
- g_free (text);
+ if (!apply_xmlnode_text (gnc_price_set_typestr, p, sub_node))
+ return FALSE;
}
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
{
diff --git a/libgnucash/backend/xml/gnc-recurrence-xml-v2.cpp b/libgnucash/backend/xml/gnc-recurrence-xml-v2.cpp
index 7ffb68e314..76e8aa188f 100644
--- a/libgnucash/backend/xml/gnc-recurrence-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-recurrence-xml-v2.cpp
@@ -52,15 +52,13 @@ const gchar* recurrence_version_string = "1.0.0";
static gboolean
recurrence_period_type_handler (xmlNodePtr node, gpointer d)
{
- PeriodType pt;
- char* nodeTxt;
-
- nodeTxt = dom_tree_to_text (node);
- g_return_val_if_fail (nodeTxt, FALSE);
- pt = recurrencePeriodTypeFromString (nodeTxt);
- ((Recurrence*) d)->ptype = pt;
- g_free (nodeTxt);
- return (pt != -1);
+ auto r = static_cast<Recurrence*>(d);
+ auto set_ptype = [](Recurrence *r, const char* txt)
+ {
+ r->ptype = recurrencePeriodTypeFromString (txt);
+ };
+ apply_xmlnode_text (set_ptype, r, node);
+ return (r->ptype != -1);
}
static gboolean
@@ -85,15 +83,13 @@ recurrence_mult_handler (xmlNodePtr node, gpointer r)
static gboolean
recurrence_weekend_adj_handler (xmlNodePtr node, gpointer d)
{
- WeekendAdjust wadj;
- char* nodeTxt;
-
- nodeTxt = dom_tree_to_text (node);
- g_return_val_if_fail (nodeTxt, FALSE);
- wadj = recurrenceWeekendAdjustFromString (nodeTxt);
- ((Recurrence*) d)->wadj = wadj;
- g_free (nodeTxt);
- return (wadj != -1);
+ auto r = static_cast<Recurrence*>(d);
+ auto set_wadj = [](Recurrence *r, const char* txt)
+ {
+ r->wadj = recurrenceWeekendAdjustFromString (txt);
+ };
+ apply_xmlnode_text (set_wadj, r, node);
+ return (r->wadj != -1);
}
static struct dom_tree_handler recurrence_dom_handlers[] =
diff --git a/libgnucash/backend/xml/gnc-schedxaction-xml-v2.cpp b/libgnucash/backend/xml/gnc-schedxaction-xml-v2.cpp
index db76a4d1ba..e5e14a8a7c 100644
--- a/libgnucash/backend/xml/gnc-schedxaction-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-schedxaction-xml-v2.cpp
@@ -223,52 +223,40 @@ gboolean
sx_name_handler (xmlNodePtr node, gpointer sx_pdata)
{
struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
- SchedXaction* sx = pdata->sx;
- gchar* tmp = dom_tree_to_text (node);
- DEBUG ("sx named [%s]", tmp);
- g_return_val_if_fail (tmp, FALSE);
- xaccSchedXactionSetName (sx, tmp);
- g_free (tmp);
- return TRUE;
+ return apply_xmlnode_text (xaccSchedXactionSetName, pdata->sx, node);
}
static gboolean
sx_enabled_handler (xmlNodePtr node, gpointer sx_pdata)
{
struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
- SchedXaction* sx = pdata->sx;
- gchar* tmp = dom_tree_to_text (node);
-
- sx->enabled = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
- g_free (tmp);
-
- return TRUE;
+ auto set_enabled = [](SchedXaction* sx, const char* txt)
+ {
+ sx->enabled = !g_strcmp0 (txt, "y");
+ };
+ return apply_xmlnode_text (set_enabled, pdata->sx, node);
}
static gboolean
sx_autoCreate_handler (xmlNodePtr node, gpointer sx_pdata)
{
struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
- SchedXaction* sx = pdata->sx;
- gchar* tmp = dom_tree_to_text (node);
-
- sx->autoCreateOption = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
- g_free (tmp);
-
- return TRUE;
+ auto set_autocreate = [](SchedXaction* sx, const char* txt)
+ {
+ sx->autoCreateOption = !g_strcmp0 (txt, "y");
+ };
+ return apply_xmlnode_text (set_autocreate, pdata->sx, node);
}
static gboolean
sx_notify_handler (xmlNodePtr node, gpointer sx_pdata)
{
struct sx_pdata* pdata = static_cast<decltype (pdata)> (sx_pdata);
- SchedXaction* sx = pdata->sx;
- gchar* tmp = dom_tree_to_text (node);
-
- sx->autoCreateNotify = (g_strcmp0 (tmp, "y") == 0 ? TRUE : FALSE);
- g_free (tmp);
-
- return TRUE;
+ auto set_notify = [](SchedXaction* sx, const char* txt)
+ {
+ sx->autoCreateNotify = !g_strcmp0 (txt, "y");
+ };
+ return apply_xmlnode_text (set_notify, pdata->sx, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-tax-table-xml-v2.cpp b/libgnucash/backend/xml/gnc-tax-table-xml-v2.cpp
index 25eb5756af..b0f12f6f24 100644
--- a/libgnucash/backend/xml/gnc-tax-table-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-tax-table-xml-v2.cpp
@@ -161,20 +161,13 @@ static gboolean
ttentry_type_handler (xmlNodePtr node, gpointer ttentry_pdata)
{
struct ttentry_pdata* pdata = static_cast<decltype (pdata)> (ttentry_pdata);
- GncAmountType type;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncAmountStringToType (str, &type);
- g_free (str);
-
- if (ret)
- gncTaxTableEntrySetType (pdata->ttentry, type);
-
- return ret;
+ auto tte_settype = [](GncTaxTableEntry* tt, const char *str)
+ {
+ GncAmountType type;
+ if (gncAmountStringToType (str, &type))
+ gncTaxTableEntrySetType (tt, type);
+ };
+ return apply_xmlnode_text (tte_settype, pdata->ttentry, node);
}
static gboolean
@@ -281,12 +274,7 @@ static gboolean
taxtable_name_handler (xmlNodePtr node, gpointer taxtable_pdata)
{
struct taxtable_pdata* pdata = static_cast<decltype (pdata)> (taxtable_pdata);
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- gncTaxTableSetName (pdata->table, txt);
- g_free (txt);
- return TRUE;
+ return apply_xmlnode_text (gncTaxTableSetName, pdata->table, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-transaction-xml-v2.cpp b/libgnucash/backend/xml/gnc-transaction-xml-v2.cpp
index db0d577b27..83c70f57e8 100644
--- a/libgnucash/backend/xml/gnc-transaction-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-transaction-xml-v2.cpp
@@ -199,26 +199,6 @@ struct split_pdata
QofBook* book;
};
-static inline gboolean
-set_spl_string (xmlNodePtr node, Split* spl,
- void (*func) (Split* spl, const char* txt))
-{
- if (auto txt = dom_node_to_text (node))
- {
- func (spl, txt);
- return TRUE;
- }
-
- gchar* tmp = dom_tree_to_text (node);
- g_return_val_if_fail (tmp, FALSE);
-
- func (spl, tmp);
-
- g_free (tmp);
-
- return TRUE;
-}
-
static inline gboolean
set_spl_gnc_num (xmlNodePtr node, Split* spl,
void (*func) (Split* spl, gnc_numeric gn))
@@ -243,35 +223,25 @@ static gboolean
spl_memo_handler (xmlNodePtr node, gpointer data)
{
struct split_pdata* pdata = static_cast<decltype (pdata)> (data);
- return set_spl_string (node, pdata->split, xaccSplitSetMemo);
+ return apply_xmlnode_text (xaccSplitSetMemo, pdata->split, node);
}
static gboolean
spl_action_handler (xmlNodePtr node, gpointer data)
{
struct split_pdata* pdata = static_cast<decltype (pdata)> (data);
- return set_spl_string (node, pdata->split, xaccSplitSetAction);
+ return apply_xmlnode_text (xaccSplitSetAction, pdata->split, node);
}
static gboolean
spl_reconciled_state_handler (xmlNodePtr node, gpointer data)
{
struct split_pdata* pdata = static_cast<decltype (pdata)> (data);
-
- if (auto txt = dom_node_to_text (node))
+ auto set_reconciled = [](Split* s, const char *txt)
{
- xaccSplitSetReconcile (pdata->split, txt[0]);
- return TRUE;
- }
-
- gchar* tmp = dom_tree_to_text (node);
- g_return_val_if_fail (tmp, FALSE);
-
- xaccSplitSetReconcile (pdata->split, tmp[0]);
-
- g_free (tmp);
-
- return TRUE;
+ xaccSplitSetReconcile(s, txt[0]);
+ };
+ return apply_xmlnode_text (set_reconciled, pdata->split, node);
}
static gboolean
@@ -408,29 +378,6 @@ struct trans_pdata
QofBook* book;
};
-static inline gboolean
-set_tran_string (xmlNodePtr node, Transaction* trn,
- void (*func) (Transaction* trn, const char* txt))
-{
- if (auto txt = dom_node_to_text (node))
- {
- func (trn, txt);
- return TRUE;
- }
-
- gchar* tmp;
-
- tmp = dom_tree_to_text (node);
-
- g_return_val_if_fail (tmp, FALSE);
-
- func (trn, tmp);
-
- g_free (tmp);
-
- return TRUE;
-}
-
static gboolean
set_tran_time64 (xmlNodePtr node, Transaction * trn,
void (*func) (Transaction *, time64))
@@ -474,7 +421,7 @@ trn_num_handler (xmlNodePtr node, gpointer trans_pdata)
struct trans_pdata* pdata = static_cast<decltype (pdata)> (trans_pdata);
Transaction* trn = pdata->trans;
- return set_tran_string (node, trn, xaccTransSetNum);
+ return apply_xmlnode_text (xaccTransSetNum, trn, node);
}
static gboolean
@@ -501,7 +448,7 @@ trn_description_handler (xmlNodePtr node, gpointer trans_pdata)
struct trans_pdata* pdata = static_cast<decltype (pdata)> (trans_pdata);
Transaction* trn = pdata->trans;
- return set_tran_string (node, trn, xaccTransSetDescription);
+ return apply_xmlnode_text (xaccTransSetDescription, trn, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/gnc-vendor-xml-v2.cpp b/libgnucash/backend/xml/gnc-vendor-xml-v2.cpp
index 57b5996d72..d8698eae3e 100644
--- a/libgnucash/backend/xml/gnc-vendor-xml-v2.cpp
+++ b/libgnucash/backend/xml/gnc-vendor-xml-v2.cpp
@@ -130,20 +130,6 @@ struct vendor_pdata
QofBook* book;
};
-static gboolean
-set_string (xmlNodePtr node, GncVendor* vendor,
- void (*func) (GncVendor* vendor, const char* txt))
-{
- char* txt = dom_tree_to_text (node);
- g_return_val_if_fail (txt, FALSE);
-
- func (vendor, txt);
-
- g_free (txt);
-
- return TRUE;
-}
-
static gboolean
set_boolean (xmlNodePtr node, GncVendor* vendor,
void (*func) (GncVendor* vendor, gboolean b))
@@ -163,7 +149,7 @@ vendor_name_handler (xmlNodePtr node, gpointer vendor_pdata)
{
struct vendor_pdata* pdata = static_cast<decltype (pdata)> (vendor_pdata);
- return set_string (node, pdata->vendor, gncVendorSetName);
+ return apply_xmlnode_text (gncVendorSetName, pdata->vendor, node);
}
static gboolean
@@ -194,7 +180,7 @@ vendor_id_handler (xmlNodePtr node, gpointer vendor_pdata)
{
struct vendor_pdata* pdata = static_cast<decltype (pdata)> (vendor_pdata);
- return set_string (node, pdata->vendor, gncVendorSetID);
+ return apply_xmlnode_text (gncVendorSetID, pdata->vendor, node);
}
static gboolean
@@ -202,7 +188,7 @@ vendor_notes_handler (xmlNodePtr node, gpointer vendor_pdata)
{
struct vendor_pdata* pdata = static_cast<decltype (pdata)> (vendor_pdata);
- return set_string (node, pdata->vendor, gncVendorSetNotes);
+ return apply_xmlnode_text (gncVendorSetNotes, pdata->vendor, node);
}
static gboolean
@@ -232,20 +218,13 @@ static gboolean
vendor_taxincluded_handler (xmlNodePtr node, gpointer vendor_pdata)
{
struct vendor_pdata* pdata = static_cast<decltype (pdata)> (vendor_pdata);
- GncTaxIncluded type;
- char* str;
- gboolean ret;
-
- str = dom_tree_to_text (node);
- g_return_val_if_fail (str, FALSE);
-
- ret = gncTaxIncludedStringToType (str, &type);
- g_free (str);
-
- if (ret)
- gncVendorSetTaxIncluded (pdata->vendor, type);
-
- return ret;
+ auto set_taxincluded = [](GncVendor* vendor, const char* str)
+ {
+ GncTaxIncluded type;
+ if (gncTaxIncludedStringToType (str, &type))
+ gncVendorSetTaxIncluded (vendor, type);
+ };
+ return apply_xmlnode_text (set_taxincluded, pdata->vendor, node);
}
static gboolean
diff --git a/libgnucash/backend/xml/io-gncxml-v1.cpp b/libgnucash/backend/xml/io-gncxml-v1.cpp
index 51f50b2a05..8dd6ec7c66 100644
--- a/libgnucash/backend/xml/io-gncxml-v1.cpp
+++ b/libgnucash/backend/xml/io-gncxml-v1.cpp
@@ -2959,17 +2959,13 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
}
else if (g_strcmp0 ("price:source", (char*)sub_node->name) == 0)
{
- char* text = dom_tree_to_text (sub_node);
- if (!text) return FALSE;
- gnc_price_set_source_string (p, text);
- g_free (text);
+ if (!apply_xmlnode_text (gnc_price_set_source_string, p, sub_node))
+ return false;
}
else if (g_strcmp0 ("price:type", (char*)sub_node->name) == 0)
{
- char* text = dom_tree_to_text (sub_node);
- if (!text) return FALSE;
- gnc_price_set_typestr (p, text);
- g_free (text);
+ if (!apply_xmlnode_text (gnc_price_set_typestr, p, sub_node))
+ return false;
}
else if (g_strcmp0 ("price:value", (char*)sub_node->name) == 0)
{
diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp
index a13440fe8a..327dae7226 100644
--- a/libgnucash/backend/xml/io-gncxml-v2.cpp
+++ b/libgnucash/backend/xml/io-gncxml-v2.cpp
@@ -369,7 +369,6 @@ gnc_counter_end_handler (gpointer data_for_children,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
- char* strval;
gint64 val;
char* type;
xmlNodePtr tree = (xmlNodePtr)data_for_children;
@@ -392,9 +391,9 @@ gnc_counter_end_handler (gpointer data_for_children,
* This is invalid xml because the namespace isn't declared in the
* tag itself. This should be changed to 'type' at some point. */
type = (char*)xmlGetProp (tree, BAD_CAST "cd:type");
- strval = dom_tree_to_text (tree);
- if (!string_to_gint64 (strval, &val))
+ if (!apply_xmlnode_text<bool> ([&val](auto txt){ return string_to_gint64 (txt, &val);}, tree))
{
+ auto strval = dom_tree_to_text (tree);
PERR ("string_to_gint64 failed with input: %s",
strval ? strval : "(null)");
ret = FALSE;
@@ -449,7 +448,6 @@ gnc_counter_end_handler (gpointer data_for_children,
}
}
- g_free (strval);
xmlFree (type);
xmlFreeNode (tree);
return ret;
diff --git a/libgnucash/backend/xml/sixtp-dom-parsers.cpp b/libgnucash/backend/xml/sixtp-dom-parsers.cpp
index 34d560190d..6b9dcaaa6b 100644
--- a/libgnucash/backend/xml/sixtp-dom-parsers.cpp
+++ b/libgnucash/backend/xml/sixtp-dom-parsers.cpp
@@ -47,74 +47,46 @@ dom_node_to_text (xmlNodePtr node) noexcept
std::optional<GncGUID>
dom_tree_to_guid (xmlNodePtr node)
{
- if (!node->properties)
- {
+ auto type = xmlGetProp (node, BAD_CAST "type");
+ if (!type)
return {};
- }
- if (strcmp ((char*) node->properties->name, "type") != 0)
- {
- PERR ("Unknown attribute for id tag: %s",
- node->properties->name ?
- (char*) node->properties->name : "(null)");
+ bool ok = !g_strcmp0 ((char*)type, "guid") || !g_strcmp0 ((char*)type, "new");
+
+ xmlFree (type);
+
+ if (!ok)
return {};
- }
+ auto extract_guid = [](auto str) -> std::optional<GncGUID>
{
- char* type;
+ if (GncGUID guid; string_to_guid (str, &guid))
+ return guid;
- type = (char*)xmlNodeGetContent (node->properties->xmlAttrPropertyValue);
+ return {};
+ };
- /* handle new and guid the same for the moment */
- if ((g_strcmp0 ("guid", type) == 0) || (g_strcmp0 ("new", type) == 0))
- {
- GncGUID gid;
- char* guid_str;
-
- guid_str = (char*)xmlNodeGetContent (node->xmlChildrenNode);
- string_to_guid (guid_str, &gid);
- xmlFree (guid_str);
- xmlFree (type);
- return gid;
- }
- else
- {
- PERR ("Unknown type %s for attribute type for tag %s",
- type ? type : "(null)",
- node->properties->name ?
- (char*) node->properties->name : "(null)");
- xmlFree (type);
- return {};
- }
- }
+ return apply_xmlnode_text<std::optional<GncGUID>>(extract_guid, node);
}
static KvpValue*
dom_tree_to_integer_kvp_value (xmlNodePtr node)
{
- gchar* text;
- gint64 daint;
- KvpValue* ret = NULL;
-
- text = dom_tree_to_text (node);
-
- if (string_to_gint64 (text, &daint))
+ auto node_to_int_kvp = [](auto txt) -> KvpValue*
{
- ret = new KvpValue {daint};
- }
- g_free (text);
+ if (gint64 daint; string_to_gint64 (txt, &daint))
+ return new KvpValue{daint};
- return ret;
+ return nullptr;
+ };
+ return apply_xmlnode_text<KvpValue*> (node_to_int_kvp, node, nullptr);
}
template <typename T>
static bool
dom_tree_to_num (xmlNodePtr node, std::function<bool(const char*, T*)>string_to_num, T* num_ptr)
{
- auto text = dom_tree_to_text (node);
- auto ret = string_to_num (text, num_ptr);
- g_free (text);
- return ret;
+ return apply_xmlnode_text<T>([&](auto txt){ return string_to_num (txt, num_ptr);}, node, false);
}
gboolean
@@ -138,46 +110,36 @@ dom_tree_to_guint (xmlNodePtr node, guint* i)
gboolean
dom_tree_to_boolean (xmlNodePtr node, gboolean* b)
{
- gchar* text;
-
- text = dom_tree_to_text (node);
- if (g_ascii_strncasecmp (text, "true", 4) == 0)
- {
- *b = TRUE;
- g_free (text);
- return TRUE;
- }
- else if (g_ascii_strncasecmp (text, "false", 5) == 0)
- {
- *b = FALSE;
- g_free (text);
- return TRUE;
- }
- else
+ auto set_bool = [b](auto text) -> gboolean
{
- *b = FALSE;
- g_free (text);
- return FALSE;
- }
+ if (g_ascii_strncasecmp (text, "true", 4) == 0)
+ {
+ *b = TRUE;
+ return TRUE;
+ }
+ else if (g_ascii_strncasecmp (text, "false", 5) == 0)
+ {
+ *b = FALSE;
+ return TRUE;
+ }
+ else
+ {
+ *b = FALSE;
+ return FALSE;
+ }
+ };
+ return apply_xmlnode_text<gboolean> (set_bool, node);
}
static KvpValue*
dom_tree_to_double_kvp_value (xmlNodePtr node)
{
- gchar* text;
- double dadoub;
- KvpValue* ret = NULL;
-
- text = dom_tree_to_text (node);
-
- if (string_to_double (text, &dadoub))
+ auto node_to_double_kvp = [](auto txt) -> KvpValue*
{
- ret = new KvpValue {dadoub};
- }
-
- g_free (text);
-
- return ret;
+ if (double dadoub; string_to_double (txt, &dadoub)) return new KvpValue{dadoub};
+ return nullptr;
+ };
+ return apply_xmlnode_text<KvpValue*> (node_to_double_kvp, node, nullptr);
}
static KvpValue*
@@ -189,30 +151,18 @@ dom_tree_to_numeric_kvp_value (xmlNodePtr node)
static KvpValue*
dom_tree_to_string_kvp_value (xmlNodePtr node)
{
- const gchar* datext;
- KvpValue* ret = NULL;
-
- datext = dom_tree_to_text (node);
- if (datext)
+ auto node_to_string_kvp = [](auto txt) -> KvpValue*
{
- ret = new KvpValue {datext};
- }
-
- return ret;
+ return new KvpValue {g_strdup (txt)};
+ };
+ return apply_xmlnode_text<KvpValue*> (node_to_string_kvp, node, nullptr);
}
static KvpValue*
dom_tree_to_guid_kvp_value (xmlNodePtr node)
{
- KvpValue* ret = NULL;
-
auto daguid = dom_tree_to_guid (node);
- if (daguid)
- {
- ret = new KvpValue {guid_copy (&*daguid)};
- }
-
- return ret;
+ return daguid ? new KvpValue {guid_copy (&*daguid)} : nullptr;
}
static KvpValue*
@@ -225,19 +175,8 @@ dom_tree_to_time64_kvp_value (xmlNodePtr node)
static KvpValue*
dom_tree_to_gdate_kvp_value (xmlNodePtr node)
{
- GDate* date;
- KvpValue* ret = NULL;
-
- date = dom_tree_to_gdate (node);
-
- if (date)
- {
- ret = new KvpValue {*date};
- }
-
- g_free (date);
-
- return ret;
+ auto date = dom_tree_to_gdate (node);
+ return date ? new KvpValue {*date} : nullptr;
}
gboolean
@@ -314,17 +253,8 @@ dom_tree_to_list_kvp_value (xmlNodePtr node)
static KvpValue*
dom_tree_to_frame_kvp_value (xmlNodePtr node)
{
- KvpFrame* frame;
- KvpValue* ret = NULL;
-
- frame = dom_tree_to_kvp_frame (node);
-
- if (frame)
- {
- ret = new KvpValue {frame};
- }
-
- return ret;
+ KvpFrame* frame = dom_tree_to_kvp_frame (node);
+ return frame ? new KvpValue {frame} : nullptr;
}
@@ -354,22 +284,14 @@ static KvpValue*
dom_tree_to_kvp_value (xmlNodePtr node)
{
xmlChar* xml_type;
- gchar* type;
struct kvp_val_converter* mark;
KvpValue* ret = NULL;
xml_type = xmlGetProp (node, BAD_CAST "type");
- if (xml_type)
- {
- type = g_strdup ((char*) xml_type);
- xmlFree (xml_type);
- }
- else
- type = NULL;
for (mark = val_converters; mark->tag; mark++)
{
- if (g_strcmp0 (type, mark->tag) == 0)
+ if (g_strcmp0 (reinterpret_cast<char*>(xml_type), mark->tag) == 0)
{
ret = (mark->converter) (node);
}
@@ -380,7 +302,7 @@ dom_tree_to_kvp_value (xmlNodePtr node)
/* FIXME: deal with unknown type tag here */
}
- g_free (type);
+ xmlFree (xml_type);
return ret;
}
@@ -400,12 +322,18 @@ dom_tree_to_kvp_frame_given (xmlNodePtr node, KvpFrame* frame)
xmlNodePtr mark2;
gchar* key = NULL;
KvpValue* val = NULL;
+ bool must_free{false};
for (mark2 = mark->xmlChildrenNode; mark2; mark2 = mark2->next)
{
if (g_strcmp0 ((char*)mark2->name, "slot:key") == 0)
{
- key = dom_tree_to_text (mark2);
+ key = const_cast<char*>(dom_node_to_text (mark2));
+ if (!key)
+ {
+ key = dom_tree_to_text (mark2);
+ must_free = true;
+ }
}
else if (g_strcmp0 ((char*)mark2->name, "slot:value") == 0)
{
@@ -429,7 +357,8 @@ dom_tree_to_kvp_frame_given (xmlNodePtr node, KvpFrame* frame)
{
/* FIXME: should put some error here */
}
- g_free (key);
+ if (must_free)
+ g_free (key);
}
}
}
@@ -499,16 +428,12 @@ dom_tree_to_text (xmlNodePtr tree)
gnc_numeric
dom_tree_to_gnc_numeric (xmlNodePtr node)
{
- gchar* content = dom_tree_to_text (node);
- if (!content)
- return gnc_numeric_zero ();
-
- gnc_numeric num = gnc_numeric_from_string (content);
- if (gnc_numeric_check (num))
- num = gnc_numeric_zero ();
-
- g_free (content);
- return num;
+ auto node_to_numeric = [](auto txt)
+ {
+ gnc_numeric num = gnc_numeric_from_string(txt);
+ return gnc_numeric_check (num) ? gnc_numeric_zero() : num;
+ };
+ return apply_xmlnode_text<gnc_numeric> (node_to_numeric, node, gnc_numeric_zero());
}
@@ -544,18 +469,8 @@ dom_tree_to_time64 (xmlNodePtr node)
{
return INT64_MAX;
}
- else
- {
- gchar* content = dom_tree_to_text (n);
- if (!content)
- {
- return INT64_MAX;
- }
-
- ret = gnc_iso8601_to_time64_gmt (content);
- g_free (content);
- seen = TRUE;
- }
+ seen = TRUE;
+ ret = apply_xmlnode_text<time64> (gnc_iso8601_to_time64_gmt, n, INT64_MAX);
}
break;
default:
@@ -589,6 +504,14 @@ dom_tree_to_gdate (xmlNodePtr node)
gboolean seen_date = FALSE;
xmlNodePtr n;
+ auto try_setting_date = [&ret](const char *content) -> bool
+ {
+ gint year = 0, month = 0, day = 0;
+ if (sscanf (content, "%d-%d-%d", &year, &month, &day) != 3) return false;
+ g_date_set_dmy (&ret, day, static_cast<GDateMonth>(month), year);
+ return (g_date_valid (&ret));
+ };
+
/* creates an invalid date */
g_date_clear (&ret, 1);
@@ -602,33 +525,9 @@ dom_tree_to_gdate (xmlNodePtr node)
case XML_ELEMENT_NODE:
if (g_strcmp0 ("gdate", (char*)n->name) == 0)
{
- if (seen_date)
- {
+ if (seen_date || !apply_xmlnode_text<bool> (try_setting_date, n))
return NULL;
- }
- else
- {
- gchar* content = dom_tree_to_text (n);
- gint year, month, day;
- if (!content)
- {
- return NULL;
- }
-
- if (sscanf (content, "%d-%d-%d", &year, &month, &day) != 3)
- {
- g_free (content);
- return NULL;
- }
- g_free (content);
- seen_date = TRUE;
- g_date_set_dmy (&ret, day, static_cast<GDateMonth> (month), year);
- if (!g_date_valid (&ret))
- {
- PWARN ("invalid date");
- return NULL;
- }
- }
+ seen_date = TRUE;
}
break;
default:
@@ -652,6 +551,14 @@ struct CommodityRef
std::string id;
};
+std::string
+gnc_strstrip (std::string_view sv)
+{
+ while (!sv.empty () && g_ascii_isspace (sv.front())) sv.remove_prefix (1);
+ while (!sv.empty () && g_ascii_isspace (sv.back())) sv.remove_suffix (1);
+ return std::string (sv);
+}
+
static std::optional<CommodityRef>
parse_commodity_ref (xmlNodePtr node, QofBook* book)
{
@@ -666,8 +573,8 @@ parse_commodity_ref (xmlNodePtr node, QofBook* book)
are required, though for now, order is irrelevant. */
CommodityRef rv;
- gchar* space_str = NULL;
- gchar* id_str = NULL;
+ bool space_set{false};
+ bool id_set{false};
xmlNodePtr n;
if (!node) return {};
@@ -683,29 +590,21 @@ parse_commodity_ref (xmlNodePtr node, QofBook* book)
case XML_ELEMENT_NODE:
if (g_strcmp0 ("cmdty:space", (char*)n->name) == 0)
{
- if (space_str)
+ if (space_set)
{
return {};
}
- else
- {
- gchar* content = dom_tree_to_text (n);
- if (!content) return {};
- space_str = content;
- }
+ rv.space = apply_xmlnode_text<std::string> (gnc_strstrip, n);
+ space_set = true;
}
else if (g_strcmp0 ("cmdty:id", (char*)n->name) == 0)
{
- if (id_str)
+ if (id_set)
{
return {};
}
- else
- {
- gchar* content = dom_tree_to_text (n);
- if (!content) return {};
- id_str = content;
- }
+ rv.id = apply_xmlnode_text<std::string> (gnc_strstrip, n);
+ id_set = true;
}
break;
default:
@@ -714,17 +613,10 @@ parse_commodity_ref (xmlNodePtr node, QofBook* book)
break;
}
}
- if (space_str && id_str)
- {
- g_strstrip (space_str);
- g_strstrip (id_str);
- rv = {space_str, id_str};
- }
-
- g_free (space_str);
- g_free (id_str);
+ if (space_set && id_set)
+ return rv;
- return rv;
+ return {};
}
gnc_commodity*
diff --git a/libgnucash/backend/xml/sixtp-dom-parsers.h b/libgnucash/backend/xml/sixtp-dom-parsers.h
index 6a0d1de5bc..0538b4b68a 100644
--- a/libgnucash/backend/xml/sixtp-dom-parsers.h
+++ b/libgnucash/backend/xml/sixtp-dom-parsers.h
@@ -34,6 +34,8 @@
std::optional<GncGUID> dom_tree_to_guid (xmlNodePtr node);
+std::string gnc_strstrip (std::string_view sv);
+
gnc_commodity* dom_tree_to_commodity_ref (xmlNodePtr node, QofBook* book);
gnc_commodity* dom_tree_to_commodity_ref_no_engine (xmlNodePtr node, QofBook*);
commit 753e4354561614c47784f6ee12c9d13a20bad5c2
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Tue Dec 9 17:15:58 2025 +0800
[sixtp-dom-parsers.h] add templated functions for node text
* apply_xmlnode_text (node, f, optional default_val)
retrieves text; and calls and returns f(text)
on failure (i.e. node==null || node has no text), it returns default_val
* apply_xmlnode_text (node, obj, f)
retrieves text; and calls and returns f(obj, text)
on success, it will return true, on failure it returns false
diff --git a/libgnucash/backend/xml/sixtp-dom-parsers.h b/libgnucash/backend/xml/sixtp-dom-parsers.h
index 37083438d9..6a0d1de5bc 100644
--- a/libgnucash/backend/xml/sixtp-dom-parsers.h
+++ b/libgnucash/backend/xml/sixtp-dom-parsers.h
@@ -71,6 +71,40 @@ struct dom_tree_handler
int gotten;
};
+template <typename T, typename F,
+ std::enable_if_t<std::is_invocable_r_v<void, F, const char*>, int> = 0>
+inline T
+apply_xmlnode_text (F&& f, xmlNodePtr node, T default_val = T{})
+{
+ if (!node)
+ return default_val;
+
+ if (auto txt = dom_node_to_text(node))
+ return f(txt);
+
+ if (auto txt = dom_tree_to_text(node))
+ {
+ auto rv = f(txt);
+ g_free(txt);
+ return rv;
+ }
+
+ return default_val;
+}
+
+template <typename Obj, typename F,
+ std::enable_if_t<std::is_invocable_r_v<void, F, Obj*, const char*>, int> = 0>
+inline bool
+apply_xmlnode_text (F&& f, Obj* obj, xmlNodePtr node)
+{
+ auto set_str = [&](auto txt)
+ {
+ f (obj, txt);
+ return true;
+ };
+ return apply_xmlnode_text<bool> (set_str, node, false);
+}
+
gboolean dom_tree_generic_parse (xmlNodePtr node,
struct dom_tree_handler* handlers,
gpointer data);
Summary of changes:
libgnucash/backend/xml/gnc-account-xml-v2.cpp | 26 +-
libgnucash/backend/xml/gnc-address-xml-v2.cpp | 29 +-
libgnucash/backend/xml/gnc-bill-term-xml-v2.cpp | 15 +-
libgnucash/backend/xml/gnc-budget-xml-v2.cpp | 15 +-
libgnucash/backend/xml/gnc-commodity-xml-v2.cpp | 13 +-
libgnucash/backend/xml/gnc-customer-xml-v2.cpp | 40 +--
libgnucash/backend/xml/gnc-employee-xml-v2.cpp | 22 +-
libgnucash/backend/xml/gnc-entry-xml-v2.cpp | 87 ++----
libgnucash/backend/xml/gnc-freqspec-xml-v2.cpp | 7 +-
libgnucash/backend/xml/gnc-invoice-xml-v2.cpp | 18 +-
libgnucash/backend/xml/gnc-job-xml-v2.cpp | 20 +-
libgnucash/backend/xml/gnc-order-xml-v2.cpp | 19 +-
libgnucash/backend/xml/gnc-owner-xml-v2.cpp | 31 +-
libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp | 12 +-
libgnucash/backend/xml/gnc-recurrence-xml-v2.cpp | 32 +-
libgnucash/backend/xml/gnc-schedxaction-xml-v2.cpp | 44 +--
libgnucash/backend/xml/gnc-tax-table-xml-v2.cpp | 28 +-
libgnucash/backend/xml/gnc-transaction-xml-v2.cpp | 69 +----
libgnucash/backend/xml/gnc-vendor-xml-v2.cpp | 41 +--
libgnucash/backend/xml/io-example-account.cpp | 4 +-
libgnucash/backend/xml/io-gncxml-v1.cpp | 12 +-
libgnucash/backend/xml/io-gncxml-v2.cpp | 8 +-
libgnucash/backend/xml/sixtp-dom-parsers.cpp | 322 +++++++--------------
libgnucash/backend/xml/sixtp-dom-parsers.h | 34 ++-
.../backend/xml/test/test-dom-converters1.cpp | 6 +-
libgnucash/backend/xml/test/test-file-stuff.cpp | 18 +-
.../backend/xml/test/test-string-converters.cpp | 10 +-
libgnucash/backend/xml/test/test-xml-account.cpp | 11 +-
libgnucash/backend/xml/test/test-xml-commodity.cpp | 11 +-
.../backend/xml/test/test-xml-transaction.cpp | 12 +-
30 files changed, 318 insertions(+), 698 deletions(-)
More information about the gnucash-changes
mailing list