This commit is contained in:
Christopher Lam 2025-02-10 08:47:19 +08:00 committed by GitHub
commit 5d832cd68a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 257 additions and 355 deletions

View File

@ -32,7 +32,6 @@ static const GncGUID * gncAccountGetGUID(Account *x)
%typemap(newfree) TransList * "g_list_free($1);" %typemap(newfree) TransList * "g_list_free($1);"
%typemap(newfree) PriceList * "g_list_free($1);" %typemap(newfree) PriceList * "g_list_free($1);"
%typemap(newfree) LotList * "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);" %typemap(freearg) AccountList * "g_list_free($1);"

View File

@ -84,7 +84,7 @@ GLIST_HELPER_INOUT(LotList, SWIGTYPE_p_GNCLot);
GLIST_HELPER_INOUT(AccountList, SWIGTYPE_p_Account); GLIST_HELPER_INOUT(AccountList, SWIGTYPE_p_Account);
GLIST_HELPER_INOUT(PriceList, SWIGTYPE_p_GNCPrice); GLIST_HELPER_INOUT(PriceList, SWIGTYPE_p_GNCPrice);
// TODO: free PriceList? // 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(SplitsVec, SWIGTYPE_p_Split, Split);
VECTORREF_HELPER_INOUT(SplitsVec&, SWIGTYPE_p_Split, Split); VECTORREF_HELPER_INOUT(SplitsVec&, SWIGTYPE_p_Split, Split);
VECTOR_HELPER_INOUT(AccountVec, SWIGTYPE_p_Account, Account); VECTOR_HELPER_INOUT(AccountVec, SWIGTYPE_p_Account, Account);

View File

@ -64,6 +64,7 @@ namespace std {
%begin %begin
%{ %{
#include <gnc-commodity.hpp>
#include <gnc-optiondb.h> #include <gnc-optiondb.h>
#include <gnc-optiondb.hpp> #include <gnc-optiondb.hpp>
#include <gnc-optiondb-impl.hpp> #include <gnc-optiondb-impl.hpp>
@ -1975,26 +1976,13 @@ gnc_register_multichoice_callback_option(GncOptionDBPtr& db,
const char* key, const char* doc_string, const char* key, const char* doc_string,
const char *value) const char *value)
{ {
gnc_commodity* commodity{};
const auto book{qof_session_get_book(gnc_get_current_session())}; const auto book{qof_session_get_book(gnc_get_current_session())};
const auto commodity_table{gnc_commodity_table_get_table(book)}; const auto commodity_table{gnc_commodity_table_get_table(book)};
const auto namespaces{gnc_commodity_table_get_namespaces(commodity_table)}; for (const auto& name_space : gnc_commodity_table_get_namespaces(commodity_table))
GncOption* rv = nullptr; if (auto commodity = gnc_commodity_table_lookup (commodity_table, name_space.c_str(),
for (auto node = namespaces; node && commodity == nullptr; value))
node = g_list_next(node)) return gnc_make_commodity_option(section, name, key, doc_string, commodity);
{ return nullptr;
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;
} }
static GncOption* static GncOption*

View File

@ -791,6 +791,14 @@ class GncCommodityTable(GnuCashCoreClass):
which includes most of the world's currencies. which includes most of the world's currencies.
""" """
def get_quotable_commodities (self):
print ("hello from get_quotable_commodities")
return
def get_commodities(self):
print ("hello from get_commodities")
return
def _get_namespaces_py(self): def _get_namespaces_py(self):
return [ns.get_name() for ns in self.get_namespaces_list()] return [ns.get_name() for ns in self.get_namespaces_list()]

View File

@ -289,7 +289,7 @@ typedef char gchar;
} }
} }
%typemap(out) GList *, CommodityList *, SplitList *, AccountList *, LotList *, %typemap(out) GList *, SplitList *, AccountList *, LotList *,
MonetaryList *, PriceList *, EntryList * { MonetaryList *, PriceList *, EntryList * {
gpointer data; gpointer data;
GList *l; GList *l;
@ -332,4 +332,45 @@ typedef char gchar;
} }
$result = list; $result = list;
} }
%typemap(out) CommodityVec
{
PyObject *list = PyList_New(0);
for (auto data : $1)
{
if (GNC_IS_ACCOUNT(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_Account, 0));
else if (GNC_IS_SPLIT(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_Split, 0));
else if (GNC_IS_TRANSACTION(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_Transaction, 0));
else if (GNC_IS_COMMODITY(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_gnc_commodity, 0));
else if (GNC_IS_COMMODITY_NAMESPACE(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_gnc_commodity_namespace, 0));
else if (GNC_IS_LOT(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_GNCLot, 0));
else if (GNC_IS_PRICE(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_GNCPrice, 0));
else if (GNC_IS_INVOICE(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncInvoice, 0));
else if (GNC_IS_ENTRY(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncEntry, 0));
else if (GNC_IS_CUSTOMER(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncCustomer, 0));
else if (GNC_IS_VENDOR(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncVendor, 0));
else if (GNC_IS_EMPLOYEE(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncEmployee, 0));
else if (GNC_IS_JOB(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncJob, 0));
else if (GNC_IS_TAXTABLE(data))
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p__gncTaxTable, 0));
else if ($1_descriptor == $descriptor(MonetaryList *))
PyList_Append(list, SWIG_NewPointerObj(data, $descriptor(gnc_monetary *), 0));
else
PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_void, 0));
}
$result = list;
}
#endif #endif

View File

