]> Savannah Git Hosting - gnulib.git/commitdiff
mbrtoc32: Work around bug in Cygwin 3.5.3.
authorBruno Haible <bruno@clisp.org>
Thu, 23 May 2024 21:46:52 +0000 (23:46 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 31 May 2024 21:50:27 +0000 (23:50 +0200)
* m4/mbrtoc32.m4 (gl_MBRTOC32_UTF8_LOCALE): New macro.
(gl_FUNC_MBRTOC32): Invoke it. If mbrtoc32 has this bug, define
MBRTOC32_MULTIBYTE_LOCALE_BUG and reset LOCALE_ZH_CN to 'none'.
* lib/mbrtoc32.c (mbrtoc32): Test MBRTOC32_MULTIBYTE_LOCALE_BUG.
* doc/posix-functions/mbrtoc32.texi: Mention the Cygwin bug.

ChangeLog
doc/posix-functions/mbrtoc32.texi
lib/mbrtoc32.c
m4/mbrtoc32.m4

index aefe54aa2ce54691c207febcf03c7fe7ced97242..ca996e5e03b539778fcff0d6ca219411afa5ef85 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-05-23  Bruno Haible  <bruno@clisp.org>
+
+       mbrtoc32: Work around bug in Cygwin 3.5.3.
+       * m4/mbrtoc32.m4 (gl_MBRTOC32_UTF8_LOCALE): New macro.
+       (gl_FUNC_MBRTOC32): Invoke it. If mbrtoc32 has this bug, define
+       MBRTOC32_MULTIBYTE_LOCALE_BUG and reset LOCALE_ZH_CN to 'none'.
+       * lib/mbrtoc32.c (mbrtoc32): Test MBRTOC32_MULTIBYTE_LOCALE_BUG.
+       * doc/posix-functions/mbrtoc32.texi: Mention the Cygwin bug.
+
 2024-05-23  Bruno Haible  <bruno@clisp.org>
 
        c32is*, c32toupper tests: Avoid test failures on Cygwin.
index db7d6a082140215cb6ea31fbf6c55e903b4e0914..aae8d51ee8b790699d85bf92e6e5e907f57cb51d 100644 (file)
@@ -33,6 +33,12 @@ FreeBSD 13.2,
 Solaris 11.4, mingw, MSVC 14.
 @c For MSVC this is because it assumes that the input is always UTF-8 encoded.
 @c See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/mbrtoc16-mbrtoc323
+@item
+This function does not work when it's fed the input bytes one-by-one
+on some platforms:
+@c https://cygwin.com/pipermail/cygwin/2024-May/255989.html
+@c https://cygwin.com/pipermail/cygwin/2024-May/255990.html
+Cygwin 3.5.3.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index b8d07ccb009dabc30033d331b088b1a67f8f0283..1eb5f85db2c1e9a45eb823338007a53f77f4e67d 100644 (file)
@@ -1,5 +1,5 @@
 /* Convert multibyte character to 32-bit wide character.
-   Copyright (C) 2020-2023 Free Software Foundation, Inc.
+   Copyright (C) 2020-2024 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -113,7 +113,7 @@ mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps)
   if (ps == NULL)
     ps = &internal_state;
 
-# if HAVE_WORKING_MBRTOC32
+# if HAVE_WORKING_MBRTOC32 && !MBRTOC32_MULTIBYTE_LOCALE_BUG
   /* mbrtoc32() may produce different values for wc than mbrtowc().  Therefore
      use mbrtoc32().  */
 
index 25196039bbc094ef9560337cb8dbf72e1a465a23..f35d38db234fd663d5a4b91bf1e95ba70ffbeaff 100644 (file)
@@ -1,5 +1,5 @@
-# mbrtoc32.m4 serial 17
-dnl Copyright (C) 2014-2023 Free Software Foundation, Inc.
+# mbrtoc32.m4 serial 17.1
+dnl Copyright (C) 2014-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -26,6 +26,7 @@ AC_DEFUN([gl_FUNC_MBRTOC32],
     else
       gl_MBRTOC32_EMPTY_INPUT
       gl_MBRTOC32_C_LOCALE
+      gl_MBRTOC32_UTF8_LOCALE
       case "$gl_cv_func_mbrtoc32_empty_input" in
         *yes) ;;
         *) AC_DEFINE([MBRTOC32_EMPTY_INPUT_BUG], [1],
@@ -40,6 +41,15 @@ AC_DEFUN([gl_FUNC_MBRTOC32],
            REPLACE_MBRTOC32=1
            ;;
       esac
+      case "$gl_cv_func_mbrtoc32_utf8_locale_works" in
+        *yes) ;;
+        *) AC_DEFINE([MBRTOC32_MULTIBYTE_LOCALE_BUG], [1],
+             [Define if the mbrtoc32 function does not accept the input bytes one-by-one.])
+           REPLACE_MBRTOC32=1
+           dnl Our replacement mbrtoc32 can handle UTF-8, but not GB18030.
+           LOCALE_ZH_CN=none
+           ;;
+      esac
     fi
     if test $HAVE_WORKING_MBRTOC32 = 0; then
       REPLACE_MBRTOC32=1
@@ -162,6 +172,53 @@ AC_DEFUN([gl_MBRTOC32_C_LOCALE],
     ])
 ])
 
+dnl Test whether mbrtoc32 works when it's fed the bytes one-by-one in an UTF-8
+dnl locale.
+
+AC_DEFUN([gl_MBRTOC32_UTF8_LOCALE],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtoc32 works in an UTF-8 locale],
+    [gl_cv_func_mbrtoc32_utf8_locale_works],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <locale.h>
+            #ifdef __HAIKU__
+             #include <stdint.h>
+            #endif
+            #include <uchar.h>
+          ]], [[
+            char *locale = setlocale (LC_ALL, "en_US.UTF-8");
+            if (locale)
+              {
+                /* This test fails on Cygwin 3.5.3.  */
+                mbstate_t state = { 0, };
+                char32_t uc = 0xDEADBEEF;
+                /* \360\237\220\203 = U+0001F403 */
+                if (mbrtoc32 (&uc, "\360", 1, &state) != (size_t)-2)
+                  return 1;
+                if (mbrtoc32 (&uc, "\237", 1, &state) != (size_t)-2)
+                  return 2;
+                if (mbrtoc32 (&uc, "\220", 1, &state) != (size_t)-2)
+                  return 3;
+                if (mbrtoc32 (&uc, "\203", 1, &state) != 1)
+                  return 4;
+                if (uc != 0x0001F403)
+                  return 5;
+              }
+            return 0;
+          ]])],
+       [gl_cv_func_mbrtoc32_utf8_locale_works=yes],
+       [gl_cv_func_mbrtoc32_utf8_locale_works=no],
+       [case "$host_os" in
+                   # Guess no on Cygwin.
+          cygwin*) gl_cv_func_mbrtoc32_utf8_locale_works="guessing yes" ;;
+          *)       gl_cv_func_mbrtoc32_utf8_locale_works="$gl_cross_guess_normal" ;;
+        esac
+       ])
+    ])
+])
+
 dnl Test whether mbrtoc32 works not worse than mbrtowc.
 dnl Result is HAVE_WORKING_MBRTOC32.