From d213558062609296c620d9bf48b92f012953a4bd Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 14 Oct 2018 09:19:12 +0200 Subject: [PATCH] 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. --- ChangeLog | 8 +++ doc/posix-functions/mbsnrtowcs.texi | 3 + m4/mbsnrtowcs.m4 | 103 +++++++++++++++++++++++++++- 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1a0d61285a..e0d199729d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2018-10-14 Bruno Haible + + 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. + 2018-10-14 Bruno Haible doc: Update for Solaris 11.4. diff --git a/doc/posix-functions/mbsnrtowcs.texi b/doc/posix-functions/mbsnrtowcs.texi index d2e5ce0343..cba6d63ab6 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. +@item +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 3eb60b7115..485a1cea0f 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 +#include +#include +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +#include +#include +#include +#include +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 + ]) +]) -- 2.39.5