@ -42,12 +42,15 @@
#include "dialog-commodity.h" #include "dialog-commodity.h"
#include "dialog-utils.h" #include "dialog-utils.h"
#include "gnc-commodity.hpp"
#include "gnc-engine.h" #include "gnc-engine.h"
#include "gnc-gtk-utils.h" #include "gnc-gtk-utils.h"
#include "gnc-gui-query.h" #include "gnc-gui-query.h"
#include "gnc-ui-util.h" #include "gnc-ui-util.h"
#include "gnc-ui.h" #include "gnc-ui.h"
#include <algorithm>
/* This static indicates the debugging module that this .o belongs to. */ /* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_GUI; static QofLogModule log_module = GNC_MOD_GUI;
@ -426,15 +429,6 @@ gnc_ui_select_commodity_namespace_changed_cb (GtkComboBox *cbwe,
/******************************************************************** /********************************************************************
* gnc_ui_update_commodity_picker * gnc_ui_update_commodity_picker
********************************************************************/ ********************************************************************/
static int
collate(gconstpointer a, gconstpointer b)
{
if (!a)
return -1;
if (!b)
return 1;
return g_utf8_collate (static_cast<const char*>(a), static_cast<const char*>(b));
}
void void
@ -442,16 +436,13 @@ gnc_ui_update_commodity_picker (GtkWidget *cbwe,
const gchar * name_space, const gchar * name_space,
const gchar * init_string) const gchar * init_string)
{ {
GList * commodities; std::vector<std::string> commodity_items;
GList * iterator = nullptr;
GList * commodity_items = nullptr;
GtkComboBox *combo_box; GtkComboBox *combo_box;
GtkEntry *entry; GtkEntry *entry;
GtkTreeModel *model; GtkTreeModel *model;
GtkTreeIter iter; GtkTreeIter iter;
gnc_commodity_table *table; gnc_commodity_table *table;
gint current = 0, match = 0; gint current = 0, match = 0;
gchar *name;
g_return_if_fail(GTK_IS_COMBO_BOX(cbwe)); g_return_if_fail(GTK_IS_COMBO_BOX(cbwe));
g_return_if_fail(name_space); g_return_if_fail(name_space);
@ -468,29 +459,23 @@ gnc_ui_update_commodity_picker (GtkWidget *cbwe,
gtk_combo_box_set_active(combo_box, -1); gtk_combo_box_set_active(combo_box, -1);
table = gnc_commodity_table_get_table (gnc_get_current_book ()); 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)
{
commodity_items =
g_list_prepend (commodity_items,
(gpointer) gnc_commodity_get_printname(GNC_COMMODITY(iterator->data)));
}
g_list_free(commodities);
commodity_items = g_list_sort(commodity_items, collate); for (auto comm : gnc_commodity_table_get_commodities(table, name_space))
for (iterator = commodity_items; iterator; iterator = iterator->next) commodity_items.push_back (gnc_commodity_get_printname(comm));
std::sort (commodity_items.end(), commodity_items.begin());
for (auto name : commodity_items)
{ {
name = (char *)iterator->data;
gtk_list_store_append(GTK_LIST_STORE(model), &iter); gtk_list_store_append(GTK_LIST_STORE(model), &iter);
gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, name, -1); gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, name.c_str(), -1);
if (init_string && g_utf8_collate(name, init_string) == 0) if (init_string && name == init_string)
match = current; match = current;
current++; current++;
} }
gtk_combo_box_set_active(combo_box, match); gtk_combo_box_set_active(combo_box, match);
g_list_free(commodity_items);
} }
@ -560,7 +545,7 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
GtkComboBox *combo_box; GtkComboBox *combo_box;
GtkTreeModel *model; GtkTreeModel *model;
GtkTreeIter iter, match; GtkTreeIter iter, match;
GList *namespaces, *node; std::vector<std::string> namespaces;
gboolean matched = FALSE; gboolean matched = FALSE;
g_return_if_fail(GTK_IS_COMBO_BOX (cbwe)); g_return_if_fail(GTK_IS_COMBO_BOX (cbwe));
@ -582,12 +567,10 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
case DIAG_COMM_NON_CURRENCY_SELECT: case DIAG_COMM_NON_CURRENCY_SELECT:
namespaces = namespaces =
gnc_commodity_table_get_namespaces (gnc_get_current_commodities()); gnc_commodity_table_get_namespaces (gnc_get_current_commodities());
node = g_list_find_custom (namespaces, GNC_COMMODITY_NS_CURRENCY, collate);
if (node) if (auto it = std::find (namespaces.begin(), namespaces.end(), GNC_COMMODITY_NS_CURRENCY);
{ it != namespaces.end())
namespaces = g_list_remove_link (namespaces, node); namespaces.erase (it);
g_list_free_1 (node);
}
if (gnc_commodity_namespace_is_iso (init_string)) if (gnc_commodity_namespace_is_iso (init_string))
init_string = nullptr; init_string = nullptr;
@ -595,7 +578,7 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
case DIAG_COMM_CURRENCY: case DIAG_COMM_CURRENCY:
default: default:
namespaces = g_list_prepend (nullptr, (gpointer)GNC_COMMODITY_NS_CURRENCY); namespaces = { GNC_COMMODITY_NS_CURRENCY };
break; break;
} }
@ -623,10 +606,10 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
} }
/* add all others to the combobox */ /* add all others to the combobox */
namespaces = g_list_sort(namespaces, collate); std::sort (namespaces.begin(), namespaces.end());
for (node = namespaces; node; node = node->next) for (const auto& ns_str : namespaces)
{ {
auto ns = static_cast<const char*>(node->data); auto ns = ns_str.c_str();
/* Skip template, legacy and currency namespaces. /* Skip template, legacy and currency namespaces.
The latter was added as first entry earlier */ The latter was added as first entry earlier */
if ((g_utf8_collate(ns, GNC_COMMODITY_NS_LEGACY) == 0) || if ((g_utf8_collate(ns, GNC_COMMODITY_NS_LEGACY) == 0) ||
@ -650,7 +633,6 @@ gnc_ui_update_namespace_picker (GtkWidget *cbwe,
if (matched) if (matched)
gtk_combo_box_set_active_iter (combo_box, &match); gtk_combo_box_set_active_iter (combo_box, &match);
g_list_free(namespaces);
} }

View File

@ -48,6 +48,8 @@
#include <config.h> #include <config.h>
#include <algorithm>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <string.h> #include <string.h>
@ -56,6 +58,7 @@
#include "gnc-currency-edit.h" #include "gnc-currency-edit.h"
#include "gnc-commodity.h" #include "gnc-commodity.h"
#include "gnc-commodity.hpp"
#include "gnc-gtk-utils.h" #include "gnc-gtk-utils.h"
#include "gnc-ui-util.h" #include "gnc-ui-util.h"
#include "gnc-engine.h" #include "gnc-engine.h"
@ -311,12 +314,10 @@ add_item(gnc_commodity *commodity, GNCCurrencyEdit *gce)
static void static void
fill_currencies(GNCCurrencyEdit *gce) fill_currencies(GNCCurrencyEdit *gce)
{ {
GList *currencies; auto currencies = gnc_commodity_table_get_commodities
currencies = gnc_commodity_table_get_commodities
(gnc_get_current_commodities (), GNC_COMMODITY_NS_CURRENCY); (gnc_get_current_commodities (), GNC_COMMODITY_NS_CURRENCY);
g_list_foreach(currencies, (GFunc)add_item, gce); std::for_each (currencies.begin(), currencies.end(),
g_list_free(currencies); [gce](auto comm){ add_item (comm, gce); });
} }

View File

@ -242,16 +242,13 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb)
auto oldest = gnc_time (nullptr); auto oldest = gnc_time (nullptr);
auto model = gtk_tree_view_get_model (view); auto model = gtk_tree_view_get_model (view);
const auto commodity_table = gnc_get_current_commodities (); 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<char*>(node_n->data); auto tmp_namespace = tmp_namespace_str.c_str();
DEBUG("Looking at namespace %s", tmp_namespace); DEBUG("Looking at namespace %s", tmp_namespace);
auto commodity_list = gnc_commodity_table_get_commodities (commodity_table, tmp_namespace); for (auto tmp_commodity : gnc_commodity_table_get_commodities (commodity_table, tmp_namespace))
for (auto node_c = commodity_list; node_c; node_c = g_list_next (node_c))
{ {
auto tmp_commodity = static_cast<gnc_commodity*>(node_c->data);
auto num = gnc_pricedb_num_prices (pdb, tmp_commodity); 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); DEBUG("Looking at commodity %s, Number of prices %d", gnc_commodity_get_fullname (tmp_commodity), num);
@ -279,9 +276,7 @@ gnc_prices_dialog_load_view (GtkTreeView *view, GNCPriceDB *pdb)
g_list_free_full (list, (GDestroyNotify)gnc_price_unref); g_list_free_full (list, (GDestroyNotify)gnc_price_unref);
} }
} }
g_list_free (commodity_list);
} }
g_list_free (namespace_list);
return oldest; return oldest;
} }

