I wrote:
> 2026-09-16  Bruno Haible  <[email protected]>
> 
>       c32rtomb: Make consistent with mbrtoc32 in the C locale.
>       Suggested by Paul Eggert.
>       * m4/c32rtomb.m4 (gl_FUNC_C32RTOMB): Require gl_MBRTOC32_C_LOCALE,
>       gl_MBRTOC32_C_LOCALE_LIKE_ISO_8859. When mbrtoc32 gets overridden due to
>       the C locale, set also REPLACE_C32RTOMB to 1.
>       * lib/c32rtomb.c: Include hard-locale.h, <locale.h>.
>       (c32rtomb): On OpenBSD, NetBSD ≥ 11, glibc, Cygwin, mingw, MSVC, do
>       special handling of non-ASCII characters in the C locale.
>       * modules/c32rtomb (Depends-on): Add hard-locale.
>       * tests/test-c32rtomb.c (main): Check that c32rtomb does the inverse of
>       mbrtoc32 in the C locale.

This patch was tested through a testdir of 'c32isprint', which depends on
c32rtomb.

But in a testdir of 'c32isprint uchar-h-c23', I still see a test failure
on macOS, FreeBSD, NetBSD 10, Solaris 11:

FAIL: test-c32rtomb.sh
======================

../../gltests/test-c32rtomb.c:132: assertion 'ret == 1' failed

This patch fixes it.


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

        c32rtomb + uchar-h-c23: Make consistent with mbrtoc32 in the C locale.
        * lib/c32rtomb.c (c32rtomb) [GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION]:
        Do special handling of non-ASCII characters in the C locale.

diff --git a/lib/c32rtomb.c b/lib/c32rtomb.c
index cb8274f14a..9da0abb6be 100644
--- a/lib/c32rtomb.c
+++ b/lib/c32rtomb.c
@@ -35,7 +35,8 @@
 #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)
+     || _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
@@ -166,6 +167,13 @@ c32rtomb (char *s, char32_t wc, mbstate_t *ps)
 
   /* char32_t and wchar_t are equivalent.  */
 # if GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION
+  if ((wc >= 0xDF80 && wc <= 0xDFFF) && !hard_locale (LC_CTYPE))
+    {
+      /* In the "C" locale, map the code points U+DF80..U+DFFF back to the 
bytes
+         0x80..0xFF, for consistency with the mbrtoc32 and btoc32 functions.  
*/
+      s[0] = (unsigned char) (wc - 0xDF00);
+      return 1;
+    }
   if (wc != 0)
     {
       wc = unicode_to_locale_encoding (wc);




Reply via email to