From: Victor Chiletto vchiletto@codeweavers.com
Gives us more control over what we map to which is required due to changes in Chinese locales. --- dlls/msvcrt/locale.c | 99 ++++++++++++++++++++++---------------- dlls/msvcrt/tests/locale.c | 12 ++--- 2 files changed, 64 insertions(+), 47 deletions(-)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 6527e06eacd..a2291c60eeb 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -168,43 +168,53 @@ static struct lconv cloc_lconv = /* Friendly country strings & language names abbreviations. */ static const char * const _country_synonyms[] = { - "american", "enu", - "american english", "enu", - "american-english", "enu", - "english-american", "enu", - "english-us", "enu", - "english-usa", "enu", - "us", "enu", - "usa", "enu", - "australian", "ena", - "english-aus", "ena", - "belgian", "nlb", - "french-belgian", "frb", - "canadian", "enc", - "english-can", "enc", - "french-canadian", "frc", - "chinese", "chs", - "chinese-simplified", "chs", - "chinese-traditional", "cht", - "dutch-belgian", "nlb", - "english-nz", "enz", - "uk", "eng", - "english-uk", "eng", - "french-swiss", "frs", - "swiss", "des", - "german-swiss", "des", - "italian-swiss", "its", - "german-austrian", "dea", - "portuguese", "ptb", - "portuguese-brazil", "ptb", - "spanish-mexican", "esm", - "norwegian-bokmal", "nor", - "norwegian-nynorsk", "non", - "spanish-modern", "esn" + "american", "en", + "american english", "en-US", + "american-english", "en-US", + "english-american", "en-US", + "english-us", "en-US", + "english-usa", "en-US", + "us", "en-US", + "usa", "en-US", + "australian", "en-AU", + "english-aus", "en-AU", + "belgian", "nl-BE", + "french-belgian", "fr-BE", + "canadian", "en-CA", + "english-can", "en-CA", + "french-canadian", "fr-CA", +#if _MSVCR_VER >= 110 + "chinese", "zh", + "chinese-simplified", "zh", + "chinese-traditional", "zh-HK", + "chs", "zh", + "cht", "zh-HK", +#else + "chinese", "zh-CN", + "chinese-simplified", "zh-CN", + "chinese-traditional", "zh-TW", + "chs", "zh-CN", + "cht", "zh-TW", +#endif + "dutch-belgian", "nl-BE", + "english-nz", "en-NZ", + "uk", "en-GB", + "english-uk", "en-GB", + "french-swiss", "fr-CH", + "swiss", "de-CH", + "german-swiss", "de-CH", + "italian-swiss", "it-CH", + "german-austrian", "de-AT", + "portuguese", "pt-BR", + "portuguese-brazil", "pt-BR", + "spanish-mexican", "es-MX", + "norwegian-bokmal", "nb", + "norwegian-nynorsk", "nn", + "spanish-modern", "es-ES" };
/* INTERNAL: Map a synonym to an ISO code */ -static void remap_synonym(char *name) +static BOOL remap_synonym(char *name) { unsigned int i; for (i = 0; i < ARRAY_SIZE(_country_synonyms); i += 2) @@ -213,9 +223,11 @@ static void remap_synonym(char *name) { TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]); strcpy(name, _country_synonyms[i+1]); - return; + return TRUE; } } + + return FALSE; }
/* Note: Flags are weighted in order of matching importance */ @@ -265,7 +277,6 @@ find_best_locale_proc( WCHAR *name, DWORD locale_flags, LPARAM lParam )
TRACE("%s\n", wine_dbgstr_w(res->search_language));
-#if _MSVCR_VER >= 110 if (res->allow_sname && compare_info(name,LOCALE_SNAME,buff,res->search_language, TRUE)) { TRACE(":Found locale: %s->%s\n", wine_dbgstr_w(res->search_language), wine_dbgstr_w(buff)); @@ -273,7 +284,6 @@ find_best_locale_proc( WCHAR *name, DWORD locale_flags, LPARAM lParam ) wcscpy(res->found_lang_sname, name); return STOP_LOOKING; } -#endif
/* Check Language */ if (compare_info(name,LOCALE_SISO639LANGNAME,buff,res->search_language, TRUE) || @@ -321,7 +331,7 @@ BOOL locale_to_sname(const char *locale, unsigned short *codepage, BOOL *sname_m { thread_data_t *data = msvcrt_get_thread_data(); const char *cp, *region; - BOOL is_sname = FALSE; + BOOL is_sname = FALSE, remapped = FALSE; DWORD locale_cp;
if (!strcmp(locale, data->cached_locale)) { @@ -357,14 +367,21 @@ BOOL locale_to_sname(const char *locale, unsigned short *codepage, BOOL *sname_m search_language_buf[cp-locale] = '\0'; }
+ if ((remapped = remap_synonym(search_language_buf))) + { + search.allow_sname = TRUE; + } + +#if _MSVCR_VER >= 110 if(!cp && !region) { - remap_synonym(search_language_buf); search.allow_sname = TRUE; } +#endif
MultiByteToWideChar(CP_ACP, 0, search_language_buf, -1, search.search_language, MAX_ELEM_LEN); - MultiByteToWideChar(CP_ACP, 0, search_country_buf, -1, search.search_country, MAX_ELEM_LEN); + if (!remapped) + MultiByteToWideChar(CP_ACP, 0, search_country_buf, -1, search.search_country, MAX_ELEM_LEN);
EnumSystemLocalesEx( find_best_locale_proc, 0, (LPARAM)&search, NULL);
@@ -378,7 +395,7 @@ BOOL locale_to_sname(const char *locale, unsigned short *codepage, BOOL *sname_m return FALSE;
wcsncpy(sname, search.found_lang_sname, sname_size); - is_sname = (search.match_flags & FOUND_SNAME) != 0; + is_sname = !remapped && (search.match_flags & FOUND_SNAME) != 0; }
/* Obtain code page */ diff --git a/dlls/msvcrt/tests/locale.c b/dlls/msvcrt/tests/locale.c index 95c468bc140..f77e8f93abb 100644 --- a/dlls/msvcrt/tests/locale.c +++ b/dlls/msvcrt/tests/locale.c @@ -114,14 +114,14 @@ static void test_setlocale(void) ret = setlocale(LC_ALL, "chinese"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - todo_wine ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") + ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") || !strcmp(ret, "Chinese (Simplified)_China.936") || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "chinese-simplified"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - todo_wine ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") + ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") || !strcmp(ret, "Chinese (Simplified)_China.936") || broken(!strcmp(ret, "Chinese_People's Republic of China.936")) || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret); @@ -129,20 +129,20 @@ static void test_setlocale(void) ret = setlocale(LC_ALL, "chinese-traditional"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - todo_wine ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950") + ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950") || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "chs"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - todo_wine ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") + ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") || !strcmp(ret, "Chinese (Simplified)_China.936") || broken(!strcmp(ret, "Chinese_People's Republic of China.936")), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "cht"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - todo_wine ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950") + ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950") || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "Chinese_China.936"); @@ -150,7 +150,7 @@ static void test_setlocale(void) if(ret) { trace("Chinese_China.936=%s\n", ret); - todo_wine ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") /* Vista - Win7 */ + ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") /* Vista - Win7 */ || !strcmp(ret, "Chinese (Simplified)_China.936") /* Win8 - Win10 */ || broken(!strcmp(ret, "Chinese_People's Republic of China.936")), "ret = %s\n", ret); }