]> Savannah Git Hosting - gnulib.git/commitdiff
setlocale_null-unlocked: New module.
authorBruno Haible <bruno@clisp.org>
Thu, 15 Feb 2024 09:30:54 +0000 (10:30 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 15 Feb 2024 18:58:01 +0000 (19:58 +0100)
* lib/setlocale_null.h (setlocale_null_r_unlocked,
setlocale_null_unlocked): New declarations.
* lib/setlocale_null-unlocked.c: New file, based on
lib/setlocale_null.c.
* lib/setlocale_null.c: Don't include <wchar.h>.
(setlocale_null_unlocked, setlocale_null_r_unlocked): Remove functions.
* modules/setlocale-null-unlocked: New file.
* modules/setlocale-null (Depends-on): Add setlocale-null-unlocked.

ChangeLog
lib/setlocale_null-unlocked.c [new file with mode: 0644]
lib/setlocale_null.c
lib/setlocale_null.h
modules/setlocale-null
modules/setlocale-null-unlocked [new file with mode: 0644]

index 4ba5cbfc28d2a82e1f7e725e2274e6363a9af4cb..b2668b99bf62f5f177e5ac50a7972ef3e2cab45d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2024-02-15  Bruno Haible  <bruno@clisp.org>
+
+       setlocale_null-unlocked: New module.
+       * lib/setlocale_null.h (setlocale_null_r_unlocked,
+       setlocale_null_unlocked): New declarations.
+       * lib/setlocale_null-unlocked.c: New file, based on
+       lib/setlocale_null.c.
+       * lib/setlocale_null.c: Don't include <wchar.h>.
+       (setlocale_null_unlocked, setlocale_null_r_unlocked): Remove functions.
+       * modules/setlocale-null-unlocked: New file.
+       * modules/setlocale-null (Depends-on): Add setlocale-null-unlocked.
+
 2024-02-15  Bruno Haible  <bruno@clisp.org>
 
        setlocale-null: Refactor.
diff --git a/lib/setlocale_null-unlocked.c b/lib/setlocale_null-unlocked.c
new file mode 100644 (file)
index 0000000..0a86f0d
--- /dev/null
@@ -0,0 +1,149 @@
+/* Query the name of the current global locale, without locking.
+   Copyright (C) 2019-2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2019.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "setlocale_null.h"
+
+#include <errno.h>
+#include <locale.h>
+#include <string.h>
+#if defined _WIN32 && !defined __CYGWIN__
+# include <wchar.h>
+#endif
+
+/* Use the system's setlocale() function, not the gnulib override, here.  */
+#undef setlocale
+
+const char *
+setlocale_null_unlocked (int category)
+{
+  const char *result = setlocale (category, NULL);
+
+#ifdef __ANDROID__
+  if (result == NULL)
+    switch (category)
+      {
+      case LC_CTYPE:
+      case LC_NUMERIC:
+      case LC_TIME:
+      case LC_COLLATE:
+      case LC_MONETARY:
+      case LC_MESSAGES:
+      case LC_ALL:
+      case LC_PAPER:
+      case LC_NAME:
+      case LC_ADDRESS:
+      case LC_TELEPHONE:
+      case LC_MEASUREMENT:
+        result = "C";
+        break;
+      default:
+        break;
+      }
+#endif
+
+  return result;
+}
+
+int
+setlocale_null_r_unlocked (int category, char *buf, size_t bufsize)
+{
+#if defined _WIN32 && !defined __CYGWIN__ && defined _MSC_VER
+  /* On native Windows, nowadays, the setlocale() implementation is based
+     on _wsetlocale() and uses malloc() for the result.  We are better off
+     using _wsetlocale() directly.  */
+  const wchar_t *result = _wsetlocale (category, NULL);
+
+  if (result == NULL)
+    {
+      /* CATEGORY is invalid.  */
+      if (bufsize > 0)
+        /* Return an empty string in BUF.
+           This is a convenience for callers that don't want to write explicit
+           code for handling EINVAL.  */
+        buf[0] = '\0';
+      return EINVAL;
+    }
+  else
+    {
+      size_t length = wcslen (result);
+      if (length < bufsize)
+        {
+          size_t i;
+
+          /* Convert wchar_t[] -> char[], assuming plain ASCII.  */
+          for (i = 0; i <= length; i++)
+            buf[i] = result[i];
+
+          return 0;
+        }
+      else
+        {
+          if (bufsize > 0)
+            {
+              /* Return a truncated result in BUF.
+                 This is a convenience for callers that don't want to write
+                 explicit code for handling ERANGE.  */
+              size_t i;
+
+              /* Convert wchar_t[] -> char[], assuming plain ASCII.  */
+              for (i = 0; i < bufsize; i++)
+                buf[i] = result[i];
+              buf[bufsize - 1] = '\0';
+            }
+          return ERANGE;
+        }
+    }
+#else
+  const char *result = setlocale_null_unlocked (category);
+
+  if (result == NULL)
+    {
+      /* CATEGORY is invalid.  */
+      if (bufsize > 0)
+        /* Return an empty string in BUF.
+           This is a convenience for callers that don't want to write explicit
+           code for handling EINVAL.  */
+        buf[0] = '\0';
+      return EINVAL;
+    }
+  else
+    {
+      size_t length = strlen (result);
+      if (length < bufsize)
+        {
+          memcpy (buf, result, length + 1);
+          return 0;
+        }
+      else
+        {
+          if (bufsize > 0)
+            {
+              /* Return a truncated result in BUF.
+                 This is a convenience for callers that don't want to write
+                 explicit code for handling ERANGE.  */
+              memcpy (buf, result, bufsize - 1);
+              buf[bufsize - 1] = '\0';
+            }
+          return ERANGE;
+        }
+    }
+#endif
+}
index 152452e04ffa118fc414b5386565d9f678a1c5ce..5ecf413de01ed9e95b0953b7560e0fb1afccd8e6 100644 (file)
@@ -25,9 +25,6 @@
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
-#if defined _WIN32 && !defined __CYGWIN__
-# include <wchar.h>
-#endif
 
 #if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE)
 
 
 #endif
 
-/* Use the system's setlocale() function, not the gnulib override, here.  */
-#undef setlocale
-
-static const char *
-setlocale_null_unlocked (int category)
-{
-  const char *result = setlocale (category, NULL);
-
-#ifdef __ANDROID__
-  if (result == NULL)
-    switch (category)
-      {
-      case LC_CTYPE:
-      case LC_NUMERIC:
-      case LC_TIME:
-      case LC_COLLATE:
-      case LC_MONETARY:
-      case LC_MESSAGES:
-      case LC_ALL:
-      case LC_PAPER:
-      case LC_NAME:
-      case LC_ADDRESS:
-      case LC_TELEPHONE:
-      case LC_MEASUREMENT:
-        result = "C";
-        break;
-      default:
-        break;
-      }
-#endif
-
-  return result;
-}
-
-static int
-setlocale_null_r_unlocked (int category, char *buf, size_t bufsize)
-{
-#if defined _WIN32 && !defined __CYGWIN__ && defined _MSC_VER
-  /* On native Windows, nowadays, the setlocale() implementation is based
-     on _wsetlocale() and uses malloc() for the result.  We are better off
-     using _wsetlocale() directly.  */
-  const wchar_t *result = _wsetlocale (category, NULL);
-
-  if (result == NULL)
-    {
-      /* CATEGORY is invalid.  */
-      if (bufsize > 0)
-        /* Return an empty string in BUF.
-           This is a convenience for callers that don't want to write explicit
-           code for handling EINVAL.  */
-        buf[0] = '\0';
-      return EINVAL;
-    }
-  else
-    {
-      size_t length = wcslen (result);
-      if (length < bufsize)
-        {
-          size_t i;
-
-          /* Convert wchar_t[] -> char[], assuming plain ASCII.  */
-          for (i = 0; i <= length; i++)
-            buf[i] = result[i];
-
-          return 0;
-        }
-      else
-        {
-          if (bufsize > 0)
-            {
-              /* Return a truncated result in BUF.
-                 This is a convenience for callers that don't want to write
-                 explicit code for handling ERANGE.  */
-              size_t i;
-
-              /* Convert wchar_t[] -> char[], assuming plain ASCII.  */
-              for (i = 0; i < bufsize; i++)
-                buf[i] = result[i];
-              buf[bufsize - 1] = '\0';
-            }
-          return ERANGE;
-        }
-    }
-#else
-  const char *result = setlocale_null_unlocked (category);
-
-  if (result == NULL)
-    {
-      /* CATEGORY is invalid.  */
-      if (bufsize > 0)
-        /* Return an empty string in BUF.
-           This is a convenience for callers that don't want to write explicit
-           code for handling EINVAL.  */
-        buf[0] = '\0';
-      return EINVAL;
-    }
-  else
-    {
-      size_t length = strlen (result);
-      if (length < bufsize)
-        {
-          memcpy (buf, result, length + 1);
-          return 0;
-        }
-      else
-        {
-          if (bufsize > 0)
-            {
-              /* Return a truncated result in BUF.
-                 This is a convenience for callers that don't want to write
-                 explicit code for handling ERANGE.  */
-              memcpy (buf, result, bufsize - 1);
-              buf[bufsize - 1] = '\0';
-            }
-          return ERANGE;
-        }
-    }
-#endif
-}
-
 #if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin < 3.4.6 */
 
 /* Use a lock, so that no two threads can invoke setlocale_null_r_unlocked
index defa2b41a634adbaa94e2aaf8c84248504a1ab26..966c53cfaa5341e4dd3d48d1c7dc8017a363b1ec 100644 (file)
@@ -44,6 +44,34 @@ extern "C" {
    55+5*58.  */
 #define SETLOCALE_NULL_ALL_MAX (148+12*256+1)
 
+/* setlocale_null_r_unlocked (CATEGORY, BUF, BUFSIZE) is like
+   setlocale (CATEGORY, NULL), except that
+     - it returns the resulting locale category name or locale name in the
+       user-supplied buffer BUF, which must be BUFSIZE bytes long.
+   The recommended minimum buffer size is
+     - SETLOCALE_NULL_MAX for CATEGORY != LC_ALL, and
+     - SETLOCALE_NULL_ALL_MAX for CATEGORY == LC_ALL.
+   The return value is an error code: 0 if the call is successful, EINVAL if
+   CATEGORY is invalid, or ERANGE if BUFSIZE is smaller than the length needed
+   size (including the trailing NUL byte).  In the latter case, a truncated
+   result is returned in BUF, but still NUL-terminated if BUFSIZE > 0.
+   This call is guaranteed to be multithread-safe only if
+     - CATEGORY != LC_ALL and SETLOCALE_NULL_ONE_MTSAFE is true, or
+     - CATEGORY == LC_ALL and SETLOCALE_NULL_ALL_MTSAFE is true,
+   and the other threads must not make other setlocale invocations (since
+   changing the global locale has side effects on all threads).  */
+extern int setlocale_null_r_unlocked (int category, char *buf, size_t bufsize)
+  _GL_ARG_NONNULL ((2));
+
+/* setlocale_null_unlocked (CATEGORY) is like setlocale (CATEGORY, NULL).
+   The return value is NULL if CATEGORY is invalid.
+   This call is guaranteed to be multithread-safe only if
+     - CATEGORY != LC_ALL and SETLOCALE_NULL_ONE_MTSAFE is true, or
+     - CATEGORY == LC_ALL and SETLOCALE_NULL_ALL_MTSAFE is true,
+   and the other threads must not make other setlocale invocations (since
+   changing the global locale has side effects on all threads).  */
+extern const char *setlocale_null_unlocked (int category);
+
 /* setlocale_null_r (CATEGORY, BUF, BUFSIZE) is like setlocale (CATEGORY, NULL),
    except that
      - it is guaranteed to be multithread-safe,
index 91efd51483f7cfc4583d169e7bea862d05c5ad49..782e29ad8de008ae239878ff116f68e4bf0eb6c8 100644 (file)
@@ -13,6 +13,7 @@ m4/visibility.m4
 Depends-on:
 locale
 snippet/arg-nonnull
+setlocale-null-unlocked
 
 configure.ac:
 gl_FUNC_SETLOCALE_NULL
diff --git a/modules/setlocale-null-unlocked b/modules/setlocale-null-unlocked
new file mode 100644 (file)
index 0000000..21d9611
--- /dev/null
@@ -0,0 +1,27 @@
+Description:
+setlocale_null_unlocked() function: query the name of the current global locale,
+without locking.
+
+Files:
+lib/setlocale_null.h
+lib/setlocale_null-unlocked.c
+
+Depends-on:
+locale
+snippet/arg-nonnull
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += setlocale_null-unlocked.c
+
+Include:
+#include "setlocale_null.h"
+
+Link:
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible