From: Bruno Haible Date: Mon, 23 Dec 2024 16:54:38 +0000 (+0100) Subject: intl: Support the UTF-8 environment on native Windows. X-Git-Tag: v0.24~81 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=588c9adbca670b06a4f99486c88f2feefbb4c563;p=thirdparty%2Fgettext.git intl: Support the UTF-8 environment on native Windows. Reported by Lasse Collin in . * gettext-runtime/intl/setlocale.c: Include . (setlocale_unixlike): In the UTF-8 environment, append a suffix ".65001" to the locale names passed to the native setlocale(). --- diff --git a/gettext-runtime/intl/setlocale.c b/gettext-runtime/intl/setlocale.c index 71a61a3f1..65883b696 100644 --- a/gettext-runtime/intl/setlocale.c +++ b/gettext-runtime/intl/setlocale.c @@ -71,6 +71,11 @@ extern void gl_locale_name_canonicalize (char *name); #endif +#if defined _WIN32 && !defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +#endif + /* Get _nl_msg_cat_cntr declaration. */ #include "gettextP.h" @@ -669,6 +674,7 @@ search (const struct table_entry *table, size_t table_size, const char *string, static char * setlocale_unixlike (int category, const char *locale) { + int is_utf8 = (GetACP () == 65001); char *result; char llCC_buf[64]; char ll_buf[64]; @@ -679,6 +685,15 @@ setlocale_unixlike (int category, const char *locale) if (locale != NULL && strcmp (locale, "POSIX") == 0) locale = "C"; + /* The native Windows implementation of setlocale, in the UTF-8 environment, + does not understand the locale names "C.UTF-8" or "C.utf8" or "C.65001", + but it understands "English_United States.65001", which is functionally + equivalent. */ + if (locale != NULL + && ((is_utf8 && strcmp (locale, "C") == 0) + || strcmp (locale, "C.UTF-8") == 0)) + locale = "English_United States.65001"; + /* First, try setlocale with the original argument unchanged. */ result = setlocale (category, locale); if (result != NULL) @@ -711,7 +726,15 @@ setlocale_unixlike (int category, const char *locale) */ if (strcmp (llCC_buf, locale) != 0) { - result = setlocale (category, llCC_buf); + if (is_utf8) + { + char buf[64+6]; + strcpy (buf, llCC_buf); + strcat (buf, ".65001"); + result = setlocale (category, buf); + } + else + result = setlocale (category, llCC_buf); if (result != NULL) return result; } @@ -728,7 +751,15 @@ setlocale_unixlike (int category, const char *locale) for (i = range.lo; i < range.hi; i++) { /* Try the replacement in language_table[i]. */ - result = setlocale (category, language_table[i].english); + if (is_utf8) + { + char buf[64+6]; + strcpy (buf, language_table[i].english); + strcat (buf, ".65001"); + result = setlocale (category, buf); + } + else + result = setlocale (category, language_table[i].english); if (result != NULL) return result; } @@ -782,13 +813,15 @@ setlocale_unixlike (int category, const char *locale) size_t part1_len = strlen (part1); const char *part2 = country_table[j].english; size_t part2_len = strlen (part2) + 1; - char buf[64+64]; + char buf[64+64+6]; - if (!(part1_len + 1 + part2_len <= sizeof (buf))) + if (!(part1_len + 1 + part2_len + 6 <= sizeof (buf))) abort (); memcpy (buf, part1, part1_len); buf[part1_len] = '_'; memcpy (buf + part1_len + 1, part2, part2_len); + if (is_utf8) + strcat (buf, ".65001"); /* Try the concatenated replacements. */ result = setlocale (category, buf); @@ -806,8 +839,16 @@ setlocale_unixlike (int category, const char *locale) for (i = language_range.lo; i < language_range.hi; i++) { /* Try only the language replacement. */ - result = - setlocale (category, language_table[i].english); + if (is_utf8) + { + char buf[64+6]; + strcpy (buf, language_table[i].english); + strcat (buf, ".65001"); + result = setlocale (category, buf); + } + else + result = + setlocale (category, language_table[i].english); if (result != NULL) return result; }