View File

@ -40,6 +40,7 @@
#include "gnc-uri-utils.h" #include "gnc-uri-utils.h"
#include "gnc-ui-util.h" #include "gnc-ui-util.h"
#include "dialog-utils.h" #include "dialog-utils.h"
#include "gnc-commodity.hpp"
#include "gnc-component-manager.h" #include "gnc-component-manager.h"
@ -445,9 +446,6 @@ GtkTreeModel *get_model (bool all_commodity)
{ {
GtkTreeModel *store, *model; GtkTreeModel *store, *model;
const gnc_commodity_table *commodity_table = gnc_get_current_commodities (); 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; GtkTreeIter iter;
store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
@ -460,9 +458,9 @@ GtkTreeModel *get_model (bool all_commodity)
gtk_list_store_set (GTK_LIST_STORE(store), &iter, gtk_list_store_set (GTK_LIST_STORE(store), &iter,
DISPLAYED_COMM, " ", SORT_COMM, " ", COMM_PTR, nullptr, SEP, false, -1); 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); DEBUG("Looking at namespace %s", tmp_namespace);
/* Hide the template entry */ /* Hide the template entry */
@ -470,8 +468,6 @@ GtkTreeModel *get_model (bool all_commodity)
{ {
if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY ) == 0) || (all_commodity == true)) if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY ) == 0) || (all_commodity == true))
{ {
auto comm_list = gnc_commodity_table_get_commodities (commodity_table, tmp_namespace);
// if this is the CURRENCY, add a row to be identified as a separator row // 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)) if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0) && (all_commodity == true))
{ {
@ -480,11 +476,10 @@ GtkTreeModel *get_model (bool all_commodity)
SORT_COMM, "CURRENCY-", COMM_PTR, nullptr, SEP, true, -1); SORT_COMM, "CURRENCY-", COMM_PTR, nullptr, SEP, true, -1);
} }
for (auto node = comm_list; node; node = g_list_next (node)) for (auto tmp_commodity : gnc_commodity_table_get_commodities (commodity_table, tmp_namespace))
{ {
const gchar *name_str; const gchar *name_str;
gchar *sort_str; gchar *sort_str;
tmp_commodity = (gnc_commodity*)node->data;
DEBUG("Looking at commodity %s", gnc_commodity_get_fullname (tmp_commodity)); DEBUG("Looking at commodity %s", gnc_commodity_get_fullname (tmp_commodity));
name_str = gnc_commodity_get_printname (tmp_commodity); name_str = gnc_commodity_get_printname (tmp_commodity);
@ -502,11 +497,9 @@ GtkTreeModel *get_model (bool all_commodity)
g_free (sort_str); g_free (sort_str);
} }
g_list_free (comm_list);
} }
} }
} }
g_list_free (namespace_list);
g_object_unref (store); g_object_unref (store);
return model; return model;

View File

@ -32,6 +32,7 @@
#include "gnc-ui-util.h" #include "gnc-ui-util.h"
#include "Account.h" #include "Account.h"
#include "Transaction.h" #include "Transaction.h"
#include "gnc-commodity.hpp"
#include "gnc-pricedb.h" #include "gnc-pricedb.h"
#include <gnc-exp-parser.h> #include <gnc-exp-parser.h>
@ -201,19 +202,16 @@ gnc_commodity* parse_commodity (const std::string& comm_str)
if (!comm) if (!comm)
{ {
/* If that fails try mnemonic in all other namespaces */ /* If that fails try mnemonic in all other namespaces */
auto namespaces = gnc_commodity_table_get_namespaces(table); for (const auto& ns_str : gnc_commodity_table_get_namespaces(table))
for (auto ns = namespaces; ns; ns = ns->next)
{ {
gchar* ns_str = (gchar*)ns->data; if (ns_str == GNC_COMMODITY_NS_CURRENCY)
if (g_utf8_collate(ns_str, GNC_COMMODITY_NS_CURRENCY) == 0)
continue; continue;
comm = gnc_commodity_table_lookup (table, comm = gnc_commodity_table_lookup (table,
ns_str, comm_str.c_str()); ns_str.c_str(), comm_str.c_str());
if (comm) if (comm)
break; break;
} }
g_list_free (namespaces);
} }
if (!comm) if (!comm)

View File

