summaryrefslogtreecommitdiff
path: root/m4/mbrtowc.m4
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2008-12-21 02:55:00 +0100
committerBruno Haible <bruno@clisp.org>2008-12-21 02:55:00 +0100
commit2c11b49f00662697a6b27da0beb86adb4b6fae97 (patch)
treeda3a8a8eff9c5d5986a4dc400acf153d25f1b0cf /m4/mbrtowc.m4
parent6d65e7578f692b2d06574e25a848cef93b02ed25 (diff)
downloadgnulib-2c11b49f00662697a6b27da0beb86adb4b6fae97.tar.gz
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Diffstat (limited to 'm4/mbrtowc.m4')
-rw-r--r--m4/mbrtowc.m4275
1 files changed, 274 insertions, 1 deletions
diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index 099b748fd3..6eeacc4e24 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -1,4 +1,4 @@
-# mbrtowc.m4 serial 10
+# mbrtowc.m4 serial 11
dnl Copyright (C) 2001-2002, 2004-2005, 2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -9,15 +9,288 @@ AC_DEFUN([gl_FUNC_MBRTOWC],
AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
AC_REQUIRE([AC_TYPE_MBSTATE_T])
+ gl_MBSTATE_T_BROKEN
+ if test $REPLACE_MBSTATE_T = 1; then
+ REPLACE_MBRTOWC=1
+ fi
AC_CHECK_FUNCS_ONCE([mbrtowc])
if test $ac_cv_func_mbrtowc = no; then
HAVE_MBRTOWC=0
+ fi
+ if test $HAVE_MBRTOWC != 0 && test $REPLACE_MBRTOWC != 1; then
+ gl_MBRTOWC_NULL_ARG
+ gl_MBRTOWC_RETVAL
+ gl_MBRTOWC_NUL_RETVAL
+ case "$gl_cv_func_mbrtowc_null_arg" in
+ *yes) ;;
+ *) AC_DEFINE([MBRTOWC_NULL_ARG_BUG], [1],
+ [Define if the mbrtowc function has the NULL string argument bug.])
+ REPLACE_MBRTOWC=1
+ ;;
+ esac
+ case "$gl_cv_func_mbrtowc_retval" in
+ *yes) ;;
+ *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],
+ [Define if the mbrtowc function returns a wrong return value.])
+ REPLACE_MBRTOWC=1
+ ;;
+ esac
+ case "$gl_cv_func_mbrtowc_nul_retval" in
+ *yes) ;;
+ *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],
+ [Define if the mbrtowc function does not return 0 for a NUL character.])
+ REPLACE_MBRTOWC=1
+ ;;
+ esac
+ fi
+ if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
gl_REPLACE_WCHAR_H
AC_LIBOBJ([mbrtowc])
gl_PREREQ_MBRTOWC
fi
])
+dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
+dnl redefines the semantics of the given mbstate_t type.
+dnl Result is REPLACE_MBSTATE_T.
+dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
+dnl avoid inconsistencies.
+
+AC_DEFUN([gl_MBSTATE_T_BROKEN],
+[
+ AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+ AC_REQUIRE([AC_TYPE_MBSTATE_T])
+ AC_CHECK_FUNCS_ONCE([mbsinit])
+ AC_CHECK_FUNCS_ONCE([mbrtowc])
+ if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+ gl_MBRTOWC_INCOMPLETE_STATE
+ case "$gl_cv_func_mbrtowc_incomplete_state" in
+ *yes) REPLACE_MBSTATE_T=0 ;;
+ *) REPLACE_MBSTATE_T=1 ;;
+ esac
+ else
+ REPLACE_MBSTATE_T=1
+ fi
+ if test $REPLACE_MBSTATE_T = 1; then
+ gl_REPLACE_WCHAR_H
+ fi
+])
+
+dnl Test whether mbrtowc puts the state into non-initial state when parsing an
+dnl incomplete multibyte character.
+dnl Result is gl_cv_func_mbrtowc_incomplete_state.
+
+AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gt_LOCALE_JA])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
+ [gl_cv_func_mbrtowc_incomplete_state],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on AIX and OSF/1.
+ osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
+ esac
+changequote([,])dnl
+ if test $LOCALE_JA != none; then
+ AC_TRY_RUN([
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+ if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+ {
+ const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+ mbstate_t state;
+ wchar_t wc;
+ int ret;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+ if (mbsinit (&state))
+ return 1;
+ }
+ return 0;
+}],
+ [gl_cv_func_mbrtowc_incomplete_state=yes],
+ [gl_cv_func_mbrtowc_incomplete_state=no],
+ [])
+ fi
+ ])
+])
+
+dnl Test whether mbrtowc supports a NULL string argument correctly.
+dnl Result is gl_cv_func_mbrtowc_null_arg.
+
+AC_DEFUN([gl_MBRTOWC_NULL_ARG],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gt_LOCALE_FR_UTF8])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],
+ [gl_cv_func_mbrtowc_null_arg],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on OSF/1.
+ osf*) gl_cv_func_mbrtowc_null_arg="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_mbrtowc_null_arg="guessing yes" ;;
+ esac
+changequote([,])dnl
+ if test $LOCALE_FR_UTF8 != none; then
+ AC_TRY_RUN([
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+ if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+ {
+ mbstate_t state;
+ wchar_t wc;
+ int ret;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ mbrtowc (&wc, NULL, 5, &state);
+ /* Check that wc was not modified. */
+ if (wc != (wchar_t) 0xBADFACE)
+ return 1;
+ }
+ return 0;
+}], [gl_cv_func_mbrtowc_null_arg=yes], [gl_cv_func_mbrtowc_null_arg=no], [])
+ fi
+ ])
+])
+
+dnl Test whether mbrtowc, when parsing the end of a multibyte character,
+dnl correctly returns the number of bytes that were needed to complete the
+dnl character (not the total number of bytes of the multibyte character).
+dnl Result is gl_cv_func_mbrtowc_retval.
+
+AC_DEFUN([gl_MBRTOWC_RETVAL],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gt_LOCALE_FR_UTF8])
+ AC_REQUIRE([gt_LOCALE_JA])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrtowc has a correct return value],
+ [gl_cv_func_mbrtowc_retval],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on HP-UX and Solaris.
+ hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_mbrtowc_retval="guessing yes" ;;
+ esac
+changequote([,])dnl
+ if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
+ AC_TRY_RUN([
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+ /* This fails on Solaris. */
+ if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+ {
+ char input[] = "B\303\274\303\237er"; /* "Büßer" */
+ mbstate_t state;
+ wchar_t wc;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+ {
+ input[1] = '\0';
+ if (mbrtowc (&wc, input + 2, 5, &state) != 1)
+ return 1;
+ }
+ }
+ /* This fails on HP-UX 11.11. */
+ if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+ {
+ char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+ mbstate_t state;
+ wchar_t wc;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+ {
+ input[1] = '\0';
+ if (mbrtowc (&wc, input + 2, 5, &state) != 2)
+ return 1;
+ }
+ }
+ return 0;
+}],
+ [gl_cv_func_mbrtowc_retval=yes],
+ [gl_cv_func_mbrtowc_retval=no],
+ [])
+ fi
+ ])
+])
+
+dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
+dnl Result is gl_cv_func_mbrtowc_nul_retval.
+
+AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gt_LOCALE_ZH_CN])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
+ [gl_cv_func_mbrtowc_nul_retval],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on Solaris 9.
+ solaris2.9) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
+ esac
+changequote([,])dnl
+ if test $LOCALE_ZH_CN != none; then
+ AC_TRY_RUN([
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+ /* This fails on Solaris 9. */
+ if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+ {
+ mbstate_t state;
+ wchar_t wc;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, "", 1, &state) != 0)
+ return 1;
+ }
+ return 0;
+}],
+ [gl_cv_func_mbrtowc_nul_retval=yes],
+ [gl_cv_func_mbrtowc_nul_retval=no],
+ [])
+ fi
+ ])
+])
+
# Prerequisites of lib/mbrtowc.c.
AC_DEFUN([gl_PREREQ_MBRTOWC], [
: