bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new module 'setlocale-null'


From: Bruno Haible
Subject: Re: new module 'setlocale-null'
Date: Wed, 18 Dec 2019 10:55:06 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-166-generic; KDE/5.18.0; x86_64; ; )

setlocale (category, NULL)_can return NULL in two situations:
  - when the category argument is invalid, or
  - on Android (tested on Android 4.3).


2019-12-18  Bruno Haible  <address@hidden>

        setlocale-null: Handle NULL result from setlocale.
        * lib/locale.in.h (setlocale_null): Document EINVAL return value.
        * lib/setlocale_null.c (setlocale_null_unlocked): Handle NULL result
        from setlocale or _wsetlocale.

diff --git a/lib/locale.in.h b/lib/locale.in.h
index 5986683..67e6020 100644
--- a/lib/locale.in.h
+++ b/lib/locale.in.h
@@ -228,10 +228,10 @@ _GL_WARN_ON_USE (setlocale, "setlocale works differently 
on native Windows - "
    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, 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.
+   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.
    For this call to be multithread-safe, *all* calls to
    setlocale (CATEGORY, NULL) in all other threads must have been converted
    to use setlocale_null as well, and the other threads must not make other
diff --git -w a/lib/setlocale_null.c b/lib/setlocale_null.c
index 350eca7..8072a45 100644
--- a/lib/setlocale_null.c
+++ b/lib/setlocale_null.c
@@ -63,6 +63,19 @@ setlocale_null_unlocked (int category, char *buf, size_t 
bufsize)
      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)
         {
@@ -90,8 +103,45 @@ setlocale_null_unlocked (int category, char *buf, size_t 
bufsize)
             }
           return ERANGE;
         }
+    }
 #else
   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
+
+  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)
         {
@@ -110,6 +160,7 @@ setlocale_null_unlocked (int category, char *buf, size_t 
bufsize)
             }
           return ERANGE;
         }
+    }
 #endif
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]