2001-08-07 18:36:04 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc-commodity.c -- api for tradable commodities (incl. currency) *
|
|
|
|
* Copyright (C) 2000 Bill Gribble *
|
2003-06-10 17:22:47 -05:00
|
|
|
* Copyright (C) 2001,2003 Linas Vepstas <linas@linas.org> *
|
2001-08-07 18:36:04 -05:00
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or *
|
|
|
|
* modify it under the terms of the GNU General Public License as *
|
|
|
|
* published by the Free Software Foundation; either version 2 of *
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License*
|
|
|
|
* along with this program; if not, contact: *
|
|
|
|
* *
|
|
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
|
|
|
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
|
|
|
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
|
|
|
* *
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
#include <ctype.h>
|
2001-08-07 18:36:04 -05:00
|
|
|
#include <limits.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2003-07-26 03:08:20 -05:00
|
|
|
#include <stdlib.h>
|
2001-08-07 18:36:04 -05:00
|
|
|
#include <glib.h>
|
2003-07-03 17:40:18 -05:00
|
|
|
#include <regex.h>
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
#include "gnc-commodity.h"
|
|
|
|
#include "gnc-engine-util.h"
|
2003-06-10 17:22:47 -05:00
|
|
|
#include "gnc-trace.h"
|
2001-10-12 05:50:35 -05:00
|
|
|
#include "guid.h"
|
2003-08-10 22:06:17 -05:00
|
|
|
#include "messages.h"
|
2003-06-24 19:52:46 -05:00
|
|
|
#include "qofbook.h"
|
2003-06-24 21:08:22 -05:00
|
|
|
#include "qofobject.h"
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2001-10-12 05:50:35 -05:00
|
|
|
static short module = MOD_ENGINE;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-06-10 17:22:47 -05:00
|
|
|
/* Parts per unit is nominal, i.e. number of 'partname' units in
|
2001-08-07 18:36:04 -05:00
|
|
|
* a 'unitname' unit. fraction is transactional, i.e. how many
|
|
|
|
* of the smallest-transactional-units of the currency are there
|
|
|
|
* in a 'unitname' unit. */
|
|
|
|
|
2003-06-10 17:22:47 -05:00
|
|
|
struct gnc_commodity_s
|
|
|
|
{
|
2002-01-01 22:28:32 -06:00
|
|
|
char * fullname;
|
|
|
|
char * namespace;
|
|
|
|
char * mnemonic;
|
|
|
|
char * printname;
|
|
|
|
char * exchange_code; /* CUSIP or other identifying code */
|
|
|
|
int fraction;
|
|
|
|
char * unique_name;
|
|
|
|
gint16 mark; /* user-defined mark, handy for traversals */
|
2003-05-10 19:45:03 -05:00
|
|
|
|
|
|
|
gboolean quote_flag; /* user wants price quotes */
|
2003-07-01 22:35:20 -05:00
|
|
|
gnc_quote_source * quote_source; /* current/old source of quotes */
|
2003-05-10 19:45:03 -05:00
|
|
|
char * quote_tz;
|
2001-08-07 18:36:04 -05:00
|
|
|
};
|
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
struct gnc_commodity_namespace_s
|
|
|
|
{
|
|
|
|
char * namespace;
|
2001-08-07 18:36:04 -05:00
|
|
|
GHashTable * table;
|
|
|
|
};
|
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
struct gnc_commodity_table_s
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
GHashTable * table;
|
|
|
|
};
|
|
|
|
|
2002-01-01 22:28:32 -06:00
|
|
|
typedef struct gnc_commodity_namespace_s gnc_commodity_namespace;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
struct gnc_new_iso_code
|
|
|
|
{
|
2003-05-29 18:47:52 -05:00
|
|
|
const char *old_code;
|
|
|
|
const char *new_code;
|
|
|
|
} gnc_new_iso_codes[] = {
|
|
|
|
{"RUB", "RUR"}, // Russian Ruble
|
|
|
|
{"PLZ", "PLN"}, // Polish Zloty
|
|
|
|
};
|
|
|
|
#define GNC_NEW_ISO_CODES \
|
|
|
|
(sizeof(gnc_new_iso_codes) / sizeof(struct gnc_new_iso_code))
|
2003-07-01 22:35:20 -05:00
|
|
|
|
|
|
|
static gboolean fq_is_installed = FALSE;
|
|
|
|
|
|
|
|
struct gnc_quote_source_s {
|
|
|
|
gboolean supported;
|
|
|
|
QuoteSourceType type;
|
|
|
|
gint index;
|
|
|
|
char *user_name; /* User friendly name */
|
|
|
|
char *old_internal_name; /* Name used internally (deprecated) */
|
|
|
|
char *internal_name; /* Name used internally and by finance::quote. */
|
|
|
|
};
|
|
|
|
|
|
|
|
static gnc_quote_source currency_quote_source =
|
|
|
|
{ TRUE, 0, 0, "CURRENCY", "currency", "currency" };
|
|
|
|
|
|
|
|
static gnc_quote_source single_quote_sources[] = {
|
|
|
|
{ FALSE, 0, 0, "AEX", "AEX", "aex" },
|
|
|
|
{ FALSE, 0, 0, "ASX", "ASX", "asx" },
|
|
|
|
{ FALSE, 0, 0, "DWS", "DWS", "dwsfunds" },
|
|
|
|
{ FALSE, 0, 0, "Fidelity Direct", "FIDELITY_DIRECT", "fidelity_direct" },
|
|
|
|
{ FALSE, 0, 0, "Motley Fool", "FOOL", "fool" },
|
|
|
|
{ FALSE, 0, 0, "Fund Library", "FUNDLIBRARY", "fundlibrary" },
|
|
|
|
{ FALSE, 0, 0, "TD Waterhouse Canada", "TDWATERHOUSE", "tdwaterhouse" },
|
|
|
|
{ FALSE, 0, 0, "TIAA-CREF", "TIAACREF", "tiaacref" },
|
|
|
|
{ FALSE, 0, 0, "T. Rowe Price", "TRPRICE_DIRECT", "troweprice_direct" },
|
|
|
|
{ FALSE, 0, 0, "Trustnet", "TRUSTNET", "trustnet" },
|
|
|
|
{ FALSE, 0, 0, "Union Investments", "UNIONFUNDS", "unionfunds" },
|
|
|
|
{ FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" },
|
|
|
|
{ FALSE, 0, 0, "VWD", "VWD", "vwd" },
|
|
|
|
{ FALSE, 0, 0, "Yahoo", "YAHOO", "yahoo" },
|
|
|
|
{ FALSE, 0, 0, "Yahoo Asia", "YAHOO_ASIA", "yahoo_asia" },
|
|
|
|
{ FALSE, 0, 0, "Yahoo Australia", "YAHOO_AUSTRALIA", "yahoo_australia" },
|
|
|
|
{ FALSE, 0, 0, "Yahoo Europe", "YAHOO_EUROPE", "yahoo_europe" },
|
|
|
|
{ FALSE, 0, 0, "Zuerich Investments", "ZIFUNDS", "zifunds" },
|
|
|
|
};
|
|
|
|
static gnc_quote_source multiple_quote_sources[] = {
|
|
|
|
{ FALSE, 0, 0, "Asia (Yahoo, ...)", "ASIA", "asia" },
|
|
|
|
{ FALSE, 0, 0, "Australia (ASX, Yahoo, ...)", "AUSTRALIA", "australia" },
|
|
|
|
{ FALSE, 0, 0, "Canada (Yahoo, ...)", "CANADA", "canada" },
|
|
|
|
{ FALSE, 0, 0, "Canada Mutual (Fund Library, ...)", "CANADAMUTUAL", "canadamutual" },
|
|
|
|
{ FALSE, 0, 0, "Dutch (AEX, ...)", "DUTCH", "dutch" },
|
|
|
|
{ FALSE, 0, 0, "Europe (Yahoo, ...)", "EUROPE", "europe" },
|
|
|
|
{ FALSE, 0, 0, "Fidelity (Fidelity, ...)", "FIDELITY", "fidelity" },
|
|
|
|
{ FALSE, 0, 0, "Nasdaq (Yahoo, ...)", "NASDAQ", "nasdaq" },
|
|
|
|
{ FALSE, 0, 0, "NYSE (Yahoo, ...)", "NYSE", "nyse" },
|
|
|
|
{ FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
|
|
|
|
{ FALSE, 0, 0, "U.K. Unit Trusts", "UKUNITTRUSTS", "uk_unit_trusts" },
|
|
|
|
{ FALSE, 0, 0, "USA (Yahoo, Fool ...)", "USA", "usa" },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const int num_single_quote_sources =
|
|
|
|
sizeof(single_quote_sources) / sizeof(gnc_quote_source);
|
|
|
|
static const int num_multiple_quote_sources =
|
|
|
|
sizeof(multiple_quote_sources) / sizeof(gnc_quote_source);
|
|
|
|
static GList *new_quote_sources = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_fq_installed
|
|
|
|
*
|
|
|
|
* This function indicates whether or not the Finance::Quote module
|
|
|
|
* is installed on a users computer.
|
|
|
|
********************************************************************/
|
|
|
|
gboolean
|
|
|
|
gnc_quote_source_fq_installed (void)
|
|
|
|
{
|
|
|
|
return fq_is_installed;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_num_entries
|
|
|
|
*
|
|
|
|
* Return the number of entries for a given type of price source.
|
|
|
|
********************************************************************/
|
|
|
|
gint gnc_quote_source_num_entries(QuoteSourceType type)
|
|
|
|
{
|
|
|
|
if (type == SOURCE_CURRENCY)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (type == SOURCE_SINGLE)
|
|
|
|
return num_single_quote_sources;
|
2003-05-29 18:47:52 -05:00
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
if (type == SOURCE_MULTI)
|
|
|
|
return num_multiple_quote_sources;
|
|
|
|
|
|
|
|
return g_list_length(new_quote_sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_init_tables
|
|
|
|
*
|
|
|
|
* Update the type/index values for prices sources.
|
|
|
|
********************************************************************/
|
|
|
|
static void
|
|
|
|
gnc_quote_source_init_tables (void)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 0; i < num_single_quote_sources; i++) {
|
|
|
|
single_quote_sources[i].type = SOURCE_SINGLE;
|
|
|
|
single_quote_sources[i].index = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num_multiple_quote_sources; i++) {
|
|
|
|
multiple_quote_sources[i].type = SOURCE_MULTI;
|
|
|
|
multiple_quote_sources[i].index = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
currency_quote_source.type = SOURCE_CURRENCY;
|
|
|
|
currency_quote_source.index = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_add_new
|
|
|
|
*
|
|
|
|
* Add a new price source. Called when unknown source names are found
|
|
|
|
* either in the F::Q installation (a newly available source) or in
|
|
|
|
* the user's data file (a source that has vanished but needs to be
|
|
|
|
* tracked.)
|
|
|
|
********************************************************************/
|
|
|
|
gnc_quote_source *
|
|
|
|
gnc_quote_source_add_new (const char *source_name, gboolean supported)
|
|
|
|
{
|
|
|
|
gnc_quote_source *new_source;
|
|
|
|
|
|
|
|
DEBUG("Creating new source %s", source_name);
|
|
|
|
new_source = malloc(sizeof(gnc_quote_source));
|
|
|
|
new_source->supported = supported;
|
|
|
|
new_source->type = SOURCE_UNKNOWN;
|
|
|
|
new_source->index = g_list_length(new_quote_sources);
|
|
|
|
|
|
|
|
/* This name can be changed if/when support for this price source is
|
|
|
|
* integrated into gnucash. */
|
|
|
|
new_source->user_name = strdup(source_name);
|
|
|
|
|
|
|
|
/* This name is permanent and must be kept the same if/when support
|
|
|
|
* for this price source is integrated into gnucash (i.e. for a
|
|
|
|
* nice user name). */
|
|
|
|
new_source->old_internal_name = strdup(source_name);
|
|
|
|
new_source->internal_name = strdup(source_name);
|
|
|
|
new_quote_sources = g_list_append(new_quote_sources, new_source);
|
|
|
|
return new_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_lookup_by_xxx
|
|
|
|
*
|
|
|
|
* Lookup a price source data structure based upon various criteria.
|
|
|
|
********************************************************************/
|
|
|
|
gnc_quote_source *
|
|
|
|
gnc_quote_source_lookup_by_ti (QuoteSourceType type, gint index)
|
|
|
|
{
|
|
|
|
gnc_quote_source *source;
|
|
|
|
GList *node;
|
|
|
|
|
|
|
|
ENTER("type/index is %d/%d", type, index);
|
|
|
|
switch (type) {
|
|
|
|
case SOURCE_CURRENCY:
|
|
|
|
LEAVE("found %s", currency_quote_source.user_name);
|
|
|
|
return ¤cy_quote_source;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOURCE_SINGLE:
|
|
|
|
if (index < num_single_quote_sources) {
|
|
|
|
LEAVE("found %s", single_quote_sources[index].user_name);
|
|
|
|
return &single_quote_sources[index];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOURCE_MULTI:
|
|
|
|
if (index < num_multiple_quote_sources) {
|
|
|
|
LEAVE("found %s", multiple_quote_sources[index].user_name);
|
|
|
|
return &multiple_quote_sources[index];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOURCE_UNKNOWN:
|
|
|
|
default:
|
|
|
|
node = g_list_nth(new_quote_sources, index);
|
|
|
|
if (node) {
|
|
|
|
source = node->data;
|
|
|
|
LEAVE("found %s", source->user_name);
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LEAVE("not found");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_quote_source *
|
|
|
|
gnc_quote_source_lookup_by_internal(const char * name)
|
|
|
|
{
|
|
|
|
gnc_quote_source *source;
|
|
|
|
GList *node;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
if ((name == NULL) || (safe_strcmp(name, "") == 0)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safe_strcmp(name, currency_quote_source.internal_name) == 0)
|
|
|
|
return ¤cy_quote_source;
|
|
|
|
if (safe_strcmp(name, currency_quote_source.old_internal_name) == 0)
|
|
|
|
return ¤cy_quote_source;
|
|
|
|
|
|
|
|
for (i = 0; i < num_single_quote_sources; i++) {
|
|
|
|
if (safe_strcmp(name, single_quote_sources[i].internal_name) == 0)
|
|
|
|
return &single_quote_sources[i];
|
|
|
|
if (safe_strcmp(name, single_quote_sources[i].old_internal_name) == 0)
|
|
|
|
return &single_quote_sources[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num_multiple_quote_sources; i++) {
|
|
|
|
if (safe_strcmp(name, multiple_quote_sources[i].internal_name) == 0)
|
|
|
|
return &multiple_quote_sources[i];
|
|
|
|
if (safe_strcmp(name, multiple_quote_sources[i].old_internal_name) == 0)
|
|
|
|
return &multiple_quote_sources[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, node = new_quote_sources; node; node = node->next, i++) {
|
|
|
|
source = node->data;
|
|
|
|
if (safe_strcmp(name, source->internal_name) == 0)
|
|
|
|
return source;
|
|
|
|
if (safe_strcmp(name, source->old_internal_name) == 0)
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
|
|
|
LEAVE("Unknown source %s", name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_get_xxx
|
|
|
|
*
|
|
|
|
* Accessor functions - get functions only. There are no set functions.
|
|
|
|
********************************************************************/
|
|
|
|
QuoteSourceType
|
|
|
|
gnc_quote_source_get_type (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return SOURCE_SINGLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG("type is %d",source->type);
|
|
|
|
return source->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gnc_quote_source_get_index (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG("index is %d", source->index);
|
|
|
|
return source->index;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gnc_quote_source_get_supported (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG("%ssupported", source && source->supported ? "" : "not ");
|
|
|
|
return source->supported;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
gnc_quote_source_get_user_name (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
LEAVE("user name %s", source->user_name);
|
|
|
|
return source->user_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
gnc_quote_source_get_old_internal_name (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
LEAVE("old internal name %s", source->old_internal_name);
|
|
|
|
return source->old_internal_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
gnc_quote_source_get_internal_name (gnc_quote_source *source)
|
|
|
|
{
|
|
|
|
ENTER("%p", source);
|
|
|
|
if (!source) {
|
|
|
|
LEAVE("bad source");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
LEAVE("internal name %s", source->internal_name);
|
|
|
|
return source->internal_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_quote_source_set_fq_installed
|
|
|
|
*
|
|
|
|
* Update gnucash internal tables on what Finance::Quote sources are
|
|
|
|
* installed.
|
|
|
|
********************************************************************/
|
|
|
|
void
|
|
|
|
gnc_quote_source_set_fq_installed (GList *sources_list)
|
|
|
|
{
|
|
|
|
gnc_quote_source *source;
|
|
|
|
char *source_name;
|
|
|
|
GList *node;
|
|
|
|
|
|
|
|
ENTER(" ");
|
|
|
|
fq_is_installed = TRUE;
|
|
|
|
|
|
|
|
if (!sources_list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (node = sources_list; node; node = node->next) {
|
|
|
|
source_name = node->data;
|
|
|
|
|
|
|
|
source = gnc_quote_source_lookup_by_internal(source_name);
|
|
|
|
if (source != NULL) {
|
|
|
|
DEBUG("Found source %s: %s", source_name, source->user_name);
|
|
|
|
source->supported = TRUE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_quote_source_add_new(source_name, TRUE);
|
|
|
|
}
|
|
|
|
LEAVE(" ");
|
|
|
|
}
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_new
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
reset_printname(gnc_commodity *com)
|
|
|
|
{
|
|
|
|
g_free(com->printname);
|
|
|
|
com->printname = g_strdup_printf("%s (%s)",
|
|
|
|
com->mnemonic ? com->mnemonic : "",
|
|
|
|
com->fullname ? com->fullname : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reset_unique_name(gnc_commodity *com)
|
|
|
|
{
|
|
|
|
g_free(com->unique_name);
|
|
|
|
com->unique_name = g_strdup_printf("%s::%s",
|
|
|
|
com->namespace ? com->namespace : "",
|
|
|
|
com->mnemonic ? com->mnemonic : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_new(const char * fullname,
|
|
|
|
const char * namespace, const char * mnemonic,
|
|
|
|
const char * exchange_code,
|
2002-01-02 00:31:49 -06:00
|
|
|
int fraction)
|
2001-08-07 18:36:04 -05:00
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity * retval = g_new0(gnc_commodity, 1);
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
retval->fullname = g_cache_insert(str_cache, (gpointer)fullname);
|
|
|
|
retval->namespace = g_cache_insert(str_cache, (gpointer)namespace);
|
|
|
|
retval->mnemonic = g_cache_insert(str_cache, (gpointer)mnemonic);
|
|
|
|
retval->exchange_code = g_cache_insert(str_cache, (gpointer)exchange_code);
|
2001-08-07 18:36:04 -05:00
|
|
|
retval->fraction = fraction;
|
|
|
|
retval->mark = 0;
|
2003-08-16 23:20:25 -05:00
|
|
|
retval->quote_flag = 0;
|
|
|
|
retval->quote_source = NULL;
|
|
|
|
retval->quote_tz = NULL;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
reset_printname(retval);
|
|
|
|
reset_unique_name(retval);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_destroy
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2001-10-03 05:07:45 -05:00
|
|
|
gnc_commodity_destroy(gnc_commodity * cm)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
/* Set at creation */
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->fullname);
|
2001-10-03 05:07:45 -05:00
|
|
|
cm->fullname = NULL;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->namespace);
|
2001-10-03 05:07:45 -05:00
|
|
|
cm->namespace = NULL;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->exchange_code);
|
2001-10-03 05:07:45 -05:00
|
|
|
cm->exchange_code = NULL;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->mnemonic);
|
2001-10-03 05:07:45 -05:00
|
|
|
cm->mnemonic = NULL;
|
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
/* Set through accessor functions */
|
|
|
|
cm->quote_source = NULL;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->quote_tz);
|
2003-05-10 19:45:03 -05:00
|
|
|
cm->quote_tz = NULL;
|
|
|
|
|
|
|
|
/* Automatically generated */
|
|
|
|
g_free(cm->printname);
|
|
|
|
cm->printname = NULL;
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
g_free(cm->unique_name);
|
2001-10-03 05:07:45 -05:00
|
|
|
cm->unique_name = NULL;
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
cm->mark = 0;
|
2001-10-03 05:07:45 -05:00
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
g_free(cm);
|
|
|
|
}
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
void
|
|
|
|
gnc_commodity_copy(gnc_commodity * dest, gnc_commodity *src)
|
|
|
|
{
|
|
|
|
gnc_commodity_set_fullname (dest, src->fullname);
|
|
|
|
gnc_commodity_set_namespace (dest, src->namespace);
|
|
|
|
gnc_commodity_set_fraction (dest, src->fraction);
|
|
|
|
gnc_commodity_set_exchange_code (dest, src->exchange_code);
|
|
|
|
gnc_commodity_set_quote_flag (dest, src->quote_flag);
|
|
|
|
gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src));
|
|
|
|
gnc_commodity_set_quote_tz (dest, src->quote_tz);
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_clone(gnc_commodity *src)
|
|
|
|
{
|
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
|
|
|
gnc_commodity * dest = g_new0(gnc_commodity, 1);
|
|
|
|
|
|
|
|
dest->fullname = g_cache_insert(str_cache, src->fullname);
|
|
|
|
dest->namespace = g_cache_insert(str_cache, src->namespace);
|
|
|
|
dest->mnemonic = g_cache_insert(str_cache, src->mnemonic);
|
|
|
|
dest->exchange_code = g_cache_insert(str_cache, src->exchange_code);
|
|
|
|
dest->fraction = src->fraction;
|
|
|
|
dest->mark = 0;
|
|
|
|
|
|
|
|
dest->quote_flag = src->quote_flag;
|
|
|
|
dest->quote_source = g_cache_insert(str_cache, src->quote_source);
|
|
|
|
dest->quote_tz = g_cache_insert(str_cache, src->quote_tz);
|
|
|
|
|
|
|
|
reset_printname(dest);
|
|
|
|
reset_unique_name(dest);
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_mnemonic
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_mnemonic(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->mnemonic;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_printname
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_printname(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->printname;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_namespace
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_namespace(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->namespace;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_fullname
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_fullname(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->fullname;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_unique_name
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_unique_name(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->unique_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_exchange_code
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char *
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_exchange_code(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->exchange_code;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_fraction
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
int
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_fraction(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return 0;
|
|
|
|
return cm->fraction;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_mark
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gint16
|
2002-01-01 22:28:32 -06:00
|
|
|
gnc_commodity_get_mark(const gnc_commodity * cm)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return 0;
|
|
|
|
return cm->mark;
|
|
|
|
}
|
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_quote_flag
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gnc_commodity_get_quote_flag(const gnc_commodity *cm)
|
|
|
|
{
|
|
|
|
if(!cm) return FALSE;
|
|
|
|
return (cm->quote_flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_quote_source
|
|
|
|
********************************************************************/
|
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
gnc_quote_source*
|
2003-05-10 19:45:03 -05:00
|
|
|
gnc_commodity_get_quote_source(const gnc_commodity *cm)
|
|
|
|
{
|
|
|
|
if(!cm) return NULL;
|
|
|
|
if (!cm->quote_source && gnc_commodity_is_iso(cm))
|
2003-07-01 22:35:20 -05:00
|
|
|
return ¤cy_quote_source;
|
2003-05-10 19:45:03 -05:00
|
|
|
return cm->quote_source;
|
|
|
|
}
|
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
gnc_quote_source*
|
|
|
|
gnc_commodity_get_default_quote_source(const gnc_commodity *cm)
|
|
|
|
{
|
|
|
|
if (cm && gnc_commodity_is_iso(cm))
|
|
|
|
return ¤cy_quote_source;
|
|
|
|
/* Should make this a user option at some point. */
|
|
|
|
return gnc_quote_source_lookup_by_internal("yahoo");
|
|
|
|
}
|
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_quote_tz
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
const char*
|
|
|
|
gnc_commodity_get_quote_tz(const gnc_commodity *cm)
|
|
|
|
{
|
|
|
|
if(!cm) return NULL;
|
|
|
|
return cm->quote_tz;
|
|
|
|
}
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_mnemonic
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_set_mnemonic(gnc_commodity * cm, const char * mnemonic)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
if(cm->mnemonic == mnemonic) return;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->mnemonic);
|
|
|
|
cm->mnemonic = g_cache_insert(str_cache, (gpointer)mnemonic);
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
reset_printname(cm);
|
|
|
|
reset_unique_name(cm);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_namespace
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_set_namespace(gnc_commodity * cm, const char * namespace)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
if(cm->namespace == namespace) return;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->namespace);
|
|
|
|
cm->namespace = g_cache_insert(str_cache, (gpointer)namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
reset_printname(cm);
|
|
|
|
reset_unique_name(cm);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_fullname
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_set_fullname(gnc_commodity * cm, const char * fullname)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
if(cm->fullname == fullname) return;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->fullname);
|
|
|
|
cm->fullname = g_cache_insert(str_cache, (gpointer)fullname);
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
reset_printname(cm);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_exchange_code
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_set_exchange_code(gnc_commodity * cm,
|
2002-01-02 04:08:17 -06:00
|
|
|
const char * exchange_code)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
if(cm->exchange_code == exchange_code) return;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->exchange_code);
|
|
|
|
cm->exchange_code = g_cache_insert(str_cache, (gpointer)exchange_code);
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_fraction
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_set_fraction(gnc_commodity * cm, int fraction)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
cm->fraction = fraction;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
2003-05-10 19:45:03 -05:00
|
|
|
* gnc_commodity_set_mark
|
2001-08-07 18:36:04 -05:00
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_set_mark(gnc_commodity * cm, gint16 mark)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(!cm) return;
|
|
|
|
cm->mark = mark;
|
|
|
|
}
|
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_quote_flag
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_set_quote_flag(gnc_commodity *cm, const gboolean flag)
|
|
|
|
{
|
|
|
|
ENTER ("(cm=%p, flag=%d)", cm, flag);
|
|
|
|
|
|
|
|
if(!cm) return;
|
|
|
|
cm->quote_flag = flag;
|
|
|
|
LEAVE(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_quote_source
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2003-07-01 22:35:20 -05:00
|
|
|
gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
|
2003-05-10 19:45:03 -05:00
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2003-07-01 22:35:20 -05:00
|
|
|
ENTER ("(cm=%p, src=%p(%s))", cm, src, src ? src->internal_name : "unknown");
|
2003-05-10 19:45:03 -05:00
|
|
|
|
|
|
|
if(!cm) return;
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->quote_source);
|
|
|
|
cm->quote_source = g_cache_insert(str_cache, src);
|
2003-05-10 19:45:03 -05:00
|
|
|
LEAVE(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_set_quote_tz
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2003-05-10 19:45:03 -05:00
|
|
|
ENTER ("(cm=%p, tz=%s)", cm, tz);
|
|
|
|
|
|
|
|
if(!cm) return;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove(str_cache, cm->quote_tz);
|
|
|
|
if (cm->quote_tz) cm->quote_tz = NULL;
|
|
|
|
|
|
|
|
if (tz && *tz) cm->quote_tz = g_cache_insert(str_cache, (gpointer)tz);
|
2003-05-10 19:45:03 -05:00
|
|
|
|
|
|
|
LEAVE(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************\
|
|
|
|
\********************************************************************/
|
|
|
|
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_equiv
|
|
|
|
* are two commodities the same?
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gboolean
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_equiv(const gnc_commodity * a, const gnc_commodity * b)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if(a == b) return TRUE;
|
|
|
|
if(!a || !b) return FALSE;
|
|
|
|
if(safe_strcmp(a->namespace, b->namespace) != 0) return FALSE;
|
|
|
|
if(safe_strcmp(a->mnemonic, b->mnemonic) != 0) return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2001-10-12 05:50:35 -05:00
|
|
|
gboolean
|
|
|
|
gnc_commodity_equal(const gnc_commodity * a, const gnc_commodity * b)
|
|
|
|
{
|
|
|
|
if (a == b) return TRUE;
|
|
|
|
|
|
|
|
if (!a || !b)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("one is NULL");
|
2001-10-12 05:50:35 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safe_strcmp(a->namespace, b->namespace) != 0)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("namespaces differ: %s vs %s", a->namespace, b->namespace);
|
2001-10-12 05:50:35 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safe_strcmp(a->mnemonic, b->mnemonic) != 0)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("mnemonics differ: %s vs %s", a->mnemonic, b->mnemonic);
|
2001-10-12 05:50:35 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safe_strcmp(a->fullname, b->fullname) != 0)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("fullnames differ: %s vs %s", a->fullname, b->fullname);
|
2001-10-12 05:50:35 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safe_strcmp(a->exchange_code, b->exchange_code) != 0)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("exchange codes differ: %s vs %s",
|
2001-10-12 05:50:35 -05:00
|
|
|
a->exchange_code, b->exchange_code);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (a->fraction != b->fraction)
|
|
|
|
{
|
2002-12-07 17:50:14 -06:00
|
|
|
DEBUG ("fractions differ: %d vs %d", a->fraction, b->fraction);
|
2001-10-12 05:50:35 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_new
|
|
|
|
* make a new commodity table
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gnc_commodity_table *
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_table_new(void)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_table * retval = g_new0(gnc_commodity_table, 1);
|
|
|
|
retval->table = g_hash_table_new(&g_str_hash, &g_str_equal);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2003-06-09 22:33:06 -05:00
|
|
|
/********************************************************************
|
|
|
|
* book anchor functons
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
#define GNC_COMMODITY_TABLE "gnc_commodity_table"
|
|
|
|
gnc_commodity_table *
|
2003-06-24 19:52:46 -05:00
|
|
|
gnc_commodity_table_get_table(QofBook *book)
|
2003-06-09 22:33:06 -05:00
|
|
|
{
|
|
|
|
if (!book) return NULL;
|
2003-06-24 19:52:46 -05:00
|
|
|
return qof_book_get_data (book, GNC_COMMODITY_TABLE);
|
2003-06-09 22:33:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-24 19:52:46 -05:00
|
|
|
gnc_commodity_table_set_table(QofBook *book, gnc_commodity_table *ct)
|
2003-06-09 22:33:06 -05:00
|
|
|
{
|
2003-06-09 22:36:48 -05:00
|
|
|
gnc_commodity_table *old_ct;
|
2003-06-09 22:33:06 -05:00
|
|
|
if (!book) return;
|
2003-06-09 22:36:48 -05:00
|
|
|
|
|
|
|
old_ct = gnc_commodity_table_get_table (book);
|
2003-06-09 22:38:11 -05:00
|
|
|
if (old_ct == ct) return;
|
2003-06-24 19:52:46 -05:00
|
|
|
qof_book_set_data (book, GNC_COMMODITY_TABLE, ct);
|
2003-06-09 22:36:48 -05:00
|
|
|
gnc_commodity_table_destroy (old_ct);
|
2003-06-09 22:33:06 -05:00
|
|
|
}
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_get_size
|
|
|
|
* get the size of the commodity table
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
guint
|
|
|
|
gnc_commodity_table_get_number_of_namespaces(gnc_commodity_table* tbl)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail(tbl, 0);
|
|
|
|
g_return_val_if_fail(tbl->table, 0);
|
|
|
|
return g_hash_table_size(tbl->table);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
count_coms(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
GHashTable *tbl = ((gnc_commodity_namespace*)value)->table;
|
|
|
|
guint *count = (guint*)user_data;
|
|
|
|
|
|
|
|
if(safe_strcmp((char*)key, GNC_COMMODITY_NS_ISO) == 0)
|
|
|
|
{
|
|
|
|
/* don't count default commodities */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!value) return;
|
|
|
|
|
|
|
|
*count += g_hash_table_size(tbl);
|
|
|
|
}
|
|
|
|
|
|
|
|
guint
|
|
|
|
gnc_commodity_table_get_size(gnc_commodity_table* tbl)
|
|
|
|
{
|
|
|
|
guint count = 0;
|
|
|
|
g_return_val_if_fail(tbl, 0);
|
|
|
|
g_return_val_if_fail(tbl->table, 0);
|
|
|
|
|
|
|
|
g_hash_table_foreach(tbl->table, count_coms, (gpointer)&count);
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_lookup
|
|
|
|
* locate a commodity by namespace and mnemonic.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_table_lookup(const gnc_commodity_table * table,
|
2003-05-29 18:47:52 -05:00
|
|
|
const char * namespace, const char * mnemonic)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * nsp = NULL;
|
2003-05-30 13:34:06 -05:00
|
|
|
unsigned int i;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
if (!table || !namespace || !mnemonic) return NULL;
|
|
|
|
|
|
|
|
nsp = g_hash_table_lookup(table->table, (gpointer)namespace);
|
|
|
|
|
|
|
|
if(nsp) {
|
2003-01-11 15:36:34 -06:00
|
|
|
/*
|
2003-05-29 18:47:52 -05:00
|
|
|
* Backward compatability support for currencies that have
|
|
|
|
* recently changed.
|
2003-01-11 15:36:34 -06:00
|
|
|
*/
|
2003-05-29 18:47:52 -05:00
|
|
|
for (i = 0; i < GNC_NEW_ISO_CODES; i++) {
|
|
|
|
if (strcmp(mnemonic, gnc_new_iso_codes[i].old_code) == 0) {
|
|
|
|
mnemonic = gnc_new_iso_codes[i].new_code;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-08-07 18:36:04 -05:00
|
|
|
return g_hash_table_lookup(nsp->table, (gpointer)mnemonic);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_lookup
|
|
|
|
* locate a commodity by unique name.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_table_lookup_unique(const gnc_commodity_table *table,
|
|
|
|
const char * unique_name)
|
|
|
|
{
|
|
|
|
char *namespace;
|
|
|
|
char *mnemonic;
|
|
|
|
gnc_commodity *commodity;
|
|
|
|
|
|
|
|
if (!table || !unique_name) return NULL;
|
|
|
|
|
|
|
|
namespace = g_strdup (unique_name);
|
|
|
|
mnemonic = strstr (namespace, "::");
|
|
|
|
if (!mnemonic)
|
|
|
|
{
|
|
|
|
g_free (namespace);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*mnemonic = '\0';
|
|
|
|
mnemonic += 2;
|
|
|
|
|
|
|
|
commodity = gnc_commodity_table_lookup (table, namespace, mnemonic);
|
|
|
|
|
|
|
|
g_free (namespace);
|
|
|
|
|
|
|
|
return commodity;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_find_full
|
|
|
|
* locate a commodity by namespace and printable name
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_table_find_full(const gnc_commodity_table * table,
|
|
|
|
const char * namespace,
|
2003-08-16 23:20:25 -05:00
|
|
|
const char * fullname)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity * retval=NULL;
|
|
|
|
GList * all;
|
|
|
|
GList * iterator;
|
|
|
|
|
|
|
|
if (!fullname || (fullname[0] == '\0'))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
all = gnc_commodity_table_get_commodities(table, namespace);
|
|
|
|
|
|
|
|
for(iterator = all; iterator; iterator=iterator->next) {
|
|
|
|
if(!strcmp(fullname,
|
|
|
|
gnc_commodity_get_printname(iterator->data))) {
|
|
|
|
retval = iterator->data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (all);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_insert
|
|
|
|
* add a commodity to the table.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gnc_commodity *
|
|
|
|
gnc_commodity_table_insert(gnc_commodity_table * table,
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity * comm)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache;
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * nsp = NULL;
|
|
|
|
gnc_commodity *c;
|
|
|
|
|
|
|
|
if (!table) return NULL;
|
|
|
|
if (!comm) return NULL;
|
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
ENTER ("(table=%p, comm=%p) %s %s", table, comm, comm->mnemonic, comm->fullname);
|
2001-08-07 18:36:04 -05:00
|
|
|
c = gnc_commodity_table_lookup (table, comm->namespace, comm->mnemonic);
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
if (c)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if (c == comm)
|
2003-08-10 22:06:17 -05:00
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
return c;
|
2003-08-10 22:06:17 -05:00
|
|
|
}
|
2003-08-16 23:20:25 -05:00
|
|
|
gnc_commodity_copy (c, comm);
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_destroy (comm);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsp = g_hash_table_lookup(table->table, (gpointer)(comm->namespace));
|
2003-08-16 23:20:25 -05:00
|
|
|
str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
if(!nsp)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
nsp = g_new0(gnc_commodity_namespace, 1);
|
|
|
|
nsp->table = g_hash_table_new(g_str_hash, g_str_equal);
|
2003-08-16 23:20:25 -05:00
|
|
|
nsp->namespace = g_cache_insert(str_cache, comm->namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_hash_table_insert(table->table,
|
2003-08-16 23:20:25 -05:00
|
|
|
nsp->namespace,
|
2001-08-07 18:36:04 -05:00
|
|
|
(gpointer)nsp);
|
|
|
|
}
|
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
PINFO ("insert %p %s into nsp=%p %s", comm->mnemonic, comm->mnemonic, nsp->table, nsp->namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_hash_table_insert(nsp->table,
|
2003-08-16 23:20:25 -05:00
|
|
|
(gpointer)g_cache_insert(str_cache, comm->mnemonic),
|
2001-08-07 18:36:04 -05:00
|
|
|
(gpointer)comm);
|
|
|
|
|
2003-08-10 22:06:17 -05:00
|
|
|
LEAVE ("(table=%p, comm=%p)", table, comm);
|
2001-08-07 18:36:04 -05:00
|
|
|
return comm;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_remove
|
|
|
|
* remove a commodity from the table.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_table_remove(gnc_commodity_table * table,
|
|
|
|
gnc_commodity * comm)
|
|
|
|
{
|
|
|
|
gnc_commodity_namespace * nsp;
|
|
|
|
gnc_commodity *c;
|
|
|
|
|
|
|
|
if (!table) return;
|
|
|
|
if (!comm) return;
|
|
|
|
|
|
|
|
c = gnc_commodity_table_lookup (table, comm->namespace, comm->mnemonic);
|
|
|
|
if (c != comm) return;
|
|
|
|
|
|
|
|
nsp = g_hash_table_lookup (table->table, comm->namespace);
|
|
|
|
if (!nsp) return;
|
|
|
|
|
|
|
|
g_hash_table_remove (nsp->table, comm->mnemonic);
|
2003-08-16 23:48:40 -05:00
|
|
|
/* XXX minor mem leak, should remove the key as well */
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_has_namespace
|
2003-05-10 19:45:03 -05:00
|
|
|
* see if the commodities namespace exists. May have zero commodities.
|
2001-08-07 18:36:04 -05:00
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
int
|
|
|
|
gnc_commodity_table_has_namespace(const gnc_commodity_table * table,
|
2002-01-02 04:08:17 -06:00
|
|
|
const char * namespace)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * nsp = NULL;
|
|
|
|
|
|
|
|
if(!table || !namespace) { return 0; }
|
|
|
|
|
|
|
|
nsp = g_hash_table_lookup(table->table, (gpointer)namespace);
|
|
|
|
if(nsp) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-01-02 04:08:17 -06:00
|
|
|
hash_keys_helper(gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
GList ** l = data;
|
|
|
|
*l = g_list_prepend(*l, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GList *
|
2002-01-02 04:08:17 -06:00
|
|
|
g_hash_table_keys(GHashTable * table)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
GList * l = NULL;
|
|
|
|
g_hash_table_foreach(table, &hash_keys_helper, (gpointer) &l);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-01-02 04:08:17 -06:00
|
|
|
hash_values_helper(gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
GList ** l = data;
|
|
|
|
*l = g_list_prepend(*l, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GList *
|
2002-01-02 04:08:17 -06:00
|
|
|
g_hash_table_values(GHashTable * table)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
GList * l = NULL;
|
|
|
|
g_hash_table_foreach(table, &hash_values_helper, (gpointer) &l);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_get_namespaces
|
|
|
|
* see if any commodities in the namespace exist
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
GList *
|
2002-01-02 04:08:17 -06:00
|
|
|
gnc_commodity_table_get_namespaces(const gnc_commodity_table * table)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if (!table)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return g_hash_table_keys(table->table);
|
|
|
|
}
|
|
|
|
|
2003-04-29 01:15:34 -05:00
|
|
|
gboolean
|
|
|
|
gnc_commodity_namespace_is_iso(const char *namespace)
|
|
|
|
{
|
|
|
|
return (safe_strcmp(namespace, GNC_COMMODITY_NS_ISO) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gnc_commodity_is_iso(const gnc_commodity * cm)
|
|
|
|
{
|
|
|
|
if (!cm) return FALSE;
|
|
|
|
return (safe_strcmp(cm->namespace, GNC_COMMODITY_NS_ISO) == 0);
|
|
|
|
}
|
2001-08-07 18:36:04 -05:00
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_get_commodities
|
|
|
|
* list commodities in a give namespace
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
GList *
|
|
|
|
gnc_commodity_table_get_commodities(const gnc_commodity_table * table,
|
2002-01-02 04:08:17 -06:00
|
|
|
const char * namespace)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * ns = NULL;
|
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
if (!table)
|
|
|
|
return NULL;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-05-10 19:45:03 -05:00
|
|
|
ns = g_hash_table_lookup(table->table, (gpointer)namespace);
|
|
|
|
if (!ns)
|
2001-08-07 18:36:04 -05:00
|
|
|
return NULL;
|
2003-05-10 19:45:03 -05:00
|
|
|
|
|
|
|
return g_hash_table_values(ns->table);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_get_quotable_commodities
|
|
|
|
* list commodities in a given namespace that get price quotes
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
get_quotables_helper1(gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
|
|
|
gnc_commodity *comm = value;
|
|
|
|
GList ** l = data;
|
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
if (!comm->quote_flag ||
|
|
|
|
!comm->quote_source || !comm->quote_source->supported)
|
2003-05-10 19:45:03 -05:00
|
|
|
return;
|
|
|
|
*l = g_list_prepend(*l, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
get_quotables_helper2 (gnc_commodity *comm, gpointer data)
|
|
|
|
{
|
|
|
|
GList ** l = data;
|
|
|
|
|
2003-07-01 22:35:20 -05:00
|
|
|
if (!comm->quote_flag ||
|
|
|
|
!comm->quote_source || !comm->quote_source->supported)
|
2003-05-10 19:45:03 -05:00
|
|
|
return TRUE;
|
|
|
|
*l = g_list_prepend(*l, comm);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GList *
|
|
|
|
gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table,
|
2003-07-03 17:40:18 -05:00
|
|
|
const char *expression)
|
2003-05-10 19:45:03 -05:00
|
|
|
{
|
2003-07-03 17:40:18 -05:00
|
|
|
gnc_commodity_namespace * ns = NULL;
|
|
|
|
const char *namespace;
|
|
|
|
GList * nslist, * tmp;
|
2003-05-10 19:45:03 -05:00
|
|
|
GList * l = NULL;
|
2003-07-03 17:40:18 -05:00
|
|
|
regex_t pattern;
|
2003-05-10 19:45:03 -05:00
|
|
|
|
2003-07-03 17:40:18 -05:00
|
|
|
ENTER("table=%p, expression=%s", table, expression);
|
2003-05-10 19:45:03 -05:00
|
|
|
if (!table)
|
|
|
|
return NULL;
|
|
|
|
|
2003-07-03 17:40:18 -05:00
|
|
|
if (expression && *expression) {
|
|
|
|
if (regcomp(&pattern, expression, REG_EXTENDED|REG_ICASE) != 0) {
|
|
|
|
LEAVE("Cannot compile regex");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
nslist = gnc_commodity_table_get_namespaces(table);
|
|
|
|
for (tmp = nslist; tmp; tmp = tmp->next) {
|
|
|
|
namespace = tmp->data;
|
|
|
|
if (regexec(&pattern, namespace, 0, NULL, 0) == 0) {
|
|
|
|
DEBUG("Running list of %s commodities", namespace);
|
|
|
|
ns = g_hash_table_lookup(table->table, namespace);
|
|
|
|
if (ns) {
|
|
|
|
g_hash_table_foreach(ns->table, &get_quotables_helper1, (gpointer) &l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g_list_free(nslist);
|
|
|
|
regfree(&pattern);
|
2003-05-10 19:45:03 -05:00
|
|
|
} else {
|
|
|
|
gnc_commodity_table_foreach_commodity(table, get_quotables_helper2,
|
|
|
|
(gpointer) &l);
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
2003-05-10 19:45:03 -05:00
|
|
|
LEAVE("list head %p", l);
|
|
|
|
return l;
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_add_namespace
|
|
|
|
* add an empty namespace if it does not exist
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_table_add_namespace(gnc_commodity_table * table,
|
2002-01-02 04:08:17 -06:00
|
|
|
const char * namespace)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * ns = NULL;
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
if(table)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
ns = g_hash_table_lookup(table->table, (gpointer)namespace);
|
|
|
|
}
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
if(!ns)
|
|
|
|
{
|
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
ns = g_new0(gnc_commodity_namespace, 1);
|
|
|
|
ns->table = g_hash_table_new(g_str_hash, g_str_equal);
|
2003-08-16 23:20:25 -05:00
|
|
|
ns->namespace = g_cache_insert(str_cache, (gpointer)namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_hash_table_insert(table->table,
|
2003-08-16 23:20:25 -05:00
|
|
|
(gpointer) ns->namespace,
|
2001-08-07 18:36:04 -05:00
|
|
|
(gpointer) ns);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_delete_namespace
|
|
|
|
* delete a namespace
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static int
|
2002-01-02 04:08:17 -06:00
|
|
|
ns_helper(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
2003-08-16 23:48:40 -05:00
|
|
|
GCache *str_cache = user_data;
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity * c = value;
|
|
|
|
gnc_commodity_destroy(c);
|
2003-08-16 23:48:40 -05:00
|
|
|
g_cache_remove (str_cache, key); /* key is commodity mnemonic */
|
2001-08-07 18:36:04 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
|
2002-01-02 04:08:17 -06:00
|
|
|
const char * namespace)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
gnc_commodity_namespace * ns;
|
|
|
|
if (!table) return;
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
ns = g_hash_table_lookup(table->table, namespace);
|
|
|
|
if (ns)
|
|
|
|
{
|
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
|
|
|
g_hash_table_remove(table->table, namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-08-16 23:48:40 -05:00
|
|
|
g_hash_table_foreach_remove(ns->table, ns_helper, str_cache);
|
2003-08-16 23:20:25 -05:00
|
|
|
g_hash_table_destroy(ns->table);
|
|
|
|
g_cache_remove (str_cache, ns->namespace);
|
|
|
|
g_free(ns);
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_foreach_commodity
|
|
|
|
* call user-defined function once for every commodity in every
|
|
|
|
* namespace
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
gboolean ok;
|
|
|
|
gboolean (*func)(gnc_commodity *, gpointer);
|
|
|
|
gpointer user_data;
|
|
|
|
} IterData;
|
|
|
|
|
|
|
|
static void
|
|
|
|
iter_commodity (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
IterData *iter_data = (IterData *) user_data;
|
|
|
|
gnc_commodity *cm = (gnc_commodity *) value;
|
|
|
|
|
|
|
|
if (iter_data->ok)
|
|
|
|
{
|
|
|
|
iter_data->ok = (iter_data->func)(cm, iter_data->user_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
iter_namespace (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
GHashTable *namespace_hash = ((gnc_commodity_namespace *) value)->table;
|
|
|
|
g_hash_table_foreach (namespace_hash, iter_commodity, user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2003-05-10 19:45:03 -05:00
|
|
|
gnc_commodity_table_foreach_commodity (const gnc_commodity_table * tbl,
|
2001-08-07 18:36:04 -05:00
|
|
|
gboolean (*f)(gnc_commodity *, gpointer),
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
IterData iter_data;
|
|
|
|
|
2001-12-31 15:14:28 -06:00
|
|
|
if (!tbl || !f) return FALSE;
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
iter_data.ok = TRUE;
|
|
|
|
iter_data.func = f;
|
|
|
|
iter_data.user_data = user_data;
|
|
|
|
|
|
|
|
g_hash_table_foreach(tbl->table, iter_namespace, (gpointer)&iter_data);
|
|
|
|
|
|
|
|
return iter_data.ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_destroy
|
|
|
|
* cleanup and free.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static int
|
2001-12-31 15:14:28 -06:00
|
|
|
ct_helper(gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
2003-08-16 23:20:25 -05:00
|
|
|
GCache *str_cache = gnc_engine_get_string_cache ();
|
2001-08-07 18:36:04 -05:00
|
|
|
gnc_commodity_namespace * ns = value;
|
2003-08-16 23:20:25 -05:00
|
|
|
|
2003-08-17 00:03:15 -05:00
|
|
|
g_hash_table_foreach_remove(ns->table, ns_helper, str_cache);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_hash_table_destroy(ns->table);
|
|
|
|
ns->table = NULL;
|
2003-08-16 23:20:25 -05:00
|
|
|
g_cache_remove (str_cache, ns->namespace);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_free(ns);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-31 15:14:28 -06:00
|
|
|
gnc_commodity_table_destroy(gnc_commodity_table * t)
|
|
|
|
{
|
2001-08-07 18:36:04 -05:00
|
|
|
if (!t) return;
|
2003-08-10 22:06:17 -05:00
|
|
|
ENTER ("table=%p", t);
|
2001-08-07 18:36:04 -05:00
|
|
|
|
2003-08-17 00:03:15 -05:00
|
|
|
g_hash_table_foreach_remove(t->table, ct_helper, NULL);
|
2001-08-07 18:36:04 -05:00
|
|
|
g_hash_table_destroy(t->table);
|
2003-08-10 22:06:17 -05:00
|
|
|
t->table = NULL;
|
2001-08-07 18:36:04 -05:00
|
|
|
g_free(t);
|
2003-08-10 22:06:17 -05:00
|
|
|
LEAVE ("table=%p", t);
|
2001-08-07 18:36:04 -05:00
|
|
|
}
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
/* =========================================================== */
|
|
|
|
|
2001-10-12 05:50:35 -05:00
|
|
|
static gboolean
|
|
|
|
table_equal_helper (gnc_commodity *cm_1, gpointer user_data)
|
|
|
|
{
|
|
|
|
gnc_commodity_table *t_2 = user_data;
|
|
|
|
gnc_commodity *cm_2;
|
|
|
|
|
|
|
|
cm_2 = gnc_commodity_table_lookup (t_2,
|
|
|
|
gnc_commodity_get_namespace (cm_1),
|
|
|
|
gnc_commodity_get_mnemonic (cm_1));
|
|
|
|
|
|
|
|
if (!cm_2)
|
|
|
|
{
|
|
|
|
PWARN ("one has commodity %s, the other does not",
|
|
|
|
gnc_commodity_get_unique_name (cm_1));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gnc_commodity_equal (cm_1, cm_2);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gnc_commodity_table_equal(gnc_commodity_table *t_1,
|
|
|
|
gnc_commodity_table *t_2)
|
|
|
|
{
|
|
|
|
gboolean ok;
|
|
|
|
|
|
|
|
if (t_1 == t_2) return TRUE;
|
|
|
|
if (!t_1 || !t_2) return FALSE;
|
|
|
|
|
|
|
|
ok = gnc_commodity_table_foreach_commodity (t_1, table_equal_helper, t_2);
|
|
|
|
if (!ok)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return gnc_commodity_table_foreach_commodity (t_2, table_equal_helper, t_1);
|
|
|
|
}
|
|
|
|
|
2003-08-16 23:20:25 -05:00
|
|
|
/* =========================================================== */
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
table_copy_helper (gnc_commodity *src_cm, gpointer user_data)
|
|
|
|
{
|
|
|
|
gnc_commodity_table *dest = user_data;
|
|
|
|
gnc_commodity_table_insert (dest, gnc_commodity_clone (src_cm));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gnc_commodity_table_copy(gnc_commodity_table *dest,
|
|
|
|
gnc_commodity_table *src)
|
|
|
|
{
|
|
|
|
gnc_commodity_table_foreach_commodity (src, table_copy_helper, dest);
|
|
|
|
}
|
|
|
|
|
2001-12-11 10:15:08 -06:00
|
|
|
/********************************************************************
|
|
|
|
* gnc_commodity_table_add_default_data
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
gboolean
|
2002-01-02 00:31:49 -06:00
|
|
|
gnc_commodity_table_add_default_data(gnc_commodity_table *table)
|
2001-12-11 10:15:08 -06:00
|
|
|
{
|
2003-08-10 22:06:17 -05:00
|
|
|
ENTER ("table=%p", table);
|
2003-01-06 01:15:30 -06:00
|
|
|
#include "iso-4217-currencies.c"
|
2001-12-11 10:15:08 -06:00
|
|
|
|
|
|
|
gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_AMEX);
|
|
|
|
gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_NYSE);
|
|
|
|
gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_NASDAQ);
|
|
|
|
gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_EUREX);
|
|
|
|
gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_MUTUAL);
|
2003-08-10 22:06:17 -05:00
|
|
|
LEAVE ("table=%p", table);
|
2001-12-11 10:15:08 -06:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-06-10 17:22:47 -05:00
|
|
|
/********************************************************************
|
|
|
|
********************************************************************/
|
|
|
|
/* gncObject function implementation and registration */
|
|
|
|
|
|
|
|
static void
|
2003-06-24 19:52:46 -05:00
|
|
|
commodity_table_book_begin (QofBook *book)
|
2003-06-10 17:22:47 -05:00
|
|
|
{
|
|
|
|
gnc_commodity_table *ct;
|
2003-08-10 22:06:17 -05:00
|
|
|
ENTER ("book=%p", book);
|
2003-06-10 17:22:47 -05:00
|
|
|
|
|
|
|
ct = gnc_commodity_table_new ();
|
|
|
|
if(!gnc_commodity_table_add_default_data(ct))
|
|
|
|
{
|
|
|
|
PWARN("unable to initialize book's commodity_table");
|
|
|
|
}
|
|
|
|
gnc_commodity_table_set_table (book, ct);
|
2003-08-10 22:06:17 -05:00
|
|
|
LEAVE ("book=%p", book);
|
2003-06-10 17:22:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-06-24 19:52:46 -05:00
|
|
|
commodity_table_book_end (QofBook *book)
|
2003-06-10 17:22:47 -05:00
|
|
|
{
|
|
|
|
gnc_commodity_table_set_table (book, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX Why is the commodity table never marked dirty/clean?
|
|
|
|
* Don't we have to save user-created/modified commodities?
|
|
|
|
* I don't get it ... does this need fixing?
|
|
|
|
*/
|
2003-06-24 21:08:22 -05:00
|
|
|
static QofObject commodity_table_object_def =
|
2003-06-10 17:22:47 -05:00
|
|
|
{
|
2003-06-26 21:51:10 -05:00
|
|
|
interface_version: QOF_OBJECT_VERSION,
|
2003-06-10 17:22:47 -05:00
|
|
|
name: GNC_ID_COMMODITY_TABLE,
|
|
|
|
type_label: "CommodityTable",
|
|
|
|
book_begin: commodity_table_book_begin,
|
|
|
|
book_end: commodity_table_book_end,
|
|
|
|
is_dirty: NULL,
|
|
|
|
mark_clean: NULL,
|
2003-06-10 19:43:28 -05:00
|
|
|
foreach: NULL,
|
2003-06-10 17:22:47 -05:00
|
|
|
printable: NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gnc_commodity_table_register (void)
|
|
|
|
{
|
2003-07-01 22:35:20 -05:00
|
|
|
gnc_quote_source_init_tables();
|
2003-06-24 21:08:22 -05:00
|
|
|
return qof_object_register (&commodity_table_object_def);
|
2003-06-10 17:22:47 -05:00
|
|
|
}
|
|
|
|
|
2001-08-07 18:36:04 -05:00
|
|
|
/* ========================= END OF FILE ============================== */
|