Paul Eggert wrote:
> > Currently it fails on: glibc, OpenBSD, Cygwin, mingw, MSVC. (Which is a 
> > little
> > more than the platforms from
> > <https://lists.gnu.org/archive/html/bug-gnulib/2026-08/msg00308.html>.)
> The test also fails on NetBSD 11.0 because in the C locale its mbrtoc32 
> treats bytes in the range 0x80-0xFF as encoding errors, like glibc does. It 
> seems that NetBSD 11.0 was the first NetBSD version to support mbrtoc32.

Good point. I've now replaced NetBSD 10 with NetBSD 11 in my CI, and while in
a testdir of module 'c32rtomb' I see
  FAIL: test-c32rtomb.sh
(like you say), in a testdir of module 'c32isprint' I see
  FAIL: test-c32isprint.sh
  FAIL: test-c32rtomb.sh

So, the test-c32isprint failure needs to be fixed first. This patch does it.


2026-09-15  Bruno Haible  <[email protected]>

        mbrtoc32: Fix test-c32isprint failure on NetBSD 11.
        * lib/mbrtoc32.c (mbrtoc32)
        [HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB && 
!_GL_WCHAR_T_IS_UCS4]:
        In the C locale, map 0x80..0xFF differently.
        * lib/btoc32.c (btoc32)
        [HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB && 
!_GL_WCHAR_T_IS_UCS4]:
        Likewise.
        * lib/c32is-impl.h (FUNC): Update comments.
        * lib/c32to-impl.h (FUNC): Likewise.
        * lib/c32width.c (c32width): Likewise.
        * doc/posix-functions/mbrtoc32.texi: Mention the NetBSD problem.

diff --git a/doc/posix-functions/mbrtoc32.texi 
b/doc/posix-functions/mbrtoc32.texi
index b64fb4b9ce..595848518d 100644
--- a/doc/posix-functions/mbrtoc32.texi
+++ b/doc/posix-functions/mbrtoc32.texi
@@ -25,7 +25,7 @@
 In the C or POSIX locales,
 this function returns values like in ISO-8859-1 locales,
 which leads to @code{c32isprint} etc.@: being inconsistent with @code{isprint}:
-OpenBSD 7.9.
+NetBSD 11.0, OpenBSD 7.9.
 @item
 This function returns 0 instead of @code{(size_t) -2} when the input
 is empty:
diff --git a/lib/btoc32.c b/lib/btoc32.c
index c067efd943..9c028eb5c9 100644
--- a/lib/btoc32.c
+++ b/lib/btoc32.c
@@ -27,6 +27,8 @@
 #include <wchar.h>
 
 #if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 \
+    || (!GNULIB_defined_mbstate_t && HAVE_WORKING_MBRTOC32 && 
HAVE_WORKING_C32RTOMB \
+        && !_GL_WCHAR_T_IS_UCS4) \
     || (!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)
@@ -45,6 +47,8 @@ wint_t
 btoc32 (int c)
 {
 #if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 /* OpenBSD */ \
+    || (!GNULIB_defined_mbstate_t && HAVE_WORKING_MBRTOC32 && 
HAVE_WORKING_C32RTOMB \
+        && !_GL_WCHAR_T_IS_UCS4) /* NetBSD ≥ 11 */ \
     || (!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)
diff --git a/lib/c32is-impl.h b/lib/c32is-impl.h
index 2cd03dc4d2..8115217908 100644
--- a/lib/c32is-impl.h
+++ b/lib/c32is-impl.h
@@ -57,7 +57,7 @@ FUNC (wint_t wc)
   else
     return 0;
 
-#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */
+#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, NetBSD ≥ 11, 
Android */
   /* mbrtoc32() is essentially defined by the system libc.  */
 
 # if _GL_WCHAR_T_IS_UCS4
@@ -92,7 +92,7 @@ FUNC (wint_t wc)
     return UCS_FUNC (wc);
 # endif
 
-#else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */
+#else /* macOS, FreeBSD, NetBSD < 11, OpenBSD, HP-UX, Solaris, Minix, Android 
*/
   /* char32_t and wchar_t are equivalent.  */
   static_assert (sizeof (char32_t) == sizeof (wchar_t));
 
diff --git a/lib/c32to-impl.h b/lib/c32to-impl.h
index b89cc98e2d..1c8dc1beb0 100644
--- a/lib/c32to-impl.h
+++ b/lib/c32to-impl.h
@@ -74,7 +74,7 @@ FUNC (wint_t wc)
     return UCS_FUNC (wc);
 # endif
 
-#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */
+#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, NetBSD ≥ 11, 
Android */
   /* mbrtoc32() is essentially defined by the system libc.  */
 
 # if _GL_WCHAR_T_IS_UCS4
@@ -90,7 +90,7 @@ FUNC (wint_t wc)
     return wc;
 # endif
 
-#else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */
+#else /* macOS, FreeBSD, NetBSD < 11, OpenBSD, HP-UX, Solaris, Minix, Android 
*/
   /* char32_t and wchar_t are equivalent.  */
   static_assert (sizeof (char32_t) == sizeof (wchar_t));
 
diff --git a/lib/c32width.c b/lib/c32width.c
index da944cfe74..807fb0cacb 100644
--- a/lib/c32width.c
+++ b/lib/c32width.c
@@ -58,7 +58,7 @@ c32width (char32_t wc)
   else
     return wcwidth (wc);
 
-#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */
+#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, NetBSD ≥ 11, 
Android */
   /* mbrtoc32() is essentially defined by the system libc.  */
 
 # if _GL_WCHAR_T_IS_UCS4
@@ -90,7 +90,7 @@ c32width (char32_t wc)
     return uc_width (wc, locale_charset ());
 # endif
 
-#else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */
+#else /* macOS, FreeBSD, NetBSD < 11, OpenBSD, HP-UX, Solaris, Minix, Android 
*/
   /* char32_t and wchar_t are equivalent.  */
   static_assert (sizeof (char32_t) == sizeof (wchar_t));
 
diff --git a/lib/mbrtoc32.c b/lib/mbrtoc32.c
index 34ac7b8348..00de09a258 100644
--- a/lib/mbrtoc32.c
+++ b/lib/mbrtoc32.c
@@ -94,6 +94,7 @@ 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 \
+      || (HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB && 
!_GL_WCHAR_T_IS_UCS4) \
       || _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))
@@ -141,6 +142,7 @@ 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 \
+      || (HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB && 
!_GL_WCHAR_T_IS_UCS4) \
       || _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))
@@ -270,7 +272,8 @@ mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t 
*ps)
   /* mbrtoc32() may produce different values for wc than mbrtowc().  Therefore
      use mbrtoc32().  */
 
-#  if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 /* OpenBSD */
+#  if MBRTOC32_IN_C_LOCALE_MAYBE_LIKE_ISO_8859 /* OpenBSD */ \
+      || !_GL_WCHAR_T_IS_UCS4 /* NetBSD ≥ 11 */
   if (!hard_locale (LC_CTYPE))
     {
       /* In the "C" locale, map the bytes 0x80..0xFF to U+DF80..U+DFFF, so that




Reply via email to