From 6321552c0e6cc7a4f32930cdf445ad249a5d01f8 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 16 Sep 2018 03:15:54 +0200 Subject: [PATCH] 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. --- ChangeLog | 9 +++++++++ lib/setlocale.c | 32 +++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79516723b2..c6006d65e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2018-09-15 Bruno Haible + + 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. + 2018-09-15 Bruno Haible strstr, strcasestr: Add workaround against glibc-2.28 bug. diff --git a/lib/setlocale.c b/lib/setlocale.c index ef5fb4c2a7..77bdabab46 100644 --- a/lib/setlocale.c +++ b/lib/setlocale.c @@ -29,6 +29,7 @@ /* Specification. */ #include +#include #include #include @@ -822,6 +823,7 @@ rpl_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, @@ -848,8 +850,21 @@ rpl_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 @@ -859,7 +874,7 @@ rpl_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; @@ -876,7 +891,18 @@ rpl_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. */ -- 2.39.5