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));