Work around mbrtowc bug in zh_CN.GB18030 locale on Solaris 8.
authorBruno Haible <bruno@clisp.org>
Thu, 26 Feb 2009 01:21:14 +0000 (02:21 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 26 Feb 2009 01:21:14 +0000 (02:21 +0100)
ChangeLog
doc/posix-functions/mbrtowc.texi
m4/mbrtowc.m4

index 5962517..0cab1f9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-02-25  Bruno Haible  <bruno@clisp.org>
 
+       Work around mbrtowc bug in zh_CN.GB18030 locale on Solaris 8.
+       * m4/mbrtowc.m4 (gl_MBRTOWC_SANITYCHECK): New macro.
+       (gl_MBSTATE_T_BROKEN): Invoke it. Replace mbstate_t when it says "no".
+       * doc/posix-functions/mbrtowc.texi: Document the Solaris 8 bug.
+       Reported by Gary V. Vaughan <gary@gnu.org>.
+
+2009-02-25  Bruno Haible  <bruno@clisp.org>
+
        Work around broken INT8_MAX, UINT8_MAX etc. values on HP-UX 11.23.
        * m4/stdint.m4 (gl_STDINT_H): Also check whether the expansions of
        INT8_MAX, UINT8_MAX etc. contain casts to elementary types.
index df8c59b..8e19b36 100644 (file)
@@ -16,6 +16,10 @@ This function does not put the state into non-initial state when parsing an
 incomplete multibyte character on some platforms:
 AIX 5.1, OSF/1 5.1.
 @item
+This function does not produce correct results in the zh_CN.GB18030 locale on
+some platforms:
+Solaris 8.
+@item
 This function does not ignore the @code{pwc} argument if the string argument is
 NULL on some platforms:
 OSF/1 5.1.
index 726497b..ace6980 100644 (file)
@@ -1,4 +1,4 @@
-# mbrtowc.m4 serial 13
+# mbrtowc.m4 serial 14
 dnl Copyright (C) 2001-2002, 2004-2005, 2008, 2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -65,9 +65,15 @@ AC_DEFUN([gl_MBSTATE_T_BROKEN],
   AC_CHECK_FUNCS_ONCE([mbrtowc])
   if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
     gl_MBRTOWC_INCOMPLETE_STATE
+    gl_MBRTOWC_SANITYCHECK
+    REPLACE_MBSTATE_T=0
     case "$gl_cv_func_mbrtowc_incomplete_state" in
-      *yes) REPLACE_MBSTATE_T=0 ;;
-      *)    REPLACE_MBSTATE_T=1 ;;
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+    case "$gl_cv_func_mbrtowc_sanitycheck" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
     esac
   else
     REPLACE_MBSTATE_T=1
@@ -126,6 +132,57 @@ int main ()
     ])
 ])
 
+dnl Test whether mbrtowc works not worse than mbtowc.
+dnl Result is gl_cv_func_mbrtowc_sanitycheck.
+
+AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
+[
+  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 works as well as mbtowc],
+    [gl_cv_func_mbrtowc_sanitycheck],
+    [
+      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 8.
+        solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
+                    # Guess yes otherwise.
+        *)          gl_cv_func_mbrtowc_sanitycheck="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 8:
+     mbrtowc returns 2, and sets wc to 0x00F0.
+     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 3, 6, &state) != 4
+          && mbtowc (&wc, input + 3, 6) == 4)
+        return 1;
+    }
+  return 0;
+}],
+          [gl_cv_func_mbrtowc_sanitycheck=yes],
+          [gl_cv_func_mbrtowc_sanitycheck=no],
+          [])
+      fi
+    ])
+])
+
 dnl Test whether mbrtowc supports a NULL string argument correctly.
 dnl Result is gl_cv_func_mbrtowc_null_arg.