On Android 4.3, I'm seeing these test failures:
FAIL: test-setlocale2.sh ======================== FAIL test-setlocale2.sh (exit status: 1) FAIL: test-mbrtowc5.sh ====================== FAIL test-mbrtowc5.sh (exit status: 1) FAIL: test-localename ===================== ../../gltests/test-localename.c:103: assertion 'ret != NULL' failed FAIL test-localename (exit status: 139) The cause is that the native setlocale() function always fails. (See <https://android.googlesource.com/platform/bionic/+/29c7f0b4d18f812267c2194b85204e19e41d0387>.) This patch provides a workaround. 2019-01-25 Bruno Haible <br...@clisp.org> setlocale: Work around bug on Android 4.3. * m4/setlocale.m4 (gl_FUNC_SETLOCALE): Test whether setlocale supports the "C" locale. * lib/setlocale.c (setlocale_unixlike): New wrapper for Android. * doc/posix-functions/setlocale.texi: Mention the Android bug. diff --git a/doc/posix-functions/setlocale.texi b/doc/posix-functions/setlocale.texi index 1da6d13..32c9902 100644 --- a/doc/posix-functions/setlocale.texi +++ b/doc/posix-functions/setlocale.texi @@ -20,6 +20,10 @@ On Windows platforms (excluding Cygwin) and Cygwin 1.5.x, On Windows platforms (excluding Cygwin), @code{setlocale} understands different locale names, that are not based on ISO 639 language names and ISO 3166 country names. +@item +On Android 4.3, which which doesn't have locales, the @code{setlocale} function +always fails. The replacement, however, supports only the locale names +@code{"C"} and @code{"POSIX"}. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/setlocale.c b/lib/setlocale.c index 3abdf2c..e14805e 100644 --- a/lib/setlocale.c +++ b/lib/setlocale.c @@ -794,6 +794,39 @@ setlocale_unixlike (int category, const char *locale) return NULL; } +# elif defined __ANDROID__ + +/* Like setlocale, but accept also the locale names "C" and "POSIX". */ +static char * +setlocale_unixlike (int category, const char *locale) +{ + char *result = setlocale (category, locale); + 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: + if (locale == NULL + || strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0) + result = (char *) "C"; + break; + default: + break; + } + return result; +} +# define setlocale setlocale_unixlike + # else # define setlocale_unixlike setlocale # endif diff --git a/m4/setlocale.m4 b/m4/setlocale.m4 index d04985c..dba68c4 100644 --- a/m4/setlocale.m4 +++ b/m4/setlocale.m4 @@ -1,4 +1,4 @@ -# setlocale.m4 serial 5 +# setlocale.m4 serial 6 dnl Copyright (C) 2011-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,6 +19,32 @@ AC_DEFUN([gl_FUNC_SETLOCALE], 1.5.*) REPLACE_SETLOCALE=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) ;; + *) REPLACE_SETLOCALE=1 ;; + esac + ;; esac ])