Cygwin 3.6.7 was recently released. It's the first release that has a
working Turkish locale, i.e. where the upper-/lower-case mappings for
the 'i' and 'I' characters work as expected for Turkish. The Gnulib
test test-mbmemcasecoll-4.sh, that was previously skipped, is now executed,
and it fails:

FAIL: test-mbmemcasecoll-4.sh
=============================

../../gltests/test-mbmemcasecmp.h:288: assertion 'my_casecmp (input, countof 
(input), casefolded_tr, countof (casefolded_tr)) == 0' failed
Stack trace:
0x10040152d test_utf_8
        ../../gltests/test-mbmemcasecmp.h:288
0x100414e49 main
        ../../gltests/test-mbmemcasecoll.c:63

The reason is that c32tolower (0x49) returns 0x69, where 0x131 would be the 
correct result. And this is because in c32to-impl.c the
  return UCS_FUNC (wc);
branch is taken, which is locale-agnostic.

This patch fixes it, by ensuring that 
  return WCHAR_FUNC (wc);
is executed, at least for the characters in the Unicode BMP.


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

        c32tolower, c32toupper: Fix for Turkish locale in Cygwin 3.6.7.
        * lib/c32to-impl.h (FUNC): Move _GL_SMALL_WCHAR_T case up.

diff --git a/lib/c32to-impl.h b/lib/c32to-impl.h
index f6eaf5fdb4..b89cc98e2d 100644
--- a/lib/c32to-impl.h
+++ b/lib/c32to-impl.h
@@ -53,22 +53,6 @@ FUNC (wint_t wc)
   else
     return wc;
 
-#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */
-  /* mbrtoc32() is essentially defined by the system libc.  */
-
-# if _GL_WCHAR_T_IS_UCS4
-  /* The char32_t encoding of a multibyte character is known to be the same as
-     the wchar_t encoding.  */
-  return WCHAR_FUNC (wc);
-# else
-  /* The char32_t encoding of a multibyte character is known to be UCS-4,
-     different from the wchar_t encoding.  */
-  if (wc != WEOF)
-    return UCS_FUNC (wc);
-  else
-    return wc;
-# endif
-
 #elif _GL_SMALL_WCHAR_T                 /* Cygwin, mingw, MSVC */
   /* The wchar_t encoding is UTF-16.
      The char32_t encoding is UCS-4.  */
@@ -90,6 +74,22 @@ FUNC (wint_t wc)
     return UCS_FUNC (wc);
 # endif
 
+#elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */
+  /* mbrtoc32() is essentially defined by the system libc.  */
+
+# if _GL_WCHAR_T_IS_UCS4
+  /* The char32_t encoding of a multibyte character is known to be the same as
+     the wchar_t encoding.  */
+  return WCHAR_FUNC (wc);
+# else
+  /* The char32_t encoding of a multibyte character is known to be UCS-4,
+     different from the wchar_t encoding.  */
+  if (wc != WEOF)
+    return UCS_FUNC (wc);
+  else
+    return wc;
+# endif
+
 #else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */
   /* char32_t and wchar_t are equivalent.  */
   static_assert (sizeof (char32_t) == sizeof (wchar_t));




Reply via email to