From bbf0d3fdf25e8f85c7751ac0ee90a0f50a0f054d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 1 Apr 2023 14:51:22 +0200 Subject: vasnwprintf-posix: Fix behaviour in the C locale. * lib/vasnprintf.c (VASNPRINTF): If NEED_WPRINTF_DIRECTIVE_C is set, implement the 'c' directive here. * m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke gl_MBRTOWC_C_LOCALE. If mbrtowc is buggy in the C locale, define NEED_WPRINTF_DIRECTIVE_C. * modules/vasnwprintf (Files): Add m4/mbrtowc.m4. * tests/test-vasnwprintf-posix.c (test_function): Add tests of %s and %c in the C locale. * doc/posix-functions/fwprintf.texi: Mention the C locale behaviour bug. * doc/posix-functions/swprintf.texi: Likewise. * doc/posix-functions/vfwprintf.texi: Likewise. * doc/posix-functions/vswprintf.texi: Likewise. * doc/posix-functions/vwprintf.texi: Likewise. * doc/posix-functions/wprintf.texi: Likewise. --- tests/test-vasnwprintf-posix.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'tests') diff --git a/tests/test-vasnwprintf-posix.c b/tests/test-vasnwprintf-posix.c index 74a26079d3..125b9386a4 100644 --- a/tests/test-vasnwprintf-posix.c +++ b/tests/test-vasnwprintf-posix.c @@ -3757,6 +3757,28 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *, free (result); } + /* On Android ≥ 5.0, the default locale is the "C.UTF-8" locale, not the + "C" locale. Furthermore, when you attempt to set the "C" or "POSIX" + locale via setlocale(), what you get is a "C" locale with UTF-8 encoding, + that is, effectively the "C.UTF-8" locale. */ +#ifndef __ANDROID__ + { /* The conversion of %s to wide characters is done as if through repeated + invocations of mbrtowc(), and in the "C" and "POSIX" locales, "an + [EILSEQ] error cannot occur since all byte values are valid characters", + says POSIX:2018. */ + int c; + + for (c = 0; c < 0x100; c++) + { + char s[2] = { c, '\0' }; + size_t length; + wchar_t *result = my_asnwprintf (NULL, &length, L"%s", s); + ASSERT (result != NULL); + free (result); + } + } +#endif + #if HAVE_WCHAR_T static wchar_t L_xyz[4] = { 'x', 'y', 'z', 0 }; @@ -3960,6 +3982,26 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *, free (result); } + /* On Android ≥ 5.0, the default locale is the "C.UTF-8" locale, not the + "C" locale. Furthermore, when you attempt to set the "C" or "POSIX" + locale via setlocale(), what you get is a "C" locale with UTF-8 encoding, + that is, effectively the "C.UTF-8" locale. */ +#ifndef __ANDROID__ + { /* The conversion of %c to wide character is done as if through btowc(), + and in the "C" and "POSIX" locales, "btowc() shall not return WEOF if + c has a value in the range 0 to 255 inclusive", says POSIX:2018. */ + int c; + + for (c = 0; c < 0x100; c++) + { + size_t length; + wchar_t *result = my_asnwprintf (NULL, &length, L"%c", c); + ASSERT (result != NULL); + free (result); + } + } +#endif + #if HAVE_WCHAR_T static wint_t L_x = (wchar_t) 'x'; -- cgit v1.2.1