diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/nlsfuncs.cc | 66 |
2 files changed, 68 insertions, 3 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f4df5b0a4..89b3252bc 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2010-01-25 Corinna Vinschen <corinna@vinschen.de> + + * nlsfuncs.cc (__get_lcid_from_locale): Fix a comment. Handle special + language/TERRITORY combinations explicitely. Explain why. + 2010-01-24 Corinna Vinschen <corinna@vinschen.de> * nlsfuncs.cc (__set_charset_from_locale): Fix comment. diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc index 9689e3e47..58659b616 100644 --- a/winsup/cygwin/nlsfuncs.cc +++ b/winsup/cygwin/nlsfuncs.cc @@ -73,15 +73,47 @@ __get_lcid_from_locale (const char *name) /* "POSIX" already converted to "C" in loadlocale. */ if (!strcmp (locale, "C")) return 0; - /* Convert to form understood by LocaleNameToLCID */ c = strchr (locale, '_'); - if (c) - *c = '-'; if (wincap.has_localenames ()) { wchar_t wlocale[ENCODING_LEN + 1]; + + /* Convert to RFC 4646 syntax which is the standard for the locale names + replacing LCIDs starting with Vista. */ + if (c) + *c = '-'; mbstowcs (wlocale, locale, ENCODING_LEN + 1); lcid = LocaleNameToLCID (wlocale, 0); + if (lcid == 0) + { + /* Unfortunately there are a couple of locales for which no form + without a Script part per RFC 4646 exists. */ + struct { + const char *loc; + const wchar_t *wloc; + } sc_only_locale[] = { + { "az-AZ" , L"az-Latn-AZ" }, + { "bs-BA" , L"bs-Latn-BA" }, + { "ha-NG" , L"ha-Latn-NG" }, + { "iu-CA" , L"iu-Cans-CA" }, + { "mn-CN" , L"mn-Mong-CN" }, + { "sr-CS" , L"sr-Latn-CS" }, + { "sr-BA" , L"sr-Latn-BA" }, + { "sr-RS" , L"sr-Latn-RS" }, + { "sr-ME" , L"sr-Latn-ME" }, + { "tg-TJ" , L"tg-Cyrl-TJ" }, + { "tzm-DZ", L"tzm-Latn-DZ" }, + { "uz-UZ" , L"uz-Latn-UZ" }, + { NULL , NULL } + }; + for (int i = 0; sc_only_locale[i].loc + && sc_only_locale[i].loc[0] <= locale[0]; ++i) + if (!strcmp (locale, sc_only_locale[i].loc)) + { + lcid = LocaleNameToLCID (sc_only_locale[i].wloc, 0); + break; + } + } last_lcid = lcid ?: (LCID) -1; debug_printf ("LCID=0x%04x", last_lcid); return last_lcid; @@ -120,6 +152,34 @@ __get_lcid_from_locale (const char *name) if (sublang > 0x14) lcid = 0; } + if (lcid == 0 && territory) + { + /* Unfortunately there are a four language LCID number areas + representing multiple languages. Fortunately onle two of them + already existed pre-Vista. The concealed languages have to be + tested explicitly, since they are not catched by the above loops. */ + struct { + const char *loc; + LCID lcid; + } ambiguous_locale[] = { + { "bs_BA", MAKELANGID (LANG_BOSNIAN, 0x05) }, + { "nn_NO", MAKELANGID (LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK) }, + { "sr_BA", MAKELANGID (LANG_BOSNIAN, + SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN) }, + { "sr_SP", MAKELANGID (LANG_SERBIAN, SUBLANG_SERBIAN_LATIN) }, + { NULL, 0 }, + }; + *--c = '_'; + for (int i = 0; ambiguous_locale[i].loc + && ambiguous_locale[i].loc[0] <= locale[0]; ++i) + if (!strcmp (locale, ambiguous_locale[i].loc) + && GetLocaleInfo (ambiguous_locale[i].lcid, LOCALE_SISO639LANGNAME, + iso, 10)) + { + lcid = ambiguous_locale[i].lcid; + break; + } + } last_lcid = lcid ?: (LCID) -1; debug_printf ("LCID=0x%04x", last_lcid); return last_lcid; |