From: Bruno Haible Date: Sat, 12 Feb 2011 17:24:03 +0000 (+0100) Subject: Borrow a setlocale bug workaround from gnulib. X-Git-Tag: v0.18.2~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c377b90dd53689b89b673377da86953100886ac;p=thirdparty%2Fgettext.git Borrow a setlocale bug workaround from gnulib. --- diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index fe3c4448b..cdb8b999f 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,3 +1,9 @@ +2011-02-12 Bruno Haible + + Workaround native Windows bug. + * setlocale.c (rpl_setlocale): On native Windows, when setlocale + succeeds but sets LC_CTYPE to "C", report a failure. + 2011-02-12 Bruno Haible Avoid clashing overrides for setlocale. diff --git a/gettext-runtime/intl/setlocale.c b/gettext-runtime/intl/setlocale.c index 2a5e2605b..2b1b888d6 100644 --- a/gettext-runtime/intl/setlocale.c +++ b/gettext-runtime/intl/setlocale.c @@ -856,6 +856,14 @@ libintl_setlocale (int category, const char *locale) if (setlocale_unixlike (LC_ALL, base_name) == NULL) goto fail; +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* On native Windows, setlocale(LC_ALL,...) may succeed but set the + LC_CTYPE category to an invalid value ("C") when it does not + support the specified encoding. Report a failure instead. */ + if (strchr (base_name, '.') != NULL + && strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) + goto fail; +# endif for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++) { @@ -898,7 +906,45 @@ libintl_setlocale (int category, const char *locale) } } else - return setlocale_single (category, locale); + { +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL) + { + char *saved_locale; + + /* Back up the old locale. */ + saved_locale = setlocale (LC_ALL, NULL); + if (saved_locale == NULL) + return NULL; + saved_locale = strdup (saved_locale); + if (saved_locale == NULL) + return NULL; + + if (setlocale_unixlike (LC_ALL, locale) == NULL) + { + free (saved_locale); + return NULL; + } + + /* On native Windows, setlocale(LC_ALL,...) may succeed but set the + LC_CTYPE category to an invalid value ("C") when it does not + support the specified encoding. Report a failure instead. */ + if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) + { + if (saved_locale[0] != '\0') /* don't risk an endless recursion */ + setlocale (LC_ALL, saved_locale); + free (saved_locale); + return NULL; + } + + /* It was really successful. */ + free (saved_locale); + return setlocale (LC_ALL, NULL); + } + else +# endif + return setlocale_single (category, locale); + } } # if HAVE_NEWLOCALE