From b951b2189465c4bef4963685a2bdcf19271f74f3 Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Thu, 25 Aug 2011 12:26:15 +1000 Subject: [PATCH] Add global (wide-character) currency and numeric variables Add the variables decimal_point, thousands_sep, currency_symbol, mon_decimal_point and mon_thousands_sep, with code to initialise them. --- src/utils.c | 33 +++++++++++++++++++++++++++++++-- src/utils.h | 19 ++++++++++++++----- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/utils.c b/src/utils.c index c2a1dfd..8c3e890 100644 --- a/src/utils.c +++ b/src/utils.c @@ -38,6 +38,13 @@ // Global copy, suitably modified, of localeconv() information struct lconv lconvinfo; +// localeconv() information, converted to wide strings +wchar_t *decimal_point; // Locale's radix character +wchar_t *thousands_sep; // Locale's thousands separator +wchar_t *currency_symbol; // Local currency symbol +wchar_t *mon_decimal_point; // Local monetary radix character +wchar_t *mon_thousands_sep; // Local monetary thousands separator + /************************************************************************ * Module-specific constants and variable definitions * @@ -303,6 +310,7 @@ void init_locale (void) { char *cur, *cloc; struct lconv *lc; + wchar_t *buf; cur = xstrdup(setlocale(LC_MONETARY, NULL)); @@ -329,6 +337,27 @@ void init_locale (void) lconvinfo.p_sep_by_space = MOD_POSIX_P_SEP_BY_SPACE; } + // Convert localeconv() information to wide strings + + buf = xmalloc(BUFSIZE * sizeof(wchar_t)); + + xmbstowcs(buf, lconvinfo.decimal_point, BUFSIZE); + decimal_point = xwcsdup(buf); + + xmbstowcs(buf, lconvinfo.thousands_sep, BUFSIZE); + thousands_sep = xwcsdup(buf); + + xmbstowcs(buf, lconvinfo.currency_symbol, BUFSIZE); + currency_symbol = xwcsdup(buf); + + xmbstowcs(buf, lconvinfo.mon_decimal_point, BUFSIZE); + mon_decimal_point = xwcsdup(buf); + + xmbstowcs(buf, lconvinfo.mon_thousands_sep, BUFSIZE); + mon_thousands_sep = xwcsdup(buf); + + free(buf); + setlocale(LC_MONETARY, cur); free(cur); } @@ -555,7 +584,7 @@ size_t xmbstowcs (wchar_t *restrict dest, const char *restrict src, size_t len) } } else if (p != NULL) { // Multibyte string was too long: truncate dest - dest[len - 1] = '\0'; + dest[len - 1] = L'\0'; n--; break; } else { @@ -590,7 +619,7 @@ size_t xwcrtomb (char *restrict dest, wchar_t wc, mbstate_t *restrict mbstate) Hence, restore the original, try to store an ending shift sequence, then EILSEQ_REPL. */ memcpy(&mbcopy, mbstate, sizeof(mbcopy)); - if ((n = wcrtomb(dest, '\0', &mbcopy)) == (size_t) -1) { + if ((n = wcrtomb(dest, L'\0', &mbcopy)) == (size_t) -1) { errno_exit(_("xwcrtomb: NUL")); } dest[n] = EILSEQ_REPL; diff --git a/src/utils.h b/src/utils.h index 49a5c3f..a30a108 100644 --- a/src/utils.h +++ b/src/utils.h @@ -43,6 +43,7 @@ #define EILSEQ_REPL '?' // Illegal character sequence replacement +#define EILSEQ_REPL_WC L'?' // ... wide character version /************************************************************************ @@ -52,6 +53,13 @@ // Global copy, suitably modified, of localeconv() information extern struct lconv lconvinfo; +// localeconv() information, converted to wide strings +extern wchar_t *decimal_point; // Locale's radix character +extern wchar_t *thousands_sep; // Locale's thousands separator +extern wchar_t *currency_symbol; // Local currency symbol +extern wchar_t *mon_decimal_point; // Local monetary radix character +extern wchar_t *mon_thousands_sep; // Local monetary thousands separator + /************************************************************************ * Initialisation and environment function prototypes * @@ -229,11 +237,12 @@ extern int randi (int limit); Parameters: (none) Returns: (nothing) - This function initialises the global variable lconvinfo with values - suitable for this program. In particular, if the POSIX or C locale is - in effect, the currency_symbol and frac_digits members are updated to - be something reasonable. This function must be called before using - localeconf_info. + This function initialises the global variable lconvinfo, as well as + decimal_point, thousands_sep, currency_symbol, mon_decimal_point and + mon_thousands_sep, with values suitable for this program. In + particular, if the POSIX or C locale is in effect, the currency_symbol + and frac_digits members of lconvinfo are updated to be something + reasonable. This function must be called before using localeconf_info. */ extern void init_locale (void);