gecko-dev/lib/libi18n/country.c
1998-10-23 18:51:40 +00:00

386 lines
11 KiB
C

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "intlpriv.h"
/* Mapping table between platform code and ISO code.
*/
typedef struct
{
char iso_code[6];
unsigned short win_langid;
unsigned short mac_lang;
unsigned short mac_region;
} ISO_Lang_Country_To_Platform;
static ISO_Lang_Country_To_Platform iso_mapping_table[] = {
{"af-ZA", 0x0436, 32767, 32767},
{"ar-AE", 0x3801, 32767, 32767},
{"ar-BH", 0x3c01, 32767, 32767},
{"ar-DZ", 0x1401, 32767, 32767},
{"ar-EG", 0x0c01, 32767, 32767},
{"ar-IQ", 0x0801, 32767, 32767},
{"ar-JO", 0x2c01, 32767, 32767},
{"ar-KW", 0x3401, 32767, 32767},
{"ar-LB", 0x3001, 32767, 32767},
{"ar-LY", 0x1001, 32767, 32767},
{"ar-MA", 0x1801, 32767, 32767},
{"ar-OM", 0x2001, 32767, 32767},
{"ar-QA", 0x4001, 32767, 32767},
{"ar-SA", 0x0401, 32767, 32767},
{"ar-SY", 0x2801, 32767, 32767},
{"ar-TN", 0x1c01, 32767, 32767},
{"ar-YE", 0x2401, 32767, 32767},
{"az-AZ", 0x042c, 32767, 32767},
{"az-AZ", 0x082c, 32767, 32767},
{"be-BY", 0x0423, 32767, 32767},
{"bg-BG", 0x0402, 32767, 32767},
{"ca-ES", 0x0403, 32767, 32767},
{"cs-CZ", 0x0405, 32767, 32767},
{"da-DK", 0x0406, 32767, 32767},
{"de-AT", 0x0c07, 32767, 32767},
{"de-CH", 0x0807, 32767, 32767},
{"de-DE", 0x0407, 32767, 32767},
{"de-LI", 0x1407, 32767, 32767},
{"de-LU", 0x1007, 32767, 32767},
{"el-GR", 0x0408, 32767, 32767},
{"en-AU", 0x0c09, 32767, 32767},
{"en-BZ", 0x2809, 32767, 32767},
{"en-CA", 0x1009, 32767, 32767},
{"en-CB", 0x2409, 32767, 32767},
{"en-GB", 0x0809, 32767, 32767},
{"en-IE", 0x1809, 32767, 32767},
{"en-JM", 0x2009, 32767, 32767},
{"en-NZ", 0x1409, 32767, 32767},
{"en-PH", 0x3409, 32767, 32767},
{"en-TT", 0x2c09, 32767, 32767},
{"en-US", 0x0409, 0, 0},
{"en-ZA", 0x1c09, 32767, 32767},
{"en-ZW", 0x3009, 32767, 32767},
{"es-AR", 0x2c0a, 32767, 32767},
{"es-BO", 0x400a, 32767, 32767},
{"es-CL", 0x340a, 32767, 32767},
{"es-CO", 0x240a, 32767, 32767},
{"es-CR", 0x140a, 32767, 32767},
{"es-DO", 0x1c0a, 32767, 32767},
{"es-EC", 0x300a, 32767, 32767},
{"es-ES", 0x040a, 32767, 32767},
{"es-ES", 0x0c0a, 32767, 32767},
{"es-GT", 0x100a, 32767, 32767},
{"es-HN", 0x480a, 32767, 32767},
{"es-MX", 0x080a, 32767, 32767},
{"es-NI", 0x4c0a, 32767, 32767},
{"es-PA", 0x180a, 32767, 32767},
{"es-PE", 0x280a, 32767, 32767},
{"es-PR", 0x500a, 32767, 32767},
{"es-PY", 0x3c0a, 32767, 32767},
{"es-SV", 0x440a, 32767, 32767},
{"es-UY", 0x380a, 32767, 32767},
{"es-VE", 0x200a, 32767, 32767},
{"et-EE", 0x0425, 32767, 32767},
{"eu-ES", 0x042d, 32767, 32767},
{"fa-IR", 0x0429, 32767, 32767},
{"fi-FI", 0x040b, 32767, 32767},
{"fo-FO", 0x0438, 32767, 32767},
{"fr-BE", 0x080c, 32767, 32767},
{"fr-CA", 0x0c0c, 32767, 32767},
{"fr-CH", 0x100c, 32767, 32767},
{"fr-FR", 0x040c, 32767, 32767},
{"fr-LU", 0x140c, 32767, 32767},
{"fr-MC", 0x180c, 32767, 32767},
{"hr-HR", 0x041a, 32767, 32767},
{"hu-HU", 0x040e, 32767, 32767},
{"id-ID", 0x0421, 32767, 32767},
{"is-IS", 0x040f, 32767, 32767},
{"it-CH", 0x0810, 32767, 32767},
{"it-IT", 0x0410, 32767, 32767},
{"iw-IL", 0x040d, 32767, 32767},
{"ja-JP", 0x0411, 32767, 32767},
{"kk-KZ", 0x043f, 32767, 32767},
{"ko-KR", 0x0412, 32767, 32767},
{"lt-LT", 0x0427, 32767, 32767},
{"lt-LT", 0x0827, 32767, 32767},
{"lv-LV", 0x0426, 32767, 32767},
{"mk-MK", 0x042f, 32767, 32767},
{"ms-BN", 0x083e, 32767, 32767},
{"ms-MY", 0x043e, 32767, 32767},
{"nl-BE", 0x0813, 32767, 32767},
{"nl-NL", 0x0413, 32767, 32767},
{"no-NO", 0x0414, 32767, 32767},
{"no-NO", 0x0814, 32767, 32767},
{"pl-PL", 0x0415, 32767, 32767},
{"pt-BR", 0x0416, 32767, 32767},
{"pt-PT", 0x0816, 32767, 32767},
{"ro-RO", 0x0418, 32767, 32767},
{"ru-RU", 0x0419, 32767, 32767},
{"sk-SK", 0x041b, 32767, 32767},
{"sl-SI", 0x0424, 32767, 32767},
{"sq-AL", 0x041c, 32767, 32767},
{"sr-SP", 0x081a, 32767, 32767},
{"sr-SP", 0x0c1a, 32767, 32767},
{"sv-FI", 0x081d, 32767, 32767},
{"sv-SE", 0x041d, 32767, 32767},
{"sw-KE", 0x0441, 32767, 32767},
{"th-TH", 0x041e, 32767, 32767},
{"tr-TR", 0x041f, 32767, 32767},
{"tt-TA", 0x0444, 32767, 32767},
{"uk-UA", 0x0422, 32767, 32767},
{"ur-PK", 0x0420, 32767, 32767},
{"uz-UZ", 0x0443, 32767, 32767},
{"uz-UZ", 0x0843, 32767, 32767},
{"vi-VN", 0x042a, 32767, 32767},
{"zh-CN", 0x0804, 32767, 32767},
{"zh-HK", 0x0c04, 32767, 32767},
{"zh-MO", 0x1404, 32767, 32767},
{"zh-SG", 0x1004, 32767, 32767},
{"zh-TW", 0x0404, 32767, 32767},
{"", 0, 0, 0}
};
static XP_Bool MatchPlatformId(ISO_Lang_Country_To_Platform *entry, XP_Bool bLanguage,
unsigned short platformIdNum, char *platformIdStr)
{
#if defined(XP_WIN)
return platformIdNum == entry->win_langid;
#elif defined(XP_MAC)
return bLanguage ? (platformIdNum == entry->mac_lang) : (platformIdNum == entry->mac_region);
#elif defined(XP_UNIX)
/* implement XFE code here */
#endif
XP_ASSERT(0); /* platform not supported */
return FALSE;
}
static XP_Bool MatchISOCode(ISO_Lang_Country_To_Platform *entry, char *ISOCode)
{
return (XP_STRCMP(entry->iso_code, ISOCode) == 0);
}
PUBLIC const char *INTL_PlatformIdToISOCode(unsigned short platformIdNum, char *platformIdStr, XP_Bool bLanguage)
{
ISO_Lang_Country_To_Platform *tmpPtr = iso_mapping_table;
while (tmpPtr->iso_code[0])
{
if (MatchPlatformId(tmpPtr, bLanguage, platformIdNum, platformIdStr))
break;
tmpPtr++;
}
#ifdef DEBUG
#ifdef XP_WIN
/* Not found in the table, this is usually ok as EnumSystemLocales() passes unavailable langid
* even called with LCID_INSTALLED.
* For debugging, we verify by calling GetLocaleInfo(). If that API works then it means the table is missing the entry.
*/
if(!tmpPtr->iso_code[0])
{
char locale_string[128];
XP_ASSERT( GetLocaleInfo(platformIdNum, LOCALE_SENGLANGUAGE,
locale_string, sizeof(locale_string)) == 0 );
}
#else
XP_ASSERT(tmpPtr->iso_code[0]);
#endif
#endif /* DEBUG */
return tmpPtr->iso_code;
}
PUBLIC char *INTL_GetLanguageCountry(INTL_LanguageCountry_Selector selector)
{
/* return constants until FE implemented */
#if defined(XP_WIN)
return FE_GetLanguageCountry(selector);
#else
switch (selector)
{
case INTL_LanguageSel:
case INTL_LanguageCollateSel:
case INTL_LanguageMonetarySel:
case INTL_LanguageNumericSel:
case INTL_LanguageTimeSel:
return XP_STRDUP("en");
case INTL_CountrySel:
case INTL_CountryCollateSel:
case INTL_CountryMonetarySel:
case INTL_CountryNumericSel:
case INTL_CountryTimeSel:
return XP_STRDUP("US");
case INTL_ALL_LocalesSel:
return XP_STRDUP("en-US,en-GB,fr-FR");
default:
return XP_STRDUP("");
}
#endif
}
/* FE implementations, for now put them here for potability. */
#if defined(XP_WIN)
/* Definitions of states to check if API supports ISO code. */
typedef enum
{
kAPI_ISONAME_NotInitialzied,
kAPI_ISONAME_Supported,
kAPI_ISONAME_NotSupported
} STATE_API_Support_ISONAME;
static STATE_API_Support_ISONAME bAPI_Support_ISONAME = kAPI_ISONAME_NotInitialzied;
static BOOL API_Support_ISONAME()
{
char locale_string[128];
return GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SISO639LANGNAME,
locale_string, sizeof(locale_string)) != 0;
}
/* Variables and callbacks for construct a string of all installed locales. */
static char *locale_buf = NULL;
static int locale_num =0;
BOOL CALLBACK EnumLocalesProc0(LPTSTR lpLocaleString)
{
char locale_string[128];
char *endptr;
LCID lcid = (LCID) strtol(lpLocaleString, &endptr, 16); /* the argument is in hex string */
if (GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, locale_string, sizeof(locale_string)))
locale_num++;
return TRUE;
}
BOOL CALLBACK EnumLocalesProc(LPTSTR lpLocaleString)
{
char locale_string[128];
char *endptr;
LCID lcid = (LCID) strtol(lpLocaleString, &endptr, 16); /* the argument is in hex string */
if (bAPI_Support_ISONAME == kAPI_ISONAME_Supported)
{
if (GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, locale_string, sizeof(locale_string)))
{
XP_STRCAT(locale_buf, locale_string);
XP_STRCAT(locale_buf, "-");
if (GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, locale_string, sizeof(locale_string)))
{
XP_STRCAT(locale_buf, locale_string);
XP_STRCAT(locale_buf, ",");
}
}
}
else
{
const char *iso_code = INTL_PlatformIdToISOCode((unsigned short) LANGIDFROMLCID(lcid), NULL, TRUE);
if (iso_code && iso_code[0])
{
XP_STRCAT(locale_buf, iso_code);
XP_STRCAT(locale_buf, ",");
}
}
return TRUE;
}
static const char *GetAllLocales(void)
{
int len;
/* It it possible to re-use the buffer if NT4 or earlier since locales cannot be added
* while the Navigator is running.
*/
XP_FREEIF(locale_buf);
locale_num = 0;
/* get length and allocate a buffer */
(void) EnumSystemLocales(EnumLocalesProc0, LCID_INSTALLED);
locale_buf = (char *) XP_ALLOC(locale_num * 6 + 1);
if (locale_buf == NULL)
return "";
locale_buf[0] = '\0';
/* copy locale info to the buffer */
(void) EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
/* trim the last comma */
len = XP_STRLEN(locale_buf);
if (len >= 1)
locale_buf[len-1] = '\0';
return (const char *) locale_buf;
}
char *FE_GetLanguageCountry(INTL_LanguageCountry_Selector selector)
{
char *name = NULL;
char locale_string[128];
LCID lcid = GetUserDefaultLCID();
/* check if the API supports the ISO code output */
if (bAPI_Support_ISONAME == kAPI_ISONAME_NotInitialzied)
bAPI_Support_ISONAME = API_Support_ISONAME() ? kAPI_ISONAME_Supported : kAPI_ISONAME_NotSupported;
switch (selector)
{
case INTL_LanguageSel:
case INTL_LanguageCollateSel:
case INTL_LanguageMonetarySel:
case INTL_LanguageNumericSel:
case INTL_LanguageTimeSel:
if (bAPI_Support_ISONAME == kAPI_ISONAME_Supported)
{
if (GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, locale_string, sizeof(locale_string)) > 0)
name = XP_STRDUP(locale_string);
}
else
{
name = (char *) INTL_PlatformIdToISOCode((unsigned short) LANGIDFROMLCID(lcid), NULL, TRUE);
XP_ASSERT(name && XP_STRLEN(name)==5);
name = XP_STRDUP(XP_STRNCPY_SAFE(locale_string, name, 3)); /* copy language */
}
break;
case INTL_CountrySel:
case INTL_CountryCollateSel:
case INTL_CountryMonetarySel:
case INTL_CountryNumericSel:
case INTL_CountryTimeSel:
if (bAPI_Support_ISONAME == kAPI_ISONAME_Supported)
{
if (GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, locale_string, sizeof(locale_string)) > 0)
name = XP_STRDUP(locale_string);
}
else
{
name = (char *) INTL_PlatformIdToISOCode((unsigned short) LANGIDFROMLCID(lcid), NULL, FALSE);
XP_ASSERT(name && XP_STRLEN(name)==5);
name = XP_STRDUP(XP_STRNCPY_SAFE(locale_string, &name[3], 3)); /* copy country */
}
break;
case INTL_ALL_LocalesSel:
name = XP_STRDUP(GetAllLocales());
break;
default:
name = XP_STRDUP("");
break;
}
return name;
}
#endif /* XP_WIN */