From aeaf08a8a4fc9b782e90c0350b785ecd2971a3f9 Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Fri, 19 Aug 2011 17:14:00 +1000 Subject: [PATCH] Possible bug fix: test for "C" locale when return string is opaque On some systems the return string from setlocale() may be opaque, so we need to explicitly set the locale to "C", then test the return value from that. --- src/utils.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/utils.c b/src/utils.c index 4629c8b..e698ad3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -61,7 +61,6 @@ static char *program_name_str = NULL; // Canonical program name static char *home_directory_str = NULL; // Full pathname to home static char *data_directory_str = NULL; // Writable data dir pathname -static char *current_mon_locale; // As returned by setlocale() static bool add_currency_symbol = false; // Do we need to add "$"? @@ -302,24 +301,26 @@ extern int randi (int limit) void init_locale (void) { + char *cur, *cloc; struct lconv *lc; - current_mon_locale = setlocale(LC_MONETARY, NULL); + cur = xstrdup(setlocale(LC_MONETARY, NULL)); lc = localeconv(); - - assert(current_mon_locale != NULL); assert(lc != NULL); lconvinfo = *lc; - /* Are we in the POSIX locale? This test may not be portable as the - string returned by setlocale() is supposed to be opaque. */ add_currency_symbol = false; - if ( strcmp(current_mon_locale, "POSIX") == 0 - || strcmp(current_mon_locale, "C") == 0 - || strcmp(current_mon_locale, "C.UTF-8") == 0 - || strcmp(current_mon_locale, "C.utf8") == 0) { + + /* Are we in the POSIX locale? The string returned by setlocale() is + supposed to be opaque, but in practise is not. To be on the safe + side, we explicitly set the locale to "C", then test the returned + value of that, too. */ + cloc = setlocale(LC_MONETARY, "C"); + if ( strcmp(cur, cloc) == 0 + || strcmp(cur, "POSIX") == 0 || strcmp(cur, "C") == 0 + || strcmp(cur, "C.UTF-8") == 0 || strcmp(cur, "C.utf8") == 0) { add_currency_symbol = true; lconvinfo.currency_symbol = MOD_POSIX_CURRENCY_SYMBOL; @@ -327,6 +328,9 @@ void init_locale (void) lconvinfo.p_cs_precedes = MOD_POSIX_P_CS_PRECEDES; lconvinfo.p_sep_by_space = MOD_POSIX_P_SEP_BY_SPACE; } + + setlocale(LC_MONETARY, cur); + free(cur); }