Fixed bug #3867: nsIWin32Locale::GetPlatformLocale not returning the correct value for en_US

This commit is contained in:
tague%netscape.com 1999-04-06 05:46:29 +00:00
Родитель a3caca534e
Коммит 3d8b5c2eec
3 изменённых файлов: 426 добавлений и 77 удалений

Просмотреть файл

@ -27,6 +27,13 @@
NS_DEFINE_IID(kIWin32LocaleIID, NS_IWIN32LOCALE_IID);
NS_DEFINE_IID(kIWin32LocaleImplCID, NS_WIN32LOCALE_CID);
#define USER_DEFINED_PRIMARYLANG 0x0200
#define USER_DEFINED_SUBLANGUAGE 0x20
#define LENGTH_LANGUAGE_LIST 51
#define LENGTH_COUNTRY_LIST 96
#define LENGTH_OVERRIDE_LIST 9
struct iso_lang_mapping
{
char* iso_code;
@ -41,10 +48,17 @@ struct iso_country_mapping
};
typedef struct iso_country_mapping iso_country_mapping;
struct iso_country_override
{
char* iso_country_code;
char* iso_lang_code;
DWORD country_code;
};
typedef struct iso_country_override iso_country_override;
//
// ISO <--> Windows 32 Mappings from www.unicode.org
//
iso_lang_mapping language_list[50] =
iso_lang_mapping language_list[LENGTH_LANGUAGE_LIST] =
{
{"af", 0x0036},
{"sq", 0x001c},
@ -63,6 +77,7 @@ iso_lang_mapping language_list[50] =
{"fo", 0x0038},
{"fa", 0x0029},
{"fi", 0x000b},
{"fr", 0x000c},
{"de", 0x0007},
{"el", 0x0008},
{"iw", 0x000d},
@ -97,7 +112,7 @@ iso_lang_mapping language_list[50] =
{"vi", 0x002a}
};
iso_country_mapping country_list[94] =
iso_country_mapping country_list[LENGTH_COUNTRY_LIST] =
{
{"AL",0x0400},
{"DZ",0x1400},
@ -126,6 +141,7 @@ iso_country_mapping country_list[94] =
{"EE",0x0400},
{"FO",0x0400},
{"FI",0x0400},
{"FR",0x0400},
{"DE",0x0400},
{"GR",0x0400},
{"GT",0x1000},
@ -184,6 +200,7 @@ iso_country_mapping country_list[94] =
{"TT",0x2c00},
{"TN",0x1c00},
{"TR",0x0400},
{"TW",0x0400},
{"UA",0x0400},
{"AE",0x3800},
{"GB",0x0800},
@ -195,7 +212,18 @@ iso_country_mapping country_list[94] =
{"ZW",0x3000}
};
iso_country_override country_override[LENGTH_OVERRIDE_LIST] =
{
{"CA","fr",0x0c00},
{"CA","en",0x1000},
{"CH","de",0x0800},
{"CH","it",0x0800},
{"CH","fr",0x1000},
{"LU","de",0x1000},
{"LU","fr",0x1400},
{"ZA","en",0x1c00},
{"ZA","af",0x0400}
};
/* nsIWin32LocaleImpl */
NS_IMPL_ISUPPORTS(nsIWin32LocaleImpl,kIWin32LocaleIID)
@ -222,24 +250,50 @@ nsIWin32LocaleImpl::GetPlatformLocale(const nsString* locale,LCID* winLCID)
char* locale_string;
char language_code[3];
char country_code[3];
int i;
char region_code[3];
DWORD winLangCode = 0, winSublangCode=0;
locale_string = locale->ToNewCString();
if (locale_string!=NULL)
{
PR_sscanf("%s2-%s2-%s",language_code,country_code);
for(i=0;i<50;i++)
{
if(strcmp(language_code,language_list[i].iso_code))
{
*winLCID = MAKELCID(language_list[i].lang_code,SORT_DEFAULT);
delete[] locale_string;
return NS_OK;
}
{
if (!ParseLocaleString(locale_string,language_code,country_code,region_code)) {
*winLCID = MAKELCID(MAKELANGID(USER_DEFINED_PRIMARYLANG,USER_DEFINED_SUBLANGUAGE),
SORT_DEFAULT);
return NS_OK;
}
delete[] locale_string;
return NS_ERROR_FAILURE;
// we have a LL-CC-RR style string
winLangCode = GetLangIDFromISOCode(language_code);
if (winLangCode==0) {
//
// didn't find a corresponding language code -- return user default
//
*winLCID = MAKELCID(MAKELANGID(USER_DEFINED_PRIMARYLANG,USER_DEFINED_SUBLANGUAGE),
SORT_DEFAULT);
return NS_OK;
}
if (strlen(country_code)==0) {
//
// no country code specified -- use SUBLANG_DEFAULT
//
*winLCID = MAKELCID(MAKELANGID(winLangCode,SUBLANG_DEFAULT),
SORT_DEFAULT);
return NS_OK;
}
winSublangCode = GetSublangIDFromISOCode(language_code,country_code);
if (winSublangCode==0) {
//
// didn't find a corresponding language code -- return user default
//
*winLCID = MAKELCID(MAKELANGID(winLangCode,USER_DEFINED_SUBLANGUAGE),
SORT_DEFAULT);
return NS_OK;
}
*winLCID = winLangCode | winSublangCode;
return NS_OK;
}
return NS_ERROR_FAILURE;
@ -248,35 +302,157 @@ nsIWin32LocaleImpl::GetPlatformLocale(const nsString* locale,LCID* winLCID)
NS_IMETHODIMP
nsIWin32LocaleImpl::GetXPLocale(LCID winLCID, nsString* locale)
{
LCID lang_id;
char language_code[3];
char country_code[3];
DWORD lang_id, sublang_id;
const char* lang_code;
const char* country_code;
char rfc_locale_string[9];
int i;
language_code[0] = 0;
country_code[0] = 0;
lang_id = PRIMARYLANGID(LANGIDFROMLCID(winLCID));
sublang_id = SUBLANGID(LANGIDFROMLCID(winLCID));
lang_id = LANGIDFROMLCID(winLCID);
for(i=0;i<50;i++)
{
if (lang_id==language_list[i].lang_code)
{
strcpy(language_code,language_list[i].iso_code);
}
if (sublang_id!=USER_DEFINED_SUBLANGUAGE) {
sublang_id = sublang_id << 10;
}
for(i=0;i<94;i++)
{
if (winLCID==country_list[i].country_code)
{
strcpy(country_code,country_list[i].iso_code);
}
if (lang_id==USER_DEFINED_PRIMARYLANG && sublang_id==USER_DEFINED_SUBLANGUAGE) {
*locale = "x-user-defined";
return NS_OK;
}
PR_snprintf(rfc_locale_string,9,"%s-%s",language_code,country_code);
lang_code = GetISOCodeFromLangID(lang_id);
if (lang_code==nsnull) {
*locale = "x-user-defined";
return NS_OK;
}
country_code = GetISOCodeFromSublangID(sublang_id,lang_code);
if (country_code==nsnull) {
PR_snprintf(rfc_locale_string,9,"%s%c",lang_code,0);
} else {
PR_snprintf(rfc_locale_string,9,"%s-%s%c",lang_code,country_code,0);
}
*locale = rfc_locale_string;
return NS_OK;
}
//
// returns PR_FALSE/PR_TRUE depending on if it was of the form LL-CC-RR
PRBool
nsIWin32LocaleImpl::ParseLocaleString(const char* locale_string, char* language, char* country, char* region)
{
size_t len;
len = strlen(locale_string);
if (len==0 || (len!=2 && len!=5 && len!=8))
return PR_FALSE;
if (len==2) {
language[0]=locale_string[0];
language[1]=locale_string[1];
language[2]=0;
country[0]=0;
region[0]=0;
} else if (len==5) {
language[0]=locale_string[0];
language[1]=locale_string[1];
language[2]=0;
country[0]=locale_string[3];
country[1]=locale_string[4];
country[2]=0;
region[0]=0;
if (locale_string[2]!='-') return PR_FALSE;
} else if (len==8) {
language[0]=locale_string[0];
language[1]=locale_string[1];
language[2]=0;
country[0]=locale_string[3];
country[1]=locale_string[4];
country[2]=0;
region[0]=locale_string[6];
region[1]=locale_string[7];
region[2]=0;
if (locale_string[2]!='-' || locale_string[5]!='-') return PR_FALSE;
} else {
return PR_FALSE;
}
return PR_TRUE;
}
DWORD
nsIWin32LocaleImpl::GetLangIDFromISOCode(const char* lang)
{
int i;
for(i=0;i<LENGTH_LANGUAGE_LIST;i++) {
if (strcmp(lang,language_list[i].iso_code)==0) {
return language_list[i].lang_code;
}
}
return 0;
}
DWORD
nsIWin32LocaleImpl::GetSublangIDFromISOCode(const char* lang, const char* country)
{
int i;
DWORD winSublangCode = 0;
for(i=0;i<LENGTH_COUNTRY_LIST;i++) {
if (strcmp(country,country_list[i].iso_code)==0) {
winSublangCode = country_list[i].country_code;
break;
}
}
for(i=0;i<LENGTH_OVERRIDE_LIST;i++) {
if (strcmp(country,country_override[i].iso_country_code)==0 &&
strcmp(lang,country_override[i].iso_lang_code)==0) {
winSublangCode = country_override[i].country_code;
break;
}
}
return winSublangCode;
}
const char*
nsIWin32LocaleImpl::GetISOCodeFromLangID(DWORD lang_id)
{
int i;
for(i=0;i<LENGTH_LANGUAGE_LIST;i++) {
if (language_list[i].lang_code==lang_id) {
return language_list[i].iso_code;
}
}
return nsnull;
}
const char*
nsIWin32LocaleImpl::GetISOCodeFromSublangID(DWORD sublang_id, const char* lang)
{
int i;
//
// check the overrides first
//
for(i=0;i<LENGTH_OVERRIDE_LIST;i++) {
if (country_override[i].country_code==sublang_id &&
strcmp(lang,country_override[i].iso_lang_code)==0) {
return country_override[i].iso_country_code;
}
}
for(i=0;i<LENGTH_COUNTRY_LIST;i++) {
if (country_list[i].country_code==sublang_id) {
return country_list[i].iso_code;
}
}
return nsnull;
}

Просмотреть файл

@ -39,6 +39,13 @@ public:
NS_IMETHOD GetPlatformLocale(const nsString* locale,LCID* winLCID);
NS_IMETHOD GetXPLocale(LCID winLCID,nsString* locale);
protected:
inline PRBool ParseLocaleString(const char* locale_string, char* language, char* country, char* region);
inline DWORD GetLangIDFromISOCode(const char* lang);
inline DWORD GetSublangIDFromISOCode(const char* lang, const char* country);
inline const char* GetISOCodeFromLangID(const DWORD lang_id);
inline const char* GetISOCodeFromSublangID(const DWORD lang_id, const char* lang);
};
#endif

Просмотреть файл

@ -25,15 +25,6 @@
#include <windows.h>
#endif
#ifdef XP_MAC
#define LOCALE_DLL_NAME "NSLOCALE_DLL"
#elif defined(XP_PC)
#define LOCALE_DLL_NAME "NSLOCALE.DLL"
#else
#define LOCALE_DLL_NAME "libnslocale.so"
#endif
NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
NS_DEFINE_IID(kILocaleFactoryIID, NS_ILOCALEFACTORY_IID);
NS_DEFINE_CID(kLocaleCID, NS_LOCALE_CID);
@ -44,6 +35,10 @@ NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
#ifdef XP_PC
NS_DEFINE_CID(kWin32LocaleFactoryCID, NS_WIN32LOCALEFACTORY_CID);
NS_DEFINE_IID(kIWin32LocaleIID, NS_IWIN32LOCALE_IID);
#define USER_DEFINED_PRIMARYLANG 0x0200
#define USER_DEFINED_SUBLANGUAGE 0x20
#endif
@ -332,7 +327,8 @@ win32locale_test(void)
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id!=0,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
@ -344,7 +340,8 @@ win32locale_test(void)
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id!=0,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(USER_DEFINED_PRIMARYLANG,USER_DEFINED_SUBLANGUAGE),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
@ -353,19 +350,211 @@ win32locale_test(void)
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id!=0,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
win32Locale->Release();
}
void
win32locale_conversion_test(void)
{
nsresult result;
nsIWin32Locale* win32Locale;
nsString* locale;
LCID loc_id;
result = nsComponentManager::CreateInstance(kWin32LocaleFactoryCID,
NULL,
kIWin32LocaleIID,
(void**)&win32Locale);
NS_ASSERTION(win32Locale!=NULL,"nsLocaleTest: factory_create_interface failed.");
NS_ASSERTION(result==NS_OK,"nsLocaleTest: factory_create_interface failed");
//
// check english variants
//
locale = new nsString("en"); // generic english
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("en-US"); // US english
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("en-GB"); // UK english
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_UK),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("en-CA"); // Canadian english
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_CAN),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
//
// japanese
//
locale = new nsString("ja");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("ja-JP");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
//
// chinese Locales
//
locale = new nsString("zh");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("zh-CN");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("zh-TW");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
//
// german and variants
//
locale = new nsString("de");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("de-DE");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("de-AT");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN_AUSTRIAN),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
//
// french and it's variants
//
locale = new nsString("fr");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_DEFAULT),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("fr-FR");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
locale = new nsString("fr-CA");
loc_id = 0;
result = win32Locale->GetPlatformLocale(locale,&loc_id);
NS_ASSERTION(result==NS_OK,"nsLocaleTest: GetPlatformLocale failed.");
NS_ASSERTION(loc_id==MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH_CANADIAN),SORT_DEFAULT),
"nsLocaleTest: GetPlatformLocale failed.");
delete locale;
//
// delete the XPCOM inteface
//
win32Locale->Release();
}
void
win32locale_reverse_conversion_test(void)
{
nsresult result;
nsIWin32Locale* win32Locale;
nsString* locale, *xp_locale;
LCID loc_id;
result = nsComponentManager::CreateInstance(kWin32LocaleFactoryCID,
NULL,
kIWin32LocaleIID,
(void**)&win32Locale);
NS_ASSERTION(win32Locale!=NULL,"nsLocaleTest: factory_create_interface failed.");
NS_ASSERTION(result==NS_OK,"nsLocaleTest: factory_create_interface failed");
//
// english and variants
//
win32Locale->Release();
}
#endif XP_PC
int
main(int argc, char** argv)
{
nsresult res;
//
// what are we doing?
@ -374,31 +563,6 @@ main(int argc, char** argv)
printf("---------------------\n");
printf("This test has completed successfully if no error messages are printed.\n");
//
// register the Locale Factory
//
res = nsComponentManager::RegisterComponent(kLocaleFactoryCID,
NULL,
NULL,
LOCALE_DLL_NAME,
PR_FALSE,
PR_FALSE);
NS_ASSERTION(res==NS_OK,"nsLocaleTest: RegisterComponent failed.");
#ifdef XP_PC
//
// register the Windows specific factory
//
res = nsComponentManager::RegisterComponent(kWin32LocaleFactoryCID,
NULL,
NULL,
LOCALE_DLL_NAME,
PR_FALSE,
PR_FALSE);
NS_ASSERTION(res==NS_OK,"nsLocaleTest: Register nsIWin32LocaleFactory failed.");
#endif
//
// run the nsILocaleFactory tests (nsILocale gets tested in the prcoess)
//
@ -413,6 +577,8 @@ main(int argc, char** argv)
//
win32factory_create_interface();
win32locale_test();
win32locale_conversion_test();
win32locale_reverse_conversion_test();
#endif