diff --git a/bindings/guile/gnc-optiondb.i b/bindings/guile/gnc-optiondb.i index c2ac2e432a5..ae7d65adc94 100644 --- a/bindings/guile/gnc-optiondb.i +++ b/bindings/guile/gnc-optiondb.i @@ -64,6 +64,7 @@ namespace std { %begin %{ +#include #include #include #include @@ -1982,13 +1983,9 @@ gnc_register_multichoice_callback_option(GncOptionDBPtr& db, 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) return gnc_make_commodity_option(section, name, key, doc_string, diff --git a/gnucash/gnome-utils/dialog-commodity.cpp b/gnucash/gnome-utils/dialog-commodity.cpp index 3f8b7442fdb..b46a0022721 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 777976b2b56..ac83428eb3f 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 ddb0a2a1e40..ee2815e2a0a 100644 --- a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp +++ b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp @@ -39,6 +39,7 @@ #include "gnc-uri-utils.h" #include "gnc-ui-util.h" #include "dialog-utils.h" +#include "gnc-commodity.hpp" #include "gnc-component-manager.h" @@ -445,9 +446,7 @@ 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 *commodity_list = 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,10 +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); - namespace_list = g_list_first (namespace_list); - while (namespace_list != nullptr) + for (const auto& tmp_namespace_str : gnc_commodity_table_get_namespaces (commodity_table)) { - tmp_namespace = (char*)namespace_list->data; + auto tmp_namespace = tmp_namespace_str.c_str(); DEBUG("Looking at namespace %s", tmp_namespace); /* Hide the template entry */ @@ -507,10 +505,8 @@ GtkTreeModel *get_model (bool all_commodity) } } } - namespace_list = g_list_next (namespace_list); } g_list_free (commodity_list); - 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 9589c93381b..eba545c6dd9 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,15 +202,13 @@ 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; } diff --git a/gnucash/import-export/import-commodity-matcher.cpp b/gnucash/import-export/import-commodity-matcher.cpp index afd5d589495..24aff8e1801 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 1438050c80a..f7180dd3b0f 100644 --- a/libgnucash/app-utils/gnc-quotes.cpp +++ b/libgnucash/app-utils/gnc-quotes.cpp @@ -978,8 +978,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 (); @@ -996,10 +994,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); @@ -1011,7 +1008,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 193fb7a5449..39f71ffc3d8 100644 --- a/libgnucash/backend/xml/io-gncxml-v2.cpp +++ b/libgnucash/backend/xml/io-gncxml-v2.cpp @@ -45,6 +45,7 @@ #include #include +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-pricedb-p.h" #include "Scrub.h" @@ -928,14 +929,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) { @@ -1038,25 +1031,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); + + std::sort (namespaces.begin(), namespaces.end()); - for (lp = namespaces; success && lp; lp = lp->next) + 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) @@ -1079,10 +1067,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 b0b2a6fd3ab..5d811ee800a 100644 --- a/libgnucash/engine/gnc-commodity.cpp +++ b/libgnucash/engine/gnc-commodity.cpp @@ -1938,18 +1938,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 @@ -1972,13 +1963,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 * @@ -2027,20 +2020,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; } @@ -2094,8 +2084,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(); @@ -2112,11 +2100,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); @@ -2126,7 +2113,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 9fde3220daa..c981b31420c 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 223d9abe727..57dfbcda089 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 f423164db7f..fee7e0d57ba 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; } diff --git a/libgnucash/engine/test-core/test-engine-stuff.cpp b/libgnucash/engine/test-core/test-engine-stuff.cpp index 3eb0479e366..76a03b4fc9a 100644 --- a/libgnucash/engine/test-core/test-engine-stuff.cpp +++ b/libgnucash/engine/test-core/test-engine-stuff.cpp @@ -59,6 +59,7 @@ #include "Account.h" #include "AccountP.hpp" +#include "gnc-commodity.hpp" #include "gnc-engine.h" #include "gnc-session.h" #include "Transaction.h" @@ -447,21 +448,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; @@ -472,9 +471,6 @@ get_random_commodity_from_table (gnc_commodity_table *table) } while (!com); - - g_list_free (namespaces); - return com; } @@ -558,16 +554,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; @@ -587,8 +580,6 @@ make_random_changes_to_commodity_table (gnc_commodity_table *table) g_list_free (commodities); } - - g_list_free (namespaces); } /* ================================================================= */ /* Price stuff */