Now, I still see a test failure in a testdir for the modules
  mbrtoc32 mbrtoc32-regular uchar-c23 btoc32 c32isprint
on macOS, FreeBSD, NetBSD, Solaris 11, Solaris 11 OpenIndiana.

Namely:

FAIL: test-c32isprint.sh
========================

../../gltests/test-c32isprint.c:121: assertion 'is == 0' failed


This patch fixes it.


2026-08-31  Bruno Haible  <[email protected]>

        mbrtoc32: Fix test-c32isprint failure with uchar-h-c23.
        * m4/uchar_h-c23.m4: New file, extracted from modules/uchar-h-c23.
        * modules/uchar-h-c23 (Files): Add it.
        (configure.ac): Just invoke gl_UCHAR_H_C23.
        * m4/mbrtoc32.m4 (gl_FUNC_MBRTOC32): Require gl_UCHAR_H_C23. If
        GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION is defined, set REPLACE_MBRTOC32
        to 1.
        * lib/mbrtoc32.c (mbrtoc32): Enable special handling of the C locale
        also when GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION.
        * lib/btoc32.c (btoc32): Likewise.

>From 7bf0471db6b2e1011de49d42c1786c0e63ffc010 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Tue, 1 Sep 2026 01:24:01 +0200
Subject: [PATCH] mbrtoc32: Fix test-c32isprint failure with uchar-h-c23.

* m4/uchar_h-c23.m4: New file, extracted from modules/uchar-h-c23.
* modules/uchar-h-c23 (Files): Add it.
(configure.ac): Just invoke gl_UCHAR_H_C23.
* m4/mbrtoc32.m4 (gl_FUNC_MBRTOC32): Require gl_UCHAR_H_C23. If
GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION is defined, set REPLACE_MBRTOC32
to 1.
* lib/mbrtoc32.c (mbrtoc32): Enable special handling of the C locale
also when GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION.
* lib/btoc32.c (btoc32): Likewise.
---
 ChangeLog           | 13 +++++++++++++
 lib/btoc32.c        |  8 ++++++--
 lib/mbrtoc32.c      | 23 +++++++++++++++++++++--
 m4/mbrtoc32.m4      |  8 +++++++-
 m4/uchar_h-c23.m4   | 33 +++++++++++++++++++++++++++++++++
 modules/uchar-h-c23 | 22 ++--------------------
 6 files changed, 82 insertions(+), 25 deletions(-)
 create mode 100644 m4/uchar_h-c23.m4

diff --git a/ChangeLog b/ChangeLog
index 1e14954645..5da4ae37b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2026-08-31  Bruno Haible  <[email protected]>
+
+	mbrtoc32: Fix test-c32isprint failure with uchar-h-c23.
+	* m4/uchar_h-c23.m4: New file, extracted from modules/uchar-h-c23.
+	* modules/uchar-h-c23 (Files): Add it.
+	(configure.ac): Just invoke gl_UCHAR_H_C23.
+	* m4/mbrtoc32.m4 (gl_FUNC_MBRTOC32): Require gl_UCHAR_H_C23. If
+	GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION is defined, set REPLACE_MBRTOC32
+	to 1.
+	* lib/mbrtoc32.c (mbrtoc32): Enable special handling of the C locale
+	also when GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION.
+	* lib/btoc32.c (btoc32): Likewise.
+
 2026-08-31  Bruno Haible  <[email protected]>
 
 	mbrtoc32: Don't enable the OpenBSD workaround on Solaris 11 OpenIndiana.
diff --git a/lib/btoc32.c b/lib/btoc32.c
index 31b3890723..c067efd943 100644
--- a/lib/btoc32.c
+++ b/lib/btoc32.c
@@ -27,7 +27,9 @@
 #include <wchar.h>
 
 #if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 \
-    || (!GNULIB_defined_mbstate_t && _GL_SMALL_WCHAR_T)
+    || (!GNULIB_defined_mbstate_t && _GL_SMALL_WCHAR_T) \
+    || ((!(HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB) && !_GL_SMALL_WCHAR_T) \
+        && GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION)
 # include "hard-locale.h"
 # include <locale.h>
 #endif
