From 00893e79fc62966067af1a106567db96bd170338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 3 Mar 2024 19:11:32 +0100 Subject: New upstream version 1.2 --- lib/setlocale_null-unlocked.c | 149 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 lib/setlocale_null-unlocked.c (limited to 'lib/setlocale_null-unlocked.c') diff --git a/lib/setlocale_null-unlocked.c b/lib/setlocale_null-unlocked.c new file mode 100644 index 00000000..0a86f0df --- /dev/null +++ b/lib/setlocale_null-unlocked.c @@ -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 . */ + +/* Written by Bruno Haible , 2019. */ + +#include + +/* Specification. */ +#include "setlocale_null.h" + +#include +#include +#include +#if defined _WIN32 && !defined __CYGWIN__ +# include +#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 +} -- cgit v1.2.3