]> Dogcows Code - chaz/homebank/blob - src/hb-currency.c
Merge branch 'upstream'
[chaz/homebank] / src / hb-currency.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2012 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "hb-currency.h"
24 #include <libsoup/soup.h>
25
26 #ifdef G_OS_WIN32
27 #include <windows.h>
28 #endif
29
30 /****************************************************************************/
31 /* Debug macros */
32 /****************************************************************************/
33
34 #define MYDEBUG 0
35
36 #if MYDEBUG
37 #define DB(x) (x);
38 #else
39 #define DB(x);
40 #endif
41
42 /* our global datas */
43 extern struct HomeBank *GLOBALS;
44 extern struct Preferences *PREFS;
45
46 extern Currency4217 iso4217cur[];
47 extern guint n_iso4217cur;
48
49 Currency4217 *iso4217format_get(gchar *code);
50
51 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
52
53 void
54 da_cur_free(Currency *item)
55 {
56 DB( g_print("da_cur_free\n") );
57 if(item != NULL)
58 {
59 DB( g_print(" => %d, %s\n", item->key, item->iso_code) );
60
61 g_free(item->name);
62 g_free(item->iso_code);
63 g_free(item->symbol);
64 g_free(item->decimal_char);
65 g_free(item->grouping_char);
66
67 g_free(item);
68 }
69 }
70
71
72 Currency *
73 da_cur_malloc(void)
74 {
75 DB( g_print("da_cur_malloc\n") );
76 return g_malloc0(sizeof(Currency));
77 }
78
79
80 void
81 da_cur_destroy(void)
82 {
83 DB( g_print("da_cur_destroy\n") );
84 g_hash_table_destroy(GLOBALS->h_cur);
85 }
86
87 void
88 da_cur_new(void)
89 {
90 Currency4217 *curfmt;
91
92 DB( g_print("da_cur_new\n") );
93 GLOBALS->h_cur = g_hash_table_new_full(g_int_hash, g_int_equal, (GDestroyNotify)g_free, (GDestroyNotify)da_cur_free);
94
95 // insert default base currency
96 curfmt = iso4217format_get(PREFS->IntCurrSymbol);
97 if(curfmt == NULL)
98 curfmt = iso4217format_get("USD");
99
100 if(curfmt)
101 {
102 DB( g_printf("curfmt %p\n", curfmt) );
103
104 currency_add_from_user(curfmt);
105 }
106 }
107
108
109 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
110 static void da_cur_max_key_ghfunc(gpointer key, Currency *item, guint32 *max_key)
111 {
112 *max_key = MAX(*max_key, item->key);
113 }
114
115 static gboolean da_cur_iso_grfunc(gpointer key, Currency *item, gchar *iso)
116 {
117 if( iso && item->iso_code )
118 {
119 if(!strcasecmp(iso, item->iso_code))
120 return TRUE;
121 }
122 return FALSE;
123 }
124
125 guint
126 da_cur_length(void)
127 {
128 return g_hash_table_size(GLOBALS->h_cur);
129 }
130
131 gboolean
132 da_cur_remove(guint32 key)
133 {
134 DB( g_print("da_cur_remove %d\n", key) );
135
136 return g_hash_table_remove(GLOBALS->h_cur, &key);
137 }
138
139
140 void
141 da_cur_init_from4217(Currency *cur, Currency4217 *curfmt)
142 {
143 cur->symbol = g_strdup(curfmt->curr_symbol);
144 cur->sym_prefix = curfmt->curr_is_prefix;
145 cur->decimal_char = g_strdup(curfmt->curr_dec_char);
146 cur->grouping_char = g_strdup(curfmt->curr_grp_char);
147 cur->frac_digits = curfmt->curr_frac_digit;
148 da_cur_initformat(cur);
149 }
150
151
152 void
153 da_cur_initformat(Currency *item)
154 {
155 DB( g_print("init currency %s, %d \n", item->symbol, item->frac_digits) );
156
157 // for formatd
158 g_snprintf(item->format , 8-1, "%%.%df", item->frac_digits);
159
160 if(item->sym_prefix == TRUE)
161 g_snprintf(item->monfmt , 32-1, "%s %%s", item->symbol);
162 else
163 g_snprintf(item->monfmt , 32-1, "%%s %s", item->symbol);
164
165 DB( g_print("fmt '%s'\n", item->format) );
166 DB( g_print("monfmt '%s'\n", item->monfmt) );
167 }
168
169
170 gboolean
171 da_cur_insert(Currency *item)
172 {
173 guint32 *new_key;
174
175 DB( g_print("da_cur_insert\n") );
176
177 new_key = g_new0(guint32, 1);
178 *new_key = item->key;
179 g_hash_table_insert(GLOBALS->h_cur, new_key, item);
180
181 da_cur_initformat(item);
182
183 return TRUE;
184 }
185
186
187 gboolean
188 da_cur_append(Currency *item)
189 {
190 Currency *existitem;
191 guint32 *new_key;
192
193 DB( g_print("da_cur_append\n") );
194
195 /* ensure no duplicate */
196 //g_strstrip(item->name);
197 if(item->iso_code != NULL)
198 {
199 existitem = da_cur_get_by_iso_code( item->iso_code );
200 if( existitem == NULL )
201 {
202 new_key = g_new0(guint32, 1);
203 *new_key = da_cur_get_max_key() + 1;
204 item->key = *new_key;
205 //item->pos = da_cur_length() + 1;
206
207 DB( g_print(" -> insert id: %d\n", *new_key) );
208
209 g_hash_table_insert(GLOBALS->h_cur, new_key, item);
210
211 da_cur_initformat(item);
212
213 return TRUE;
214 }
215
216
217 }
218
219 DB( g_print(" -> %s already exist: %d\n", item->iso_code, item->key) );
220
221 return FALSE;
222 }
223
224
225 guint32
226 da_cur_get_max_key(void)
227 {
228 guint32 max_key = 0;
229
230 g_hash_table_foreach(GLOBALS->h_cur, (GHFunc)da_cur_max_key_ghfunc, &max_key);
231 return max_key;
232 }
233
234
235
236 Currency *
237 da_cur_get_by_iso_code(gchar *iso_code)
238 {
239 DB( g_print("da_cur_get_by_iso_code\n") );
240
241 return g_hash_table_find(GLOBALS->h_cur, (GHRFunc)da_cur_iso_grfunc, iso_code);
242 }
243
244 Currency *
245 da_cur_get(guint32 key)
246 {
247 //DB( g_print("da_cur_get\n") );
248
249 return g_hash_table_lookup(GLOBALS->h_cur, &key);
250 }
251
252
253
254
255
256 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
257
258 /**
259 * currency_is_used:
260 *
261 * controls if a currency is used [base or account]
262 *
263 * Return value: TRUE if used, FALSE, otherwise
264 */
265 gboolean
266 currency_is_used(guint32 key)
267 {
268 GList *list;
269 gboolean retval;
270
271 if(GLOBALS->kcur == key)
272 return TRUE;
273
274 retval = FALSE;
275
276 list = g_hash_table_get_values(GLOBALS->h_acc);
277 while (list != NULL)
278 {
279 Account *item = list->data;
280
281 if(item->kcur == key)
282 {
283 retval = TRUE;
284 goto end;
285 }
286 list = g_list_next(list);
287 }
288
289 end:
290 g_list_free(list);
291
292 return retval;
293 }
294
295
296
297 Currency4217 *iso4217format_get(gchar *code)
298 {
299 Currency4217 *cur;
300 guint i;
301
302 for (i = 0; i< n_iso4217cur; i++)
303 {
304 cur = &iso4217cur[i];
305 if(g_strcmp0(cur->curr_iso_code, code) == 0)
306 {
307 return cur;
308 }
309 }
310 return NULL;
311 }
312
313
314 static void currency_get_system_format(Currency *item)
315 {
316 DB( g_printf("\n[(currency] get format from system '%s'\n", item->iso_code) );
317
318
319 #ifdef G_OS_UNIX
320
321 struct lconv *lc = localeconv();
322
323 DB( g_print("int_curr_symbol '%s'\n", lc->int_curr_symbol) );
324
325 DB( g_print("mon_decimal_point is utf8: %d\n", g_utf8_validate(lc->mon_decimal_point, -1, NULL)) );
326 DB( g_print("mon_decimal_point '%s'\n", lc->mon_decimal_point) );
327 DB( g_print("mon_decimal_point %x %x %x %x\n", lc->mon_decimal_point[0], lc->mon_decimal_point[1], lc->mon_decimal_point[2], lc->mon_decimal_point[3]) );
328
329 DB( g_print("mon_thousands_sep is utf8: %d\n", g_utf8_validate(lc->mon_thousands_sep, -1, NULL)) );
330 DB( g_print("mon_thousands_sep '%s'\n", lc->mon_thousands_sep) );
331 DB( g_print("mon_thousands_sep %x %x %x %x\n", lc->mon_thousands_sep[0], lc->mon_thousands_sep[1], lc->mon_thousands_sep[2], lc->mon_thousands_sep[3]) );
332
333
334 DB( g_print("frac_digits '%d'\n", (gint)lc->frac_digits) );
335
336 DB( g_print("currency_symbol '%s'\n", lc->currency_symbol) );
337
338 DB( g_print("p_cs_precedes '%d'\n", lc->p_cs_precedes) );
339
340 DB( g_print("n_cs_precedes '%d'\n", lc->n_cs_precedes) );
341
342 /* ok assign */
343 item->symbol = g_strdup(lc->currency_symbol);
344
345 if( lc->p_cs_precedes || lc->n_cs_precedes )
346 {
347 item->sym_prefix = TRUE;
348 DB( g_print("locale mon cs is a prefix\n") );
349 }
350 else
351 {
352 item->sym_prefix = FALSE;
353 }
354
355 item->decimal_char = g_strdup(lc->mon_decimal_point);
356
357 item->grouping_char = g_strdup(lc->mon_thousands_sep);
358
359 //todo:fix
360 //PREFS->base_cur.grouping_char = g_locale_to_utf8(lc->mon_thousands_sep, -1, NULL, NULL, NULL);
361 //PREFS->base_cur.grouping_char = g_convert (lc->mon_thousands_sep, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
362
363 DB( g_print(" -> grouping_char: '%s'\n", item->grouping_char) );
364
365 item->frac_digits = lc->frac_digits;
366
367 //fix 378992/421228
368 if( item->frac_digits > MAX_FRAC_DIGIT )
369 {
370 item->frac_digits = 2;
371 g_free(item->decimal_char);
372 item->decimal_char = g_strdup(".");
373 }
374
375 #else
376 #ifdef G_OS_WIN32
377 #define BUFFER_SIZE 512
378 char buffer[BUFFER_SIZE];
379 //LPWSTR wcBuffer = buffer;
380 LPSTR wcBuffer = buffer;
381 int iResult;
382
383 //https://msdn.microsoft.com/en-us/library/windows/desktop/dd464799%28v=vs.85%29.aspx
384
385 //see g_locale_to_utf8 here
386 iResult = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, wcBuffer, BUFFER_SIZE);
387 if(iResult > 0)
388 {
389 DB( g_print("LOCALE_SCURRENCY='%s'\n", buffer) );
390 item->symbol = g_locale_to_utf8(buffer, -1, NULL, NULL, NULL);
391 }
392
393 item->sym_prefix = FALSE;
394 iResult = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IPOSSYMPRECEDES, wcBuffer, BUFFER_SIZE);
395 if(iResult > 0)
396 {
397 DB( g_print("LOCALE_IPOSSYMPRECEDES='%s'\n", buffer) );
398 //todo item->sym_prefix
399
400 }
401
402 iResult = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, wcBuffer, BUFFER_SIZE);
403 if(iResult > 0)
404 {
405 DB( g_print("LOCALE_SDECIMAL='%s'\n", buffer) );
406 item->decimal_char = g_locale_to_utf8(buffer, -1, NULL, NULL, NULL);
407 }
408
409 iResult = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, wcBuffer, BUFFER_SIZE);
410 if(iResult > 0)
411 {
412 DB( g_print("LOCALE_STHOUSAND='%s'\n", buffer) );
413 item->grouping_char = g_locale_to_utf8(buffer, -1, NULL, NULL, NULL);
414 }
415
416 iResult = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRDIGITS, wcBuffer, BUFFER_SIZE);
417 if(iResult > 0)
418 {
419 DB( g_print("LOCALE_ICURRDIGITS='%s'\n", buffer) );
420 item->frac_digits = atoi(buffer);
421 }
422 else
423 item->frac_digits = 2;
424
425 #endif
426 #endif
427
428
429 }
430
431
432 Currency *currency_add_from_user(Currency4217 *curfmt)
433 {
434 Currency *item;
435
436 DB( g_printf("\n[(currency] found adding %s\n", curfmt->curr_iso_code) );
437
438 //item = da_cur_get_by_iso_code(curfmt->curr_iso_code);
439
440 item = da_cur_malloc();
441 //no mem alloc here
442 //item->key = i;
443 if(curfmt != NULL)
444 {
445 item->name = g_strdup(curfmt->name);
446 //item->country = cur.country_name;
447 item->iso_code = g_strdup(curfmt->curr_iso_code);
448
449 //1634615 if the currency match the system, fill with it
450 if(!strcmp(item->iso_code, PREFS->IntCurrSymbol))
451 {
452 currency_get_system_format(item);
453 }
454 else
455 {
456 item->frac_digits = curfmt->curr_frac_digit;
457 item->symbol = g_strdup(curfmt->curr_symbol);
458 item->sym_prefix = curfmt->curr_is_prefix;
459 item->decimal_char = g_strdup(curfmt->curr_dec_char);
460 item->grouping_char = g_strdup(curfmt->curr_grp_char);
461 }
462 }
463 else
464 {
465 item->name = g_strdup("unknow");
466 //item->country = cur.country_name;
467 item->iso_code = g_strdup("XXX");
468 item->frac_digits = 2;
469 item->symbol = g_strdup("XXX");
470 item->sym_prefix = FALSE;
471 item->decimal_char = g_strdup(".");
472 item->grouping_char = NULL;
473 }
474
475 da_cur_append(item);
476
477 return item;
478 }
479
480
481
482
483
484 static void
485 start_element_handler (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names,
486 const gchar **attribute_values, gpointer user_data, GError **error)
487 {
488 ParseExchangeContext *ctx = user_data;
489 gint i;
490
491 //DB( g_print("** start element: '%s' iso=%s\n", element_name, ctx->iso) );
492
493 ctx->elt_name = element_name;
494
495 switch(element_name[0])
496 {
497 case 'r':
498 {
499 if(!strcmp (element_name, "rate"))
500 {
501 i = 0;
502 //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
503 //we have only 1 attribute id :: store isocode pair
504 if(attribute_names[i] != NULL && !strcmp (attribute_names[i], "id"))
505 {
506 g_stpcpy (ctx->iso, attribute_values[i]);
507 }
508 }
509 }
510 break;
511 }
512 }
513
514
515 static void
516 text_handler(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
517 {
518 ParseExchangeContext *ctx = user_data;
519
520 if(text_len == 0)
521 return;
522
523 //DB( g_print("** text: '%s' %d\n", text, text_len) );
524
525 if(!strcmp (ctx->elt_name, "Rate"))
526 {
527 ctx->rate = g_ascii_strtod(text, NULL);
528 //DB( g_print(" stored '%s' %.2f\n", text, ctx->rate) );
529 }
530 }
531
532
533 static void
534 end_element_handler (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
535 {
536 ParseExchangeContext *ctx = user_data;
537 Currency *cur;
538
539 DB( g_print("** end element: '%s'\n", element_name) );
540
541 if(!strcmp (element_name, "rate"))
542 {
543 DB( g_print(" should store here !!\n") );
544 DB( g_print(" %s %f\n", ctx->iso, ctx->rate) );
545 cur = da_cur_get_by_iso_code (ctx->iso + 3);
546 if(cur)
547 {
548 DB( g_print(" found cur='%s'\n", cur->iso_code) );
549 cur->rate = ctx->rate;
550 cur->mdate = GLOBALS->today;
551 }
552
553 //clean all
554 ctx->elt_name = NULL;
555 *ctx->iso = '\0';
556 ctx->rate = 0.0;
557 }
558 }
559
560
561 static GMarkupParser hb_xchange_parser = {
562 start_element_handler,
563 end_element_handler,
564 text_handler,
565 NULL,
566 NULL //cleanup
567 };
568
569
570 static gboolean currency_online_parse(const gchar *buffer, GError **error)
571 {
572 GMarkupParseContext *context;
573 ParseExchangeContext ctx;
574 gboolean retval;
575
576 memset(&ctx, 0, sizeof(ParseExchangeContext));
577 context = g_markup_parse_context_new (&hb_xchange_parser, 0, &ctx, NULL);
578
579 retval = g_markup_parse_context_parse (context, buffer, -1, error);
580 //retval = g_markup_parse_context_parse (context, badyahooxml, -1, error);
581 g_markup_parse_context_free (context);
582
583 return retval;
584 }
585
586
587 static gchar *currency_get_query(void)
588 {
589 GList *list;
590 GString *node;
591 Currency *base;
592 Currency *item;
593 gint i;
594
595 //http://query.yahooapis.com/v1/public/yql
596 //?q=select * from yahoo.finance.xchange where pair in ("EURGBP","EURUSD")
597 //&env=store://datatables.org/alltableswithkeys
598
599 node = g_string_sized_new(1024);
600 g_string_append(node, "http://query.yahooapis.com/v1/public/yql");
601 g_string_append(node, "?q=select * from yahoo.finance.xchange where pair in (");
602
603 base = da_cur_get (GLOBALS->kcur);
604
605 list = g_hash_table_get_values(GLOBALS->h_cur);
606 i = g_list_length (list) - 1;
607
608 while (list != NULL)
609 {
610 item = list->data;
611
612 if(item->key != GLOBALS->kcur)
613 {
614 g_string_append_printf(node, "\"%s%s\"", base->iso_code, item->iso_code);
615 if(i > 1)
616 {
617 g_string_append(node, ",");
618 }
619 i--;
620 }
621 list = g_list_next(list);
622 }
623 g_list_free(list);
624
625 g_string_append(node, ")&env=store://datatables.org/alltableswithkeys");
626
627 return g_string_free(node, FALSE);
628 }
629
630
631 gboolean currency_sync_online(GError **error)
632 {
633 SoupSession *session;
634 SoupMessage *msg;
635 gchar *query;
636 gboolean retval = TRUE;
637
638 DB( g_printf("\n[currency] sync online\n") );
639
640 query = currency_get_query();
641 DB( g_printf(" - query is '%s'\n", query) );
642
643 session = soup_session_new ();
644 msg = soup_message_new ("GET", query);
645 if(msg != NULL)
646 {
647 soup_session_send_message (session, msg);
648 DB( g_print("status_code: %d %d\n", msg->status_code, SOUP_STATUS_IS_SUCCESSFUL(msg->status_code) ) );
649 DB( g_print("reason: %s\n", msg->reason_phrase) );
650 DB( g_print("datas: %s\n", msg->response_body->data) );
651
652 if( SOUP_STATUS_IS_SUCCESSFUL(msg->status_code) == TRUE )
653 {
654 retval = currency_online_parse(msg->response_body->data, error);
655 }
656 else
657 {
658 *error = g_error_new_literal(1, msg->status_code, msg->reason_phrase);
659 retval = FALSE;
660 }
661 }
662 else
663 {
664 *error = g_error_new_literal(1, 0, "cannot parse URI");
665 retval = FALSE;
666 }
667
668 g_free(query);
669
670 return retval;
671 }
672
673
674 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
675
676
677
678 //struct iso_4217_currency iso_4217_currencies[];
679
680 /*debug testing
681 static void fill_currency(void)
682 {
683 gint i;
684 struct iso_4217_currency cur;
685 Currency *item;
686
687 for (i = 0; i< 500; i++)
688 {
689 cur = iso_4217_currencies[i];
690
691 if(cur.iso_code == NULL)
692 break;
693
694 item = da_cur_malloc();
695 //no mem alloc here
696 item->key = i;
697 item->name = cur.currency;
698 item->country = cur.country;
699 item->iso_code = cur.iso_code;
700
701 da_cur_insert(item);
702
703 }
704
705
706
707 }*/
708
709 Currency4217 iso4217cur[] =
710 {
711 { "AED", 2, ".", ",", TRUE, "د.إ.‏", "UAE Dirham" },
712 { "AFN", 0, ",", ",", TRUE, "؋", "Afghani" },
713 { "ALL", 0, ",", " ", FALSE, "Lekë", "Lek" },
714 { "AMD", 2, ".", ",", FALSE, "֏", "Armenian Dram" },
715 { "ANG", 2, ",", ",", TRUE, "NAf.", "Netherlands Antillian Guilder" },
716 { "AOA", 2, ",", " ", FALSE, "Kz", "Kwanza" },
717 { "ARS", 2, ",", ".", TRUE, "$", "Argentine Peso" },
718 { "AUD", 2, ".", ",", TRUE, "$", "Australian Dollar" },
719 { "AWG", 2, ",", ".", TRUE, "Afl.", "Aruban Guilder" },
720 { "AZN", 2, ",", " ", TRUE, "₼", "Azerbaijanian Manat" },
721 { "BAM", 2, ",", ".", FALSE, "KM", "Convertible Marks" },
722 { "BBD", 2, ".", ",", TRUE, "$", "Barbados Dollar" },
723 { "BDT", 2, ".", ",", TRUE, "৳", "Taka" },
724 { "BGN", 2, ",", " ", FALSE, "лв.", "Bulgarian Lev" },
725 { "BHD", 3, ".", ",", TRUE, "د.ب.‏", "Bahraini Dinar" },
726 { "BIF", 0, ",", " ", FALSE, "FBu", "Burundi Franc" },
727 { "BMD", 2, ".", ",", TRUE, "$", "Bermudian Dollar" },
728 { "BND", 2, ",", ".", TRUE, "$", "Brunei Dollar" },
729 { "BOB", 2, ",", ".", TRUE, "Bs", "Boliviano" },
730 { "BOV", 2, ".", "", FALSE, "BOV", "Mvdol" },
731 { "BRL", 2, ",", ".", TRUE, "R$", "Brazilian Real" },
732 { "BSD", 2, ".", ",", TRUE, "$", "Bahamian Dollar" },
733 { "BTN", 2, ".", ",", TRUE, "Nu.", "Ngultrum" },
734 { "BWP", 2, ".", " ", TRUE, "P", "Pula" },
735 { "BYR", 0, ",", " ", FALSE, "Br", "Belarussian Ruble" },
736 { "BZD", 2, ".", ",", TRUE, "$", "Belize Dollar" },
737 { "CAD", 2, ",", " ", TRUE, "$", "Canadian Dollar" },
738 { "CDF", 2, ",", " ", TRUE, "FC", "Congolese Franc" },
739 { "CHE", 2, ".", "", FALSE, "CHE", "WIR Euro" },
740 { "CHF", 2, ",", "'", TRUE, "CHF", "Swiss Franc" },
741 { "CHW", 2, ".", "", FALSE, "CHW", "WIR Franc" },
742 { "CLF", 2, ".", "", FALSE, "CLF", "Unidades de fomento" },
743 { "CLP", 0, ",", ".", TRUE, "$", "Chilean Peso" },
744 { "CNY", 2, ".", ",", TRUE, "¥", "Yuan Renminbi" },
745 { "COP", 0, ",", ".", TRUE, "$", "Colombian Peso" },
746 { "COU", 2, ".", "", FALSE, "COU", "Unidad de Valor Real" },
747 { "CRC", 0, ",", ".", TRUE, "₡", "Costa Rican Colon" },
748 { "CUP", 2, ".", ",", TRUE, "$", "Cuban Peso" },
749 { "CVE", 2, "$", " ", FALSE, "​", "Cape Verde Escudo" },
750 { "CYP", 2, ".", "", FALSE, "CYP", "Cyprus Pound" },
751 { "CZK", 2, ",", " ", FALSE, "Kč", "Czech Koruna" },
752 { "DJF", 0, ",", " ", TRUE, "Fdj", "Djibouti Franc" },
753 { "DKK", 2, ",", ".", TRUE, "kr", "Danish Krone" },
754 { "DOP", 2, ".", ",", TRUE, "$", "Dominican Peso" },
755 { "DZD", 2, ",", " ", FALSE, "DA", "Algerian Dinar" },
756 { "EEK", 2, ".", "", FALSE, "EEK", "Kroon" },
757 { "EGP", 2, ".", ",", TRUE, "ج.م.‏", "Egyptian Pound" },
758 { "ERN", 2, ".", ",", TRUE, "Nfk", "Nakfa" },
759 { "ETB", 2, ".", ",", TRUE, "Br", "Ethiopian Birr" },
760 { "EUR", 2, ",", " ", TRUE, "€", "Euro" },
761 { "FJD", 2, ".", ",", TRUE, "$", "Fiji Dollar" },
762 { "FKP", 2, ".", ",", TRUE, "£", "Falkland Islands Pound" },
763 { "GBP", 2, ".", ",", TRUE, "£", "Pound Sterling" },
764 { "GEL", 2, ",", " ", TRUE, "₾", "Lari" },
765 { "GHS", 2, ".", ",", TRUE, "GH₵", "Ghana Cedi" },
766 { "GIP", 2, ".", ",", TRUE, "£", "Gibraltar Pound" },
767 { "GMD", 2, ".", ",", TRUE, "D", "Dalasi" },
768 { "GNF", 0, ",", " ", TRUE, "FG", "Guinea Franc" },
769 { "GTQ", 2, ".", ",", TRUE, "Q", "Quetzal" },
770 { "GYD", 0, ".", ",", TRUE, "$", "Guyana Dollar" },
771 { "HKD", 2, ".", ",", TRUE, "$", "Hong Kong Dollar" },
772 { "HNL", 2, ".", ",", TRUE, "L", "Lempira" },
773 { "HRK", 2, ",", ".", FALSE, "kn", "Croatian Kuna" },
774 { "HTG", 2, ",", " ", FALSE, "G", "Gourde" },
775 { "HUF", 2, ",", " ", FALSE, "HUF", "Forint" },
776 { "IDR", 0, ",", ".", TRUE, "Rp", "Rupiah" },
777 { "ILS", 2, ".", ",", TRUE, "₪", "New Israeli Sheqel" },
778 { "INR", 2, ".", ",", TRUE, "₹", "Indian Rupee" },
779 { "IQD", 2, ".", ",", TRUE, "د.ع.‏", "Iraqi Dinar" },
780 { "IRR", 2, "/", ",", TRUE, "ريال", "Iranian Rial" },
781 { "ISK", 0, ",", ".", FALSE, "ISK", "Iceland Krona" },
782 { "JMD", 2, ".", ",", TRUE, "$", "Jamaican Dollar" },
783 { "JOD", 3, ".", ",", TRUE, "د.ا.‏", "Jordanian Dinar" },
784 { "JPY", 0, ".", ",", TRUE, "¥", "Yen" },
785 { "KES", 2, ".", ",", TRUE, "Ksh", "Kenyan Shilling" },
786 { "KGS", 2, ",", " ", FALSE, "сом", "Som" },
787 { "KHR", 2, ".", ",", FALSE, "៛", "Riel" },
788 { "KMF", 0, ",", " ", TRUE, "CF", "Comoro Franc" },
789 { "KPW", 2, ".", "", FALSE, "KPW", "North Korean Won" },
790 { "KRW", 0, ".", ",", TRUE, "₩", "Won" },
791 { "KWD", 3, ".", ",", TRUE, "د.ك.‏", "Kuwaiti Dinar" },
792 { "KYD", 2, ".", ",", TRUE, "$", "Cayman Islands Dollar" },
793 { "KZT", 2, ",", " ", FALSE, "₸", "Tenge" },
794 { "LAK", 0, ",", ".", TRUE, "₭", "Kip" },
795 { "LBP", 2, ".", ",", TRUE, "ل.ل.‏", "Lebanese Pound" },
796 { "LKR", 2, ".", ",", TRUE, "Rs.", "Sri Lanka Rupee" },
797 { "LRD", 2, ".", ",", TRUE, "$", "Liberian Dollar" },
798 { "LSL", 2, ".", "", FALSE, "LSL", "Loti" },
799 { "LTL", 2, ".", "", FALSE, "LTL", "Lithuanian Litas" },
800 { "LVL", 2, ".", "", FALSE, "LVL", "Latvian Lats" },
801 { "LYD", 3, ".", ",", TRUE, "د.ل.‏", "Libyan Dinar" },
802 { "MAD", 2, ",", " ", FALSE, "DH", "Moroccan Dirham" },
803 { "MDL", 2, ",", " ", FALSE, "L", "Moldovan Leu" },
804 { "MGA", 0, ",", " ", TRUE, "Ar", "Malagasy Ariary" },
805 { "MKD", 2, ",", " ", TRUE, "den", "Denar" },
806 { "MMK", 0, ".", ",", TRUE, "K", "Kyat" },
807 { "MNT", 0, ".", ",", TRUE, "₮", "Tugrik" },
808 { "MOP", 2, ",", " ", TRUE, "MOP", "Pataca" },
809 { "MRO", 0, ",", " ", TRUE, "UM", "Ouguiya" },
810 { "MTL", 2, ".", "", FALSE, "MTL", "Maltese Lira" },
811 { "MUR", 0, ",", " ", TRUE, "Rs", "Mauritius Rupee" },
812 { "MVR", 2, ".", ",", FALSE, "ރ.", "Rufiyaa" },
813 { "MWK", 2, ".", ",", TRUE, "MK", "Kwacha" },
814 { "MXN", 2, ".", ",", TRUE, "$", "Mexican Peso" },
815 { "MXV", 2, ".", "", FALSE, "MXV", "Mexican Unidad de Inversion (UDI)" },
816 { "MYR", 2, ".", ",", TRUE, "RM", "Malaysian Ringgit" },
817 { "MZN", 2, ",", " ", FALSE, "MTn", "Metical" },
818 { "NAD", 2, ",", " ", TRUE, "$", "Namibia Dollar" },
819 { "NGN", 2, ".", ",", TRUE, "₦", "Naira" },
820 { "NIO", 2, ".", ",", TRUE, "C$", "Cordoba Oro" },
821 { "NOK", 2, ",", " ", TRUE, "kr", "Norwegian Krone" },
822 { "NPR", 2, ".", ",", TRUE, "रु", "Nepalese Rupee" },
823 { "NZD", 2, ".", ",", TRUE, "$", "New Zealand Dollar" },
824 { "OMR", 3, ".", ",", TRUE, "ر.ع.‏", "Rial Omani" },
825 { "PAB", 2, ".", ",", TRUE, "B/.", "Balboa" },
826 { "PEN", 2, ".", ",", TRUE, "S/.", "Nuevo Sol" },
827 { "PGK", 2, ".", ",", TRUE, "K", "Kina" },
828 { "PHP", 2, ",", ",", TRUE, "₱", "Philippine Peso" },
829 { "PKR", 0, ".", ",", TRUE, "Rs", "Pakistan Rupee" },
830 { "PLN", 2, ",", " ", FALSE, "zł", "Zloty" },
831 { "PYG", 0, ",", ".", TRUE, "₲", "Guarani" },
832 { "QAR", 2, ".", ",", TRUE, "ر.ق.‏", "Qatari Rial" },
833 { "RON", 2, ",", ".", FALSE, "RON", "New Leu" },
834 { "RSD", 0, ",", ".", FALSE, "RSD", "Serbian Dinar" },
835 { "RUB", 2, ",", " ", TRUE, "₽", "Russian Ruble" },
836 { "RWF", 0, ",", " ", TRUE, "RF", "Rwanda Franc" },
837 { "SAR", 2, ".", ",", TRUE, "ر.س.‏", "Saudi Riyal" },
838 { "SBD", 2, ".", ",", TRUE, "$", "Solomon Islands Dollar" },
839 { "SCR", 2, ",", " ", TRUE, "SR", "Seychelles Rupee" },
840 { "SDG", 2, ".", ",", TRUE, "SDG", "Sudanese Pound" },
841 { "SEK", 2, ",", ".", FALSE, "kr", "Swedish Krona" },
842 { "SGD", 2, ".", ",", TRUE, "$", "Singapore Dollar" },
843 { "SHP", 2, ".", ",", TRUE, "£", "Saint Helena Pound" },
844 { "SLL", 0, ".", ",", TRUE, "Le", "Leone" },
845 { "SOS", 0, ".", ",", TRUE, "S", "Somali Shilling" },
846 { "SRD", 2, ",", ".", TRUE, "$", "Surinam Dollar" },
847 { "STD", 0, ",", " ", FALSE, "Db", "Dobra" },
848 { "SVC", 2, ".", "", FALSE, "SVC", "El Salvador Colon" },
849 { "SYP", 0, ",", " ", TRUE, "LS", "Syrian Pound" },
850 { "SZL", 2, ",", " ", TRUE, "E", "Lilangeni" },
851 { "THB", 2, ".", ",", TRUE, "฿", "Baht" },
852 { "TJS", 2, ",", " ", FALSE, "смн", "Somoni" },
853 { "TMM", 2, ".", "", FALSE, "TMM", "Manat" },
854 { "TND", 3, ",", " ", TRUE, "DT", "Tunisian Dinar" },
855 { "TOP", 2, ".", ",", TRUE, "T$", "Pa'anga" },
856 { "TRY", 2, ",", ".", FALSE, "₺", "New Turkish Lira" },
857 { "TTD", 2, ".", ",", TRUE, "$", "Trinidad and Tobago Dollar" },
858 { "TWD", 2, ".", ",", TRUE, "NT$", "New Taiwan Dollar" },
859 { "TZS", 0, ".", ",", TRUE, "TSh", "Tanzanian Shilling" },
860 { "UAH", 2, ",", " ", FALSE, "₴", "Hryvnia" },
861 { "UGX", 0, ".", ",", TRUE, "USh", "Uganda Shilling" },
862 { "USD", 2, ",", " ", TRUE, "$", "US Dollar" },
863 { "USN", 2, ".", "", FALSE, "USN", "US Dollar (Next day)" },
864 { "USS", 2, ".", "", FALSE, "USS", "US Dollar (Same day)" },
865 { "UYI", 2, ".", "", FALSE, "UYI", "Uruguay Peso en Unidades Indexadas" },
866 { "UYU", 2, ",", ".", TRUE, "$", "Peso Uruguayo" },
867 { "UZS", 0, ",", " ", TRUE, "soʻm", "Uzbekistan Sum" },
868 { "VEF", 2, ",", ".", TRUE, "Bs.", "Bolivar Fuerte" },
869 { "VND", 2, ",", ".", FALSE, "₫", "Dong" },
870 { "VUV", 0, ",", " ", TRUE, "VT", "Vatu" },
871 { "WST", 2, ".", ",", TRUE, "WS$", "Tala" },
872 { "XAF", 0, ",", " ", TRUE, "FCFA", "CFA Franc BEAC" },
873 { "XAG", 2, ".", "", FALSE, "XAG", "Silver" },
874 { "XAU", 2, ".", "", FALSE, "XAU", "Gold" },
875 { "XBA", 2, ".", "", FALSE, "XBA", "European Composite Unit (EURCO)" },
876 { "XBB", 2, ".", "", FALSE, "XBB", "European Monetary Unit (E.M.U.-6)" },
877 { "XBC", 2, ".", "", FALSE, "XBC", "European Unit of Account 9 (E.U.A.-9)" },
878 { "XBD", 2, ".", "", FALSE, "XBD", "European Unit of Account 17 (E.U.A.-17)" },
879 { "XCD", 2, ",", " ", TRUE, "$", "East Caribbean Dollar" },
880 { "XDR", 2, ",", " ", TRUE, "XDR", "Special Drawing Rights" },
881 { "XFO", 2, ".", "", FALSE, "XFO", "Gold-Franc" },
882 { "XFU", 2, ".", "", FALSE, "XFU", "UIC-Franc" },
883 { "XOF", 0, ",", " ", TRUE, "CFA", "CFA Franc BCEAO" },
884 { "XPD", 2, ".", "", FALSE, "XPD", "Palladium" },
885 { "XPF", 0, ",", " ", FALSE, "FCFP", "CFP Franc" },
886 { "XPT", 2, ".", "", FALSE, "XPT", "Platinum" },
887 { "XTS", 2, ".", "", FALSE, "XTS", "Code for testing purposes" },
888 { "XXX", 2, ".", "", FALSE, "XXX", "No currency" },
889 { "YER", 2, ".", ",", TRUE, "ر.ي.‏", "Yemeni Rial" },
890 { "ZAR", 2, ",", " ", TRUE, "R", "Rand" },
891 { "ZMK", 2, ".", "", FALSE, "ZMK", "Zambian Kwacha" },
892 { "ZWD", 2, ".", "", FALSE, "ZWD", "Zimbabwe Dollar" }
893 };
894 guint n_iso4217cur = G_N_ELEMENTS (iso4217cur);
895
This page took 0.085733 seconds and 4 git commands to generate.