]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Borrow a setlocale bug workaround from gnulib.
authorBruno Haible <bruno@clisp.org>
Sat, 12 Feb 2011 17:24:03 +0000 (18:24 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 7 Jun 2011 21:39:47 +0000 (23:39 +0200)
gettext-runtime/intl/ChangeLog
gettext-runtime/intl/setlocale.c

index fe3c4448b22e54e84a9e1a369c722fc6a7f8df7f..cdb8b999f8ba2f099c00bd660f5640838457921b 100644 (file)
@@ -1,3 +1,9 @@
+2011-02-12  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        Avoid clashing overrides for setlocale.
index 2a5e2605ba85193f53d5013fdd0c112af2f4ca34..2b1b888d619cc75c5ca1dba67e28797d8e16414a 100644 (file)
@@ -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