Work around mbsrtowcs bug on various platforms.
authorBruno Haible <bruno@clisp.org>
Sun, 21 Dec 2008 12:36:23 +0000 (13:36 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 21 Dec 2008 12:36:23 +0000 (13:36 +0100)
ChangeLog
doc/posix-functions/mbsrtowcs.texi
m4/mbsrtowcs.m4
modules/mbsrtowcs

index d8b1e5210da45c1bff08a28a024070c64b716d24..70f5580cca3a078b6c214fd6dc01ae7a68dc1b7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-12-21  Bruno Haible  <bruno@clisp.org>
+
+       Work around mbsrtowcs bug.
+       * m4/mbsrtowcs.m4 (gl_MBSRTOWCS_WORKS): New macro.
+       (gl_FUNC_MBSRTOWCS): Invoke it.
+       * modules/mbsrtowcs (Files): Add m4/locale-fr.m4, m4/locale-ja.m4,
+       m4/locale-zh.m4.
+       * doc/posix-functions/mbsrtowcs.texi: Document the bug.
+
 2008-12-21  Bruno Haible  <bruno@clisp.org>
 
        * tests/test-mbsrtowcs.c (main): Execute the loop also for unlimited=1.
index e201c672250401040c4b2babd90eecc58449b49e..bc4e91475da373aade6eb2889bb82d89f660f0f9 100644 (file)
@@ -11,6 +11,9 @@ Portability problems fixed by Gnulib:
 @item
 This function is missing on some platforms:
 HP-UX 11.00, IRIX 6.5, Solaris 2.6, mingw, Interix 3.5.
+@item
+This function does not work on some platforms:
+HP-UX 11, Solaris 10.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 58ae2c683c843bebe0970efe0d2389584992b7a9..d18ef13ee54245e1ce4738e8dec002ad3b816906 100644 (file)
@@ -1,4 +1,4 @@
-# mbsrtowcs.m4 serial 2
+# mbsrtowcs.m4 serial 3
 dnl Copyright (C) 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,
@@ -17,6 +17,13 @@ AC_DEFUN([gl_FUNC_MBSRTOWCS],
   if test $ac_cv_func_mbsrtowcs = no; then
     HAVE_MBSRTOWCS=0
   fi
+  if test $HAVE_MBSRTOWCS != 0 && test $REPLACE_MBSRTOWCS != 1; then
+    gl_MBSRTOWCS_WORKS
+    case "$gl_cv_func_mbsrtowcs_works" in
+      *yes) ;;
+      *) REPLACE_MBSRTOWCS=1 ;;
+    esac
+  fi
   if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then
     gl_REPLACE_WCHAR_H
     AC_LIBOBJ([mbsrtowcs])
@@ -24,6 +31,89 @@ AC_DEFUN([gl_FUNC_MBSRTOWCS],
   fi
 ])
 
+dnl Test whether mbsrtowcs works.
+dnl Result is gl_cv_func_mbsrtowcs_works.
+
+AC_DEFUN([gl_MBSRTOWCS_WORKS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_FR_UTF8])
+  AC_REQUIRE([gt_LOCALE_JA])
+  AC_REQUIRE([gt_LOCALE_ZH_CN])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbsrtowcs works],
+    [gl_cv_func_mbsrtowcs_works],
+    [
+      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_mbsrtowcs_works="guessing no" ;;
+                          # Guess yes otherwise.
+        *)                gl_cv_func_mbsrtowcs_works="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then
+        AC_TRY_RUN([
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+int main ()
+{
+  /* Test whether the function works when started with a conversion state
+     in non-initial state.  This fails on HP-UX 11.11 and Solaris 10.  */
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      const char input[] = "B\303\274\303\237er";
+      mbstate_t state;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2))
+        if (!mbsinit (&state))
+          {
+            const char *src = input + 2;
+            if (mbsrtowcs (NULL, &src, 10, &state) != 4)
+              return 1;
+          }
+    }
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      const char input[] = "<\306\374\313\334\270\354>";
+      mbstate_t state;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (NULL, input + 3, 1, &state) == (size_t)(-2))
+        if (!mbsinit (&state))
+          {
+            const char *src = input + 4;
+            if (mbsrtowcs (NULL, &src, 10, &state) != 3)
+              return 1;
+          }
+    }
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      const char input[] = "B\250\271\201\060\211\070er";
+      mbstate_t state;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2))
+        if (!mbsinit (&state))
+          {
+            const char *src = input + 2;
+            if (mbsrtowcs (NULL, &src, 10, &state) != 4)
+              return 1;
+          }
+    }
+  return 0;
+}],
+          [gl_cv_func_mbsrtowcs_works=yes],
+          [gl_cv_func_mbsrtowcs_works=no],
+          [])
+      fi
+    ])
+])
+
 # Prerequisites of lib/mbsrtowcs.c.
 AC_DEFUN([gl_PREREQ_MBSRTOWCS], [
   :
index 7df1dbb74e677ba000e77bacd71680622f6f1bae..0a5450a5e4076b52bb763189e1c494da6b0ac94a 100644 (file)
@@ -5,6 +5,9 @@ Files:
 lib/mbsrtowcs.c
 m4/mbsrtowcs.m4
 m4/mbstate_t.m4
+m4/locale-fr.m4
+m4/locale-ja.m4
+m4/locale-zh.m4
 
 Depends-on:
 wchar