From 8d138c3f66c2beb8a7661e57bb44ce436bf8fc33 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 3 Dec 2022 16:16:15 +0100 Subject: [PATCH] Cygwin: fix LC_CTYPE in global locale to be a real C.UTF-8 locale https://cygwin.com/pipermail/cygwin/2022-December/252571.html Cygwin's default locale is "C.UTF-8" as far as LC_CTYPE settings are concerned. However, while __global_locale contains fixed mbtowc and wctomb pointers, the lc_ctype_T pointer is still pointing to _C_ctype_locale, representing the standard "C" locale. The problem with this is that the codeset name as well as MB_CUR_MAX is wrong. Fix this by introducing a new lc_ctype_T structure called _C_utf8_ctype_locale, setting the default codeset to "UTF-8" and MB_CUR_MAX to 6. Use this as lc_ctype_T pointer in __global_locale by default on Cygwin. Fixes: a6a477fa8190 ("POSIX-1.2008 per-thread locales, groundwork part 1") Co-Authored-By: Takashi Yano Signed-off-by: Corinna Vinschen --- newlib/libc/locale/lctype.c | 16 ++++++++++++++++ newlib/libc/locale/locale.c | 3 ++- newlib/libc/locale/setlocale.h | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/newlib/libc/locale/lctype.c b/newlib/libc/locale/lctype.c index 644669765..a07ab6812 100644 --- a/newlib/libc/locale/lctype.c +++ b/newlib/libc/locale/lctype.c @@ -39,6 +39,22 @@ const struct lc_ctype_T _C_ctype_locale = { #endif }; +#ifdef __CYGWIN__ +static char numsix[] = { '\6', '\0'}; + +const struct lc_ctype_T _C_utf8_ctype_locale = { + "UTF-8", /* codeset */ + numsix /* mb_cur_max */ +#ifdef __HAVE_LOCALE_INFO_EXTENDED__ + , + { "0", "1", "2", "3", "4", /* outdigits */ + "5", "6", "7", "8", "9" }, + { L"0", L"1", L"2", L"3", L"4", /* woutdigits */ + L"5", L"6", L"7", L"8", L"9" } +#endif +}; +#endif + /* NULL locale indicates global locale (called from setlocale) */ int __ctype_load_locale (struct __locale_t *locale, const char *name, diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index e523d2366..65e2b1833 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -272,10 +272,11 @@ struct __locale_t __global_locale = { NULL, NULL }, /* LC_ALL */ #ifdef __CYGWIN__ { &_C_collate_locale, NULL }, /* LC_COLLATE */ + { &_C_utf8_ctype_locale, NULL }, /* LC_CTYPE */ #else { NULL, NULL }, /* LC_COLLATE */ -#endif { &_C_ctype_locale, NULL }, /* LC_CTYPE */ +#endif { &_C_monetary_locale, NULL }, /* LC_MONETARY */ { &_C_numeric_locale, NULL }, /* LC_NUMERIC */ { &_C_time_locale, NULL }, /* LC_TIME */ diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h index 9f7fd7c10..3530ec664 100644 --- a/newlib/libc/locale/setlocale.h +++ b/newlib/libc/locale/setlocale.h @@ -64,6 +64,9 @@ struct lc_ctype_T #endif }; extern const struct lc_ctype_T _C_ctype_locale; +#ifdef __CYGWIN__ +extern const struct lc_ctype_T _C_utf8_ctype_locale; +#endif struct lc_monetary_T { -- 2.43.5