]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
setlocale: Improve support for locales not supported by libc.
authorBruno Haible <bruno@clisp.org>
Sun, 16 Sep 2018 01:09:06 +0000 (03:09 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 16 Sep 2018 01:09:06 +0000 (03:09 +0200)
Reported by Dapeng Gao <peter@dpgao.cc> at
<https://savannah.gnu.org/bugs/?54479>.

* gettext-runtime/intl/setlocale.c: Include <stdio.h>.
(libintl_setlocale): Use a more error-tolerant strategy when the locale to be
set is not supported by libc: Emit warnings instead of failing.

gettext-runtime/intl/setlocale.c

index edbce091a97f881aad8a6526bf7f07aaee32a9ac..3b770c02d805dc1adcc51e07dbb0bd9549c05b8d 100644 (file)
@@ -26,6 +26,7 @@
    See the comments in localename.c, function gl_locale_name_default.  */
 
 #include <locale.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -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.  */