@ -24,6 +24,7 @@
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca> @author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/ */
#include <config.h> #include <config.h>
#include <algorithm>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
@ -34,6 +35,7 @@
#include "Account.h" #include "Account.h"
#include "Transaction.h" #include "Transaction.h"
#include "dialog-commodity.h" #include "dialog-commodity.h"
#include "gnc-commodity.hpp"
#include "gnc-engine.h" #include "gnc-engine.h"
#include "gnc-ui-util.h" #include "gnc-ui-util.h"
@ -64,28 +66,23 @@ gnc_commodity * gnc_import_select_commodity(const char * cusip,
DEBUG("Looking for commodity with exchange_code: %s", cusip); DEBUG("Looking for commodity with exchange_code: %s", cusip);
g_assert(commodity_table); 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<const char*>(n->data); auto ns = ns_str.c_str();
DEBUG("Looking at namespace %s", ns); DEBUG("Looking at namespace %s", ns);
GList *comm_list = gnc_commodity_table_get_commodities (commodity_table, ns); auto commodities{gnc_commodity_table_get_commodities (commodity_table, ns)};
for (GList *m = comm_list; !retval && m; m = g_list_next (m)) auto it = std::find_if (commodities.begin(), commodities.end(),
[cusip](auto com)
{ return !g_strcmp0 (gnc_commodity_get_cusip (com), cusip); });
if (it != commodities.end())
{ {
auto com = static_cast<gnc_commodity*>(m->data); retval = *it;
DEBUG("Looking at commodity %s", gnc_commodity_get_fullname (com)); DEBUG("Commodity %s matches.", gnc_commodity_get_fullname (*it));
if (!g_strcmp0 (gnc_commodity_get_cusip (com), cusip)) break;
{ };
retval = com;
DEBUG("Commodity %s matches.", gnc_commodity_get_fullname (com));
}
}
g_list_free (comm_list);
} }
g_list_free(namespace_list);
if (retval == NULL && ask_on_unknown != 0) if (retval == NULL && ask_on_unknown != 0)
{ {
const gchar *message = const gchar *message =

View File

@ -989,8 +989,6 @@ CommVec
gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table) gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table)
{ {
gnc_commodity_namespace * ns = NULL; gnc_commodity_namespace * ns = NULL;
const char *name_space;
GList * nslist, * tmp;
CommVec l; CommVec l;
regex_t pattern; regex_t pattern;
const char *expression = gnc_prefs_get_namespace_regexp (); const char *expression = gnc_prefs_get_namespace_regexp ();
@ -1007,10 +1005,9 @@ gnc_quotes_get_quotable_commodities (const gnc_commodity_table * table)
return CommVec (); return CommVec ();
} }
nslist = gnc_commodity_table_get_namespaces (table); for (const auto& name_space_str : gnc_commodity_table_get_namespaces (table))
for (tmp = nslist; tmp; tmp = tmp->next)
{ {
name_space = static_cast<const char *> (tmp->data); auto name_space = name_space_str.c_str();
if (regexec (&pattern, name_space, 0, NULL, 0) == 0) if (regexec (&pattern, name_space, 0, NULL, 0) == 0)
{ {
// DEBUG ("Running list of %s commodities", name_space); // 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); regfree (&pattern);
} }
else else

View File

@ -46,6 +46,7 @@
#include <errno.h> #include <errno.h>
#include <cstdint> #include <cstdint>
#include "gnc-commodity.hpp"
#include "gnc-engine.h" #include "gnc-engine.h"
#include "gnc-pricedb-p.h" #include "gnc-pricedb-p.h"
#include "Scrub.h" #include "Scrub.h"
@ -930,20 +931,9 @@ write_counts (FILE* out, ...)
} }
static gint static gint
compare_namespaces (gconstpointer a, gconstpointer b) compare_commodity_less (gnc_commodity* a, gnc_commodity* b)
{ {
const gchar* sa = (const gchar*) a; return (g_strcmp0 (gnc_commodity_get_mnemonic (a), gnc_commodity_get_mnemonic (b)) < 0);
const gchar* sb = (const gchar*) b;
return (g_strcmp0 (sa, sb));
}
static gint
compare_commodity_ids (gconstpointer a, gconstpointer 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)));
} }
static gboolean write_pricedb (FILE* out, QofBook* book, sixtp_gdv2* gd); static gboolean write_pricedb (FILE* out, QofBook* book, sixtp_gdv2* gd);
@ -1039,31 +1029,24 @@ gboolean
write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd) write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd)
{ {
gnc_commodity_table* tbl; gnc_commodity_table* tbl;
GList* namespaces;
GList* lp;
gboolean success = TRUE; gboolean success = TRUE;
tbl = gnc_commodity_table_get_table (book); tbl = gnc_commodity_table_get_table (book);
namespaces = gnc_commodity_table_get_namespaces (tbl); auto namespaces = gnc_commodity_table_get_namespaces (tbl);
if (namespaces)
{
namespaces = g_list_sort (namespaces, compare_namespaces);
}
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; xmlNodePtr comnode;
comms = gnc_commodity_table_get_commodities (tbl, auto comms = gnc_commodity_table_get_commodities (tbl, name_space.c_str());
static_cast<const char*> (lp->data)); std::sort (comms.begin(), comms.end(), compare_commodity_less);
comms = g_list_sort (comms, compare_commodity_ids);
for (lp2 = comms; lp2; lp2 = lp2->next) for (auto comm : comms)
{ {
comnode = gnc_commodity_dom_tree_create (static_cast<const gnc_commodity*> comnode = gnc_commodity_dom_tree_create (comm);
(lp2->data));
if (comnode == NULL) if (comnode == NULL)
continue; continue;
@ -1079,11 +1062,10 @@ write_commodities (FILE* out, QofBook* book, sixtp_gdv2* gd)
sixtp_run_callback (gd, "commodities"); sixtp_run_callback (gd, "commodities");
} }
g_list_free (comms); if (!success)
break;
} }
if (namespaces) g_list_free (namespaces);
return success; return success;
} }

View File

