]> Savannah Git Hosting - gnulib.git/commitdiff
localename: Notice setlocale() invocations on more platforms.
authorBruno Haible <bruno@clisp.org>
Thu, 15 Feb 2024 00:33:51 +0000 (01:33 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 15 Feb 2024 00:33:51 +0000 (01:33 +0100)
* lib/localename.c (HAVE_LOCALE_NULL): Define also on musl, FreeBSD,
NetBSD, Solaris, Haiku.
* modules/localename (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* tests/test-localename.c (C_CANONICALIZED): New macro, for Haiku.
(is_default): New function, for musl libc and Haiku.
(test_locale_name, test_locale_name_posix): Use these definitions.
* modules/localename-tests (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.

ChangeLog
lib/localename.c
modules/localename
modules/localename-tests
tests/test-localename.c

index 4a7ef0fb85acfbb854b46e45acf6b7f476fc0f9d..023c1d4d50b4426e1c44ae81adaf2a0476d39c5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-02-14  Bruno Haible  <bruno@clisp.org>
+
+       localename: Notice setlocale() invocations on more platforms.
+       * lib/localename.c (HAVE_LOCALE_NULL): Define also on musl, FreeBSD,
+       NetBSD, Solaris, Haiku.
+       * modules/localename (Files): Add m4/musl.m4.
+       (configure.ac): Invoke gl_MUSL_LIBC.
+       * tests/test-localename.c (C_CANONICALIZED): New macro, for Haiku.
+       (is_default): New function, for musl libc and Haiku.
+       (test_locale_name, test_locale_name_posix): Use these definitions.
+       * modules/localename-tests (Files): Add m4/musl.m4.
+       (configure.ac): Invoke gl_MUSL_LIBC.
+
 2024-02-14  Bruno Haible  <bruno@clisp.org>
 
        Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv.
index b4c78df8aee77d4bb7c6e055991f6e86b880e5b6..3bfcdabf4fdcabe30ee2c34872a04aeda921e09e 100644 (file)
@@ -3297,9 +3297,31 @@ gl_locale_name_thread (int category, _GL_UNUSED const char *categoryname)
    "Directs 'setlocale()' to query 'category' and return the current
     setting of 'local'."
    However it does not specify the exact format.  Neither do SUSV2 and
-   ISO C 99.  So we can use this feature only on selected systems (e.g.
-   those using GNU C Library).  */
-#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
+   ISO C 99.  So we can use this feature only on selected systems, where
+   the return value has the XPG syntax
+     language[_territory][.codeset][@modifier]
+   or
+     C[.codeset]
+   namely
+     - glibc systems (except for aliases from /usr/share/locale/locale.alias,
+       that no one uses any more),
+     - musl libc,
+     - FreeBSD, NetBSD,
+     - Solaris,
+     - Haiku.
+   We cannot use it on
+     - macOS, Cygwin (because these systems have a facility for customizing the
+       default locale, and setlocale (category, NULL) ignores it and merely
+       returns "C" or "C.UTF-8"),
+     - OpenBSD (because on OpenBSD ≤ 6.1, LC_ALL does not set the LC_NUMERIC,
+       LC_TIME, LC_COLLATE, LC_MONETARY categories).
+     - AIX (because here the return value has the syntax
+         language[_script]_territory[.codeset]
+       e.g. zh_Hans_CN.UTF-8),
+     - native Windows (because it has locale names such as French_France.1252),
+     - Android (because it only supports the C and C.UTF-8 locales).
+ */
+#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__) || MUSL_LIBC || defined __FreeBSD__ || defined __NetBSD__ || defined __sun || defined __HAIKU__
 # define HAVE_LOCALE_NULL
 #endif
 
@@ -3334,8 +3356,8 @@ gl_locale_name_posix (int category, _GL_UNUSED const char *categoryname)
     /* On other systems we ignore what setlocale reports and instead look at the
        environment variables directly.  This is necessary
          1. on systems which have a facility for customizing the default locale
-            (Mac OS X, native Windows, Cygwin) and where the system's setlocale()
-            function ignores this default locale (Mac OS X, Cygwin), in two cases:
+            (macOS, native Windows, Cygwin) and where the system's setlocale()
+            function ignores this default locale (macOS, Cygwin), in two cases:
             a. when the user missed to use the setlocale() override from libintl
                (for example by not including <libintl.h>),
             b. when setlocale supports only the "C" locale, such as on Cygwin
index fc097829beec3352a89150cb887aafee06451a35..4c33624548af917c7a0ce7ef4fdfafedd176bb30 100644 (file)
@@ -10,6 +10,7 @@ m4/localename.m4
 m4/intl-thread-locale.m4
 m4/intlmacosx.m4
 m4/lcmessage.m4
+m4/musl.m4
 
 Depends-on:
 extensions
@@ -26,6 +27,7 @@ thread-optim
 configure.ac:
 gl_LOCALENAME
 gl_LOCALE_MODULE_INDICATOR([localename])
+gl_MUSL_LIBC
 
 Makefile.am:
 lib_SOURCES += localename.c localename-table.c
index f90d82da0d182fc6ab491197a60d5c7f93cd1bff..0c24d5b4b680d319f4848ae26e792dae21cfea93 100644 (file)
@@ -1,6 +1,7 @@
 Files:
 tests/test-localename.c
 tests/macros.h
+m4/musl.m4
 
 Depends-on:
 locale
@@ -11,6 +12,7 @@ strdup
 
 configure.ac:
 gl_CHECK_FUNCS_ANDROID([newlocale], [[#include <locale.h>]])
+gl_MUSL_LIBC
 
 Makefile.am:
 TESTS += test-localename
index fe31201361e2e34167fe6082260e8a795eec919d..03b70527d503305d6da9d390a1da03081ba52ee3 100644 (file)
 # pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
 #endif
 
+/* The name that setlocale(,NULL) returns for the "C" locale.  */
+#ifdef __HAIKU__
+# define C_CANONICALIZED "POSIX"
+#else
+# define C_CANONICALIZED "C"
+#endif
+
+static int
+is_default (const char *name)
+{
+  return strcmp (name, gl_locale_name_default ()) == 0
+         || (strcmp (name, C_CANONICALIZED) == 0
+             && strcmp (gl_locale_name_default (), "C") == 0)
+#if MUSL_LIBC
+         || (strcmp (name, "C.UTF-8") == 0
+             && strcmp (gl_locale_name_default (), "C") == 0)
+#endif
+         ;
+}
+
 #if HAVE_GOOD_USELOCALE
 
 static struct { int cat; int mask; const char *string; } const categories[] =
@@ -110,10 +130,8 @@ test_locale_name (void)
   unsetenv ("LC_TELEPHONE");
   ret = setlocale (LC_ALL, "");
   ASSERT (ret != NULL);
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
-  ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
-                  gl_locale_name_default ()) == 0);
+  ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
+  ASSERT (is_default (gl_locale_name (LC_NUMERIC, "LC_NUMERIC")));
 
   /* Check that an empty environment variable is treated like an unset
      environment variable.  */
@@ -123,32 +141,28 @@ test_locale_name (void)
   unsetenv ("LC_MESSAGES");
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+  ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "", 1);
   unsetenv ("LC_MESSAGES");
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+  ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
   setenv ("LC_MESSAGES", "", 1);
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+  ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
   unsetenv ("LC_MESSAGES");
   setenv ("LANG", "", 1);
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+  ASSERT (is_default (gl_locale_name (LC_MESSAGES, "LC_MESSAGES")));
 
   /* Check that LC_ALL overrides the others, and LANG is overridden by the
      others.  */
