From: Bruno Haible Date: Sun, 16 Sep 2018 01:09:06 +0000 (+0200) Subject: setlocale: Improve support for locales not supported by libc. X-Git-Tag: v0.20~395 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0fb6a58fafe99b87558b2f053debef9749790d2;p=thirdparty%2Fgettext.git setlocale: Improve support for locales not supported by libc. Reported by Dapeng Gao at . * gettext-runtime/intl/setlocale.c: Include . (libintl_setlocale): Use a more error-tolerant strategy when the locale to be set is not supported by libc: Emit warnings instead of failing. --- diff --git a/gettext-runtime/intl/setlocale.c b/gettext-runtime/intl/setlocale.c index edbce091a..3b770c02d 100644 --- a/gettext-runtime/intl/setlocale.c +++ b/gettext-runtime/intl/setlocale.c @@ -26,6 +26,7 @@ See the comments in localename.c, function gl_locale_name_default. */ #include +#include #include #include @@ -832,6 +833,7 @@ libintl_setlocale (int category, const char *locale) /* Set LC_CTYPE first. Then the other categories. */ static int const categories[] = { + LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, @@ -858,8 +860,21 @@ libintl_setlocale (int category, const char *locale) if (base_name == NULL) base_name = gl_locale_name_default (); - if (setlocale_unixlike (LC_ALL, base_name) == NULL) - goto fail; + if (setlocale_unixlike (LC_ALL, base_name) != NULL) + { + /* LC_CTYPE category already set. */ + i = 1; + } + else + { + /* On Mac OS X, "UTF-8" is a valid locale name for LC_CTYPE but + not for LC_ALL. Therefore this call may fail. So, try + another base_name. */ + base_name = "C"; + if (setlocale_unixlike (LC_ALL, base_name) == NULL) + goto fail; + i = 0; + } # if 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 @@ -869,7 +884,7 @@ libintl_setlocale (int category, const char *locale) goto fail; # endif - for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++) + for (; i < sizeof (categories) / sizeof (categories[0]); i++) { int cat = categories[i]; const char *name; @@ -886,7 +901,18 @@ libintl_setlocale (int category, const char *locale) # endif ) if (setlocale_single (cat, name) == NULL) +# if defined __APPLE__ && defined __MACH__ + /* On Mac OS X 10.13, some locales can be set through + System Preferences > Language & Region, that are not + supported by libc. The system's setlocale() falls + back to "C" for these locale categories. Let's do the + same, but print a warning, to limit user expectations. */ + fprintf (stderr, + "Warning: Failed to set locale category %s to %s.\n", + category_to_name (cat), name); +# else goto fail; +# endif } /* All steps were successful. */