duplocale: Work around AIX 7.1 bug.
[gnulib.git] / lib / duplocale.c
index 86432f7..3f33030 100644 (file)
@@ -1,5 +1,5 @@
 /* Duplicate a locale object.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -32,37 +32,39 @@ locale_t
 rpl_duplocale (locale_t locale)
 {
   /* Work around crash in the duplocale function in glibc < 2.12.
-     See <http://sourceware.org/bugzilla/show_bug.cgi?id=10969>.  */
+     See <http://sourceware.org/bugzilla/show_bug.cgi?id=10969>.
+     Also, on AIX 7.1, duplocale(LC_GLOBAL_LOCALE) returns (locale_t)0 with
+     errno set to EINVAL.  */
   if (locale == LC_GLOBAL_LOCALE)
     {
       /* Create a copy of the locale by fetching the name of each locale
-        category, starting with LC_CTYPE.  */
-      static struct { int cat; int mask; } categories[] =
-       {
-           { LC_NUMERIC,        LC_NUMERIC_MASK },
-           { LC_TIME,           LC_TIME_MASK },
-           { LC_COLLATE,        LC_COLLATE_MASK },
-           { LC_MONETARY,       LC_MONETARY_MASK },
-           { LC_MESSAGES,       LC_MESSAGES_MASK }
+         category, starting with LC_CTYPE.  */
+      static struct { int cat; int mask; } const categories[] =
+        {
+            { LC_NUMERIC,        LC_NUMERIC_MASK },
+            { LC_TIME,           LC_TIME_MASK },
+            { LC_COLLATE,        LC_COLLATE_MASK },
+            { LC_MONETARY,       LC_MONETARY_MASK },
+            { LC_MESSAGES,       LC_MESSAGES_MASK }
 #ifdef LC_PAPER
-         , { LC_PAPER,          LC_PAPER_MASK }
+          , { LC_PAPER,          LC_PAPER_MASK }
 #endif
 #ifdef LC_NAME
-         , { LC_NAME,           LC_NAME_MASK }
+          , { LC_NAME,           LC_NAME_MASK }
 #endif
 #ifdef LC_ADDRESS
-         , { LC_ADDRESS,        LC_ADDRESS_MASK }
+          , { LC_ADDRESS,        LC_ADDRESS_MASK }
 #endif
 #ifdef LC_TELEPHONE
-         , { LC_TELEPHONE,      LC_TELEPHONE_MASK }
+          , { LC_TELEPHONE,      LC_TELEPHONE_MASK }
 #endif
 #ifdef LC_MEASUREMENT
-         , { LC_MEASUREMENT,    LC_MEASUREMENT_MASK }
+          , { LC_MEASUREMENT,    LC_MEASUREMENT_MASK }
 #endif
 #ifdef LC_IDENTIFICATION
-         , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK }
+          , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK }
 #endif
-       };
+        };
       const char *base_name;
       locale_t base_copy;
       unsigned int i;
@@ -70,28 +72,28 @@ rpl_duplocale (locale_t locale)
       base_name = setlocale (LC_CTYPE, NULL);
       base_copy = newlocale (LC_ALL_MASK, base_name, NULL);
       if (base_copy == NULL)
-       return NULL;
+        return NULL;
 
       for (i = 0; i < SIZEOF (categories); i++)
-       {
-         int category = categories[i].cat;
-         int category_mask = categories[i].mask;
-         const char *name = setlocale (category, NULL);
-         if (strcmp (name, base_name) != 0)
-           {
-             locale_t copy = newlocale (category_mask, name, base_copy);
-             if (copy == NULL)
-               {
-                 int saved_errno = errno;
-                 freelocale (base_copy);
-                 errno = saved_errno;
-                 return NULL;
-               }
-             /* No need to call freelocale (base_copy) if copy != base_copy;
-                the newlocale function already takes care of doing it.  */
-             base_copy = copy;
-           }
-       }
+        {
+          int category = categories[i].cat;
+          int category_mask = categories[i].mask;
+          const char *name = setlocale (category, NULL);
+          if (strcmp (name, base_name) != 0)
+            {
+              locale_t copy = newlocale (category_mask, name, base_copy);
+              if (copy == NULL)
+                {
+                  int saved_errno = errno;
+                  freelocale (base_copy);
+                  errno = saved_errno;
+                  return NULL;
+                }
+              /* No need to call freelocale (base_copy) if copy != base_copy;
+                 the newlocale function already takes care of doing it.  */
+              base_copy = copy;
+            }
+        }
 
       return base_copy;
     }