@@ -158,21 +172,24 @@ test_locale_name (void)
   unsetenv ("LC_MESSAGES");
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+                  C_CANONICALIZED) == 0);
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "C", 1);
   setenv ("LC_MESSAGES", "C", 1);
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+                  C_CANONICALIZED) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
   unsetenv ("LC_MESSAGES");
   setenv ("LANG", "C", 1);
   setlocale (LC_ALL, "");
-  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+  ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+                  C_CANONICALIZED) == 0);
 
   /* Check mixed situations.  */
 
@@ -204,7 +221,7 @@ test_locale_name (void)
   if (setlocale (LC_ALL, "") != NULL)
     {
       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
-      ASSERT (strcmp (name, gl_locale_name_default ()) == 0);
+      ASSERT (is_default (name));
       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
     }
@@ -552,9 +569,9 @@ test_locale_name_posix (void)
   ret = setlocale (LC_ALL, "");
   ASSERT (ret != NULL);
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
 
   /* Check that an empty environment variable is treated like an unset
      environment variable.  */
@@ -565,7 +582,7 @@ test_locale_name_posix (void)
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "", 1);
@@ -573,7 +590,7 @@ test_locale_name_posix (void)
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -581,7 +598,7 @@ test_locale_name_posix (void)
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -589,7 +606,7 @@ test_locale_name_posix (void)
   setenv ("LANG", "", 1);
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || is_default (name));
 
   /* Check that LC_ALL overrides the others, and LANG is overridden by the
      others.  */
@@ -600,7 +617,7 @@ test_locale_name_posix (void)
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (strcmp (name, "C") == 0);
+  ASSERT (strcmp (name, C_CANONICALIZED) == 0);
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "C", 1);
@@ -608,7 +625,7 @@ test_locale_name_posix (void)
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (strcmp (name, "C") == 0);
+  ASSERT (strcmp (name, C_CANONICALIZED) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -616,7 +633,7 @@ test_locale_name_posix (void)
   setenv ("LANG", "C", 1);
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (strcmp (name, "C") == 0);
+  ASSERT (strcmp (name, C_CANONICALIZED) == 0);
 
   /* Check mixed situations.  */
 
@@ -643,7 +660,7 @@ test_locale_name_posix (void)
   if (setlocale (LC_ALL, "") != NULL)
     {
       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
-      ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+      ASSERT (name == NULL || is_default (name));
       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
     }
@@ -661,7 +678,7 @@ test_locale_name_posix (void)
         setlocale (LC_ALL, "");
         uselocale (locale);
         name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-        ASSERT (strcmp (name, "C") == 0);
+        ASSERT (strcmp (name, C_CANONICALIZED) == 0);
         uselocale (LC_GLOBAL_LOCALE);
         freelocale (locale);
       }