[gcalctool] Use currency rates from the IMF as well as the ECB to add 24 new rates: AED, BHD, BND, BWP, CLP, COP
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcalctool] Use currency rates from the IMF as well as the ECB to add 24 new rates: AED, BHD, BND, BWP, CLP, COP
- Date: Wed, 8 Dec 2010 06:26:18 +0000 (UTC)
commit cfcb0bfc150f45c416f87ce97b4297a75b118752
Author: Robert Ancell <robert ancell canonical com>
Date: Wed Dec 8 17:25:15 2010 +1100
Use currency rates from the IMF as well as the ECB to add 24 new rates: AED, BHD, BND, BWP, CLP, COP, DZD, ILS, IRR, KWD, KZT, LKR, LYD, MUR, NPR, OMR, PEN, PKR, QAR, SAR, TND, TTD, UYU, VEF
NEWS | 5 +-
src/currency.c | 423 +++++++++++++++++++++++++++++++++++++++++---------------
src/currency.h | 97 ++++++++-----
3 files changed, 370 insertions(+), 155 deletions(-)
---
diff --git a/NEWS b/NEWS
index a42631b..aea84c4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,9 @@
Overview of changes in gcalctool 5.91.4
* Use new Indian Rupee sign â?¹ (Bug #636587, Carlos Cejudo)
- * Remove Icelandic krona (ISK) from currency list, it is no longer provided
- by the ECB.
+ * Use currency rates from the IMF as well as the ECB to add 24 new rates:
+ AED, BHD, BND, BWP, CLP, COP, DZD, ILS, IRR, KWD, KZT, LKR,
+ LYD, MUR, NPR, OMR, PEN, PKR, QAR, SAR, TND, TTD, UYU, VEF
Overview of changes in gcalctool 5.91.3
diff --git a/src/currency.c b/src/currency.c
index a489510..d49d7e4 100644
--- a/src/currency.c
+++ b/src/currency.c
@@ -16,14 +16,23 @@ typedef struct {
const CurrencyInfo *info;
} Currency;
-static Currency *currencies = NULL;
-static int currency_count = 0;
+static GList *currencies = NULL;
-static gboolean downloading_rates = FALSE;
+static gboolean downloading_imf_rates = FALSE, downloading_ecb_rates = FALSE;
static gboolean loaded_rates = FALSE;
-static char*
-get_rate_filepath()
+static char *
+get_imf_rate_filepath()
+{
+ return g_build_filename(g_get_user_cache_dir (),
+ "gcalctool",
+ "rms_five.xls",
+ NULL);
+}
+
+
+static char *
+get_ecb_rate_filepath()
{
return g_build_filename(g_get_user_cache_dir (),
"gcalctool",
@@ -31,138 +40,313 @@ get_rate_filepath()
NULL);
}
-static int
-currency_get_index(const char *short_name)
+
+static Currency *
+add_currency(const gchar *short_name)
{
+ Currency *c;
int i;
- for (i = 0; i < currency_count; i++) {
- if (!strcmp(short_name, currencies[i].short_name)) {
- if (mp_is_negative(¤cies[i].value) ||
- mp_is_zero(¤cies[i].value)) {
- return -1;
- } else {
- return i;
+
+ c = g_malloc0(sizeof(Currency));
+ c->short_name = g_strdup(short_name);
+ for (i = 0; currency_info[i].short_name; i++) {
+ if (strcmp(c->short_name, currency_info[i].short_name) == 0) {
+ c->info = ¤cy_info[i];
+ break;
+ }
+ }
+ if (!c->info)
+ g_warning("Currency %s is not in the currency table", c->short_name);
+
+ currencies = g_list_append(currencies, c);
+
+ return c;
+}
+
+
+static Currency *
+get_currency(const gchar *short_name)
+{
+ GList *link;
+ for (link = currencies; link; link = link->next) {
+ Currency *c = link->data;
+ if (!strcmp(short_name, c->short_name)) {
+ if (mp_is_negative(&c->value) ||
+ mp_is_zero(&c->value)) {
+ return NULL;
}
+ else
+ return c;
}
}
- return -1;
+ return NULL;
}
-/* A file needs to be redownloaded if it doesn't exist, or every 7 days.
+
+/* A file needs to be redownloaded if it doesn't exist, or is too old.
* When an error occur, it probably won't hurt to try to download again.
*/
-static int
-currency_rates_needs_update()
+static gboolean
+file_needs_update(gchar *filename, double max_age)
{
- gchar *filename = get_rate_filepath ();
struct stat buf;
- if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
- g_free(filename);
- return 1;
- }
- if (g_stat(filename, &buf) == -1) {
- g_free(filename);
- return 1;
- }
- g_free(filename);
+ if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+ return TRUE;
- if (difftime(time(NULL), buf.st_mtime) > (60 * 60 * 24 * 7)) {
- return 1;
- }
+ if (g_stat(filename, &buf) == -1)
+ return TRUE;
+
+ if (difftime(time(NULL), buf.st_mtime) > max_age)
+ return TRUE;
- return 0;
+ return FALSE;
}
static void
-download_cb(GObject *object, GAsyncResult *result, gpointer user_data)
+download_imf_cb(GObject *object, GAsyncResult *result, gpointer user_data)
{
GError *error = NULL;
if (g_file_copy_finish(G_FILE(object), result, &error))
- g_debug("Rates updated");
+ g_debug("IMF rates updated");
else
- g_warning("Couldn't download currency file: %s", error->message);
+ g_warning("Couldn't download IMF currency rate file: %s", error->message);
g_clear_error(&error);
- downloading_rates = FALSE;
+ downloading_imf_rates = FALSE;
}
static void
-currency_download_rates()
+download_ecb_cb(GObject *object, GAsyncResult *result, gpointer user_data)
{
- gchar *filename, *directory;
- GFile *source, *dest;
+ GError *error = NULL;
- downloading_rates = TRUE;
- g_debug("Downloading rates...");
+ if (g_file_copy_finish(G_FILE(object), result, &error))
+ g_debug("ECB rates updated");
+ else
+ g_warning("Couldn't download ECB currency rate file: %s", error->message);
+ g_clear_error(&error);
+ downloading_ecb_rates = FALSE;
+}
+
+
+static void
+download_file(gchar *uri, gchar *filename, GAsyncReadyCallback callback)
+{
+ gchar *directory;
+ GFile *source, *dest;
- filename = get_rate_filepath();
directory = g_path_get_dirname(filename);
g_mkdir_with_parents(directory, 0755);
g_free(directory);
- source = g_file_new_for_uri ("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
- dest = g_file_new_for_path (filename);
- g_free(filename);
+ source = g_file_new_for_uri(uri);
+ dest = g_file_new_for_path(filename);
- g_file_copy_async (source, dest, G_FILE_COPY_OVERWRITE, G_PRIORITY_DEFAULT, NULL, NULL, NULL, download_cb, NULL);
+ g_file_copy_async(source, dest, G_FILE_COPY_OVERWRITE, G_PRIORITY_DEFAULT, NULL, NULL, NULL, callback, NULL);
g_object_unref(source);
- g_object_unref(dest);
+ g_object_unref(dest);
}
static void
-set_rate (xmlNodePtr node, Currency *cur)
+load_imf_rates()
{
- xmlAttrPtr attribute;
- for (attribute = node->properties; attribute; attribute = attribute->next) {
- if (strcmp((char *)attribute->name, "currency") == 0) {
- int i;
-
- cur->short_name = (char *)xmlNodeGetContent((xmlNodePtr) attribute);
- for (i = 0; currency_info[i].short_name; i++)
- {
- if (strcmp(cur->short_name, currency_info[i].short_name) == 0)
- {
- cur->info = ¤cy_info[i];
+ gchar *filename;
+ gchar *data, **lines;
+ gsize length;
+ GError *error = NULL;
+ int i;
+ gboolean result, in_data = FALSE;
+ struct
+ {
+ const gchar *name, *symbol;
+ } name_map[] =
+ {
+ {"Euro", "EUR"},
+ {"Japanese Yen", "JPY"},
+ {"U.K. Pound Sterling", "GBP"},
+ {"U.S. Dollar", "USD"},
+ {"Algerian Dinar", "DZD"},
+ {"Australian Dollar", "AUD"},
+ {"Bahrain Dinar", "BHD"},
+ {"Botswana Pula", "BWP"},
+ {"Brazilian Real", "BRL"},
+ {"Brunei Dollar", "BND"},
+ {"Canadian Dollar", "CAD"},
+ {"Chilean Peso", "CLP"},
+ {"Chinese Yuan", "CNY"},
+ {"Colombian Peso", "COP"},
+ {"Czech Koruna", "CZK"},
+ {"Danish Krone", "DKK"},
+ {"Hungarian Forint", "HUF"},
+ {"Icelandic Krona", "ISK"},
+ {"Indian Rupee", "INR"},
+ {"Indonesian Rupiah", "IDR"},
+ {"Iranian Rial", "IRR"},
+ {"Israeli New Sheqel", "ILS"},
+ {"Kazakhstani Tenge", "KZT"},
+ {"Korean Won", "KRW"},
+ {"Kuwaiti Dinar", "KWD"},
+ {"Libyan Dinar", "LYD"},
+ {"Malaysian Ringgit", "MYR"},
+ {"Mauritian Rupee", "MUR"},
+ {"Mexican Peso", "MXN"},
+ {"Nepalese Rupee", "NPR"},
+ {"New Zealand Dollar", "NZD"},
+ {"Norwegian Krone", "NOK"},
+ {"Rial Omani", "OMR"},
+ {"Pakistani Rupee", "PKR"},
+ {"Nuevo Sol", "PEN"},
+ {"Philippine Peso", "PHP"},
+ {"Polish Zloty", "PLN"},
+ {"Qatar Riyal", "QAR"},
+ {"Russian Ruble", "RUB"},
+ {"Saudi Arabian Riyal", "SAR"},
+ {"Singapore Dollar", "SGD"},
+ {"South African Rand", "ZAR"},
+ {"Sri Lanka Rupee", "LKR"},
+ {"Swedish Krona", "SEK"},
+ {"Swiss Franc", "CHF"},
+ {"Thai Baht", "THB"},
+ {"Trinidad And Tobago Dollar", "TTD"},
+ {"Tunisian Dinar", "TND"},
+ {"U.A.E. Dirham", "AED"},
+ {"Peso Uruguayo", "UYU"},
+ {"Bolivar Fuerte", "VEF"},
+ {NULL, NULL}
+ };
+
+ filename = get_imf_rate_filepath();
+ result = g_file_get_contents(filename, &data, &length, &error);
+ g_free(filename);
+ if (!result)
+ {
+ g_warning("Failed to read exchange rates: %s", error->message);
+ g_clear_error(&error);
+ return;
+ }
+
+ lines = g_strsplit(data, "\n", 0);
+ g_free(data);
+
+ for (i = 0; lines[i]; i++) {
+ gchar *line, **tokens;
+
+ line = g_strchug(lines[i]);
+
+ /* Start after first blank line, stop on next */
+ if (line[0] == '\0') {
+ if (!in_data) {
+ in_data = TRUE;
+ continue;
+ }
+ else
+ break;
+ }
+ if (!in_data)
+ continue;
+
+ tokens = g_strsplit(line, "\t", 0);
+ if (strcmp(tokens[0], "Currency") != 0) {
+ gint value_index, name_index;
+
+ for (value_index = 1; tokens[value_index]; value_index++) {
+ gchar *value = g_strchug (tokens[value_index]);
+ if (value[0] != '\0')
break;
+ }
+ if (tokens[value_index]) {
+ for (name_index = 0; name_map[name_index].name; name_index++) {
+ if (strcmp(name_map[name_index].name, tokens[0]) == 0)
+ break;
}
+ if (name_map[name_index].name) {
+ Currency *c = get_currency(name_map[name_index].symbol);
+ if (!c) {
+ g_debug ("Using IMF rate of %s for %s", tokens[value_index], name_map[name_index].symbol);
+ c = add_currency(name_map[name_index].symbol);
+ }
+ mp_set_from_string(tokens[value_index], 10, &c->value);
+ }
+ else
+ g_warning("Unknown currency '%s'", tokens[0]);
}
- if (!cur->info)
- g_warning("Currency %s is not in the currency table", cur->short_name);
+ }
+ g_strfreev(tokens);
+ }
+ g_strfreev(lines);
+}
+
+
+static void
+set_ecb_rate(xmlNodePtr node, Currency *eur_rate)
+{
+ xmlAttrPtr attribute;
+ gchar *name = NULL, *value = NULL;
+
+ for (attribute = node->properties; attribute; attribute = attribute->next) {
+ if (strcmp((char *)attribute->name, "currency") == 0) {
+ if (name)
+ xmlFree(name);
+ name = (gchar *)xmlNodeGetContent((xmlNodePtr)attribute);
} else if (strcmp ((char *)attribute->name, "rate") == 0) {
- char *val = (char *)xmlNodeGetContent ((xmlNodePtr) attribute);
- mp_set_from_string(val, 10, &(cur->value));
- xmlFree (val);
+ if (value)
+ xmlFree(value);
+ value = (gchar *)xmlNodeGetContent((xmlNodePtr)attribute);
}
}
+
+ /* Use data if value and no rate currently defined */
+ if (name && value && !get_currency(name)) {
+ Currency *c;
+ MPNumber r;
+
+ g_debug ("Using ECB rate of %s for %s", value, name);
+ c = add_currency(name);
+ mp_set_from_string(value, 10, &r);
+ mp_set_from_mp(&eur_rate->value, &c->value);
+ mp_divide(&c->value, &r, &c->value);
+ }
+
+ if (name)
+ xmlFree(name);
+ if (value)
+ xmlFree(value);
}
+
static void
-currency_load_rates()
+load_ecb_rates()
{
- char *filename = get_rate_filepath();
+ Currency *eur_rate;
+ char *filename = get_ecb_rate_filepath();
xmlDocPtr document;
xmlXPathContextPtr xpath_ctx;
xmlXPathObjectPtr xpath_obj;
int i, len;
- g_return_if_fail(g_file_test(filename, G_FILE_TEST_IS_REGULAR));
+ /* Scale rates to the EUR value */
+ eur_rate = get_currency("EUR");
+ if (!eur_rate) {
+ g_warning("Cannot use ECB rates as don't have EUR rate");
+ return;
+ }
xmlInitParser();
document = xmlReadFile(filename, NULL, 0);
g_free (filename);
if (document == NULL) {
- fprintf(stderr, "Couldn't parse data file\n");
+ g_error("Couldn't parse ECB rate file %s", filename);
return;
}
xpath_ctx = xmlXPathNewContext(document);
if (xpath_ctx == NULL) {
xmlFreeDoc(document);
- fprintf(stderr, "Couldn't create XPath context\n");
+ g_error("Couldn't create XPath context");
return;
}
@@ -171,52 +355,51 @@ currency_load_rates()
BAD_CAST("http://www.ecb.int/vocabulary/2002-08-01/eurofxref"));
xpath_obj = xmlXPathEvalExpression(BAD_CAST("//xref:Cube[ currency][@rate]"),
xpath_ctx);
-
if (xpath_obj == NULL) {
xmlXPathFreeContext(xpath_ctx);
xmlFreeDoc(document);
fprintf(stderr, "Couldn't create XPath object\n");
return;
}
-
len = (xpath_obj->nodesetval) ? xpath_obj->nodesetval->nodeNr : 0;
- currency_count = len + 1;
- currencies = g_slice_alloc0(sizeof(Currency) * currency_count);
for (i = 0; i < len; i++) {
- if (xpath_obj->nodesetval->nodeTab[i]->type == XML_ELEMENT_NODE) {
- set_rate(xpath_obj->nodesetval->nodeTab[i], ¤cies[i]);
- }
+ if (xpath_obj->nodesetval->nodeTab[i]->type == XML_ELEMENT_NODE)
+ set_ecb_rate(xpath_obj->nodesetval->nodeTab[i], eur_rate);
- // Avoid accessing removed elements
+ /* Avoid accessing removed elements */
if (xpath_obj->nodesetval->nodeTab[i]->type != XML_NAMESPACE_DECL)
xpath_obj->nodesetval->nodeTab[i] = NULL;
}
- currencies[len].short_name = g_strdup("EUR");
- MPNumber foo;
- mp_set_from_integer(1, &foo);
- currencies[len].value = foo;
- currencies[len].info = currency_get_info("EUR");
-
xmlXPathFreeObject(xpath_obj);
xmlXPathFreeContext(xpath_ctx);
xmlFreeDoc(document);
- xmlCleanupParser();
+ xmlCleanupParser();
+}
- for (i = 0; currency_info[i].short_name; i++)
- {
- int j;
- for (j = 0; j < currency_count; j++)
- {
- if (currencies[j].info == ¤cy_info[i])
+
+static void
+load_rates()
+{
+ int i;
+
+ /* Use the IMF provided values and top up with currencies tracked by the ECB and not the IMF */
+ load_imf_rates();
+ load_ecb_rates();
+
+ for (i = 0; currency_info[i].short_name; i++) {
+ GList *link;
+ for (link = currencies; link; link = link->next) {
+ Currency *c = link->data;
+ if (c->info == ¤cy_info[i])
break;
}
- if (j == currency_count)
- g_warning("Currency %s is not provided by server", currency_info[i].short_name);
+ if (!link)
+ g_warning("Currency %s is not provided by IMF or ECB", currency_info[i].short_name);
}
g_debug("Rates loaded");
- loaded_rates = TRUE;
+ loaded_rates = TRUE;
}
@@ -238,32 +421,44 @@ currency_convert(const MPNumber *from_amount,
const char *source_currency, const char *target_currency,
MPNumber *to_amount)
{
- int from_index, to_index;
+ gchar *path;
+ Currency *from_info, *to_info;
+
+ /* Update rates if necessary */
+ path = get_imf_rate_filepath();
+ if (!downloading_imf_rates && file_needs_update(path, 60 * 60 * 24 * 7)) {
+ downloading_imf_rates = TRUE;
+ g_debug("Downloading rates from the IMF...");
+ download_file("http://www.imf.org/external/np/fin/data/rms_five.aspx?tsvflag=Y", path, download_imf_cb);
+ }
+ g_free(path);
+ path = get_ecb_rate_filepath();
+ if (!downloading_ecb_rates && file_needs_update(path, 60 * 60 * 24 * 7)) {
+ downloading_ecb_rates = TRUE;
+ g_debug("Downloading rates from the ECB...");
+ download_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml", path, download_ecb_cb);
+ }
+ g_free(path);
- if (downloading_rates)
+ if (downloading_imf_rates || downloading_ecb_rates)
return FALSE;
- /* Update currency if necessary */
- if (currency_rates_needs_update()) {
- currency_download_rates();
- return FALSE;
- }
if (!loaded_rates)
- currency_load_rates();
+ load_rates();
- from_index = currency_get_index(source_currency);
- to_index = currency_get_index(target_currency);
- if (from_index < 0 || to_index < 0)
+ from_info = get_currency(source_currency);
+ to_info = get_currency(target_currency);
+ if (!from_info || !to_info)
return FALSE;
- if (mp_is_zero(¤cies[from_index].value) ||
- mp_is_zero(¤cies[to_index].value)) {
+ if (mp_is_zero(&from_info->value) ||
+ mp_is_zero(&to_info->value)) {
mp_set_from_integer(0, to_amount);
return FALSE;
}
- mp_divide(from_amount, ¤cies[from_index].value, to_amount);
- mp_multiply(to_amount, ¤cies[to_index].value, to_amount);
+ mp_divide(from_amount, &to_info->value, to_amount);
+ mp_multiply(to_amount, &from_info->value, to_amount);
return TRUE;
}
@@ -271,13 +466,13 @@ currency_convert(const MPNumber *from_amount,
void
currency_free_resources()
{
- int i;
+ GList *link;
- for (i = 0; i < currency_count; i++) {
- if (currencies[i].short_name != NULL)
- xmlFree(currencies[i].short_name);
+ for (link = currencies; link; link = link->next) {
+ Currency *c = link->data;
+ g_free(c->short_name);
+ g_free(c);
}
- g_slice_free1(currency_count * sizeof(Currency), currencies);
+ g_list_free(currencies);
currencies = NULL;
- currency_count = 0;
}
diff --git a/src/currency.h b/src/currency.h
index e167147..736f554 100644
--- a/src/currency.h
+++ b/src/currency.h
@@ -10,47 +10,66 @@ typedef struct {
char *symbol;
char *long_name;
} CurrencyInfo;
-
-/*
- * List taken from http://www.ecb.int/press/pr/date/2008/html/pr081205.en.html
- * with euro added.
- */
static const CurrencyInfo currency_info[] = {
- {"AUD", "$", N_("Australian dollar")},
- {"BGN", "лв", N_("Bulgarian lev")},
- {"BRL", "R$", N_("Brazilian real")},
- {"CAD", "$", N_("Canadian dollar")},
- {"CHF", "Fr", N_("Swiss franc")},
- {"CNY", "å??", N_("Chinese yuan renminbi")},
- {"CZK", "KÄ?", N_("Czech koruna")},
- {"DKK", "kr", N_("Danish krone")},
- {"EEK", "KR", N_("Estonian kroon")},
- {"EUR", "â?¬", N_("Euro")},
- {"GBP", "£", N_("Pound sterling")},
- {"HKD", "$", N_("Hong Kong dollar")},
- {"HRK", "kn", N_("Croatian kuna")},
- {"HUF", "Ft", N_("Hungarian forint")},
- {"IDR", "Rp", N_("Indonesian rupiah")},
- {"INR", "â?¹", N_("Indian rupee")},
-// {"ISK", "kr", N_("Icelandic krona")}, // NOTE: Used to be provided by the ECB
- {"JPY", "Â¥", N_("Japanese yen")},
- {"KRW", "â?©", N_("South Korean won")},
- {"LTL", "Lt", N_("Lithuanian litas")},
- {"LVL", "Ls", N_("Latvian lats")},
- {"MXN", "$", N_("Mexican peso")},
- {"MYR", "RM", N_("Malaysian ringgit")},
- {"NOK", "kr", N_("Norwegian krone")},
- {"NZD", "$", N_("New Zealand dollar")},
- {"PHP", "â?±", N_("Philippine peso")},
- {"PLN", "zÅ?", N_("Polish zloty")},
- {"RON", "L", N_("New Romanian leu")},
+ {"AED", "إ.د", N_("United Arab Emirates dirham")},
+ {"AUD", "$", N_("Australian dollar")},
+ {"BGN", "лв", N_("Bulgarian lev")},
+ {"BHD", ".ب.د", N_("Bahraini dinar")},
+ {"BND", "$", N_("Brunei dollar")},
+ {"BRL", "R$", N_("Brazilian real")},
+ {"BWP", "P", N_("Botswana pula")},
+ {"CAD", "$", N_("Canadian dollar")},
+ {"CHF", "Fr", N_("Swiss franc")},
+ {"CLP", "$", N_("Chilean peso")},
+ {"CNY", "å??", N_("Chinese yuan renminbi")},
+ {"COP", "$", N_("Colombian peso")},
+ {"CZK", "KÄ?", N_("Czech koruna")},
+ {"DKK", "kr", N_("Danish krone")},
+ {"DZD", "ج.د", N_("Algerian dinar")},
+ {"EEK", "KR", N_("Estonian kroon")},
+ {"EUR", "â?¬", N_("Euro")},
+ {"GBP", "£", N_("Pound sterling")},
+ {"HKD", "$", N_("Hong Kong dollar")},
+ {"HRK", "kn", N_("Croatian kuna")},
+ {"HUF", "Ft", N_("Hungarian forint")},
+ {"IDR", "Rp", N_("Indonesian rupiah")},
+ {"ILS", "â?ª", N_("Israeli new shekel")},
+ {"INR", "â?¹", N_("Indian rupee")},
+ {"IRR", "ï·¼", N_("Iranian rial")},
+ {"ISK", "kr", N_("Icelandic krona")},
+ {"JPY", "Â¥", N_("Japanese yen")},
+ {"KRW", "â?©", N_("South Korean won")},
+ {"KWD", "Ù?.د", N_("Kuwaiti dinar")},
+ {"KZT", "â?¸", N_("Kazakhstani tenge")},
+ {"LKR", "Rs", N_("Sri Lankan rupee")},
+ {"LTL", "Lt", N_("Lithuanian litas")},
+ {"LVL", "Ls", N_("Latvian lats")},
+ {"LYD", "د.Ù?", N_("Libyan dinar")},
+ {"MUR", "Rs", N_("Mauritian rupee")},
+ {"MXN", "$", N_("Mexican peso")},
+ {"MYR", "RM", N_("Malaysian ringgit")},
+ {"NOK", "kr", N_("Norwegian krone")},
+ {"NPR", "Rs", N_("Nepalese rupee")},
+ {"NZD", "$", N_("New Zealand dollar")},
+ {"OMR", "ع.ر.", N_("Omani rial")},
+ {"PEN", "S/.", N_("Peruvian nuevo sol")},
+ {"PHP", "â?±", N_("Philippine peso")},
+ {"PKR", "Rs", N_("Pakistani rupee")},
+ {"PLN", "zÅ?", N_("Polish zloty")},
+ {"QAR", "Ù?.ر", N_("Qatari riyal")},
+ {"RON", "L", N_("New Romanian leu")},
{"RUB", "Ñ?Ñ?б.", N_("Russian rouble")},
- {"SEK", "kr", N_("Swedish krona")},
- {"SGD", "$", N_("Singapore dollar")},
- {"THB", "฿", N_("Thai baht")},
- {"TRY", "TL", N_("New Turkish lira")},
- {"USD", "$", N_("US dollar")},
- {"ZAR", "R", N_("South African rand")},
+ {"SAR", "س.ر", N_("Saudi riyal")},
+ {"SEK", "kr", N_("Swedish krona")},
+ {"SGD", "$", N_("Singapore dollar")},
+ {"THB", "฿", N_("Thai baht")},
+ {"TND", "ت.د", N_("Tunisian dinar")},
+ {"TRY", "TL", N_("New Turkish lira")},
+ {"TTD", "$", N_("Trinidad and Tobago dollar")},
+ {"USD", "$", N_("US dollar")},
+ {"UYU", "$", N_("Uruguayan peso")},
+ {"VEF", "Bs F", N_("Venezuelan bolÃvar")},
+ {"ZAR", "R", N_("South African rand")},
{NULL, NULL}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]