+2019-01-25 Bruno Haible <bruno@clisp.org>
+
+ wcrtomb: Work around bug on Android 4.3.
+ * m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Test also whether wcrtomb works in
+ the C locale.
+ * lib/wcrtomb.c (wcrtomb): Provide alternate implementation for Android,
+ which does not have the 'wctomb' function.
+ * doc/posix-functions/wcrtomb.texi: Mention the Android bug.
+ * tests/test-wcrtomb.c (main): Accept argument '5'.
+ * tests/test-wcrtomb.sh: Add tests in the POSIX locale.
+
2019-01-25 Bruno Haible <bruno@clisp.org>
setlocale: Work around bug on Android 4.3.
This function is missing on some platforms:
Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Solaris 2.6, mingw, Interix 3.5.
@item
+This function produces wrong characters in the C locale on some platforms:
+Android 4.3.
+@item
This function returns 0 when the first argument is NULL in some locales on some platforms:
AIX 4.3, OSF/1 5.1, Solaris 11.3.
@end itemize
size_t
wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
{
- /* This implementation of wcrtomb on top of wctomb() supports only
- stateless encodings. ps must be in the initial state. */
+ /* This implementation of wcrtomb supports only stateless encodings.
+ ps must be in the initial state. */
if (ps != NULL && !mbsinit (ps))
{
errno = EINVAL;
return 1;
else
{
+#if defined __ANDROID__
+ /* Implement consistently with mbrtowc(): through a 1:1 correspondence,
+ as in ISO-8859-1. */
+ if (wc >= 0 && wc <= 0xff)
+ {
+ *s = (unsigned char) wc;
+ return 1;
+ }
+#else
+ /* Implement on top of wctomb(). */
int ret = wctomb (s, wc);
if (ret >= 0)
return ret;
+#endif
else
{
errno = EILSEQ;
-# wcrtomb.m4 serial 13
+# wcrtomb.m4 serial 14
dnl Copyright (C) 2008-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,
else
if test $REPLACE_MBSTATE_T = 1; then
REPLACE_WCRTOMB=1
- else
+ fi
+ if test $REPLACE_WCRTOMB = 0; then
+ dnl On Android 4.3, wcrtomb produces wrong characters in the C locale.
dnl On AIX 4.3, OSF/1 5.1 and Solaris <= 11.3, wcrtomb (NULL, 0, NULL)
dnl sometimes returns 0 instead of 1.
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([gt_LOCALE_JA])
AC_REQUIRE([gt_LOCALE_ZH_CN])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether wcrtomb works in the C locale],
+ [gl_cv_func_wcrtomb_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <string.h>
+#include <stdlib.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+ <wchar.h>.
+ BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+ included before <wchar.h>. */
+#include <stddef.h>
+#include <stdio.h>
+#include <wchar.h>
+int main ()
+{
+ mbstate_t state;
+ char out[64];
+ int count;
+ memset (&state, 0, sizeof (state));
+ out[0] = 'x';
+ count = wcrtomb (out, L'a', &state);
+ return !(count == 1 && out[0] == 'a');
+}]])],
+ [gl_cv_func_wcrtomb_works=yes],
+ [gl_cv_func_wcrtomb_works=no],
+ [case "$host_os" in
+ # Guess no on Android.
+ linux*-android*) gl_cv_func_wcrtomb_works="guessing no";;
+ # Guess yes otherwise.
+ *) gl_cv_func_wcrtomb_works="guessing yes";;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_wcrtomb_works" in
+ *yes) ;;
+ *) REPLACE_WCRTOMB=1 ;;
+ esac
+ fi
+ if test $REPLACE_WCRTOMB = 0; then
AC_CACHE_CHECK([whether wcrtomb return value is correct],
[gl_cv_func_wcrtomb_retval],
[