On Android (Termux environment), I see a test failure of the test-getlocalename_l test.
The problem is two-fold: 1) The newlocale() function is fake in the same sense as on OpenBSD >= 6.2. The fix is to set the macro LOCALENAME_ENHANCE_LOCALE_FUNCS, like on OpenBSD. 2) The setlocale() function does not store the arguments that were passed to it, anywhere. This is similar to the problem on native Windows, where the LC_MESSAGES category's name is not stored; but here it affects all categories. The solution is similar: to provide a place where these category names can be stored, in a module that is dependency of 'setlocale' and 'getlocalename_l-unsafe' and that acts as an enhancement of 'setlocale-null'. 2025-03-22 Bruno Haible <br...@clisp.org> getlocalename_l-unsafe: Add Android workaround, like on OpenBSD. * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): Set gt_cv_locale_fake to yes also on Android. 2025-03-22 Bruno Haible <br...@clisp.org> setlocale-messages: Rename to setlocale-fixes and add Android support. * lib/setlocale-fixes.h: Renamed from lib/setlocale-messages.h. (setlocale_fixed, setlocale_fixed_null): New declarations. * lib/setlocale-fixes.c: Renamed from lib/setlocale-messages.h. (lc_cat_name): New variable. (cat_to_index, index_to_cat): New macro. (lc_all_name): New variable. (cat_names): New constant. (fill_lc_all_name, extract_single_name, setlocale_fixed, setlocale_fixed_null): New functions. * m4/setlocale.m4 (gl_FUNC_SETLOCALE): Set NEED_SETLOCALE_IMPROVED to 1 on Android. * lib/setlocale.c: Include setlocale-fixes.h instead of setlocale-messages.h. (setlocale_unixlike) [__ANDROID__]: Use setlocale_fixed instead of setlocale_mtsafe. (setlocale_improved): On Android, use setlocale_fixed_null instead of setlocale. * lib/getlocalename_l-unsafe.c: Include setlocale-fixes.h instead of setlocale-messages.h. (getlocalename_l_unsafe): On Android, use setlocale_fixed_null instead of setlocale_null. * modules/setlocale-fixes: Renamed from modules/setlocale-messages. (Files): Update. (configure.ac): Compile the .c file also on Android. (Include): Include setlocale-fixes.h instead of setlocale-messages.h. * modules/setlocale (Depends-on): Add setlocale-fixes. Remove setlocale-messages. * modules/getlocalename_l-unsafe (Depends-on): Likewise. * doc/posix-functions/setlocale.texi: Mention the Android problem.
From 40b7c218d7ee1cadd78de79a2dcc7b32a9d92850 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Mar 2025 13:03:43 +0100 Subject: [PATCH 1/2] setlocale-messages: Rename to setlocale-fixes and add Android support. * lib/setlocale-fixes.h: Renamed from lib/setlocale-messages.h. (setlocale_fixed, setlocale_fixed_null): New declarations. * lib/setlocale-fixes.c: Renamed from lib/setlocale-messages.h. (lc_cat_name): New variable. (cat_to_index, index_to_cat): New macro. (lc_all_name): New variable. (cat_names): New constant. (fill_lc_all_name, extract_single_name, setlocale_fixed, setlocale_fixed_null): New functions. * m4/setlocale.m4 (gl_FUNC_SETLOCALE): Set NEED_SETLOCALE_IMPROVED to 1 on Android. * lib/setlocale.c: Include setlocale-fixes.h instead of setlocale-messages.h. (setlocale_unixlike) [__ANDROID__]: Use setlocale_fixed instead of setlocale_mtsafe. (setlocale_improved): On Android, use setlocale_fixed_null instead of setlocale. * lib/getlocalename_l-unsafe.c: Include setlocale-fixes.h instead of setlocale-messages.h. (getlocalename_l_unsafe): On Android, use setlocale_fixed_null instead of setlocale_null. * modules/setlocale-fixes: Renamed from modules/setlocale-messages. (Files): Update. (configure.ac): Compile the .c file also on Android. (Include): Include setlocale-fixes.h instead of setlocale-messages.h. * modules/setlocale (Depends-on): Add setlocale-fixes. Remove setlocale-messages. * modules/getlocalename_l-unsafe (Depends-on): Likewise. * doc/posix-functions/setlocale.texi: Mention the Android problem. --- ChangeLog | 33 +++ doc/posix-functions/setlocale.texi | 3 + lib/getlocalename_l-unsafe.c | 8 +- lib/setlocale-fixes.c | 241 ++++++++++++++++++ ...setlocale-messages.h => setlocale-fixes.h} | 38 ++- lib/setlocale-messages.c | 45 ---- lib/setlocale.c | 6 +- m4/setlocale.m4 | 31 +-- modules/getlocalename_l-unsafe | 2 +- modules/setlocale | 2 +- modules/setlocale-fixes | 27 ++ modules/setlocale-messages | 27 -- 12 files changed, 351 insertions(+), 112 deletions(-) create mode 100644 lib/setlocale-fixes.c rename lib/{setlocale-messages.h => setlocale-fixes.h} (54%) delete mode 100644 lib/setlocale-messages.c create mode 100644 modules/setlocale-fixes delete mode 100644 modules/setlocale-messages diff --git a/ChangeLog b/ChangeLog index ff0cc03ec9..4b4c2e8a45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2025-03-22 Bruno Haible <br...@clisp.org> + + setlocale-messages: Rename to setlocale-fixes and add Android support. + * lib/setlocale-fixes.h: Renamed from lib/setlocale-messages.h. + (setlocale_fixed, setlocale_fixed_null): New declarations. + * lib/setlocale-fixes.c: Renamed from lib/setlocale-messages.h. + (lc_cat_name): New variable. + (cat_to_index, index_to_cat): New macro. + (lc_all_name): New variable. + (cat_names): New constant. + (fill_lc_all_name, extract_single_name, setlocale_fixed, + setlocale_fixed_null): New functions. + * m4/setlocale.m4 (gl_FUNC_SETLOCALE): Set NEED_SETLOCALE_IMPROVED to 1 + on Android. + * lib/setlocale.c: Include setlocale-fixes.h instead of + setlocale-messages.h. + (setlocale_unixlike) [__ANDROID__]: Use setlocale_fixed instead of + setlocale_mtsafe. + (setlocale_improved): On Android, use setlocale_fixed_null instead of + setlocale. + * lib/getlocalename_l-unsafe.c: Include setlocale-fixes.h instead of + setlocale-messages.h. + (getlocalename_l_unsafe): On Android, use setlocale_fixed_null instead + of setlocale_null. + * modules/setlocale-fixes: Renamed from modules/setlocale-messages. + (Files): Update. + (configure.ac): Compile the .c file also on Android. + (Include): Include setlocale-fixes.h instead of setlocale-messages.h. + * modules/setlocale (Depends-on): Add setlocale-fixes. Remove + setlocale-messages. + * modules/getlocalename_l-unsafe (Depends-on): Likewise. + * doc/posix-functions/setlocale.texi: Mention the Android problem. + 2025-03-21 Bruno Haible <br...@clisp.org> getloadavg: Improve Linux and Android support. diff --git a/doc/posix-functions/setlocale.texi b/doc/posix-functions/setlocale.texi index 21b04b6553..48ea614ad5 100644 --- a/doc/posix-functions/setlocale.texi +++ b/doc/posix-functions/setlocale.texi @@ -23,6 +23,9 @@ locale names, that are not based on ISO 639 language names and ISO 3166 country names. @item +On Android 5.0 and newer, setting any category other than @code{LC_CTYPE} of +the global locale affects the @code{LC_CTYPE} category as well. +@item On Android < 5.0, which doesn't have locales, the @code{setlocale} function always fails. The replacement, however, supports only the locale names @code{"C"} and @code{"POSIX"}. diff --git a/lib/getlocalename_l-unsafe.c b/lib/getlocalename_l-unsafe.c index 627434fc24..1f24f82ddb 100644 --- a/lib/getlocalename_l-unsafe.c +++ b/lib/getlocalename_l-unsafe.c @@ -25,8 +25,8 @@ #include <stdlib.h> #include <string.h> -#if LC_MESSAGES == 1729 -# include "setlocale-messages.h" +#if LC_MESSAGES == 1729 || defined __ANDROID__ +# include "setlocale-fixes.h" #endif #include "setlocale_null.h" @@ -668,7 +668,11 @@ getlocalename_l_unsafe (int category, locale_t locale) name = setlocale_messages_null (); else #endif +#if defined __ANDROID__ + name = setlocale_fixed_null (category); +#else name = setlocale_null (category); +#endif if (name != NULL) return (struct string_with_storage) { name, STORAGE_GLOBAL }; else diff --git a/lib/setlocale-fixes.c b/lib/setlocale-fixes.c new file mode 100644 index 0000000000..771ffe15cf --- /dev/null +++ b/lib/setlocale-fixes.c @@ -0,0 +1,241 @@ +/* Make the global locale minimally POSIX compliant. + Copyright (C) 2025 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/>. */ + +#include <config.h> + +/* Specification. */ +#include "setlocale-fixes.h" + + +#if defined _WIN32 && !defined __CYGWIN__ + +# include <stddef.h> +# include <string.h> + +/* The system does not store an LC_MESSAGES locale category. Do it here. */ +static char lc_messages_name[64] = "C"; + +const char * +setlocale_messages (const char *name) +{ + if (name != NULL) + { + lc_messages_name[sizeof (lc_messages_name) - 1] = '\0'; + strncpy (lc_messages_name, name, sizeof (lc_messages_name) - 1); + } + return lc_messages_name; +} + +const char * +setlocale_messages_null (void) +{ + /* This implementation is multithread-safe, assuming no other thread changes + the LC_MESSAGES locale category. */ + return lc_messages_name; +} + +#endif + + +#if defined __ANDROID__ + +# include <stddef.h> +# include <stdlib.h> +# include <locale.h> +# include <string.h> + +/* Use the system's setlocale() function, not the gnulib override, here. */ +# undef setlocale + +/* Storage for the name of each category of the global locale. + Regarding the size, cf. SETLOCALE_NULL_MAX. */ +static char lc_cat_name[12][256+1] = + { "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C" }; +/* Mapping from the valid categories to the indices 0..12-1. */ +#define cat_to_index(cat) ((cat) - ((cat) >= LC_ALL)) +/* Mapping from the indicess 0..12-1 to the valid categories. */ +#define index_to_cat(i) ((i) + ((i) >= LC_ALL)) + +/* Storage for the name of the entire global locale. + For mixed locales, use the syntax from glibc: + LC_CTYPE=...;LC_NUMERIC=...;......;LC_IDENTIFICATION=... + Regarding the size, cf. SETLOCALE_NULL_ALL_MAX. */ +static char lc_all_name[148+12*256+1]; + +/* Category names. */ +static const char cat_names[12][17+1] = + { + [cat_to_index (LC_CTYPE)] = "LC_CTYPE", + [cat_to_index (LC_NUMERIC)] = "LC_NUMERIC", + [cat_to_index (LC_TIME)] = "LC_TIME", + [cat_to_index (LC_COLLATE)] = "LC_COLLATE", + [cat_to_index (LC_MONETARY)] = "LC_MONETARY", + [cat_to_index (LC_MESSAGES)] = "LC_MESSAGES", + [cat_to_index (LC_PAPER)] = "LC_PAPER", + [cat_to_index (LC_NAME)] = "LC_NAME", + [cat_to_index (LC_ADDRESS)] = "LC_ADDRESS", + [cat_to_index (LC_TELEPHONE)] = "LC_TELEPHONE", + [cat_to_index (LC_MEASUREMENT)] = "LC_MEASUREMENT", + [cat_to_index (LC_IDENTIFICATION)] = "LC_IDENTIFICATION", + }; + +/* Combines the contents of all lc_cat_name[], filling lc_all_name. */ +static void +fill_lc_all_name (void) +{ + bool all_same = true; + for (size_t i = 1; i < 12; i++) + if (strcmp (lc_cat_name[i], lc_cat_name[0]) != 0) + { + all_same = false; + break; + } + if (all_same) + /* Produce a simple locale name. */ + strcpy (lc_all_name, lc_cat_name[0]); + else + { + /* Produce a mixed locale name. */ + size_t i; + char *q; + for (i = 0, q = lc_all_name; i < 12; i++) + { + const char *p = cat_names[i]; + size_t n = strlen (p); + memcpy (q, p, n); q += n; + *q++ = '='; + p = lc_cat_name[i]; + n = strlen (p); + memcpy (q, p, n); q += n; + *q++ = ';'; + } + *--q = '\0'; + } +} + +/* Extracts the name of a single category from NAME and stores it in + SINGLE_NAME. CATEGORY must be a valid category name != LC_ALL. + This is basically the opposite of fill_lc_all_name. */ +static int +extract_single_name (char single_name[256+1], int category, const char *name) +{ + if (strchr (name, ';') != NULL) + { + /* A mixed locale name. */ + const char *cat_name = cat_names[cat_to_index (category)]; + size_t cat_name_len = strlen (cat_name); + const char *p = name; + for (;;) + { + const char *q = strchr (p, ';'); + if (strncmp (p, cat_name, cat_name_len) == 0 + && p[cat_name_len] == '=') + { + p += cat_name_len + 1; + size_t n = (q == NULL ? strlen (p) : q - p); + if (n >= 256+1) + n = 256; + memcpy (single_name, p, n); + single_name[n] = '\0'; + return 0; + } + if (q == NULL) + break; + p = q + 1; + } + return -1; + } + else + { + /* A simple locale name. */ + size_t n = strlen (name); + if (n >= 256+1) + n = 256; + memcpy (single_name, name, n); + single_name[n] = '\0'; + return 0; + } +} + +const char * +setlocale_fixed (int category, const char *name) +{ + if (category == LC_ALL) + { + if (name != NULL) + { + char single_name[256+1]; + int i; + + /* Test whether NAME is valid. */ + for (i = 12-1; i >= 0; i--) + if (extract_single_name (single_name, index_to_cat (i), name) < 0) + return NULL; + /* Now single_name contains the one for the index 0, + i.e. for LC_CTYPE. */ + if (setlocale (LC_CTYPE, single_name) == NULL) + return NULL; + + /* Fill lc_cat_name[]. */ + for (i = 12-1; i >= 0; i--) + { + if (extract_single_name (single_name, index_to_cat (i), name) < 0) + abort (); + strcpy (lc_cat_name[i], single_name); + } + /* Update lc_all_name. */ + fill_lc_all_name (); + } + + return lc_all_name; + } + if (category >= LC_CTYPE && category <= LC_IDENTIFICATION) + { + if (name != NULL) + { + char single_name[256+1]; + + /* Test whether NAME is valid. */ + if (extract_single_name (single_name, category, name) < 0) + return NULL; + if (category == LC_CTYPE) + if (setlocale (category, single_name) == NULL) + return NULL; + + /* Fill lc_cat_name[]. */ + strcpy (lc_cat_name[cat_to_index (category)], single_name); + /* Update lc_all_name. */ + fill_lc_all_name (); + } + + return lc_cat_name[cat_to_index (category)]; + } + return NULL; +} + +const char * +setlocale_fixed_null (int category) +{ + /* This implementation is multithread-safe, assuming no other thread changes + any locale category. */ + if (category == LC_ALL) + return lc_all_name; + if (category >= LC_CTYPE && category <= LC_IDENTIFICATION) + return lc_cat_name[cat_to_index (category)]; + return NULL; +} + +#endif diff --git a/lib/setlocale-messages.h b/lib/setlocale-fixes.h similarity index 54% rename from lib/setlocale-messages.h rename to lib/setlocale-fixes.h index 06c7a8dd41..d3cd247700 100644 --- a/lib/setlocale-messages.h +++ b/lib/setlocale-fixes.h @@ -1,4 +1,4 @@ -/* Extension of the global locale with LC_MESSAGES. +/* Make the global locale minimally POSIX compliant. Copyright (C) 2025 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify @@ -16,16 +16,19 @@ /* Written by Bruno Haible <br...@clisp.org>, 2025. */ -#ifndef _SETLOCALE_MESSAGES_H -#define _SETLOCALE_MESSAGES_H - -/* This file is only relevant on platforms that lack LC_MESSAGES, namely - native Windows. */ +#ifndef _SETLOCALE_FIXES_H +#define _SETLOCALE_FIXES_H #ifdef __cplusplus extern "C" { #endif + +#if defined _WIN32 && !defined __CYGWIN__ + +/* This section is only relevant on platforms that lack LC_MESSAGES, namely + native Windows. */ + /* setlocale_messages (NAME) is like setlocale (LC_MESSAGES, NAME). */ extern const char *setlocale_messages (const char *name); @@ -33,8 +36,29 @@ extern const char *setlocale_messages (const char *name); it is guaranteed to be multithread-safe. */ extern const char *setlocale_messages_null (void); +#endif + + +#if defined __ANDROID__ + +/* This section is only relevant on Android. + While OpenBSD ??? 6.2 and Android API level >= 21 have a fake locale_t type, + regarding the global locale, OpenBSD at least stores the name of each + category of the global locale. Android doesn't do this, and additionally + has a bug: setting any category != LC_CTYPE of the global locale affects + the LC_CTYPE category as well. */ + +/* Like setlocale (CATEGORY, NAME), but fixes these two Android bugs. */ +extern const char *setlocale_fixed (int category, const char *name); + +/* Like setlocale_null (CATEGORY), but consistent with setlocale_fixed. */ +extern const char *setlocale_fixed_null (int category); + +#endif + + #ifdef __cplusplus } #endif -#endif /* _SETLOCALE_MESSAGES_H */ +#endif /* _SETLOCALE_FIXES_H */ diff --git a/lib/setlocale-messages.c b/lib/setlocale-messages.c deleted file mode 100644 index 857236ee59..0000000000 --- a/lib/setlocale-messages.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Extension of the global locale with LC_MESSAGES. - Copyright (C) 2025 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/>. */ - -#include <config.h> - -/* Specification. */ -#include "setlocale-messages.h" - -#include <stddef.h> -#include <string.h> - -/* The system does not store an LC_MESSAGES locale category. Do it here. */ -static char lc_messages_name[64] = "C"; - -const char * -setlocale_messages (const char *name) -{ - if (name != NULL) - { - lc_messages_name[sizeof (lc_messages_name) - 1] = '\0'; - strncpy (lc_messages_name, name, sizeof (lc_messages_name) - 1); - } - return lc_messages_name; -} - -const char * -setlocale_messages_null (void) -{ - /* This implementation is multithread-safe, assuming no other thread changes - the LC_MESSAGES locale category. */ - return lc_messages_name; -} diff --git a/lib/setlocale.c b/lib/setlocale.c index 5095eddb64..b5a9bdf89c 100644 --- a/lib/setlocale.c +++ b/lib/setlocale.c @@ -33,7 +33,7 @@ #include <stdlib.h> #include <string.h> -#include "setlocale-messages.h" +#include "setlocale-fixes.h" #include "localename.h" #if HAVE_CFLOCALECOPYPREFERREDLANGUAGES || HAVE_CFPREFERENCESCOPYAPPVALUE @@ -873,7 +873,7 @@ setlocale_unixlike (int category, const char *locale) static char * setlocale_unixlike (int category, const char *locale) { - char *result = setlocale_mtsafe (category, locale); + char *result = setlocale_fixed (category, locale); if (result == NULL) switch (category) { @@ -1805,6 +1805,8 @@ setlocale_improved (int category, const char *locale) return resultbuf; } } +# elif defined __ANDROID__ + return setlocale_fixed_null (LC_ALL); # else return setlocale (LC_ALL, NULL); # endif diff --git a/m4/setlocale.m4 b/m4/setlocale.m4 index 6c033ddea4..16413cec36 100644 --- a/m4/setlocale.m4 +++ b/m4/setlocale.m4 @@ -1,5 +1,5 @@ # setlocale.m4 -# serial 10 +# serial 11 dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -18,6 +18,9 @@ AC_DEFUN([gl_FUNC_SETLOCALE] dnl On native Windows systems, setlocale(category,NULL) does not look at dnl the environment variables LC_ALL, category, and LANG. mingw* | windows*) NEED_SETLOCALE_IMPROVED=1 ;; + dnl On Android, setlocale(category,name) treats all categories as equivalent + dnl to LC_CTYPE. And on Android 4.3, setlocale(category,"C") always fails. + *-android*) NEED_SETLOCALE_IMPROVED=1 ;; dnl On Cygwin 1.5.x, setlocale always succeeds but setlocale(LC_CTYPE,NULL) dnl is then still "C". cygwin*) @@ -25,32 +28,6 @@ AC_DEFUN([gl_FUNC_SETLOCALE] 1.5.*) NEED_SETLOCALE_IMPROVED=1 ;; esac ;; - dnl On Android 4.3, setlocale(category,"C") always fails. - *) - AC_CACHE_CHECK([whether setlocale supports the C locale], - [gl_cv_func_setlocale_works], - [AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include <locale.h> -int main () -{ - return setlocale (LC_ALL, "C") == NULL; -}]])], - [gl_cv_func_setlocale_works=yes], - [gl_cv_func_setlocale_works=no], - [case "$host_os" in - # Guess no on Android. - linux*-android*) gl_cv_func_setlocale_works="guessing no";; - # Guess yes otherwise. - *) gl_cv_func_setlocale_works="guessing yes";; - esac - ]) - ]) - case "$gl_cv_func_setlocale_works" in - *yes) ;; - *) NEED_SETLOCALE_IMPROVED=1 ;; - esac - ;; esac AC_DEFINE_UNQUOTED([NEED_SETLOCALE_IMPROVED], [$NEED_SETLOCALE_IMPROVED], [Define to 1 to enable general improvements of setlocale.]) diff --git a/modules/getlocalename_l-unsafe b/modules/getlocalename_l-unsafe index b3873d7b02..c2392fc39d 100644 --- a/modules/getlocalename_l-unsafe +++ b/modules/getlocalename_l-unsafe @@ -17,7 +17,7 @@ flexmember lock bool thread-optim -setlocale-messages +setlocale-fixes setlocale-null free-posix diff --git a/modules/setlocale b/modules/setlocale index 45c35ff808..4cf9597ea8 100644 --- a/modules/setlocale +++ b/modules/setlocale @@ -7,7 +7,7 @@ m4/setlocale.m4 Depends-on: locale-h -setlocale-messages [test $NEED_SETLOCALE_IMPROVED = 1] +setlocale-fixes [test $NEED_SETLOCALE_IMPROVED = 1] localename [test $NEED_SETLOCALE_IMPROVED = 1] localename-environ [test $NEED_SETLOCALE_IMPROVED = 1] setlocale-null [test $NEED_SETLOCALE_MTSAFE = 1] diff --git a/modules/setlocale-fixes b/modules/setlocale-fixes new file mode 100644 index 0000000000..a397793da9 --- /dev/null +++ b/modules/setlocale-fixes @@ -0,0 +1,27 @@ +Description: +Make the global locale minimally POSIX compliant. + +Files: +lib/setlocale-fixes.h +lib/setlocale-fixes.c + +Depends-on: + +configure.ac: +AC_REQUIRE([AC_CANONICAL_HOST]) +gl_CONDITIONAL([GL_COND_OBJ_SETLOCALE_FIXES], + [case "$host_os" in mingw* | windows* | *-android*) true;; *) false;; esac]) + +Makefile.am: +if GL_COND_OBJ_SETLOCALE_FIXES +lib_SOURCES += setlocale-fixes.c +endif + +Include: +"setlocale-fixes.h" + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/setlocale-messages b/modules/setlocale-messages deleted file mode 100644 index bd7c078cc8..0000000000 --- a/modules/setlocale-messages +++ /dev/null @@ -1,27 +0,0 @@ -Description: -Extension of the global locale with LC_MESSAGES. - -Files: -lib/setlocale-messages.h -lib/setlocale-messages.c - -Depends-on: - -configure.ac: -AC_REQUIRE([AC_CANONICAL_HOST]) -gl_CONDITIONAL([GL_COND_OBJ_SETLOCALE_MESSAGES], - [case "$host_os" in mingw* | windows*) true;; *) false;; esac]) - -Makefile.am: -if GL_COND_OBJ_SETLOCALE_MESSAGES -lib_SOURCES += setlocale-messages.c -endif - -Include: -"setlocale-messages.h" - -License: -LGPLv2+ - -Maintainer: -all -- 2.43.0
From 979dcc75b404ed579e588e048a13145f04440e15 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Mar 2025 13:06:36 +0100 Subject: [PATCH 2/2] getlocalename_l-unsafe: Add Android workaround, like on OpenBSD. * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): Set gt_cv_locale_fake to yes also on Android. --- ChangeLog | 6 ++++++ m4/intl-thread-locale.m4 | 44 ++++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b4c2e8a45..12aa0404b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2025-03-22 Bruno Haible <br...@clisp.org> + + getlocalename_l-unsafe: Add Android workaround, like on OpenBSD. + * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): Set + gt_cv_locale_fake to yes also on Android. + 2025-03-22 Bruno Haible <br...@clisp.org> setlocale-messages: Rename to setlocale-fixes and add Android support. diff --git a/m4/intl-thread-locale.m4 b/m4/intl-thread-locale.m4 index 084eacf14a..91a1c20896 100644 --- a/m4/intl-thread-locale.m4 +++ b/m4/intl-thread-locale.m4 @@ -1,5 +1,5 @@ # intl-thread-locale.m4 -# serial 14 +# serial 15 dnl Copyright (C) 2015-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,15 +40,21 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl they did not think about the programs. dnl In this situation, even the HAVE_NAMELESS_LOCALES support cannot make dnl uselocale() work. + dnl Similarly on Android. See + dnl <https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/bionic/locale.cpp>. dnl So, define HAVE_FAKE_LOCALES and disable all per-thread locale support. - dnl Expected result: HAVE_FAKE_LOCALES is defined on OpenBSD ??? 6.2. + dnl Expected result: + dnl - HAVE_FAKE_LOCALES is defined on OpenBSD ??? 6.2, Android API level >= 21. case "$gt_cv_func_uselocale_works" in *yes) AC_CHECK_HEADERS_ONCE([xlocale.h]) - AC_CACHE_CHECK([for fake locale system (OpenBSD)], + AC_CACHE_CHECK([for fake locale system (OpenBSD, Android)], [gt_cv_locale_fake], - [AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ + [case "$host_os" in + *-android*) gt_cv_locale_fake=yes ;; + *) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include <locale.h> #if HAVE_XLOCALE_H # include <xlocale.h> @@ -62,14 +68,16 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] loc2 = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", (locale_t)0); return !(loc1 == loc2); }]])], - [gt_cv_locale_fake=yes], - [gt_cv_locale_fake=no], - [dnl Guess the locale system is fake only on OpenBSD. - case "$host_os" in - openbsd*) gt_cv_locale_fake="guessing yes" ;; - *) gt_cv_locale_fake="guessing no" ;; - esac - ]) + [gt_cv_locale_fake=yes], + [gt_cv_locale_fake=no], + [dnl Guess the locale system is fake only on OpenBSD. + case "$host_os" in + openbsd*) gt_cv_locale_fake="guessing yes" ;; + *) gt_cv_locale_fake="guessing no" ;; + esac + ]) + ;; + esac ]) ;; *) gt_cv_locale_fake=no ;; @@ -124,8 +132,10 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale', dnl which is a problem for GNU libunistring. Therefore try hard to avoid dnl enabling this code! - dnl Expected result: HAVE_NAMELESS_LOCALES is defined on OpenBSD ??? 6.2, AIX, - dnl and HAVE_AIX72_LOCALES is defined on AIX ??? 7.2. + dnl Expected result: + dnl - HAVE_NAMELESS_LOCALES is defined on OpenBSD ??? 6.2, AIX, + dnl Android API level >= 21, + dnl - HAVE_AIX72_LOCALES is defined on AIX ??? 7.2. gt_nameless_locales=$gt_fake_locales case "$host_os" in dnl It's needed on AIX 7.2. @@ -162,7 +172,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl gt_good_uselocale = gt_working_uselocale && !gt_fake_locales. dnl Expected result: HAVE_GOOD_USELOCALE is defined on all platforms except dnl FreeBSD < 9.1, NetBSD, OpenBSD, Minix, AIX < 7, AIX 7.2, HP-UX, IRIX, - dnl Solaris < 11.4, Cygwin < 2.6, mingw, MSVC 14, Android API level < 21. + dnl Solaris < 11.4, Cygwin < 2.6, mingw, MSVC 14, Android. if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then gt_good_uselocale=yes AC_DEFINE([HAVE_GOOD_USELOCALE], [1], @@ -175,7 +185,7 @@ AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME] dnl overrides newlocale(), duplocale(), freelocale() to keep track of locale dnl names. dnl Expected result: LOCALENAME_ENHANCE_LOCALE_FUNCS is defined on - dnl OpenBSD ??? 6.2, AIX 7.1, AIX ??? 7.3. + dnl OpenBSD ??? 6.2, AIX 7.1, AIX ??? 7.3, Android API level >= 21. if test $gt_working_uselocale = yes && test $gt_nameless_locales = yes; then gt_localename_enhances_locale_funcs=yes LOCALENAME_ENHANCE_LOCALE_FUNCS=1 -- 2.43.0