@ -107,13 +107,16 @@ struct _GncCommodityClass
static void commodity_free(gnc_commodity * cm); static void commodity_free(gnc_commodity * cm);
static void gnc_commodity_set_default_symbol(gnc_commodity *, const char *); static void gnc_commodity_set_default_symbol(gnc_commodity *, const char *);
using StrCommodityMap = std::unordered_map<std::string,gnc_commodity*>;
using StrCommodityNSMap = std::unordered_map<std::string,gnc_commodity_namespace*>;
struct gnc_commodity_namespace_s struct gnc_commodity_namespace_s
{ {
QofInstance inst; QofInstance inst;
const gchar *name; const gchar *name;
gboolean iso4217; gboolean iso4217;
GHashTable * cm_table; StrCommodityMap cm_table;
GList * cm_list; GList * cm_list;
}; };
@ -124,7 +127,7 @@ struct _GncCommodityNamespaceClass
struct gnc_commodity_table_s struct gnc_commodity_table_s
{ {
GHashTable * ns_table; StrCommodityNSMap ns_table;
GList * ns_list; GList * ns_list;
}; };
@ -1614,7 +1617,7 @@ gnc_commodity_table *
gnc_commodity_table_new(void) gnc_commodity_table_new(void)
{ {
gnc_commodity_table * retval = g_new0(gnc_commodity_table, 1); gnc_commodity_table * retval = g_new0(gnc_commodity_table, 1);
retval->ns_table = g_hash_table_new(&g_str_hash, &g_str_equal); new (&retval->ns_table) StrCommodityNSMap ();
retval->ns_list = nullptr; retval->ns_list = nullptr;
return retval; return retval;
} }
@ -1657,12 +1660,12 @@ gnc_commodity_obtain_twin (const gnc_commodity *from, QofBook *book)
********************************************************************/ ********************************************************************/
static void static void
count_coms(gpointer key, gpointer value, gpointer user_data) count_coms(const std::string key, gpointer value, gpointer user_data)
{ {
GHashTable *tbl = ((gnc_commodity_namespace*)value)->cm_table; auto tbl = ((gnc_commodity_namespace*)value)->cm_table;
guint *count = (guint*)user_data; guint *count = (guint*)user_data;
if (g_strcmp0((char*)key, GNC_COMMODITY_NS_CURRENCY) == 0) if (key == GNC_COMMODITY_NS_CURRENCY)
{ {
/* don't count default commodities */ /* don't count default commodities */
return; return;
@ -1670,7 +1673,7 @@ count_coms(gpointer key, gpointer value, gpointer user_data)
if (!value) return; if (!value) return;
*count += g_hash_table_size(tbl); *count += tbl.size();
} }
guint guint
@ -1678,9 +1681,9 @@ gnc_commodity_table_get_size(const gnc_commodity_table* tbl)
{ {
guint count = 0; guint count = 0;
g_return_val_if_fail(tbl, 0); g_return_val_if_fail(tbl, 0);
g_return_val_if_fail(tbl->ns_table, 0);
g_hash_table_foreach(tbl->ns_table, count_coms, (gpointer)&count); std::for_each (tbl->ns_table.begin(), tbl->ns_table.end(),
[&count](auto it){ count_coms (it.first, it.second, &count); });
return count; return count;
} }
@ -1712,7 +1715,7 @@ gnc_commodity_table_lookup(const gnc_commodity_table * table,
if (it != gnc_new_iso_codes.end()) if (it != gnc_new_iso_codes.end())
mnemonic = it->second.c_str(); mnemonic = it->second.c_str();
} }
return GNC_COMMODITY(g_hash_table_lookup(nsp->cm_table, (gpointer)mnemonic)); return GNC_COMMODITY(nsp->cm_table[mnemonic]);
} }
else else
{ {
@ -1763,29 +1766,15 @@ gnc_commodity_table_find_full(const gnc_commodity_table * table,
const char * name_space, const char * name_space,
const char * fullname) const char * fullname)
{ {
gnc_commodity * retval = nullptr;
GList * all;
GList * iterator;
if (!fullname || (fullname[0] == '\0')) if (!fullname || (fullname[0] == '\0'))
return nullptr; return nullptr;
all = gnc_commodity_table_get_commodities(table, name_space); 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)); });
for (iterator = all; iterator; iterator = iterator->next) return it == commodities.end() ? nullptr : *it;;
{
auto commodity = GNC_COMMODITY (iterator->data);
if (!strcmp(fullname,
gnc_commodity_get_printname(commodity)))
{
retval = commodity;
break;
}
}
g_list_free (all);
return retval;
} }
@ -1852,10 +1841,8 @@ gnc_commodity_table_insert(gnc_commodity_table * table,
nsp = gnc_commodity_table_add_namespace(table, ns_name, book); nsp = gnc_commodity_table_add_namespace(table, ns_name, book);
PINFO ("insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic, PINFO ("insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic,
nsp->cm_table, nsp->name); &nsp->cm_table, nsp->name);
g_hash_table_insert(nsp->cm_table, nsp->cm_table [priv->mnemonic] = comm;
(gpointer)CACHE_INSERT(priv->mnemonic),
(gpointer)comm);
nsp->cm_list = g_list_append(nsp->cm_list, comm); nsp->cm_list = g_list_append(nsp->cm_list, comm);
qof_event_gen (&comm->inst, QOF_EVENT_ADD, nullptr); qof_event_gen (&comm->inst, QOF_EVENT_ADD, nullptr);
@ -1891,7 +1878,7 @@ gnc_commodity_table_remove(gnc_commodity_table * table,
if (!nsp) return; if (!nsp) return;
nsp->cm_list = g_list_remove(nsp->cm_list, comm); nsp->cm_list = g_list_remove(nsp->cm_list, comm);
g_hash_table_remove (nsp->cm_table, priv->mnemonic); nsp->cm_table.erase (priv->mnemonic);
/* XXX minor mem leak, should remove the key as well */ /* XXX minor mem leak, should remove the key as well */
} }
@ -1922,48 +1909,21 @@ gnc_commodity_table_has_namespace(const gnc_commodity_table * table,
} }
} }
static void
hash_keys_helper(gpointer key, gpointer value, gpointer data)
{
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;
}
static void
hash_values_helper(gpointer key, gpointer value, gpointer data)
{
auto l = (GList**)data;
*l = g_list_prepend(*l, value);
}
static GList *
g_hash_table_values(GHashTable * table)
{
GList * l = nullptr;
g_hash_table_foreach(table, &hash_values_helper, (gpointer) &l);
return l;
}
/******************************************************************** /********************************************************************
* gnc_commodity_table_get_namespaces * gnc_commodity_table_get_namespaces
* see if any commodities in the namespace exist * see if any commodities in the namespace exist
********************************************************************/ ********************************************************************/
GList * std::vector<std::string>
gnc_commodity_table_get_namespaces(const gnc_commodity_table * table) gnc_commodity_table_get_namespaces(const gnc_commodity_table * table)
{ {
std::vector<std::string> rv;
if (!table) if (!table)
return nullptr; return rv;
return g_hash_table_keys(table->ns_table); std::for_each (table->ns_table.begin(), table->ns_table.end(),
[&rv](auto it){ rv.push_back (it.first); });
return rv;
} }
GList * GList *
@ -2009,41 +1969,41 @@ gnc_commodity_is_currency(const gnc_commodity *cm)
* list commodities in a given namespace * list commodities in a given namespace
********************************************************************/ ********************************************************************/
static CommodityList* static CommVec
commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table) commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table)
{ {
GList *node = nullptr, *nslist = gnc_commodity_table_get_namespaces(table); CommVec retval;
CommodityList *retval = nullptr; for (const auto& name_space : gnc_commodity_table_get_namespaces(table))
for (node = nslist; node; node=g_list_next(node))
{ {
gnc_commodity_namespace *ns = nullptr; gnc_commodity_namespace *ns = NULL;
if (g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_CURRENCY) == 0 if (name_space == GNC_COMMODITY_NS_CURRENCY || name_space == GNC_COMMODITY_NS_TEMPLATE)
|| g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_TEMPLATE) == 0)
continue; continue;
ns = gnc_commodity_table_find_namespace(table, (char*)(node->data)); ns = gnc_commodity_table_find_namespace(table, name_space.c_str());
if (!ns) if (!ns)
continue; continue;
retval = g_list_concat(g_hash_table_values(ns->cm_table), retval); std::for_each (ns->cm_table.begin(), ns->cm_table.end(),
[&retval](auto it){ retval.push_back (it.second); });
} }
g_list_free(nslist);
return retval; return retval;
} }
CommodityList * CommVec
gnc_commodity_table_get_commodities(const gnc_commodity_table * table, gnc_commodity_table_get_commodities(const gnc_commodity_table * table,
const char * name_space) const char * name_space)
{ {
gnc_commodity_namespace * ns = nullptr; CommVec retval;
if (!table) if (!table)
return nullptr; return retval;
if (g_strcmp0(name_space, GNC_COMMODITY_NS_NONISO_GUI) == 0) if (g_strcmp0(name_space, GNC_COMMODITY_NS_NONISO_GUI) == 0)
return commodity_table_get_all_noncurrency_commodities(table); 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) if (!ns)
return nullptr; return retval;
return g_hash_table_values(ns->cm_table); std::for_each (ns->cm_table.begin(), ns->cm_table.end(),
[&retval](auto it){ retval.push_back (it.second); });
return retval;
} }
/******************************************************************** /********************************************************************
@ -2054,73 +2014,70 @@ gnc_commodity_table_get_commodities(const gnc_commodity_table * table,
static void static void
get_quotables_helper1(gpointer key, gpointer value, gpointer data) get_quotables_helper1(gpointer key, gpointer value, gpointer data)
{ {
auto comm = GNC_COMMODITY(value); auto comm{GNC_COMMODITY(value)};
auto rv{static_cast<CommVec*>(data)};
gnc_commodityPrivate* priv = GET_PRIVATE(comm); gnc_commodityPrivate* priv = GET_PRIVATE(comm);
auto l = static_cast<GList**>(data);
if (!priv->quote_flag || !priv->quote_source || !priv->quote_source->get_supported()) if (!priv->quote_flag || !priv->quote_source || !priv->quote_source->get_supported())
return; return;
*l = g_list_prepend(*l, value); rv->push_back (comm);
} }
static gboolean static gboolean
get_quotables_helper2 (gnc_commodity *comm, gpointer data) get_quotables_helper2 (gnc_commodity *comm, gpointer data)
{ {
auto l = static_cast<GList**>(data);
gnc_commodityPrivate* priv = GET_PRIVATE(comm); gnc_commodityPrivate* priv = GET_PRIVATE(comm);
auto rv{static_cast<CommVec*>(data)};
if (!priv->quote_flag || priv->quote_source || !priv->quote_source->get_supported()) if (!priv->quote_flag || priv->quote_source || !priv->quote_source->get_supported())
return TRUE; return TRUE;
*l = g_list_prepend(*l, comm); rv->push_back (comm);
return TRUE; return TRUE;
} }
CommodityList * CommVec
gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table) gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table)
{ {
gnc_commodity_namespace * ns = nullptr; gnc_commodity_namespace * ns = nullptr;
const char *name_space; CommVec rv;
GList * nslist, * tmp;
GList * l = nullptr;
regex_t pattern; regex_t pattern;
const char *expression = gnc_prefs_get_namespace_regexp(); const char *expression = gnc_prefs_get_namespace_regexp();
ENTER("table=%p, expression=%s", table, expression); ENTER("table=%p, expression=%s", table, expression);
if (!table) if (!table)
return nullptr; return {};
if (expression && *expression) if (expression && *expression)
{ {
if (regcomp(&pattern, expression, REG_EXTENDED | REG_ICASE) != 0) if (regcomp(&pattern, expression, REG_EXTENDED | REG_ICASE) != 0)
{ {
LEAVE("Cannot compile regex"); LEAVE("Cannot compile regex");
return nullptr; return {};
} }
nslist = gnc_commodity_table_get_namespaces(table); for (const auto& name_space_str : gnc_commodity_table_get_namespaces(table))
for (tmp = nslist; tmp; tmp = tmp->next)
{ {
name_space = static_cast<const char*>(tmp->data); auto name_space = name_space_str.c_str();
if (regexec(&pattern, name_space, 0, nullptr, 0) == 0) if (regexec(&pattern, name_space, 0, NULL, 0) == 0)
{ {
DEBUG("Running list of %s commodities", name_space); DEBUG("Running list of %s commodities", name_space);
ns = gnc_commodity_table_find_namespace(table, name_space); ns = gnc_commodity_table_find_namespace(table, name_space);
if (ns) if (ns)
{ {
g_hash_table_foreach(ns->cm_table, &get_quotables_helper1, (gpointer) &l); std::for_each (ns->cm_table.begin(), ns->cm_table.end(),
[&rv](auto it)
{ get_quotables_helper1 (nullptr, it.second, &rv); });
} }
} }
} }
g_list_free(nslist);
regfree(&pattern); regfree(&pattern);
} }
else else
{ {
gnc_commodity_table_foreach_commodity(table, get_quotables_helper2, gnc_commodity_table_foreach_commodity(table, get_quotables_helper2, &rv);
(gpointer) &l);
} }
LEAVE("list head %p", l); LEAVE("list head %p", &rv);
return l; return rv;
} }
/******************************************************************** /********************************************************************
@ -2160,15 +2117,13 @@ gnc_commodity_table_add_namespace(gnc_commodity_table * table,
if (!ns) if (!ns)
{ {
ns = static_cast<gnc_commodity_namespace*>(g_object_new(GNC_TYPE_COMMODITY_NAMESPACE, nullptr)); ns = static_cast<gnc_commodity_namespace*>(g_object_new(GNC_TYPE_COMMODITY_NAMESPACE, nullptr));
ns->cm_table = g_hash_table_new(g_str_hash, g_str_equal); new (&ns->cm_table) StrCommodityMap ();
ns->name = CACHE_INSERT(static_cast<const char*>(name_space)); ns->name = CACHE_INSERT(static_cast<const char*>(name_space));
ns->iso4217 = gnc_commodity_namespace_is_iso(name_space); ns->iso4217 = gnc_commodity_namespace_is_iso(name_space);
qof_instance_init_data (&ns->inst, GNC_ID_COMMODITY_NAMESPACE, book); qof_instance_init_data (&ns->inst, GNC_ID_COMMODITY_NAMESPACE, book);
qof_event_gen (&ns->inst, QOF_EVENT_CREATE, nullptr); qof_event_gen (&ns->inst, QOF_EVENT_CREATE, nullptr);
g_hash_table_insert(table->ns_table, table->ns_table[ns->name] = ns;
(gpointer) ns->name,
(gpointer) ns);
table->ns_list = g_list_append(table->ns_list, ns); table->ns_list = g_list_append(table->ns_list, ns);
qof_event_gen (&ns->inst, QOF_EVENT_ADD, nullptr); qof_event_gen (&ns->inst, QOF_EVENT_ADD, nullptr);
} }
@ -2184,7 +2139,12 @@ gnc_commodity_table_find_namespace(const gnc_commodity_table * table,
return nullptr; return nullptr;
name_space = gnc_commodity_table_map_namespace(name_space); name_space = gnc_commodity_table_map_namespace(name_space);
return static_cast<gnc_commodity_namespace*>(g_hash_table_lookup(table->ns_table, (gpointer)name_space));
auto it = table->ns_table.find(name_space);
if (it == table->ns_table.end())
return nullptr;
else
return it->second;
} }
@ -2202,15 +2162,6 @@ gnc_commodity_find_commodity_by_guid(const GncGUID *guid, QofBook *book)
* delete a namespace * delete a namespace
********************************************************************/ ********************************************************************/
static int
ns_helper(gpointer key, gpointer value, gpointer user_data)
{
auto c = GNC_COMMODITY(value);
gnc_commodity_destroy(c);
CACHE_REMOVE(static_cast<char*>(key)); /* key is commodity mnemonic */
return TRUE;
}
void void
gnc_commodity_table_delete_namespace(gnc_commodity_table * table, gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
const char * name_space) const char * name_space)
@ -2224,14 +2175,15 @@ gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
return; return;
qof_event_gen (&ns->inst, QOF_EVENT_REMOVE, nullptr); qof_event_gen (&ns->inst, QOF_EVENT_REMOVE, nullptr);
g_hash_table_remove(table->ns_table, name_space); table->ns_table.erase (name_space);
table->ns_list = g_list_remove(table->ns_list, ns); table->ns_list = g_list_remove(table->ns_list, ns);
g_list_free(ns->cm_list); g_list_free(ns->cm_list);
ns->cm_list = nullptr; ns->cm_list = nullptr;
g_hash_table_foreach_remove(ns->cm_table, ns_helper, nullptr); std::for_each (ns->cm_table.begin(), ns->cm_table.end(),
g_hash_table_destroy(ns->cm_table); [](auto it){ gnc_commodity_destroy (it.second); });
ns->cm_table.~StrCommodityMap ();
CACHE_REMOVE(ns->name); CACHE_REMOVE(ns->name);
qof_event_gen (&ns->inst, QOF_EVENT_DESTROY, nullptr); qof_event_gen (&ns->inst, QOF_EVENT_DESTROY, nullptr);
@ -2267,8 +2219,9 @@ iter_commodity (gpointer key, gpointer value, gpointer user_data)
static void static void
iter_namespace (gpointer key, gpointer value, gpointer user_data) iter_namespace (gpointer key, gpointer value, gpointer user_data)
{ {
GHashTable *namespace_hash = ((gnc_commodity_namespace *) value)->cm_table; auto namespace_hash = ((gnc_commodity_namespace *) value)->cm_table;
g_hash_table_foreach (namespace_hash, iter_commodity, user_data); std::for_each (namespace_hash.begin(), namespace_hash.end(),
[user_data](auto it){ iter_commodity (nullptr, it.second, user_data); });
} }
gboolean gboolean
@ -2284,7 +2237,8 @@ gnc_commodity_table_foreach_commodity (const gnc_commodity_table * tbl,
iter_data.func = f; iter_data.func = f;
iter_data.user_data = user_data; iter_data.user_data = user_data;
g_hash_table_foreach(tbl->ns_table, iter_namespace, (gpointer)&iter_data); std::for_each (tbl->ns_table.begin(), tbl->ns_table.end(),
[&iter_data](auto it){ iter_namespace (nullptr, it.second, &iter_data); });
return iter_data.ok; return iter_data.ok;
} }
@ -2312,8 +2266,7 @@ gnc_commodity_table_destroy(gnc_commodity_table * t)
g_list_free(t->ns_list); g_list_free(t->ns_list);
t->ns_list = nullptr; t->ns_list = nullptr;
g_hash_table_destroy(t->ns_table); t->ns_table.~StrCommodityNSMap();
t->ns_table = nullptr;
LEAVE ("table=%p", t); LEAVE ("table=%p", t);
g_free(t); g_free(t);
} }

