summaryrefslogtreecommitdiff
path: root/m4
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-03-30 13:25:20 +0200
committerBruno Haible <bruno@clisp.org>2023-03-30 19:39:46 +0200
commit11fe27f76c63c14b6f88c815b656f3f72d37ea41 (patch)
tree8a4661c83efd2d544ff729373b33955d54054d47 /m4
parent60745587a2e0073df7fe4cb1ec462f423c8f2bb2 (diff)
downloadgnulib-11fe27f76c63c14b6f88c815b656f3f72d37ea41.tar.gz
btowc: Fix behaviour in the C locale.
* lib/btowc.c: Include <string.h> (btowc): Use mbrtowc instead of mbtowc when possible. * m4/btowc.m4 (gl_FUNC_BTOWC): Test for the mingw bug in the C locale. Invoke gl_MBRTOWC_C_LOCALE. If mbrtowc is buggy in the C locale, override also btowc. (gl_PREREQ_BTOWC): Test whether mbrtowc exists. * modules/btowc (Files): Add m4/mbrtowc.m4. (Depends-on): Add mbrtowc. * tests/test-btowc.c (main): Add a test of the C locale, based on tests/test-mbrtowc.c. * tests/test-btowc3.sh: New file, based on tests/test-mbrtowc5.sh. * modules/btowc-tests (Files): Add it. (Makefile.am): Test it. * doc/posix-functions/btowc.texi: Mention the two C locale behaviour bugs and that they are worked around.
Diffstat (limited to 'm4')
-rw-r--r--m4/btowc.m457
1 files changed, 56 insertions, 1 deletions
diff --git a/m4/btowc.m4 b/m4/btowc.m4
index 77218a7d1c..1cd100a2d7 100644
--- a/m4/btowc.m4
+++ b/m4/btowc.m4
@@ -1,4 +1,4 @@
-# btowc.m4 serial 12
+# btowc.m4 serial 13
dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -88,6 +88,49 @@ int main ()
fi
])
+ dnl On mingw, in the C locale, btowc is inconsistent with mbrtowc:
+ dnl mbrtowc avoids calling MultiByteToWideChar when MB_CUR_MAX is 1 and
+ dnl ___lc_codepage_func() is 0, but btowc is lacking this special case.
+ AC_CHECK_FUNCS_ONCE([mbrtowc])
+ AC_CACHE_CHECK([whether btowc is consistent with mbrtowc in the C locale],
+ [gl_cv_func_btowc_consistent],
+ [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+#if HAVE_MBRTOWC
+ wint_t wc1 = btowc (0x80);
+ wchar_t wc2 = (wchar_t) 0xbadface;
+ char buf[1] = { 0x80 };
+ mbstate_t state;
+ memset (&state, 0, sizeof (mbstate_t));
+ if (mbrtowc (&wc2, buf, 1, &state) != 1 || wc1 != wc2)
+ return 1;
+#endif
+ return 0;
+}]])],
+ [gl_cv_func_btowc_consistent=yes],
+ [gl_cv_func_btowc_consistent=no],
+ [case "$host_os" in
+ # Guess no on mingw.
+ mingw*) AC_EGREP_CPP([Problem], [
+#ifdef __MINGW32__
+ Problem
+#endif
+ ],
+ [gl_cv_func_btowc_consistent="guessing no"],
+ [gl_cv_func_btowc_consistent="guessing yes"])
+ ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_btowc_consistent="guessing yes" ;;
+ esac
+ ])
+ ])
+
case "$gl_cv_func_btowc_nul" in
*yes) ;;
*) REPLACE_BTOWC=1 ;;
@@ -96,10 +139,22 @@ int main ()
*yes) ;;
*) REPLACE_BTOWC=1 ;;
esac
+ case "$gl_cv_func_btowc_consistent" in
+ *yes) ;;
+ *) REPLACE_BTOWC=1 ;;
+ esac
+ if test $REPLACE_BTOWC = 0; then
+ gl_MBRTOWC_C_LOCALE
+ case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in
+ *yes) ;;
+ *) REPLACE_BTOWC=1 ;;
+ esac
+ fi
fi
])
# Prerequisites of lib/btowc.c.
AC_DEFUN([gl_PREREQ_BTOWC], [
:
+ AC_CHECK_FUNCS_ONCE([mbrtowc])
])