diff options
Diffstat (limited to 'lib/setlocale_null.c')
-rw-r--r-- | lib/setlocale_null.c | 176 |
1 files changed, 32 insertions, 144 deletions
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c index 778429b9..5ecf413d 100644 --- a/lib/setlocale_null.c +++ b/lib/setlocale_null.c @@ -1,5 +1,5 @@ /* Query the name of the current global locale. - Copyright (C) 2019-2022 Free Software Foundation, Inc. + 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 @@ -25,12 +25,14 @@ #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) -# if defined _WIN32 && !defined __CYGWIN__ + +# if AVOID_ANY_THREADS + +/* The option '--disable-threads' explicitly requests no locking. */ + +# elif defined _WIN32 && !defined __CYGWIN__ # define WIN32_LEAN_AND_MEAN /* avoid including junk */ # include <windows.h> @@ -51,154 +53,40 @@ # include <threads.h> # endif -#endif -/* Use the system's setlocale() function, not the gnulib override, here. */ -#undef setlocale - -static const char * -setlocale_null_androidfix (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_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]; +#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin < 3.4.6 */ - 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_androidfix (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 */ - -/* Use a lock, so that no two threads can invoke setlocale_null_unlocked +/* Use a lock, so that no two threads can invoke setlocale_null_r_unlocked at the same time. */ /* Prohibit renaming this symbol. */ # undef gl_get_setlocale_null_lock -# if defined _WIN32 && !defined __CYGWIN__ +# if AVOID_ANY_THREADS + +/* The option '--disable-threads' explicitly requests no locking. */ +# define setlocale_null_r_with_lock setlocale_null_r_unlocked + +# elif defined _WIN32 && !defined __CYGWIN__ extern __declspec(dllimport) CRITICAL_SECTION *gl_get_setlocale_null_lock (void); static int -setlocale_null_with_lock (int category, char *buf, size_t bufsize) +setlocale_null_r_with_lock (int category, char *buf, size_t bufsize) { CRITICAL_SECTION *lock = gl_get_setlocale_null_lock (); int ret; EnterCriticalSection (lock); - ret = setlocale_null_unlocked (category, buf, bufsize); + ret = setlocale_null_r_unlocked (category, buf, bufsize); LeaveCriticalSection (lock); return ret; } -# elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */ +# elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin < 3.4.6 */ extern # if defined _WIN32 || defined __CYGWIN__ @@ -223,7 +111,7 @@ extern # endif static int -setlocale_null_with_lock (int category, char *buf, size_t bufsize) +setlocale_null_r_with_lock (int category, char *buf, size_t bufsize) { if (pthread_in_use()) { @@ -232,14 +120,14 @@ setlocale_null_with_lock (int category, char *buf, size_t bufsize) if (pthread_mutex_lock (lock)) abort (); - ret = setlocale_null_unlocked (category, buf, bufsize); + ret = setlocale_null_r_unlocked (category, buf, bufsize); if (pthread_mutex_unlock (lock)) abort (); return ret; } else - return setlocale_null_unlocked (category, buf, bufsize); + return setlocale_null_r_unlocked (category, buf, bufsize); } # elif HAVE_THREADS_H @@ -247,14 +135,14 @@ setlocale_null_with_lock (int category, char *buf, size_t bufsize) extern mtx_t *gl_get_setlocale_null_lock (void); static int -setlocale_null_with_lock (int category, char *buf, size_t bufsize) +setlocale_null_r_with_lock (int category, char *buf, size_t bufsize) { mtx_t *lock = gl_get_setlocale_null_lock (); int ret; if (mtx_lock (lock) != thrd_success) abort (); - ret = setlocale_null_unlocked (category, buf, bufsize); + ret = setlocale_null_r_unlocked (category, buf, bufsize); if (mtx_unlock (lock) != thrd_success) abort (); @@ -271,27 +159,27 @@ setlocale_null_r (int category, char *buf, size_t bufsize) #if SETLOCALE_NULL_ALL_MTSAFE # if SETLOCALE_NULL_ONE_MTSAFE - return setlocale_null_unlocked (category, buf, bufsize); + return setlocale_null_r_unlocked (category, buf, bufsize); # else if (category == LC_ALL) - return setlocale_null_unlocked (category, buf, bufsize); + return setlocale_null_r_unlocked (category, buf, bufsize); else - return setlocale_null_with_lock (category, buf, bufsize); + return setlocale_null_r_with_lock (category, buf, bufsize); # endif #else # if SETLOCALE_NULL_ONE_MTSAFE if (category == LC_ALL) - return setlocale_null_with_lock (category, buf, bufsize); + return setlocale_null_r_with_lock (category, buf, bufsize); else - return setlocale_null_unlocked (category, buf, bufsize); + return setlocale_null_r_unlocked (category, buf, bufsize); # else - return setlocale_null_with_lock (category, buf, bufsize); + return setlocale_null_r_with_lock (category, buf, bufsize); # endif #endif @@ -301,7 +189,7 @@ const char * setlocale_null (int category) { #if SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE - return setlocale_null_androidfix (category); + return setlocale_null_unlocked (category); #else /* This call must be multithread-safe. To achieve this without using @@ -317,7 +205,7 @@ setlocale_null (int category) if (category == LC_ALL) { # if SETLOCALE_NULL_ALL_MTSAFE - return setlocale_null_androidfix (LC_ALL); + return setlocale_null_unlocked (LC_ALL); # else char buf[SETLOCALE_NULL_ALL_MAX]; static char resultbuf[SETLOCALE_NULL_ALL_MAX]; @@ -331,7 +219,7 @@ setlocale_null (int category) else { # if SETLOCALE_NULL_ONE_MTSAFE - return setlocale_null_androidfix (category); + return setlocale_null_unlocked (category); # else enum { |