View File

@ -115,8 +115,6 @@ GType gnc_commodity_namespace_get_type(void);
*/ */
#define GNC_COMMODITY_MAX_FRACTION 1000000000 #define GNC_COMMODITY_MAX_FRACTION 1000000000
typedef GList CommodityList;
/** @name Commodity Quote Source functions /** @name Commodity Quote Source functions
@{ @{
*/ */
@ -829,15 +827,6 @@ GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace
int gnc_commodity_table_has_namespace(const gnc_commodity_table * table, int gnc_commodity_table_has_namespace(const gnc_commodity_table * table,
const char * commodity_namespace); 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 /** Return a list of all namespace data structures in the commodity table. This
* returns both system and user defined namespace structures. * returns both system and user defined namespace structures.
* *
@ -897,41 +886,6 @@ void gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
* commodities, or the routine was passed a bad argument. */ * commodities, or the routine was passed a bad argument. */
guint gnc_commodity_table_get_size(const gnc_commodity_table* tbl); 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. /** Call a function once for each commodity in the commodity table.
* This table walk returns whenever the end of the table is reached, * This table walk returns whenever the end of the table is reached,
* or the function returns FALSE. * or the function returns FALSE.

View File

@ -34,6 +34,7 @@
#define GNC_COMMODITY_HPP #define GNC_COMMODITY_HPP
#include <vector> #include <vector>
#include <string>
#include <gnc-commodity.h> #include <gnc-commodity.h>
@ -51,6 +52,48 @@ using CommVec = std::vector<gnc_commodity*>;
void gnc_quote_source_set_fq_installed (const char* version_string, void gnc_quote_source_set_fq_installed (const char* version_string,
const std::vector<std::string>& sources_list); const std::vector<std::string>& 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<std::string> 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 */ #endif /* GNC_COMMODITY_HPP */
/** @} */ /** @} */
/** @} */ /** @} */

View File

@ -31,6 +31,7 @@
#include "kvp-frame.hpp" #include "kvp-frame.hpp"
#include "qofbookslots.h" #include "qofbookslots.h"
#include "guid.hpp" #include "guid.hpp"
#include "gnc-commodity.hpp"
#include "gnc-optiondb.h" #include "gnc-optiondb.h"
#include "gnc-optiondb.hpp" #include "gnc-optiondb.hpp"
#include "gnc-optiondb-impl.hpp" #include "gnc-optiondb-impl.hpp"
@ -693,13 +694,9 @@ gnc_register_commodity_option(GncOptionDB* db, const char* section,
gnc_commodity* commodity{}; gnc_commodity* commodity{};
const auto book{qof_session_get_book(gnc_get_current_session())}; const auto book{qof_session_get_book(gnc_get_current_session())};
const auto commodity_table{gnc_commodity_table_get_table(book)}; const auto commodity_table{gnc_commodity_table_get_table(book)};
const auto namespaces{gnc_commodity_table_get_namespaces(commodity_table)}; for (const auto& name_space : gnc_commodity_table_get_namespaces(commodity_table))
for (auto node = namespaces; node && commodity == nullptr;
node = g_list_next(node))
{ {
commodity = gnc_commodity_table_lookup(commodity_table, commodity = gnc_commodity_table_lookup(commodity_table, name_space.c_str(), value);
(const char*)(node->data),
value);
if (commodity) if (commodity)
break; break;
} }
@ -707,7 +704,6 @@ gnc_register_commodity_option(GncOptionDB* db, const char* section,
commodity, commodity,
GncOptionUIType::COMMODITY}}; GncOptionUIType::COMMODITY}};
db->register_option(section, std::move(option)); db->register_option(section, std::move(option));
g_list_free (namespaces);
} }
void void