@@ -43,7 +45,9 @@ wint_t
 btoc32 (int c)
 {
 #if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 /* OpenBSD */ \
-    || (!GNULIB_defined_mbstate_t && _GL_SMALL_WCHAR_T) /* Cygwin, mingw, MSVC */
+    || (!GNULIB_defined_mbstate_t && _GL_SMALL_WCHAR_T) /* Cygwin, mingw, MSVC */ \
+    || ((!(HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB) && !_GL_SMALL_WCHAR_T) \
+        && GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION)
   if (!hard_locale (LC_CTYPE))
     {
       /* In the "C" locale, map the bytes 0x80..0xFF to U+DF80..U+DFFF, so that
diff --git a/lib/mbrtoc32.c b/lib/mbrtoc32.c
index 826f367708..34ac7b8348 100644
--- a/lib/mbrtoc32.c
+++ b/lib/mbrtoc32.c
@@ -94,7 +94,9 @@ mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps)
 
 # if (MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 \
       || MBRTOC32_IN_C_LOCALE_MAYBE_EILSEQ \
-      || _GL_SMALL_WCHAR_T)
+      || _GL_SMALL_WCHAR_T \
+      || ((!(HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB) && !_GL_SMALL_WCHAR_T) \
+          && GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION))
 #  include "hard-locale.h"
 #  include <locale.h>
 # endif
@@ -139,7 +141,9 @@ mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps)
 # if (MBRTOC32_EMPTY_INPUT_BUG \
       || (GNULIB_WCHAR_SINGLE_LOCALE && __GLIBC__ >= 2 && !__UCLIBC__) \
       || MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 \
-      || _GL_SMALL_WCHAR_T)
+      || _GL_SMALL_WCHAR_T \
+      || ((!(HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB) && !_GL_SMALL_WCHAR_T) \
+          && GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION))
   if (n == 0)
     return (size_t) -2;
 # endif
@@ -425,6 +429,21 @@ mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps)
 # else
 
   /* char32_t and wchar_t are equivalent.  Use mbrtowc().  */
+
+#  if (!(HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB) && !_GL_SMALL_WCHAR_T) \
+      && GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION
+  if (!hard_locale (LC_CTYPE))
+    {
+      /* In the "C" locale, map the bytes 0x80..0xFF to U+DF80..U+DFFF, so that
+         the c32is* functions return false on them, for consistency with the
+         <ctype.h> is* functions.  */
+      unsigned char c = (unsigned char) s[0];
+      if (pwc != NULL)
+        *pwc = (c < 0x80 ? c : 0xDF00 + c);
+      return (c == 0 ? 0 : 1);
+    }
+#  endif
+
   wchar_t wc;
   size_t ret = mbrtowc (&wc, s, n, ps);
 
diff --git a/m4/mbrtoc32.m4 b/m4/mbrtoc32.m4
index bfd933d510..36e9d4632b 100644
--- a/m4/mbrtoc32.m4
+++ b/m4/mbrtoc32.m4
@@ -1,5 +1,5 @@
 # mbrtoc32.m4
-# serial 27
+# serial 28
 dnl Copyright (C) 2014-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -104,6 +104,12 @@ AC_DEFUN([gl_FUNC_MBRTOC32]
       case "$gl_cv_func_mbrtoc32_regular" in
         *no) REPLACE_MBRTOC32=1 ;;
       esac
+      m4_ifdef([gl_UCHAR_H_C23], [
+        AC_REQUIRE([gl_UCHAR_H_C23])
+        if test $gl_char32_t_vs_wchar_t_needs_conversion = yes; then
+          REPLACE_MBRTOC32=1
+        fi
+      ])
     fi
     if test $HAVE_WORKING_MBRTOC32 = 0; then
       REPLACE_MBRTOC32=1
diff --git a/m4/uchar_h-c23.m4 b/m4/uchar_h-c23.m4
new file mode 100644
index 0000000000..6424ddc086
--- /dev/null
+++ b/m4/uchar_h-c23.m4
@@ -0,0 +1,33 @@
+# uchar_h-c23.m4
+# serial 1
+dnl Copyright (C) 2023-2026 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.
+dnl This file is offered as-is, without any warranty.
+
+AC_DEFUN_ONCE([gl_UCHAR_H_C23],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AM_ICONV])
+  AC_DEFINE([GL_CHAR32_T_IS_UNICODE], [1],
+    [Define if gnulib's char32_t values are always Unicode code points.])
+  dnl On macOS, FreeBSD, NetBSD, Solaris, the functions mbrtoc32 and c32rtomb
+  dnl need to convert between the wchar_t encoding and Unicode.
+  gl_char32_t_vs_wchar_t_needs_conversion=no
+  case "$host_os" in
+    darwin* | freebsd* | dragonfly* | netbsd* | solaris*)
+      gl_char32_t_vs_wchar_t_needs_conversion=yes
+      AC_DEFINE([GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION], [1],
+        [Define if gnulib needs to convert between the wchar_t encoding and Unicode.])
+      LIBC32CONV="$LIBICONV"
+      LTLIBC32CONV="$LTLIBICONV"
+      ;;
+    *)
+      LIBC32CONV=
+      LTLIBC32CONV=
+      ;;
+  esac
+  AC_SUBST([LIBC32CONV])
+  AC_SUBST([LTLIBC32CONV])
+])
diff --git a/modules/uchar-h-c23 b/modules/uchar-h-c23
index 5cdc3a51c8..5292b82a4f 100644
--- a/modules/uchar-h-c23
+++ b/modules/uchar-h-c23
@@ -4,6 +4,7 @@ A <uchar.h> in which the char32_t values are always Unicode code points.
 Files:
 lib/lc-charset-unicode.h
 lib/lc-charset-unicode.c
+m4/uchar_h-c23.m4
 
 Depends-on:
 uchar-h
@@ -21,26 +22,7 @@ unistr/u8-uctomb
 mbrtowc
 
 configure.ac:
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([AM_ICONV])
-AC_DEFINE([GL_CHAR32_T_IS_UNICODE], [1],
-  [Define if gnulib's char32_t values are always Unicode code points.])
-dnl On macOS, FreeBSD, NetBSD, Solaris, the functions mbrtoc32 and c32rtomb
-dnl need to convert between the wchar_t encoding and Unicode.
-case "$host_os" in
-  darwin* | freebsd* | dragonfly* | netbsd* | solaris*)
-    AC_DEFINE([GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION], [1],
-      [Define if gnulib needs to convert between the wchar_t encoding and Unicode.])
-    LIBC32CONV="$LIBICONV"
-    LTLIBC32CONV="$LTLIBICONV"
-    ;;
-  *)
-    LIBC32CONV=
-    LTLIBC32CONV=
-    ;;
-esac
-AC_SUBST([LIBC32CONV])
-AC_SUBST([LTLIBC32CONV])
+gl_UCHAR_H_C23
 
 Makefile.am:
 lib_SOURCES += lc-charset-unicode.c
-- 
2.53.0

Reply via email to