diff --git a/bindings/engine-common.i b/bindings/engine-common.i index cd9fd4bb98c..e8001604551 100644 --- a/bindings/engine-common.i +++ b/bindings/engine-common.i @@ -32,7 +32,6 @@ static const GncGUID * gncAccountGetGUID(Account *x) %typemap(newfree) TransList * "g_list_free($1);" %typemap(newfree) PriceList * "g_list_free($1);" %typemap(newfree) LotList * "g_list_free($1);" -%typemap(newfree) CommodityList * "g_list_free($1);" %typemap(freearg) AccountList * "g_list_free($1);" diff --git a/bindings/engine.i b/bindings/engine.i index 0546363c686..84f0c699e74 100644 --- a/bindings/engine.i +++ b/bindings/engine.i @@ -80,7 +80,7 @@ GLIST_HELPER_INOUT(LotList, SWIGTYPE_p_GNCLot); GLIST_HELPER_INOUT(AccountList, SWIGTYPE_p_Account); GLIST_HELPER_INOUT(PriceList, SWIGTYPE_p_GNCPrice); // TODO: free PriceList? -GLIST_HELPER_INOUT(CommodityList, SWIGTYPE_p_gnc_commodity); +VECTOR_HELPER_INOUT(CommVec, SWIGTYPE_p_gnc_commodity, gnc_commodity); VECTOR_HELPER_INOUT(SplitsVec, SWIGTYPE_p_Split, Split); VECTOR_HELPER_INOUT(AccountVec, SWIGTYPE_p_Account, Account); diff --git a/common/base-typemaps.i b/common/base-typemaps.i index 23c2a6cd4b1..c9ddc6ac186 100644 --- a/common/base-typemaps.i +++ b/common/base-typemaps.i @@ -280,7 +280,7 @@ typedef char gchar; } } -%typemap(out) GList *, CommodityList *, SplitList *, AccountList *, LotList *, +%typemap(out) GList *, SplitList *, AccountList *, LotList *, MonetaryList *, PriceList *, EntryList * { gpointer data; GList *l; diff --git a/gnucash/gnome-utils/dialog-commodity.cpp b/gnucash/gnome-utils/dialog-commodity.cpp index b46a0022721..69273622578 100644 --- a/gnucash/gnome-utils/dialog-commodity.cpp +++ b/gnucash/gnome-utils/dialog-commodity.cpp @@ -445,7 +445,6 @@ gnc_ui_update_commodity_picker (GtkWidget *cbwe, const gchar * name_space, const gchar * init_string) { - GList * commodities; GList * iterator = nullptr; GList * commodity_items = nullptr; GtkComboBox *combo_box; @@ -471,14 +470,10 @@ gnc_ui_update_commodity_picker (GtkWidget *cbwe, gtk_combo_box_set_active(combo_box, -1); table = gnc_commodity_table_get_table (gnc_get_current_book ()); - commodities = gnc_commodity_table_get_commodities(table, name_space); - for (iterator = commodities; iterator; iterator = iterator->next) + for (auto comm : gnc_commodity_table_get_commodities(table, name_space)) { - commodity_items = - g_list_prepend (commodity_items, - (gpointer) gnc_commodity_get_printname(GNC_COMMODITY(iterator->data))); + commodity_items = g_list_prepend (commodity_items, (gpointer) gnc_commodity_get_printname(comm)); } - g_list_free(commodities); commodity_items = g_list_sort(commodity_items, collate); for (iterator = commodity_items; iterator; iterator = iterator->next) diff --git a/gnucash/gnome-utils/gnc-currency-edit.cpp b/gnucash/gnome-utils/gnc-currency-edit.cpp index 0481e5b45fd..307f626cf2a 100644 --- a/gnucash/gnome-utils/gnc-currency-edit.cpp +++ b/gnucash/gnome-utils/gnc-currency-edit.cpp @@ -48,6 +48,8 @@ #include +#include + #include #include #include @@ -56,6 +58,7 @@ #include "gnc-currency-edit.h" #include "gnc-commodity.h" +#include "gnc-commodity.hpp" #include "gnc-gtk-utils.h" #include "gnc-ui-util.h" #include "gnc-engine.h" @@ -311,12 +314,10 @@ add_item(gnc_commodity *commodity, GNCCurrencyEdit *gce) static void fill_currencies(GNCCurrencyEdit *gce) { - GList *currencies; - - currencies = gnc_commodity_table_get_commodities + auto currencies = gnc_commodity_table_get_commodities (gnc_get_current_commodities (), GNC_COMMODITY_NS_CURRENCY); - g_list_foreach(currencies, (GFunc)add_item, gce); - g_list_free(currencies); + std::for_each (currencies.begin(), currencies.end(), + [gce](auto comm){ add_item (comm, gce); }); } diff --git a/gnucash/gnome/dialog-price-edit-db.cpp b/gnucash/gnome/dialog-price-edit-db.cpp index ac83428eb3f..30cd00e90c2 100644 --- a/gnucash/gnome/dialog-price-edit-db.cpp +++ b/gnucash/gnome/dialog-price-edit-db.cpp @@ -247,10 +247,8 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb) { 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)) + for (auto tmp_commodity : gnc_commodity_table_get_commodities (commodity_table, tmp_namespace)) { - auto tmp_commodity = static_cast(node_c->data); auto num = gnc_pricedb_num_prices (pdb, tmp_commodity); DEBUG("Looking at commodity %s, Number of prices %d", gnc_commodity_get_fullname (tmp_commodity), num); @@ -278,7 +276,6 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb) g_list_free_full (list, (GDestroyNotify)gnc_price_unref); } } - g_list_free (commodity_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 ee2815e2a0a..b2264b6ea69 100644 --- a/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp +++ b/gnucash/import-export/csv-imp/assistant-csv-price-import.cpp @@ -445,8 +445,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; - GList *commodity_list = nullptr; GtkTreeIter iter; store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, @@ -469,9 +467,6 @@ GtkTreeModel *get_model (bool all_commodity) { if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY ) == 0) || (all_commodity == true)) { - commodity_list = gnc_commodity_table_get_commodities (commodity_table, tmp_namespace); - commodity_list = g_list_first (commodity_list); - // if this is the CURRENCY, add a row to be identified as a separator row if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0) && (all_commodity == true)) { @@ -480,11 +475,10 @@ GtkTreeModel *get_model (bool all_commodity) SORT_COMM, "CURRENCY-", COMM_PTR, nullptr, SEP, true, -1); } - while (commodity_list != nullptr) + for (auto tmp_commodity : gnc_commodity_table_get_commodities (commodity_table, tmp_namespace)) { const gchar *name_str; gchar *sort_str; - tmp_commodity = (gnc_commodity*)commodity_list->data; DEBUG("Looking at commodity %s", gnc_commodity_get_fullname (tmp_commodity)); name_str = gnc_commodity_get_printname (tmp_commodity); @@ -501,12 +495,10 @@ GtkTreeModel *get_model (bool all_commodity) SORT_COMM, sort_str, COMM_PTR, tmp_commodity, SEP, false, -1); g_free (sort_str); - commodity_list = g_list_next (commodity_list); } } } } - g_list_free (commodity_list); g_object_unref (store); return model; diff --git a/gnucash/import-export/import-commodity-matcher.cpp b/gnucash/import-export/import-commodity-matcher.cpp index 24aff8e1801..948f32b0362 100644 --- a/gnucash/import-export/import-commodity-matcher.cpp +++ b/gnucash/import-export/import-commodity-matcher.cpp @@ -70,18 +70,16 @@ gnc_commodity * gnc_import_select_commodity(const char * cusip, { 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)) + for (auto com : gnc_commodity_table_get_commodities (commodity_table, ns)) { - auto com = static_cast(m->data); DEBUG("Looking at commodity %s", gnc_commodity_get_fullname (com)); if (!g_strcmp0 (gnc_commodity_get_cusip (com), cusip)) { retval = com; DEBUG("Commodity %s matches.", gnc_commodity_get_fullname (com)); + break; } } - g_list_free (comm_list); if (retval) break; } diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp index 39f71ffc3d8..0573f3ea040 100644 --- a/libgnucash/backend/xml/io-gncxml-v2.cpp +++ b/libgnucash/backend/xml/io-gncxml-v2.cpp @@ -930,12 +930,9 @@ write_counts (FILE* out, ...) } static gint -compare_commodity_ids (gconstpointer a, gconstpointer b) +compare_commodity_less (gnc_commodity* a, gnc_commodity* b) { - const gnc_commodity* ca = (const gnc_commodity*) a; - const gnc_commodity* cb = (const gnc_commodity*) b; - return (g_strcmp0 (gnc_commodity_get_mnemonic (ca), - gnc_commodity_get_mnemonic (cb))); + return (g_strcmp0 (gnc_commodity_get_mnemonic (a), gnc_commodity_get_mnemonic (b)) < 0); } static gboolean write_pricedb (FILE* out, QofBook* book, sixtp_gdv2* gd); @@ -1041,16 +1038,14 @@ write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd) for (const auto& name_space : namespaces) { - GList* comms, *lp2; xmlNodePtr comnode; - comms = gnc_commodity_table_get_commodities (tbl, name_space.c_str()); - comms = g_list_sort (comms, compare_commodity_ids); + auto comms = gnc_commodity_table_get_commodities (tbl, name_space.c_str()); + std::sort (comms.begin(), comms.end(), compare_commodity_less); - for (lp2 = comms; lp2; lp2 = lp2->next) + for (auto comm : comms) { - comnode = gnc_commodity_dom_tree_create (static_cast - (lp2->data)); + comnode = gnc_commodity_dom_tree_create (comm); if (comnode == NULL) continue; @@ -1066,7 +1061,6 @@ write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd) sixtp_run_callback (gd, "commodities"); } - g_list_free (comms); if (!success) break; } diff --git a/libgnucash/engine/gnc-commodity.cpp b/libgnucash/engine/gnc-commodity.cpp index 9e712625477..0f0dcab4f93 100644 --- a/libgnucash/engine/gnc-commodity.cpp +++ b/libgnucash/engine/gnc-commodity.cpp @@ -1739,29 +1739,15 @@ gnc_commodity_table_find_full(const gnc_commodity_table * table, const char * name_space, const char * fullname) { - gnc_commodity * retval = nullptr; - GList * all; - GList * iterator; - if (!fullname || (fullname[0] == '\0')) return nullptr; - all = gnc_commodity_table_get_commodities(table, name_space); - - for (iterator = all; iterator; iterator = iterator->next) - { - auto commodity = GNC_COMMODITY (iterator->data); - if (!strcmp(fullname, - gnc_commodity_get_printname(commodity))) - { - retval = commodity; - break; - } - } - - g_list_free (all); + auto commodities{gnc_commodity_table_get_commodities(table, name_space)}; + auto it = std::find_if (commodities.begin(), commodities.end(), + [fullname](auto comm) + { return !g_strcmp0 (fullname, gnc_commodity_get_printname(comm)); }); - return retval; + return it == commodities.end() ? nullptr : *it;; } @@ -1978,10 +1964,10 @@ gnc_commodity_is_currency(const gnc_commodity *cm) * list commodities in a given namespace ********************************************************************/ -static CommodityList* +static CommVec commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table) { - CommodityList *retval = NULL; + CommVec retval; for (const auto& name_space : gnc_commodity_table_get_namespaces(table)) { gnc_commodity_namespace *ns = NULL; @@ -1990,26 +1976,33 @@ commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table 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); + auto val = g_hash_table_values(ns->cm_table); + for (auto n = val; n; n = n->next) + retval.push_back (GNC_COMMODITY(n->data)); + g_list_free (val); } return retval; } -CommodityList * +CommVec gnc_commodity_table_get_commodities(const gnc_commodity_table * table, const char * name_space) { - gnc_commodity_namespace * ns = nullptr; + CommVec retval; if (!table) - return nullptr; + return retval; if (g_strcmp0(name_space, GNC_COMMODITY_NS_NONISO_GUI) == 0) return commodity_table_get_all_noncurrency_commodities(table); - ns = gnc_commodity_table_find_namespace(table, name_space); + auto ns = gnc_commodity_table_find_namespace(table, name_space); if (!ns) - return nullptr; + return retval; - return g_hash_table_values(ns->cm_table); + auto val = g_hash_table_values(ns->cm_table); + for (auto n = val; n; n = n->next) + retval.push_back (GNC_COMMODITY(n->data)); + g_list_free (val); + return retval; } /******************************************************************** @@ -2020,45 +2013,45 @@ gnc_commodity_table_get_commodities(const gnc_commodity_table * table, static void get_quotables_helper1(gpointer key, gpointer value, gpointer data) { - auto comm = GNC_COMMODITY(value); + auto comm{GNC_COMMODITY(value)}; + auto rv{static_cast(data)}; gnc_commodityPrivate* priv = GET_PRIVATE(comm); - auto l = static_cast(data); if (!priv->quote_flag || !priv->quote_source || !priv->quote_source->get_supported()) return; - *l = g_list_prepend(*l, value); + rv->push_back (comm); } static gboolean get_quotables_helper2 (gnc_commodity *comm, gpointer data) { - auto l = static_cast(data); gnc_commodityPrivate* priv = GET_PRIVATE(comm); + auto rv{static_cast(data)}; if (!priv->quote_flag || priv->quote_source || !priv->quote_source->get_supported()) return TRUE; - *l = g_list_prepend(*l, comm); + rv->push_back (comm); return TRUE; } -CommodityList * +CommVec gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) { gnc_commodity_namespace * ns = nullptr; - GList * l = nullptr; + CommVec rv; regex_t pattern; const char *expression = gnc_prefs_get_namespace_regexp(); ENTER("table=%p, expression=%s", table, expression); if (!table) - return nullptr; + return {}; if (expression && *expression) { if (regcomp(&pattern, expression, REG_EXTENDED | REG_ICASE) != 0) { LEAVE("Cannot compile regex"); - return nullptr; + return {}; } for (const auto& name_space_str : gnc_commodity_table_get_namespaces(table)) @@ -2070,7 +2063,7 @@ gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) ns = gnc_commodity_table_find_namespace(table, name_space); if (ns) { - g_hash_table_foreach(ns->cm_table, &get_quotables_helper1, (gpointer) &l); + g_hash_table_foreach(ns->cm_table, get_quotables_helper1, &rv); } } } @@ -2078,11 +2071,10 @@ gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) } else { - gnc_commodity_table_foreach_commodity(table, get_quotables_helper2, - (gpointer) &l); + gnc_commodity_table_foreach_commodity(table, get_quotables_helper2, &rv); } - LEAVE("list head %p", l); - return l; + LEAVE("list head %p", &rv); + return rv; } /******************************************************************** diff --git a/libgnucash/engine/gnc-commodity.h b/libgnucash/engine/gnc-commodity.h index c981b31420c..8a170ee64b8 100644 --- a/libgnucash/engine/gnc-commodity.h +++ b/libgnucash/engine/gnc-commodity.h @@ -115,8 +115,6 @@ GType gnc_commodity_namespace_get_type(void); */ #define GNC_COMMODITY_MAX_FRACTION 1000000000 -typedef GList CommodityList; - /** @name Commodity Quote Source functions @{ */ @@ -888,41 +886,6 @@ void gnc_commodity_table_delete_namespace(gnc_commodity_table * table, * commodities, or the routine was passed a bad argument. */ guint gnc_commodity_table_get_size(const gnc_commodity_table* tbl); -/** Return a list of all commodities in the commodity table that are - * in the given namespace. - * - * @param table A pointer to the commodity table - * - * @param commodity_namespace A string indicating which commodities should be - * returned. It is a required argument. - * - * @return A pointer to the list of commodities. NULL if an invalid - * argument was supplied, or the namespace could not be found. - * - * @note It is the callers responsibility to free the list. */ -CommodityList * gnc_commodity_table_get_commodities( - const gnc_commodity_table * table, const char * commodity_namespace); - -/** This function returns a list of commodities for which price quotes - * should be retrieved. It will scan the entire commodity table (or - * a subset) and check each commodity to see if the price_quote_flag - * field has been set. All matching commodities are queued onto a - * list, and the head of that list is returned. Use the command-line - * given expression as a filter on the commodities to be returned. If - * non-null, only commodities in namespace that match the specified - * regular expression are checked. If none was given, all - * commodities are checked. - * - * @param table A pointer to the commodity table - * - * @return A pointer to a list of commodities. NULL if invalid - * arguments were supplied or if there no commodities are flagged for - * quote retrieval. - * - * @note It is the callers responsibility to free the list. */ -CommodityList * gnc_commodity_table_get_quotable_commodities( - const gnc_commodity_table * table); - /** Call a function once for each commodity in the commodity table. * This table walk returns whenever the end of the table is reached, * or the function returns FALSE. diff --git a/libgnucash/engine/gnc-commodity.hpp b/libgnucash/engine/gnc-commodity.hpp index 57dfbcda089..00e02e01e42 100644 --- a/libgnucash/engine/gnc-commodity.hpp +++ b/libgnucash/engine/gnc-commodity.hpp @@ -60,6 +60,40 @@ void gnc_quote_source_set_fq_installed (const char* version_string, * invalid argument was supplied. */ std::vector gnc_commodity_table_get_namespaces (const gnc_commodity_table * t); + +/** Return a vector of all commodities in the commodity table that are + * in the given namespace. + * + * @param table A pointer to the commodity table + * + * @param commodity_namespace A string indicating which commodities should be + * returned. It is a required argument. + * + * @return A pointer to the list of commodities. NULL if an invalid + * argument was supplied, or the namespace could not be found. + */ + +CommVec gnc_commodity_table_get_commodities (const gnc_commodity_table *, const char *); + +/** This function returns a vector of commodities for which price + * quotes should be retrieved. It will scan the entire commodity + * table (or a subset) and check each commodity to see if the + * price_quote_flag field has been set. All matching commodities are + * queued onto a list, and the head of that list is returned. Use + * the command-line given expression as a filter on the commodities + * to be returned. If non-null, only commodities in namespace that + * match the specified regular expression are checked. If none was + * given, all commodities are checked. + * + * @param table A pointer to the commodity table + * + * @return A pointer to a list of commodities. NULL if invalid + * arguments were supplied or if there no commodities are flagged for + * quote retrieval. + */ + +CommVec gnc_commodity_table_get_quotable_commodities (const gnc_commodity_table*); + #endif /* GNC_COMMODITY_HPP */ /** @} */ /** @} */ diff --git a/libgnucash/engine/test-core/test-engine-stuff.cpp b/libgnucash/engine/test-core/test-engine-stuff.cpp index e60b876b691..a13d53881d1 100644 --- a/libgnucash/engine/test-core/test-engine-stuff.cpp +++ b/libgnucash/engine/test-core/test-engine-stuff.cpp @@ -456,18 +456,11 @@ get_random_commodity_from_table (gnc_commodity_table *table) do { - GList *commodities; - auto name_space = namespaces.at (get_random_int_in_range (0, namespaces.size() - 1)); - commodities = gnc_commodity_table_get_commodities (table, name_space.c_str()); - if (!commodities) - continue; - - com = static_cast(get_random_list_element (commodities)); - - g_list_free (commodities); + auto commodities = gnc_commodity_table_get_commodities (table, name_space.c_str()); + com = commodities[std::rand() % commodities.size()]; } while (!com); @@ -561,24 +554,16 @@ make_random_changes_to_commodity_table (gnc_commodity_table *table) for (const auto& ns_str : namespaces) { auto ns = ns_str.c_str(); - GList *commodities; - GList *com_node; if (gnc_commodity_namespace_is_iso (ns)) continue; - commodities = gnc_commodity_table_get_commodities (table, ns); - - for (com_node = commodities; com_node; com_node = com_node->next) + for (auto com : gnc_commodity_table_get_commodities (table, ns)) { - auto com = static_cast(com_node->data); - gnc_commodity_table_remove (table, com); make_random_changes_to_commodity (com); gnc_commodity_table_insert (table, com); } - - g_list_free (commodities); } } /* ================================================================= */