mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
aef3149a23
--HG-- rename : intl/locale/src/Makefile.in => intl/locale/Makefile.in rename : intl/locale/src/PluralForm.jsm => intl/locale/PluralForm.jsm rename : intl/locale/src/langGroups.properties => intl/locale/langGroups.properties rename : intl/locale/src/language.properties => intl/locale/language.properties rename : intl/locale/src/mac/moz.build => intl/locale/mac/moz.build rename : intl/locale/src/mac/nsCollationMacUC.cpp => intl/locale/mac/nsCollationMacUC.cpp rename : intl/locale/src/mac/nsCollationMacUC.h => intl/locale/mac/nsCollationMacUC.h rename : intl/locale/src/mac/nsDateTimeFormatMac.cpp => intl/locale/mac/nsDateTimeFormatMac.cpp rename : intl/locale/src/mac/nsDateTimeFormatMac.h => intl/locale/mac/nsDateTimeFormatMac.h rename : intl/locale/src/mac/nsMacCharset.cpp => intl/locale/mac/nsMacCharset.cpp rename : intl/locale/src/nsCollation.cpp => intl/locale/nsCollation.cpp rename : intl/locale/src/nsCollation.h => intl/locale/nsCollation.h rename : intl/locale/src/nsLanguageAtomService.cpp => intl/locale/nsLanguageAtomService.cpp rename : intl/locale/src/nsLanguageAtomService.h => intl/locale/nsLanguageAtomService.h rename : intl/locale/src/nsLocale.cpp => intl/locale/nsLocale.cpp rename : intl/locale/src/nsLocale.h => intl/locale/nsLocale.h rename : intl/locale/src/nsLocaleConstructors.h => intl/locale/nsLocaleConstructors.h rename : intl/locale/src/nsLocaleService.cpp => intl/locale/nsLocaleService.cpp rename : intl/locale/src/nsPlatformCharset.h => intl/locale/nsPlatformCharset.h rename : intl/locale/src/nsScriptableDateFormat.cpp => intl/locale/nsScriptableDateFormat.cpp rename : intl/locale/src/nsUConvPropertySearch.cpp => intl/locale/nsUConvPropertySearch.cpp rename : intl/locale/src/nsUConvPropertySearch.h => intl/locale/nsUConvPropertySearch.h rename : intl/locale/src/props2arrays.py => intl/locale/props2arrays.py rename : intl/locale/src/unix/Makefile.in => intl/locale/unix/Makefile.in rename : intl/locale/src/unix/moz.build => intl/locale/unix/moz.build rename : intl/locale/src/unix/nsAndroidCharset.cpp => intl/locale/unix/nsAndroidCharset.cpp rename : intl/locale/src/unix/nsCollationUnix.cpp => intl/locale/unix/nsCollationUnix.cpp rename : intl/locale/src/unix/nsCollationUnix.h => intl/locale/unix/nsCollationUnix.h rename : intl/locale/src/unix/nsDateTimeFormatUnix.cpp => intl/locale/unix/nsDateTimeFormatUnix.cpp rename : intl/locale/src/unix/nsDateTimeFormatUnix.h => intl/locale/unix/nsDateTimeFormatUnix.h rename : intl/locale/src/unix/nsPosixLocale.cpp => intl/locale/unix/nsPosixLocale.cpp rename : intl/locale/src/unix/nsUNIXCharset.cpp => intl/locale/unix/nsUNIXCharset.cpp rename : intl/locale/src/unix/unixcharset.properties => intl/locale/unix/unixcharset.properties rename : intl/locale/src/windows/Makefile.in => intl/locale/windows/Makefile.in rename : intl/locale/src/windows/moz.build => intl/locale/windows/moz.build rename : intl/locale/src/windows/nsCollationWin.cpp => intl/locale/windows/nsCollationWin.cpp rename : intl/locale/src/windows/nsCollationWin.h => intl/locale/windows/nsCollationWin.h rename : intl/locale/src/windows/nsDateTimeFormatWin.cpp => intl/locale/windows/nsDateTimeFormatWin.cpp rename : intl/locale/src/windows/nsDateTimeFormatWin.h => intl/locale/windows/nsDateTimeFormatWin.h rename : intl/locale/src/windows/nsWin32Locale.cpp => intl/locale/windows/nsWin32Locale.cpp rename : intl/locale/src/windows/nsWinCharset.cpp => intl/locale/windows/nsWinCharset.cpp rename : intl/locale/src/windows/wincharset.properties => intl/locale/windows/wincharset.properties
240 lines
6.0 KiB
C++
240 lines
6.0 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nscore.h"
|
|
#include "nsString.h"
|
|
#include "nsPosixLocale.h"
|
|
#include "prprf.h"
|
|
#include "plstr.h"
|
|
#include "nsReadableUtils.h"
|
|
|
|
static bool
|
|
ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator);
|
|
|
|
nsresult
|
|
nsPosixLocale::GetPlatformLocale(const nsAString& locale, nsACString& posixLocale)
|
|
{
|
|
char country_code[MAX_COUNTRY_CODE_LEN+1];
|
|
char lang_code[MAX_LANGUAGE_CODE_LEN+1];
|
|
char extra[MAX_EXTRA_LEN+1];
|
|
char posix_locale[MAX_LOCALE_LEN+1];
|
|
NS_LossyConvertUTF16toASCII xp_locale(locale);
|
|
|
|
if (!xp_locale.IsEmpty()) {
|
|
if (!ParseLocaleString(xp_locale.get(),lang_code,country_code,extra,'-')) {
|
|
// strncpy(posixLocale,"C",length);
|
|
posixLocale = xp_locale; // use xp locale if parse failed
|
|
return NS_OK;
|
|
}
|
|
|
|
if (*country_code) {
|
|
if (*extra) {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s_%s.%s",lang_code,country_code,extra);
|
|
}
|
|
else {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s_%s",lang_code,country_code);
|
|
}
|
|
}
|
|
else {
|
|
if (*extra) {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s.%s",lang_code,extra);
|
|
}
|
|
else {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s",lang_code);
|
|
}
|
|
}
|
|
|
|
posixLocale = posix_locale;
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult
|
|
nsPosixLocale::GetXPLocale(const char* posixLocale, nsAString& locale)
|
|
{
|
|
char country_code[MAX_COUNTRY_CODE_LEN+1];
|
|
char lang_code[MAX_LANGUAGE_CODE_LEN+1];
|
|
char extra[MAX_EXTRA_LEN+1];
|
|
char posix_locale[MAX_LOCALE_LEN+1];
|
|
|
|
if (posixLocale!=nullptr) {
|
|
if (strcmp(posixLocale,"C")==0 || strcmp(posixLocale,"POSIX")==0) {
|
|
locale.AssignLiteral("en-US");
|
|
return NS_OK;
|
|
}
|
|
if (!ParseLocaleString(posixLocale,lang_code,country_code,extra,'_')) {
|
|
// * locale = "x-user-defined";
|
|
// use posix if parse failed
|
|
CopyASCIItoUTF16(nsDependentCString(posixLocale), locale);
|
|
return NS_OK;
|
|
}
|
|
|
|
// Special case: substitute "nb" (Norwegian Bokmal) for macrolanguage
|
|
// code "no" (Norwegian)
|
|
if (nsDependentCString(lang_code).LowerCaseEqualsLiteral("no")) {
|
|
lang_code[1] = 'b';
|
|
}
|
|
|
|
if (*country_code) {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s-%s",lang_code,country_code);
|
|
}
|
|
else {
|
|
PR_snprintf(posix_locale,sizeof(posix_locale),"%s",lang_code);
|
|
}
|
|
|
|
CopyASCIItoUTF16(nsDependentCString(posix_locale), locale);
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
//
|
|
// returns false/true depending on if it was of the form LL-CC.Extra
|
|
static bool
|
|
ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator)
|
|
{
|
|
const char *src = locale_string;
|
|
char modifier[MAX_EXTRA_LEN+1];
|
|
char *dest;
|
|
int dest_space, len;
|
|
|
|
*language = '\0';
|
|
*country = '\0';
|
|
*extra = '\0';
|
|
if (strlen(locale_string) < 2) {
|
|
return(false);
|
|
}
|
|
|
|
//
|
|
// parse the language part
|
|
//
|
|
dest = language;
|
|
dest_space = MAX_LANGUAGE_CODE_LEN;
|
|
while ((*src) && (isalpha(*src)) && (dest_space--)) {
|
|
*dest++ = tolower(*src++);
|
|
}
|
|
*dest = '\0';
|
|
len = dest - language;
|
|
if ((len != 2) && (len != 3)) {
|
|
NS_ASSERTION((len == 2) || (len == 3), "language code too short");
|
|
NS_ASSERTION(len < 3, "reminder: verify we can handle 3+ character language code in all parts of the system; eg: language packs");
|
|
*language = '\0';
|
|
return(false);
|
|
}
|
|
|
|
// check if all done
|
|
if (*src == '\0') {
|
|
return(true);
|
|
}
|
|
|
|
if ((*src != '_') && (*src != '-') && (*src != '.') && (*src != '@')) {
|
|
NS_ASSERTION(isalpha(*src), "language code too long");
|
|
NS_ASSERTION(!isalpha(*src), "unexpected language/country separator");
|
|
*language = '\0';
|
|
return(false);
|
|
}
|
|
|
|
//
|
|
// parse the country part
|
|
//
|
|
if ((*src == '_') || (*src == '-')) {
|
|
src++;
|
|
dest = country;
|
|
dest_space = MAX_COUNTRY_CODE_LEN;
|
|
while ((*src) && (isalpha(*src)) && (dest_space--)) {
|
|
*dest++ = toupper(*src++);
|
|
}
|
|
*dest = '\0';
|
|
len = dest - country;
|
|
if (len != 2) {
|
|
NS_ASSERTION(len == 2, "unexpected country code length");
|
|
*language = '\0';
|
|
*country = '\0';
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
// check if all done
|
|
if (*src == '\0') {
|
|
return(true);
|
|
}
|
|
|
|
if ((*src != '.') && (*src != '@')) {
|
|
NS_ASSERTION(isalpha(*src), "country code too long");
|
|
NS_ASSERTION(!isalpha(*src), "unexpected country/extra separator");
|
|
*language = '\0';
|
|
*country = '\0';
|
|
return(false);
|
|
}
|
|
|
|
//
|
|
// handle the extra part
|
|
//
|
|
if (*src == '.') {
|
|
src++; // move past the extra part separator
|
|
dest = extra;
|
|
dest_space = MAX_EXTRA_LEN;
|
|
while ((*src) && (*src != '@') && (dest_space--)) {
|
|
*dest++ = *src++;
|
|
}
|
|
*dest = '\0';
|
|
len = dest - extra;
|
|
if (len < 1) {
|
|
NS_ASSERTION(len > 0, "found country/extra separator but no extra code");
|
|
*language = '\0';
|
|
*country = '\0';
|
|
*extra = '\0';
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
// check if all done
|
|
if (*src == '\0') {
|
|
return(true);
|
|
}
|
|
|
|
//
|
|
// handle the modifier part
|
|
//
|
|
|
|
if (*src == '@') {
|
|
src++; // move past the modifier separator
|
|
NS_ASSERTION(strcmp("euro",src) == 0, "found non euro modifier");
|
|
dest = modifier;
|
|
dest_space = MAX_EXTRA_LEN;
|
|
while ((*src) && (dest_space--)) {
|
|
*dest++ = *src++;
|
|
}
|
|
*dest = '\0';
|
|
len = dest - modifier;
|
|
if (len < 1) {
|
|
NS_ASSERTION(len > 0, "found modifier separator but no modifier code");
|
|
*language = '\0';
|
|
*country = '\0';
|
|
*extra = '\0';
|
|
*modifier = '\0';
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
// check if all done
|
|
if (*src == '\0') {
|
|
return(true);
|
|
}
|
|
|
|
NS_ASSERTION(*src == '\0', "extra/modifier code too long");
|
|
*language = '\0';
|
|
*country = '\0';
|
|
*extra = '\0';
|
|
|
|
return(false);
|
|
}
|
|
|