bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mbsnrtowcs: work around Solaris 11.4 bug


From: Bruno Haible
Subject: mbsnrtowcs: work around Solaris 11.4 bug
Date: Sun, 14 Oct 2018 09:45:13 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-137-generic; KDE/5.18.0; x86_64; ; )

2018-10-14  Bruno Haible  <address@hidden>

        mbsnrtowcs: Work around Solaris 11.4 bug.
        * m4/mbsnrtowcs.m4 (gl_MBSNRTOWCS_WORKS_IN_TRADITIONAL_LOCALE): New
        macro.
        (gl_FUNC_MBSNRTOWCS): Invoke it.
        * doc/posix-functions/mbsnrtowcs.texi: Mention the Solaris bug.

diff --git a/doc/posix-functions/mbsnrtowcs.texi 
b/doc/posix-functions/mbsnrtowcs.texi
index d2e5ce0..cba6d63 100644
--- a/doc/posix-functions/mbsnrtowcs.texi
+++ b/doc/posix-functions/mbsnrtowcs.texi
@@ -11,6 +11,9 @@ Portability problems fixed by Gnulib:
 @item
 This function is missing on some platforms:
 Mac OS X 10.3, FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 4.3.2, 
HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin 1.5.x, mingw, MSVC 14, 
Interix 3.5, BeOS, Android 4.4.
address@hidden
+This function produces invalid wide characters on some platforms:
+Solaris 11.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/m4/mbsnrtowcs.m4 b/m4/mbsnrtowcs.m4
index 3eb60b7..485a1ce 100644
--- a/m4/mbsnrtowcs.m4
+++ b/m4/mbsnrtowcs.m4
@@ -1,4 +1,4 @@
-# mbsnrtowcs.m4 serial 4
+# mbsnrtowcs.m4 serial 5
 dnl Copyright (C) 2008, 2010-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -20,6 +20,12 @@ AC_DEFUN([gl_FUNC_MBSNRTOWCS],
   else
     if test $REPLACE_MBSTATE_T = 1; then
       REPLACE_MBSNRTOWCS=1
+    else
+      gl_MBSNRTOWCS_WORKS_IN_TRADITIONAL_LOCALE
+      case "$gl_cv_func_mbsnrtowcs_works_in_traditional_locale" in
+        *yes) ;;
+        *) REPLACE_MBSNRTOWCS=1 ;;
+      esac
     fi
   fi
 ])
@@ -28,3 +34,98 @@ AC_DEFUN([gl_FUNC_MBSNRTOWCS],
 AC_DEFUN([gl_PREREQ_MBSNRTOWCS], [
   :
 ])
+
+dnl Test whether mbsnrtowcs works in an ISO-8859-1 locale.
+dnl Result is gl_cv_func_mbsnrtowcs_works_in_traditional_locale.
+
+AC_DEFUN([gl_MBSNRTOWCS_WORKS_IN_TRADITIONAL_LOCALE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_FR])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbsnrtowcs works in a traditional locale],
+    [gl_cv_func_mbsnrtowcs_works_in_traditional_locale],
+    [
+      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.
+        solaris*) gl_cv_func_mbsnrtowcs_works_in_traditional_locale="guessing 
no" ;;
+                  # Guess yes otherwise.
+        *)        gl_cv_func_mbsnrtowcs_works_in_traditional_locale="guessing 
yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_FR != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <stdlib.h>
+#include <string.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 <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 11.4:
+     mbsnrtowcs stores a wrong wide character: 0xDF instead of btowc (0xDF).  
*/
+  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+    {
+      /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
+      char input[] = "B\374\337er"; /* "Büßer" */
+      mbstate_t state;
+      mbstate_t temp_state;
+      wchar_t wc;
+      size_t ret;
+      const char *src;
+
+      #define BUFSIZE 10
+      wchar_t buf[BUFSIZE];
+      {
+        size_t i;
+        for (i = 0; i < BUFSIZE; i++)
+          buf[i] = (wchar_t) 0xBADFACE;
+      }
+
+      memset (&state, '\0', sizeof (mbstate_t));
+
+      wc = (wchar_t) 0xBADFACE;
+      ret = mbrtowc (&wc, input, 1, &state);
+      if (!(ret == 1 && wc == 'B' && mbsinit (&state)))
+        return 1;
+      input[0] = '\0';
+
+      wc = (wchar_t) 0xBADFACE;
+      ret = mbrtowc (&wc, input + 1, 1, &state);
+      if (!(ret == 1 && wctob (wc) == (unsigned char) '\374' && mbsinit 
(&state)))
+        return 2;
+      input[1] = '\0';
+
+      src = input + 2;
+      temp_state = state;
+      ret = mbsnrtowcs (NULL, &src, 4, 1, &temp_state);
+      if (!(ret == 3 && src == input + 2 && mbsinit (&state)))
+        return 3;
+
+      src = input + 2;
+      ret = mbsnrtowcs (buf, &src, 4, 1, &state);
+      if (!(ret == 1))
+        return 4;
+      if (!(src == input + 3))
+        return 5;
+      if (!(buf[0] == btowc ((unsigned char) '\337')))
+        return 6;
+    }
+  return 0;
+}]])],
+          [gl_cv_func_mbsnrtowcs_works_in_traditional_locale=yes],
+          [gl_cv_func_mbsnrtowcs_works_in_traditional_locale=no],
+          [:])
+      fi
+    ])
+])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]