View File

@ -58,6 +58,7 @@
#include "Account.h" #include "Account.h"
#include "AccountP.hpp" #include "AccountP.hpp"
#include "gnc-commodity.hpp"
#include "gnc-engine.h" #include "gnc-engine.h"
#include "gnc-session.h" #include "gnc-session.h"
#include "Transaction.h" #include "Transaction.h"
@ -446,34 +447,22 @@ get_random_commodity_namespace(void)
static gnc_commodity * static gnc_commodity *
get_random_commodity_from_table (gnc_commodity_table *table) get_random_commodity_from_table (gnc_commodity_table *table)
{ {
GList *namespaces;
gnc_commodity *com = NULL; gnc_commodity *com = NULL;
g_return_val_if_fail (table, NULL); g_return_val_if_fail (table, NULL);
namespaces = gnc_commodity_table_get_namespaces (table); auto namespaces = gnc_commodity_table_get_namespaces (table);
do do
{ {
GList *commodities; auto name_space = namespaces.at (get_random_int_in_range (0, namespaces.size() - 1));
char *name_space;
name_space = static_cast<char*>(get_random_list_element (namespaces)); auto commodities = gnc_commodity_table_get_commodities (table, name_space.c_str());
commodities = gnc_commodity_table_get_commodities (table, name_space);
if (!commodities)
continue;
com = static_cast<gnc_commodity*>(get_random_list_element (commodities));
g_list_free (commodities);
com = commodities[std::rand() % commodities.size()];
} }
while (!com); while (!com);
g_list_free (namespaces);
return com; return com;
} }
@ -557,37 +546,24 @@ make_random_changes_to_commodity (gnc_commodity *com)
void void
make_random_changes_to_commodity_table (gnc_commodity_table *table) make_random_changes_to_commodity_table (gnc_commodity_table *table)
{ {
GList *namespaces;
GList *node;
g_return_if_fail (table); 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<const char *>(node->data); auto ns = ns_str.c_str();
GList *commodities;
GList *com_node;
if (gnc_commodity_namespace_is_iso (ns)) if (gnc_commodity_namespace_is_iso (ns))
continue; continue;
commodities = gnc_commodity_table_get_commodities (table, ns); for (auto com : gnc_commodity_table_get_commodities (table, ns))
for (com_node = commodities; com_node; com_node = com_node->next)
{ {
auto com = static_cast<gnc_commodity *>(com_node->data);
gnc_commodity_table_remove (table, com); gnc_commodity_table_remove (table, com);
make_random_changes_to_commodity (com); make_random_changes_to_commodity (com);
gnc_commodity_table_insert (table, com); gnc_commodity_table_insert (table, com);
} }
g_list_free (commodities);
} }
g_list_free (namespaces);
} }
/* ================================================================= */ /* ================================================================= */
/* Price stuff */ /* Price stuff */