From 746ab554a540c1fe3b77250beda9fcf22d88c8cd Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Tue, 9 Apr 2024 21:23:04 +0800 Subject: [PATCH] gnc_commodity_table_get_namespaces returns std::vector --- bindings/guile/gnc-optiondb.i | 24 +++------- gnucash/gnome-utils/dialog-commodity.cpp | 24 +++++----- gnucash/gnome/dialog-price-edit-db.cpp | 6 +-- .../csv-imp/assistant-csv-price-import.cpp | 8 ++-- .../csv-imp/gnc-imp-props-tx.cpp | 10 ++--- .../import-commodity-matcher.cpp | 10 ++--- libgnucash/app-utils/gnc-quotes.cpp | 8 +--- libgnucash/backend/xml/io-gncxml-v2.cpp | 28 ++++-------- libgnucash/engine/gnc-commodity.cpp | 44 +++++++------------ libgnucash/engine/gnc-commodity.h | 9 ---- libgnucash/engine/gnc-commodity.hpp | 9 ++++ libgnucash/engine/gnc-optiondb.cpp | 10 ++--- .../engine/test-core/test-engine-stuff.cpp | 23 +++------- 13 files changed, 76 insertions(+), 137 deletions(-) diff --git a/bindings/guile/gnc-optiondb.i b/bindings/guile/gnc-optiondb.i index 5e8a3df693..ec810d5fc0 100644 --- a/bindings/guile/gnc-optiondb.i +++ b/bindings/guile/gnc-optiondb.i @@ -64,6 +64,7 @@ namespace std { %begin %{ +#include #include #include #include @@ -1975,26 +1976,13 @@ gnc_register_multichoice_callback_option(GncOptionDBPtr& db, const char* key, const char* doc_string, const char *value) { - gnc_commodity* commodity{}; const auto book{qof_session_get_book(gnc_get_current_session())}; const auto commodity_table{gnc_commodity_table_get_table(book)}; - const auto namespaces{gnc_commodity_table_get_namespaces(commodity_table)}; - GncOption* rv = nullptr; - for (auto node = namespaces; node && commodity == nullptr; - node = g_list_next(node)) - { - commodity = gnc_commodity_table_lookup(commodity_table, - (const char*)(node->data), - value); - - if (commodity) - { - rv = gnc_make_commodity_option(section, name, key, doc_string, commodity); - break; - } - } - g_list_free (namespaces); - return rv; + for (const auto& name_space : gnc_commodity_table_get_namespaces(commodity_table)) + if (auto commodity = gnc_commodity_table_lookup (commodity_table, name_space.c_str(), + value)) + return gnc_make_commodity_option(section, name, key, doc_string, commodity); + return nullptr; } static GncOption* diff --git a/gnucash/gnome-utils/dialog-commodity.cpp b/gnucash/gnome-utils/dialog-commodity.cpp index 743b6c2a22..7a5a372755 100644 --- a/gnucash/gnome-utils/dialog-commodity.cpp +++ b/gnucash/gnome-utils/dialog-commodity.cpp @@ -42,12 +42,15 @@ #include "dialog-commodity.h" #include "dialog-utils.h" +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-gtk-utils.h" #include "gnc-gui-query.h" #include "gnc-ui-util.h" #include "gnc-ui.h" +#include + /* This static indicates the debugging module that this .o belongs to. */ static QofLogModule log_module = GNC_MOD_GUI; @@ -560,7 +563,7 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe, GtkComboBox *combo_box; GtkTreeModel *model; GtkTreeIter iter, match; - GList *namespaces, *node; + std::vector namespaces; gboolean matched = FALSE; g_return_if_fail(GTK_IS_COMBO_BOX (cbwe)); @@ -582,12 +585,10 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe, case DIAG_COMM_NON_CURRENCY_SELECT: namespaces = gnc_commodity_table_get_namespaces (gnc_get_current_commodities()); - node = g_list_find_custom (namespaces, GNC_COMMODITY_NS_CURRENCY, collate); - if (node) - { - namespaces = g_list_remove_link (namespaces, node); - g_list_free_1 (node); - } + + if (auto it = std::find (namespaces.begin(), namespaces.end(), GNC_COMMODITY_NS_CURRENCY); + it != namespaces.end()) + namespaces.erase (it); if (gnc_commodity_namespace_is_iso (init_string)) init_string = nullptr; @@ -595,7 +596,7 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe, case DIAG_COMM_CURRENCY: default: - namespaces = g_list_prepend (nullptr, (gpointer)GNC_COMMODITY_NS_CURRENCY); + namespaces = { GNC_COMMODITY_NS_CURRENCY }; break; } @@ -623,10 +624,10 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe, } /* add all others to the combobox */ - namespaces = g_list_sort(namespaces, collate); - for (node = namespaces; node; node = node->next) + std::sort (namespaces.begin(), namespaces.end()); + for (const auto& ns_str : namespaces) { - auto ns = static_cast(node->data); + auto ns = ns_str.c_str(); /* Skip template, legacy and currency namespaces. The latter was added as first entry earlier */ if ((g_utf8_collate(ns, GNC_COMMODITY_NS_LEGACY) == 0) || @@ -650,7 +651,6 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe, if (matched) gtk_combo_box_set_active_iter (combo_box, &match); - g_list_free(namespaces); } diff --git a/gnucash/gnome/dialog-price-edit-db.cpp b/gnucash/gnome/dialog-price-edit-db.cpp index c129a0f8ab..9966beab02 100644 --- a/gnucash/gnome/dialog-price-edit-db.cpp +++ b/gnucash/gnome/dialog-price-edit-db.cpp @@ -242,11 +242,10 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb) auto oldest = gnc_time (nullptr); auto model = gtk_tree_view_get_model (view); const auto commodity_table = gnc_get_current_commodities (); - auto namespace_list = gnc_commodity_table_get_namespaces (commodity_table); - for (auto node_n = namespace_list; node_n; node_n = g_list_next (node_n)) + for (const auto& tmp_namespace_str : gnc_commodity_table_get_namespaces (commodity_table)) { - auto tmp_namespace = static_cast(node_n->data); + auto tmp_namespace = tmp_namespace_str.c_str(); DEBUG("Looking at namespace %s", tmp_namespace); auto commodity_list = gnc_commodity_table_get_commodities (commodity_table, tmp_namespace); for (auto node_c = commodity_list; node_c; node_c = g_list_next (node_c)) @@ -281,7 +280,6 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb) } g_list_free (commodity_list); } - g_list_free (namespace_list); return oldest; } diff --git a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp index 3543b51747..bb2bfb4e65 100644 --- a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp +++ b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp @@ -40,6 +40,7 @@ #include "gnc-uri-utils.h" #include "gnc-ui-util.h" #include "dialog-utils.h" +#include "gnc-commodity.hpp" #include "gnc-component-manager.h" @@ -446,8 +447,6 @@ GtkTreeModel *get_model (bool all_commodity) GtkTreeModel *store, *model; const gnc_commodity_table *commodity_table = gnc_get_current_commodities (); gnc_commodity *tmp_commodity = nullptr; - char *tmp_namespace = nullptr; - GList *namespace_list = gnc_commodity_table_get_namespaces (commodity_table); GtkTreeIter iter; store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, @@ -460,9 +459,9 @@ GtkTreeModel *get_model (bool all_commodity) gtk_list_store_set (GTK_LIST_STORE(store), &iter, DISPLAYED_COMM, " ", SORT_COMM, " ", COMM_PTR, nullptr, SEP, false, -1); - for (auto node = namespace_list; node; node = g_list_next (node)) + for (const auto& tmp_namespace_str : gnc_commodity_table_get_namespaces (commodity_table)) { - tmp_namespace = (char*)node->data; + auto tmp_namespace = tmp_namespace_str.c_str(); DEBUG("Looking at namespace %s", tmp_namespace); /* Hide the template entry */ @@ -506,7 +505,6 @@ GtkTreeModel *get_model (bool all_commodity) } } } - g_list_free (namespace_list); g_object_unref (store); return model; diff --git a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp index 760623b943..dd09938c5e 100644 --- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp +++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp @@ -32,6 +32,7 @@ #include "gnc-ui-util.h" #include "Account.h" #include "Transaction.h" +#include "gnc-commodity.hpp" #include "gnc-pricedb.h" #include @@ -201,19 +202,16 @@ gnc_commodity* parse_commodity (const std::string& comm_str) if (!comm) { /* If that fails try mnemonic in all other namespaces */ - auto namespaces = gnc_commodity_table_get_namespaces(table); - for (auto ns = namespaces; ns; ns = ns->next) + for (const auto& ns_str : gnc_commodity_table_get_namespaces(table)) { - gchar* ns_str = (gchar*)ns->data; - if (g_utf8_collate(ns_str, GNC_COMMODITY_NS_CURRENCY) == 0) + if (ns_str == GNC_COMMODITY_NS_CURRENCY) continue; comm = gnc_commodity_table_lookup (table, - ns_str, comm_str.c_str()); + ns_str.c_str(), comm_str.c_str()); if (comm) break; } - g_list_free (namespaces); } if (!comm) diff --git a/gnucash/import-export/import-commodity-matcher.cpp b/gnucash/import-export/import-commodity-matcher.cpp index afd5d58949..24aff8e180 100644 --- a/gnucash/import-export/import-commodity-matcher.cpp +++ b/gnucash/import-export/import-commodity-matcher.cpp @@ -34,6 +34,7 @@ #include "Account.h" #include "Transaction.h" #include "dialog-commodity.h" +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-ui-util.h" @@ -64,11 +65,10 @@ gnc_commodity * gnc_import_select_commodity(const char * cusip, DEBUG("Looking for commodity with exchange_code: %s", cusip); g_assert(commodity_table); - GList *namespace_list = gnc_commodity_table_get_namespaces(commodity_table); - for (GList *n = namespace_list; !retval && n; n = g_list_next (n)) + for (const auto& ns_str : gnc_commodity_table_get_namespaces(commodity_table)) { - auto ns = static_cast(n->data); + auto ns = ns_str.c_str(); DEBUG("Looking at namespace %s", ns); GList *comm_list = gnc_commodity_table_get_commodities (commodity_table, ns); for (GList *m = comm_list; !retval && m; m = g_list_next (m)) @@ -82,10 +82,10 @@ gnc_commodity * gnc_import_select_commodity(const char * cusip, } } g_list_free (comm_list); + if (retval) + break; } - g_list_free(namespace_list); - if (retval == NULL && ask_on_unknown != 0) { const gchar *message = diff --git a/libgnucash/app-utils/gnc-quotes.cpp b/libgnucash/app-utils/gnc-quotes.cpp index 1fdf64a385..ac3938cf86 100644 --- a/libgnucash/app-utils/gnc-quotes.cpp +++ b/libgnucash/app-utils/gnc-quotes.cpp @@ -989,8 +989,6 @@ CommVec gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table) { gnc_commodity_namespace * ns = NULL; - const char *name_space; - GList * nslist, * tmp; CommVec l; regex_t pattern; const char *expression = gnc_prefs_get_namespace_regexp (); @@ -1007,10 +1005,9 @@ gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table) return CommVec (); } - nslist = gnc_commodity_table_get_namespaces (table); - for (tmp = nslist; tmp; tmp = tmp->next) + for (const auto& name_space_str : gnc_commodity_table_get_namespaces (table)) { - name_space = static_cast (tmp->data); + auto name_space = name_space_str.c_str(); if (regexec (&pattern, name_space, 0, NULL, 0) == 0) { // DEBUG ("Running list of %s commodities", name_space); @@ -1023,7 +1020,6 @@ gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table) } } } - g_list_free (nslist); regfree (&pattern); } else diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp index 562d685cfd..f0c2411e74 100644 --- a/libgnucash/backend/xml/io-gncxml-v2.cpp +++ b/libgnucash/backend/xml/io-gncxml-v2.cpp @@ -46,6 +46,7 @@ #include #include +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-pricedb-p.h" #include "Scrub.h" @@ -929,14 +930,6 @@ write_counts (FILE* out, ...) return success; } -static gint -compare_namespaces (gconstpointer a, gconstpointer b) -{ - const gchar* sa = (const gchar*) a; - const gchar* sb = (const gchar*) b; - return (g_strcmp0 (sa, sb)); -} - static gint compare_commodity_ids (gconstpointer a, gconstpointer b) { @@ -1039,25 +1032,20 @@ gboolean write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd) { gnc_commodity_table* tbl; - GList* namespaces; - GList* lp; gboolean success = TRUE; tbl = gnc_commodity_table_get_table (book); - namespaces = gnc_commodity_table_get_namespaces (tbl); - if (namespaces) - { - namespaces = g_list_sort (namespaces, compare_namespaces); - } + auto namespaces = gnc_commodity_table_get_namespaces (tbl); - for (lp = namespaces; success && lp; lp = lp->next) + std::sort (namespaces.begin(), namespaces.end()); + + for (const auto& name_space : namespaces) { GList* comms, *lp2; xmlNodePtr comnode; - comms = gnc_commodity_table_get_commodities (tbl, - static_cast (lp->data)); + comms = gnc_commodity_table_get_commodities (tbl, name_space.c_str()); comms = g_list_sort (comms, compare_commodity_ids); for (lp2 = comms; lp2; lp2 = lp2->next) @@ -1080,10 +1068,10 @@ write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd) } g_list_free (comms); + if (!success) + break; } - if (namespaces) g_list_free (namespaces); - return success; } diff --git a/libgnucash/engine/gnc-commodity.cpp b/libgnucash/engine/gnc-commodity.cpp index 6a25851a7a..48f708fb00 100644 --- a/libgnucash/engine/gnc-commodity.cpp +++ b/libgnucash/engine/gnc-commodity.cpp @@ -1923,18 +1923,9 @@ gnc_commodity_table_has_namespace(const gnc_commodity_table * table, } static void -hash_keys_helper(gpointer key, gpointer value, gpointer data) +hash_keys_helper (const char* key, gnc_commodity* value, std::vector *l) { - auto l = (GList**)data; - *l = g_list_prepend(*l, key); -} - -static GList * -g_hash_table_keys(GHashTable * table) -{ - GList * l = nullptr; - g_hash_table_foreach(table, &hash_keys_helper, (gpointer) &l); - return l; + l->push_back (key); } static void @@ -1957,13 +1948,15 @@ g_hash_table_values(GHashTable * table) * see if any commodities in the namespace exist ********************************************************************/ -GList * +std::vector gnc_commodity_table_get_namespaces(const gnc_commodity_table * table) { + std::vector rv; if (!table) - return nullptr; + return rv; - return g_hash_table_keys(table->ns_table); + g_hash_table_foreach(table->ns_table, (GHFunc)hash_keys_helper, &rv); + return rv; } GList * @@ -2012,20 +2005,17 @@ gnc_commodity_is_currency(const gnc_commodity *cm) static CommodityList* commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table) { - GList *node = nullptr, *nslist = gnc_commodity_table_get_namespaces(table); - CommodityList *retval = nullptr; - for (node = nslist; node; node=g_list_next(node)) + CommodityList *retval = NULL; + for (const auto& name_space : gnc_commodity_table_get_namespaces(table)) { - gnc_commodity_namespace *ns = nullptr; - if (g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_CURRENCY) == 0 - || g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_TEMPLATE) == 0) + gnc_commodity_namespace *ns = NULL; + if (name_space == GNC_COMMODITY_NS_CURRENCY || name_space == GNC_COMMODITY_NS_TEMPLATE) continue; - ns = gnc_commodity_table_find_namespace(table, (char*)(node->data)); + ns = gnc_commodity_table_find_namespace(table, name_space.c_str()); if (!ns) continue; retval = g_list_concat(g_hash_table_values(ns->cm_table), retval); } - g_list_free(nslist); return retval; } @@ -2079,8 +2069,6 @@ CommodityList * gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) { gnc_commodity_namespace * ns = nullptr; - const char *name_space; - GList * nslist, * tmp; GList * l = nullptr; regex_t pattern; const char *expression = gnc_prefs_get_namespace_regexp(); @@ -2097,11 +2085,10 @@ gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) return nullptr; } - nslist = gnc_commodity_table_get_namespaces(table); - for (tmp = nslist; tmp; tmp = tmp->next) + for (const auto& name_space_str : gnc_commodity_table_get_namespaces(table)) { - name_space = static_cast(tmp->data); - if (regexec(&pattern, name_space, 0, nullptr, 0) == 0) + auto name_space = name_space_str.c_str(); + if (regexec(&pattern, name_space, 0, NULL, 0) == 0) { DEBUG("Running list of %s commodities", name_space); ns = gnc_commodity_table_find_namespace(table, name_space); @@ -2111,7 +2098,6 @@ gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) } } } - g_list_free(nslist); regfree(&pattern); } else diff --git a/libgnucash/engine/gnc-commodity.h b/libgnucash/engine/gnc-commodity.h index 6bef47643e..1438ccd94c 100644 --- a/libgnucash/engine/gnc-commodity.h +++ b/libgnucash/engine/gnc-commodity.h @@ -829,15 +829,6 @@ GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace int gnc_commodity_table_has_namespace(const gnc_commodity_table * table, const char * commodity_namespace); -/** Return a list of all namespaces in the commodity table. This - * returns both system and user defined namespaces. - * - * @return A pointer to the list of names. NULL if an invalid - * argument was supplied. - * - * @note It is the callers responsibility to free the list. */ -GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table * t); - /** Return a list of all namespace data structures in the commodity table. This * returns both system and user defined namespace structures. * diff --git a/libgnucash/engine/gnc-commodity.hpp b/libgnucash/engine/gnc-commodity.hpp index 223d9abe72..57dfbcda08 100644 --- a/libgnucash/engine/gnc-commodity.hpp +++ b/libgnucash/engine/gnc-commodity.hpp @@ -34,6 +34,7 @@ #define GNC_COMMODITY_HPP #include +#include #include @@ -51,6 +52,14 @@ using CommVec = std::vector; void gnc_quote_source_set_fq_installed (const char* version_string, const std::vector& sources_list); + +/** Return a list of all namespaces in the commodity table. This + * returns both system and user defined namespaces. + * + * @return A vector to the list of names. An empty vector if an + * invalid argument was supplied. */ +std::vector gnc_commodity_table_get_namespaces (const gnc_commodity_table * t); + #endif /* GNC_COMMODITY_HPP */ /** @} */ /** @} */ diff --git a/libgnucash/engine/gnc-optiondb.cpp b/libgnucash/engine/gnc-optiondb.cpp index 17d23d8fb6..fee7e0d57b 100644 --- a/libgnucash/engine/gnc-optiondb.cpp +++ b/libgnucash/engine/gnc-optiondb.cpp @@ -31,6 +31,7 @@ #include "kvp-frame.hpp" #include "qofbookslots.h" #include "guid.hpp" +#include "gnc-commodity.hpp" #include "gnc-optiondb.h" #include "gnc-optiondb.hpp" #include "gnc-optiondb-impl.hpp" @@ -693,13 +694,9 @@ gnc_register_commodity_option(GncOptionDB* db, const char* section, gnc_commodity* commodity{}; const auto book{qof_session_get_book(gnc_get_current_session())}; const auto commodity_table{gnc_commodity_table_get_table(book)}; - const auto namespaces{gnc_commodity_table_get_namespaces(commodity_table)}; - for (auto node = namespaces; node && commodity == nullptr; - node = g_list_next(node)) + for (const auto& name_space : gnc_commodity_table_get_namespaces(commodity_table)) { - commodity = gnc_commodity_table_lookup(commodity_table, - (const char*)(node->data), - value); + commodity = gnc_commodity_table_lookup(commodity_table, name_space.c_str(), value); if (commodity) break; } @@ -707,7 +704,6 @@ gnc_register_commodity_option(GncOptionDB* db, const char* section, commodity, GncOptionUIType::COMMODITY}}; db->register_option(section, std::move(option)); - g_list_free (namespaces); } void diff --git a/libgnucash/engine/test-core/test-engine-stuff.cpp b/libgnucash/engine/test-core/test-engine-stuff.cpp index 3baf38f78d..58ba9ccd0f 100644 --- a/libgnucash/engine/test-core/test-engine-stuff.cpp +++ b/libgnucash/engine/test-core/test-engine-stuff.cpp @@ -58,6 +58,7 @@ #include "Account.h" #include "AccountP.hpp" +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-session.h" #include "Transaction.h" @@ -446,21 +447,19 @@ get_random_commodity_namespace(void) static gnc_commodity * get_random_commodity_from_table (gnc_commodity_table *table) { - GList *namespaces; gnc_commodity *com = NULL; g_return_val_if_fail (table, NULL); - namespaces = gnc_commodity_table_get_namespaces (table); + auto namespaces = gnc_commodity_table_get_namespaces (table); do { GList *commodities; - char *name_space; - name_space = static_cast(get_random_list_element (namespaces)); + auto name_space = namespaces.at (get_random_int_in_range (0, namespaces.size() - 1)); - commodities = gnc_commodity_table_get_commodities (table, name_space); + commodities = gnc_commodity_table_get_commodities (table, name_space.c_str()); if (!commodities) continue; @@ -471,9 +470,6 @@ get_random_commodity_from_table (gnc_commodity_table *table) } while (!com); - - g_list_free (namespaces); - return com; } @@ -557,16 +553,13 @@ make_random_changes_to_commodity (gnc_commodity *com) void make_random_changes_to_commodity_table (gnc_commodity_table *table) { - GList *namespaces; - GList *node; - g_return_if_fail (table); - namespaces = gnc_commodity_table_get_namespaces (table); + auto namespaces = gnc_commodity_table_get_namespaces (table); - for (node = namespaces; node; node = node->next) + for (const auto& ns_str : namespaces) { - auto ns = static_cast(node->data); + auto ns = ns_str.c_str(); GList *commodities; GList *com_node; @@ -586,8 +579,6 @@ make_random_changes_to_commodity_table (gnc_commodity_table *table) g_list_free (commodities); } - - g_list_free (namespaces); } /* ================================================================= */ /* Price stuff */