From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- intl/locale/unix/moz.build | 38 +++ intl/locale/unix/nsAndroidCharset.cpp | 49 +++ intl/locale/unix/nsCollationUnix.cpp | 189 +++++++++++ intl/locale/unix/nsCollationUnix.h | 43 +++ intl/locale/unix/nsDateTimeFormatUnix.cpp | 284 ++++++++++++++++ intl/locale/unix/nsDateTimeFormatUnix.h | 70 ++++ intl/locale/unix/nsPosixLocale.cpp | 243 ++++++++++++++ intl/locale/unix/nsUNIXCharset.cpp | 185 +++++++++++ intl/locale/unix/unixcharset.properties | 536 ++++++++++++++++++++++++++++++ 9 files changed, 1637 insertions(+) create mode 100644 intl/locale/unix/moz.build create mode 100644 intl/locale/unix/nsAndroidCharset.cpp create mode 100644 intl/locale/unix/nsCollationUnix.cpp create mode 100644 intl/locale/unix/nsCollationUnix.h create mode 100644 intl/locale/unix/nsDateTimeFormatUnix.cpp create mode 100644 intl/locale/unix/nsDateTimeFormatUnix.h create mode 100644 intl/locale/unix/nsPosixLocale.cpp create mode 100644 intl/locale/unix/nsUNIXCharset.cpp create mode 100644 intl/locale/unix/unixcharset.properties (limited to 'intl/locale/unix') diff --git a/intl/locale/unix/moz.build b/intl/locale/unix/moz.build new file mode 100644 index 000000000..7685d0a01 --- /dev/null +++ b/intl/locale/unix/moz.build @@ -0,0 +1,38 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +SOURCES += [ + 'nsCollationUnix.cpp', + 'nsDateTimeFormatUnix.cpp', + 'nsPosixLocale.cpp', +] + +if CONFIG['OS_TARGET'] == 'Android': + SOURCES += [ + 'nsAndroidCharset.cpp', + ] +else: + SOURCES += [ + 'nsUNIXCharset.cpp', + ] + GENERATED_FILES = [ + 'unixcharset.properties.h', + ] + unixcharset = GENERATED_FILES['unixcharset.properties.h'] + unixcharset.script = '../props2arrays.py' + unixcharset.inputs = ['unixcharset.properties'] + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '..', +] + +# CODESET is not automatically defined on some older versions of Redhat. +# Define _XOPEN_SOURCE so CODESET will get defined and thus allow +# nl_langinfo(CODESET) to compile on these systems. +if CONFIG['OS_ARCH'] == 'Linux': + DEFINES['_XOPEN_SOURCE'] = 500 diff --git a/intl/locale/unix/nsAndroidCharset.cpp b/intl/locale/unix/nsAndroidCharset.cpp new file mode 100644 index 000000000..ed646039c --- /dev/null +++ b/intl/locale/unix/nsAndroidCharset.cpp @@ -0,0 +1,49 @@ +/* -*- 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 "nsIPlatformCharset.h" +#include "nsPlatformCharset.h" + +NS_IMPL_ISUPPORTS(nsPlatformCharset, nsIPlatformCharset) + +nsPlatformCharset::nsPlatformCharset() +{ +} + +nsPlatformCharset::~nsPlatformCharset() +{ +} + +NS_IMETHODIMP +nsPlatformCharset::Init() +{ + return NS_OK; +} + +NS_IMETHODIMP +nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsACString& oResult) +{ + oResult.AssignLiteral("UTF-8"); + return NS_OK; +} + +NS_IMETHODIMP +nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACString &oResult) +{ + oResult.AssignLiteral("UTF-8"); + return NS_OK; +} + +nsresult +nsPlatformCharset::InitGetCharset(nsACString &oString) +{ + return NS_OK; +} + +nsresult +nsPlatformCharset::VerifyCharset(nsCString &aCharset) +{ + return NS_OK; +} diff --git a/intl/locale/unix/nsCollationUnix.cpp b/intl/locale/unix/nsCollationUnix.cpp new file mode 100644 index 000000000..3bc5a731c --- /dev/null +++ b/intl/locale/unix/nsCollationUnix.cpp @@ -0,0 +1,189 @@ +/* -*- 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 +#include "prmem.h" +#include "nsCollationUnix.h" +#include "nsIServiceManager.h" +#include "nsIComponentManager.h" +#include "nsILocaleService.h" +#include "nsIPlatformCharset.h" +#include "nsPosixLocale.h" +#include "nsCOMPtr.h" +#include "nsUnicharUtils.h" +#include "nsCRT.h" +//#define DEBUG_UNIX_COLLATION + +inline void nsCollationUnix::DoSetLocale() +{ + char *locale = setlocale(LC_COLLATE, nullptr); + mSavedLocale.Assign(locale ? locale : ""); + if (!mSavedLocale.EqualsIgnoreCase(mLocale.get())) { + (void) setlocale(LC_COLLATE, PromiseFlatCString(Substring(mLocale,0,MAX_LOCALE_LEN)).get()); + } +} + +inline void nsCollationUnix::DoRestoreLocale() +{ + if (!mSavedLocale.EqualsIgnoreCase(mLocale.get())) { + (void) setlocale(LC_COLLATE, PromiseFlatCString(Substring(mSavedLocale,0,MAX_LOCALE_LEN)).get()); + } +} + +nsCollationUnix::nsCollationUnix() : mCollation(nullptr) +{ +} + +nsCollationUnix::~nsCollationUnix() +{ + if (mCollation) + delete mCollation; +} + +NS_IMPL_ISUPPORTS(nsCollationUnix, nsICollation) + +nsresult nsCollationUnix::Initialize(nsILocale* locale) +{ +#define kPlatformLocaleLength 64 + NS_ASSERTION(!mCollation, "Should only be initialized once"); + + nsresult res; + + mCollation = new nsCollation; + + // default platform locale + mLocale.Assign('C'); + + nsAutoString localeStr; + NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_COLLATE##PLATFORM"); + + // get locale string, use app default if no locale specified + if (locale == nullptr) { + nsCOMPtr localeService = + do_GetService(NS_LOCALESERVICE_CONTRACTID, &res); + if (NS_SUCCEEDED(res)) { + nsCOMPtr appLocale; + res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); + if (NS_SUCCEEDED(res)) { + res = appLocale->GetCategory(aCategory, localeStr); + NS_ASSERTION(NS_SUCCEEDED(res), "failed to get app locale info"); + } + } + } + else { + res = locale->GetCategory(aCategory, localeStr); + NS_ASSERTION(NS_SUCCEEDED(res), "failed to get locale info"); + } + + // Get platform locale and charset name from locale, if available + if (NS_SUCCEEDED(res)) { + // keep the same behavior as 4.x as well as avoiding Linux collation key problem + if (localeStr.LowerCaseEqualsLiteral("en_us")) { // note: locale is in platform format + localeStr.Assign('C'); + } + + nsPosixLocale::GetPlatformLocale(localeStr, mLocale); + + nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res); + if (NS_SUCCEEDED(res)) { + nsAutoCString mappedCharset; + res = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset); + if (NS_SUCCEEDED(res)) { + mCollation->SetCharset(mappedCharset.get()); + } + } + } + + return NS_OK; +} + + +nsresult nsCollationUnix::CompareString(int32_t strength, + const nsAString& string1, + const nsAString& string2, + int32_t* result) +{ + nsresult res = NS_OK; + + nsAutoString stringNormalized1, stringNormalized2; + if (strength != kCollationCaseSensitive) { + res = mCollation->NormalizeString(string1, stringNormalized1); + if (NS_FAILED(res)) { + return res; + } + res = mCollation->NormalizeString(string2, stringNormalized2); + if (NS_FAILED(res)) { + return res; + } + } else { + stringNormalized1 = string1; + stringNormalized2 = string2; + } + + // convert unicode to charset + char *str1, *str2; + + res = mCollation->UnicodeToChar(stringNormalized1, &str1); + if (NS_SUCCEEDED(res) && str1) { + res = mCollation->UnicodeToChar(stringNormalized2, &str2); + if (NS_SUCCEEDED(res) && str2) { + DoSetLocale(); + *result = strcoll(str1, str2); + DoRestoreLocale(); + PR_Free(str2); + } + PR_Free(str1); + } + + return res; +} + + +nsresult nsCollationUnix::AllocateRawSortKey(int32_t strength, + const nsAString& stringIn, + uint8_t** key, uint32_t* outLen) +{ + nsresult res = NS_OK; + + nsAutoString stringNormalized; + if (strength != kCollationCaseSensitive) { + res = mCollation->NormalizeString(stringIn, stringNormalized); + if (NS_FAILED(res)) + return res; + } else { + stringNormalized = stringIn; + } + // convert unicode to charset + char *str; + + res = mCollation->UnicodeToChar(stringNormalized, &str); + if (NS_SUCCEEDED(res) && str) { + DoSetLocale(); + // call strxfrm to generate a key + size_t len = strxfrm(nullptr, str, 0) + 1; + void *buffer = PR_Malloc(len); + if (!buffer) { + res = NS_ERROR_OUT_OF_MEMORY; + } else if (strxfrm((char *)buffer, str, len) >= len) { + PR_Free(buffer); + res = NS_ERROR_FAILURE; + } else { + *key = (uint8_t *)buffer; + *outLen = len; + } + DoRestoreLocale(); + PR_Free(str); + } + + return res; +} + +nsresult nsCollationUnix::CompareRawSortKey(const uint8_t* key1, uint32_t len1, + const uint8_t* key2, uint32_t len2, + int32_t* result) +{ + *result = PL_strcmp((const char *)key1, (const char *)key2); + return NS_OK; +} diff --git a/intl/locale/unix/nsCollationUnix.h b/intl/locale/unix/nsCollationUnix.h new file mode 100644 index 000000000..dd2126b44 --- /dev/null +++ b/intl/locale/unix/nsCollationUnix.h @@ -0,0 +1,43 @@ + +/* -*- 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/. */ +#ifndef nsCollationUnix_h__ +#define nsCollationUnix_h__ + + +#include "nsICollation.h" +#include "nsCollation.h" // static library +#include "plstr.h" +#include "mozilla/Attributes.h" +#include "nsString.h" + + + +class nsCollationUnix final : public nsICollation { + +protected: + nsCollation *mCollation; + nsCString mLocale; + nsCString mSavedLocale; + bool mUseCodePointOrder; + + void DoSetLocale(); + void DoRestoreLocale(); + + ~nsCollationUnix(); + +public: + nsCollationUnix(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsICollation interface + NS_DECL_NSICOLLATION + +}; + +#endif /* nsCollationUnix_h__ */ diff --git a/intl/locale/unix/nsDateTimeFormatUnix.cpp b/intl/locale/unix/nsDateTimeFormatUnix.cpp new file mode 100644 index 000000000..a70b54102 --- /dev/null +++ b/intl/locale/unix/nsDateTimeFormatUnix.cpp @@ -0,0 +1,284 @@ +/* -*- 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 +#include "plstr.h" +#include "nsIServiceManager.h" +#include "nsDateTimeFormatUnix.h" +#include "nsIComponentManager.h" +#include "nsILocaleService.h" +#include "nsIPlatformCharset.h" +#include "nsPosixLocale.h" +#include "nsCRT.h" +#include "nsReadableUtils.h" +#include "nsUnicharUtils.h" +#include "mozilla/dom/EncodingUtils.h" + +using mozilla::dom::EncodingUtils; + +NS_IMPL_ISUPPORTS(nsDateTimeFormatUnix, nsIDateTimeFormat) + +// init this interface to a specified locale +nsresult nsDateTimeFormatUnix::Initialize(nsILocale* locale) +{ + nsAutoString localeStr; + NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_TIME##PLATFORM"); + nsresult res = NS_OK; + + // use cached info if match with stored locale + if (!locale) { + if (!mLocale.IsEmpty() && + mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) { + return NS_OK; + } + } + else { + res = locale->GetCategory(aCategory, localeStr); + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + if (!mLocale.IsEmpty() && + mLocale.Equals(localeStr, + nsCaseInsensitiveStringComparator())) { + return NS_OK; + } + } + } + + mCharset.AssignLiteral("windows-1252"); + mPlatformLocale.AssignLiteral("en_US"); + + // get locale name string, use app default if no locale specified + if (!locale) { + nsCOMPtr localeService = + do_GetService(NS_LOCALESERVICE_CONTRACTID, &res); + if (NS_SUCCEEDED(res)) { + nsCOMPtr appLocale; + res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); + if (NS_SUCCEEDED(res)) { + res = appLocale->GetCategory(aCategory, localeStr); + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + NS_ASSERTION(NS_SUCCEEDED(res), "failed to get app locale info"); + mAppLocale = localeStr; // cache app locale name + } + } + } + } + else { + res = locale->GetCategory(aCategory, localeStr); + NS_ASSERTION(NS_SUCCEEDED(res), "failed to get locale info"); + } + + if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { + mLocale = localeStr; // cache locale name + + nsPosixLocale::GetPlatformLocale(mLocale, mPlatformLocale); + + nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res); + if (NS_SUCCEEDED(res)) { + nsAutoCString mappedCharset; + res = platformCharset->GetDefaultCharsetForLocale(mLocale, mappedCharset); + if (NS_SUCCEEDED(res)) { + mCharset = mappedCharset; + } + } + } + + mDecoder = EncodingUtils::DecoderForEncoding(mCharset); + + LocalePreferred24hour(); + + return res; +} + +void nsDateTimeFormatUnix::LocalePreferred24hour() +{ + char str[100]; + time_t tt; + struct tm *tmc; + int i; + + tt = time(nullptr); + tmc = localtime(&tt); + + tmc->tm_hour=22; // put the test sample hour to 22:00 which is 10PM + tmc->tm_min=0; // set the min & sec other number than '2' + tmc->tm_sec=0; + + char *temp = setlocale(LC_TIME, mPlatformLocale.get()); + strftime(str, (size_t)99, "%X", (struct tm *)tmc); + + (void) setlocale(LC_TIME, temp); + + mLocalePreferred24hour = false; + for (i=0; str[i]; i++) { + if (str[i] == '2') { // if there is any '2', that locale use 0-23 time format + mLocalePreferred24hour = true; + break; + } + } + + mLocaleAMPMfirst = true; + if (mLocalePreferred24hour == false) { + if (str[0] && str[0] == '1') { // if the first character is '1' of 10:00, + // AMPM string is located after 10:00 + mLocaleAMPMfirst = false; + } + } +} + +nsresult nsDateTimeFormatUnix::FormatTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const time_t timetTime, + nsAString& stringOut) +{ + struct tm tmTime; + memcpy(&tmTime, localtime(&timetTime), sizeof(struct tm)); + return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut); +} + +// performs a locale sensitive date formatting operation on the struct tm parameter +nsresult nsDateTimeFormatUnix::FormatTMTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const struct tm* tmTime, + nsAString& stringOut) +{ +#define NSDATETIME_FORMAT_BUFFER_LEN 80 + char strOut[NSDATETIME_FORMAT_BUFFER_LEN*2]; // buffer for date and time + char fmtD[NSDATETIME_FORMAT_BUFFER_LEN], fmtT[NSDATETIME_FORMAT_BUFFER_LEN]; + nsresult rv; + + + // set up locale data + (void) Initialize(locale); + NS_ENSURE_TRUE(mDecoder, NS_ERROR_NOT_INITIALIZED); + + // set date format + if (dateFormatSelector == kDateFormatLong && timeFormatSelector == kTimeFormatSeconds) { + PL_strncpy(fmtD, "%c", NSDATETIME_FORMAT_BUFFER_LEN); + PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); + } else { + + switch (dateFormatSelector) { + case kDateFormatNone: + PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kDateFormatLong: + case kDateFormatShort: + PL_strncpy(fmtD, "%x", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kDateFormatYearMonth: + PL_strncpy(fmtD, "%Y/%m", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kDateFormatWeekday: + PL_strncpy(fmtD, "%a", NSDATETIME_FORMAT_BUFFER_LEN); + break; + default: + PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN); + } + + // set time format + switch (timeFormatSelector) { + case kTimeFormatNone: + PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kTimeFormatSeconds: + PL_strncpy(fmtT, "%X", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kTimeFormatNoSeconds: + PL_strncpy(fmtT, + mLocalePreferred24hour ? "%H:%M" : mLocaleAMPMfirst ? "%p %I:%M" : "%I:%M %p", + NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kTimeFormatSecondsForce24Hour: + PL_strncpy(fmtT, "%H:%M:%S", NSDATETIME_FORMAT_BUFFER_LEN); + break; + case kTimeFormatNoSecondsForce24Hour: + PL_strncpy(fmtT, "%H:%M", NSDATETIME_FORMAT_BUFFER_LEN); + break; + default: + PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); + } + } + + // generate data/time string + char *old_locale = setlocale(LC_TIME, nullptr); + (void) setlocale(LC_TIME, mPlatformLocale.get()); + if (strlen(fmtD) && strlen(fmtT)) { + PL_strncat(fmtD, " ", NSDATETIME_FORMAT_BUFFER_LEN); + PL_strncat(fmtD, fmtT, NSDATETIME_FORMAT_BUFFER_LEN); + strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, tmTime); + } + else if (strlen(fmtD) && !strlen(fmtT)) { + strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, tmTime); + } + else if (!strlen(fmtD) && strlen(fmtT)) { + strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtT, tmTime); + } + else { + PL_strncpy(strOut, "", NSDATETIME_FORMAT_BUFFER_LEN); + } + (void) setlocale(LC_TIME, old_locale); + + // convert result to unicode + int32_t srcLength = (int32_t) strlen(strOut); + int32_t unicharLength = NSDATETIME_FORMAT_BUFFER_LEN*2; + char16_t unichars[NSDATETIME_FORMAT_BUFFER_LEN*2]; // buffer for date and time + + rv = mDecoder->Convert(strOut, &srcLength, unichars, &unicharLength); + if (NS_FAILED(rv)) + return rv; + stringOut.Assign(unichars, unicharLength); + + return rv; +} + +// performs a locale sensitive date formatting operation on the PRTime parameter +nsresult nsDateTimeFormatUnix::FormatPRTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRTime prTime, + nsAString& stringOut) +{ + PRExplodedTime explodedTime; + PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime); + + return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut); +} + +// performs a locale sensitive date formatting operation on the PRExplodedTime parameter +nsresult nsDateTimeFormatUnix::FormatPRExplodedTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRExplodedTime* explodedTime, + nsAString& stringOut) +{ + struct tm tmTime; + /* be safe and set all members of struct tm to zero + * + * there are other fields in the tm struct that we aren't setting + * (tm_isdst, tm_gmtoff, tm_zone, should we set these?) and since + * tmTime is on the stack, it may be filled with garbage, but + * the garbage may vary. (this may explain why some saw bug #10412, and + * others did not. + * + * when tmTime is passed to strftime() with garbage bad things may happen. + * see bug #10412 + */ + memset( &tmTime, 0, sizeof(tmTime) ); + + tmTime.tm_yday = explodedTime->tm_yday; + tmTime.tm_wday = explodedTime->tm_wday; + tmTime.tm_year = explodedTime->tm_year; + tmTime.tm_year -= 1900; + tmTime.tm_mon = explodedTime->tm_month; + tmTime.tm_mday = explodedTime->tm_mday; + tmTime.tm_hour = explodedTime->tm_hour; + tmTime.tm_min = explodedTime->tm_min; + tmTime.tm_sec = explodedTime->tm_sec; + + return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut); +} + diff --git a/intl/locale/unix/nsDateTimeFormatUnix.h b/intl/locale/unix/nsDateTimeFormatUnix.h new file mode 100644 index 000000000..6c305556f --- /dev/null +++ b/intl/locale/unix/nsDateTimeFormatUnix.h @@ -0,0 +1,70 @@ + +/* -*- 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/. */ +#ifndef nsDateTimeFormatUnix_h__ +#define nsDateTimeFormatUnix_h__ + + +#include "nsCOMPtr.h" +#include "nsIDateTimeFormat.h" +#include "nsIUnicodeDecoder.h" + +#define kPlatformLocaleLength 64 + +class nsDateTimeFormatUnix : public nsIDateTimeFormat { + +public: + NS_DECL_THREADSAFE_ISUPPORTS + + // performs a locale sensitive date formatting operation on the time_t parameter + NS_IMETHOD FormatTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const time_t timetTime, + nsAString& stringOut) override; + + // performs a locale sensitive date formatting operation on the struct tm parameter + NS_IMETHOD FormatTMTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const struct tm* tmTime, + nsAString& stringOut) override; + + // performs a locale sensitive date formatting operation on the PRTime parameter + NS_IMETHOD FormatPRTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRTime prTime, + nsAString& stringOut) override; + + // performs a locale sensitive date formatting operation on the PRExplodedTime parameter + NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, + const nsDateFormatSelector dateFormatSelector, + const nsTimeFormatSelector timeFormatSelector, + const PRExplodedTime* explodedTime, + nsAString& stringOut) override; + + + nsDateTimeFormatUnix() {mLocale.Truncate();mAppLocale.Truncate();} + +private: + virtual ~nsDateTimeFormatUnix() {} + + // init this interface to a specified locale + NS_IMETHOD Initialize(nsILocale* locale); + + void LocalePreferred24hour(); + + nsString mLocale; + nsString mAppLocale; + nsCString mCharset; // in order to convert API result to unicode + nsCString mPlatformLocale; // for setlocale + bool mLocalePreferred24hour; // true if 24 hour format is preferred by current locale + bool mLocaleAMPMfirst; // true if AM/PM string is preferred before the time + nsCOMPtr mDecoder; +}; + +#endif /* nsDateTimeFormatUnix_h__ */ diff --git a/intl/locale/unix/nsPosixLocale.cpp b/intl/locale/unix/nsPosixLocale.cpp new file mode 100644 index 000000000..16299afed --- /dev/null +++ b/intl/locale/unix/nsPosixLocale.cpp @@ -0,0 +1,243 @@ +/* -*- 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 "mozilla/Sprintf.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) { + SprintfLiteral(posix_locale,"%s_%s.%s",lang_code,country_code,extra); + } + else { + SprintfLiteral(posix_locale,"%s_%s",lang_code,country_code); + } + } + else { + if (*extra) { + SprintfLiteral(posix_locale,"%s.%s",lang_code,extra); + } + else { + SprintfLiteral(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 (strcmp(posixLocale,"C.UTF-8")==0) { + locale.AssignLiteral("en-US.UTF-8"); + 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) { + SprintfLiteral(posix_locale,"%s-%s",lang_code,country_code); + } + else { + SprintfLiteral(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); +} + diff --git a/intl/locale/unix/nsUNIXCharset.cpp b/intl/locale/unix/nsUNIXCharset.cpp new file mode 100644 index 000000000..d72305e55 --- /dev/null +++ b/intl/locale/unix/nsUNIXCharset.cpp @@ -0,0 +1,185 @@ +/* -*- 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 + +#include "mozilla/ArrayUtils.h" + +#include "nsIPlatformCharset.h" +#include "nsUConvPropertySearch.h" +#include "nsCOMPtr.h" +#include "nsReadableUtils.h" +#include "nsEncoderDecoderUtils.h" +#if HAVE_GNU_LIBC_VERSION_H +#include +#endif +#ifdef HAVE_NL_TYPES_H +#include +#endif +#if HAVE_LANGINFO_CODESET +#include +#endif +#include "nsPlatformCharset.h" +#include "prinit.h" +#include "nsUnicharUtils.h" +#include "mozilla/dom/EncodingUtils.h" + +using mozilla::dom::EncodingUtils; +using namespace mozilla; + +static const nsUConvProp kUnixCharsets[] = { +#include "unixcharset.properties.h" +}; + +NS_IMPL_ISUPPORTS(nsPlatformCharset, nsIPlatformCharset) + +nsPlatformCharset::nsPlatformCharset() +{ +} + +static nsresult +ConvertLocaleToCharsetUsingDeprecatedConfig(const nsACString& locale, + nsACString& oResult) +{ + if (!(locale.IsEmpty())) { + if (NS_SUCCEEDED(nsUConvPropertySearch::SearchPropertyValue(kUnixCharsets, + ArrayLength(kUnixCharsets), locale, oResult))) { + return NS_OK; + } + } + NS_ERROR("unable to convert locale to charset using deprecated config"); + oResult.AssignLiteral("ISO-8859-1"); + return NS_SUCCESS_USING_FALLBACK_LOCALE; +} + +nsPlatformCharset::~nsPlatformCharset() +{ +} + +NS_IMETHODIMP +nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsACString& oResult) +{ + oResult = mCharset; + return NS_OK; +} + +NS_IMETHODIMP +nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACString &oResult) +{ + // + // if this locale is the user's locale then use the charset + // we already determined at initialization + // + if (mLocale.Equals(localeName) || + // support the 4.x behavior + (mLocale.LowerCaseEqualsLiteral("en_us") && + localeName.LowerCaseEqualsLiteral("c"))) { + oResult = mCharset; + return NS_OK; + } + +#if HAVE_LANGINFO_CODESET + // + // This locale appears to be a different locale from the user's locale. + // To do this we would need to lock the global resource we are currently + // using or use a library that provides multi locale support. + // ICU is a possible example of a multi locale library. + // http://oss.software.ibm.com/icu/ + // + // A more common cause of hitting this warning than the above is that + // Mozilla is launched under an ll_CC.UTF-8 locale. In xpLocale, + // we only store the language and the region (ll-CC) losing 'UTF-8', which + // leads |mLocale| to be different from |localeName|. Although we lose + // 'UTF-8', we init'd |mCharset| with the value obtained via + // |nl_langinfo(CODESET)| so that we're all right here. + // + NS_WARNING("GetDefaultCharsetForLocale: need to add multi locale support"); +#ifdef DEBUG_jungshik + printf("localeName=%s mCharset=%s\n", NS_ConvertUTF16toUTF8(localeName).get(), + mCharset.get()); +#endif + // until we add multi locale support: use the the charset of the user's locale + oResult = mCharset; + return NS_SUCCESS_USING_FALLBACK_LOCALE; +#else + // + // convert from locale to charset + // using the deprecated locale to charset mapping + // + NS_LossyConvertUTF16toASCII localeStr(localeName); + return ConvertLocaleToCharsetUsingDeprecatedConfig(localeStr, oResult); +#endif +} + +nsresult +nsPlatformCharset::InitGetCharset(nsACString &oString) +{ +#if HAVE_LANGINFO_CODESET + char* nl_langinfo_codeset = nullptr; + nsCString aCharset; + nsresult res; + + nl_langinfo_codeset = nl_langinfo(CODESET); + NS_ASSERTION(nl_langinfo_codeset, "cannot get nl_langinfo(CODESET)"); + + // + // see if we can use nl_langinfo(CODESET) directly + // + if (nl_langinfo_codeset) { + aCharset.Assign(nl_langinfo_codeset); + res = VerifyCharset(aCharset); + if (NS_SUCCEEDED(res)) { + oString = aCharset; + return res; + } + } + + NS_ERROR("unable to use nl_langinfo(CODESET)"); +#endif + + // + // try falling back on a deprecated (locale based) name + // + char* locale = setlocale(LC_CTYPE, nullptr); + nsAutoCString localeStr; + localeStr.Assign(locale); + return ConvertLocaleToCharsetUsingDeprecatedConfig(localeStr, oString); +} + +NS_IMETHODIMP +nsPlatformCharset::Init() +{ + // + // remember default locale so we can use the + // same charset when asked for the same locale + // + char* locale = setlocale(LC_CTYPE, nullptr); + NS_ASSERTION(locale, "cannot setlocale"); + if (locale) { + CopyASCIItoUTF16(locale, mLocale); + } else { + mLocale.AssignLiteral("en_US"); + } + + // InitGetCharset only returns NS_OK or NS_SUCESS_USING_FALLBACK_LOCALE + return InitGetCharset(mCharset); +} + +nsresult +nsPlatformCharset::VerifyCharset(nsCString &aCharset) +{ + // fast path for UTF-8. Most platform uses UTF-8 as charset now. + if (aCharset.EqualsLiteral("UTF-8")) { + return NS_OK; + } + + nsAutoCString encoding; + if (!EncodingUtils::FindEncodingForLabelNoReplacement(aCharset, encoding)) { + return NS_ERROR_UCONV_NOCONV; + } + + aCharset.Assign(encoding); + return NS_OK; +} diff --git a/intl/locale/unix/unixcharset.properties b/intl/locale/unix/unixcharset.properties new file mode 100644 index 000000000..1376b49d6 --- /dev/null +++ b/intl/locale/unix/unixcharset.properties @@ -0,0 +1,536 @@ +# 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/. + +## +## NOTE: THIS FILE IS DEPRECATED +## except for those *nix systems that do not support +## nl_langinfo(CODESET) this file should not be used +## +## All platform section +## Put the general locale to charset mapping here. +## If somehow two platform use the same locale name with different +## charset, put the least common one in the platform specific section +## This section have lower priority than the platform specific section +## +## The key is the locale name +# AIX +ar_AA=ISO-8859-6 +# Solaris +Ar_ARM=ISO-8859-6 +american.iso88591=ISO-8859-1 +bulgarian=ISO-8859-2 +bg_BG.ISO8859-5=ISO-8859-5 +# AIX +bg_BG=ISO-8859-5 +C=ISO-8859-1 +# HP +C.iso885915=ISO-8859-15 +c-french.iso88591=ISO-8859-1 +chinese=gb18030 +chinese-s=gb18030 +chinese-t.big5=Big5 +cs=ISO-8859-2 +cs_CZ=ISO-8859-2 +cs_CZ.ISO8859-2=ISO-8859-2 +cs_CZ.88592=ISO-8859-2 +czech=ISO-8859-2 +da=ISO-8859-1 +# Solaris +da.ISO8859-15=ISO-8859-15 +da_DK.ISO8859-15=ISO-8859-15 +da_DK.ISO8859-15@euro=ISO-8859-15 +# Solaris +da.ISO8859-15@euro=ISO-8859-15 +da_DK.88591=ISO-8859-1 +# HP +da_DK.iso885915@euro=ISO-8859-15 +da_DK.ISO8859-1=ISO-8859-1 +da_DK=ISO-8859-1 +# AIX +#Da_DK=IBM-850 +danish.iso88591=ISO-8859-1 +dutch.iso88591=ISO-8859-1 +de=ISO-8859-1 +# Solaris +de.ISO8859-15=ISO-8859-15 +# Solaris +de.ISO8859-15@euro=ISO-8859-15 +# Solaris +de.UTF-8=UTF-8 +# Solaris +de.UTF-8@euro=UTF-8 +de_AT=ISO-8859-1 +# Solaris +de_AT.ISO8859-15=ISO-8859-15 +# Solaris +de_AT.ISO8859-15@euro=ISO-8859-15 +de_CH=ISO-8859-1 +de_CH.88591=ISO-8859-1 +de_CH.ISO8859-1=ISO-8859-1 +de_DE.ISO8859-15=ISO-8859-15 +de_DE.ISO8859-15@euro=ISO-8859-15 +# AIX +#De_CH=IBM-850 +de_DE=ISO-8859-1 +de_DE.88591=ISO-8859-1 +# HP +de_DE.iso885915=ISO-8859-15 +# HP +de_DE.iso885915@euro=ISO-8859-15 +de_DE.ISO8859-1=ISO-8859-1 +# AIX +#De_DE=IBM-850 +# Solaris +el_GR.ISO8859-7=ISO-8859-7 +el_GR.ISO8859-7@euro=ISO-8859-7 +en_AU.ISO8859-1=ISO-8859-1 +en_CA.ISO8859-1=ISO-8859-1 +# AIX +el_GR=ISO-8859-7 +en=ISO-8859-1 +en_AU=ISO-8859-1 +en_CA=ISO-8859-1 +en_GB=ISO-8859-1 +# Solaris +en_GB.ISO8859-15=ISO-8859-15 +# Solaris +en_GB.ISO8859-15@euro=ISO-8859-15 +en_GB.88591=ISO-8859-1 +en_GB.ISO8859-1=ISO-8859-1 +# HP +en_GB.iso885915@euro=ISO-8859-15 +# AIX +#En_GB=IBM-850 +# Solaris +en_IE.ISO8859-1=ISO-8859-1 +en_IE.ISO8859-15=ISO-8859-15 +# Solaris +en_IE.ISO8859-15@euro=ISO-8859-15 +en_JP=EUC-JP +en_JP.IBM-eucJP=EUC-JP +En_JP.IBM-932=Shift_JIS +En_JP=Shift_JIS +en_KR=EUC-KR +en_KR.IBM-eucKR=EUC-KR +en_TH=ISO-8859-1 +en_US=ISO-8859-1 +en_US.88591=ISO-8859-1 +en_US.ISO8859-1=ISO-8859-1 +#FreeBSD +en_US.ISO_8859-1=ISO-8859-1 +da_DK.ISO_8859-1=ISO-8859-1 +de_AT.ISO_8859-1=ISO-8859-1 +de_CH.ISO_8859-1=ISO-8859-1 +de_DE.ISO_8859-1=ISO-8859-1 +en_AU.ISO_8859-1=ISO-8859-1 +en_CA.ISO_8859-1=ISO-8859-1 +en_GB.ISO_8859-1=ISO-8859-1 +es_ES.ISO_8859-1=ISO-8859-1 +fi_FI.ISO_8859-1=ISO-8859-1 +fr_BE.ISO_8859-1=ISO-8859-1 +fr_CA.ISO_8859-1=ISO-8859-1 +fr_CH.ISO_8859-1=ISO-8859-1 +fr_FR.ISO_8859-1=ISO-8859-1 +is_IS.ISO_8859-1=ISO-8859-1 +it_CH.ISO_8859-1=ISO-8859-1 +it_IT.ISO_8859-1=ISO-8859-1 +la_LN.ISO_8859-1=ISO-8859-1 +nl_BE.ISO_8859-1=ISO-8859-1 +nl_NL.ISO_8859-1=ISO-8859-1 +no_NO.ISO_8859-1=ISO-8859-1 +pt_PT.ISO_8859-1=ISO-8859-1 +sv_SE.ISO_8859-1=ISO-8859-1 +# FreeBSD 8859-15 +da_DK.DIS_8859-15=ISO-8859-15 +de_AT.DIS_8859-15=ISO-8859-15 +de_CH.DIS_8859-15=ISO-8859-15 +de_DE.DIS_8859-15=ISO-8859-15 +en_AU.DIS_8859-15=ISO-8859-15 +en_CA.DIS_8859-15=ISO-8859-15 +en_GB.DIS_8859-15=ISO-8859-15 +en_US.DIS_8859-15=ISO-8859-15 +es_ES.DIS_8859-15=ISO-8859-15 +fi_FI.DIS_8859-15=ISO-8859-15 +fr_BE.DIS_8859-15=ISO-8859-15 +fr_CA.DIS_8859-15=ISO-8859-15 +fr_CH.DIS_8859-15=ISO-8859-15 +fr_FR.DIS_8859-15=ISO-8859-15 +is_IS.DIS_8859-15=ISO-8859-15 +it_CH.DIS_8859-15=ISO-8859-15 +it_IT.DIS_8859-15=ISO-8859-15 +la_LN.DIS_8859-15=ISO-8859-15 +nl_BE.DIS_8859-15=ISO-8859-15 +nl_NL.DIS_8859-15=ISO-8859-15 +no_NO.DIS_8859-15=ISO-8859-15 +pt_PT.DIS_8859-15=ISO-8859-15 +sv_SE.DIS_8859-15=ISO-8859-15 +# FreeBSD 8859-2 +cs_CZ.ISO_8859-2=ISO-8859-2 +hr_HR.ISO_8859-2=ISO-8859-2 +hu_HU.ISO_8859-2=ISO-8859-2 +la_LN.ISO_8859-2=ISO-8859-2 +pl_PL.ISO_8859-2=ISO-8859-2 +sl_SI.ISO_8859-2=ISO-8859-2 +# FreeBSD 8859-4 +la_LN.ISO_8859-4=ISO-8859-4 +lt_LT.ISO_8859-4=ISO-8859-4 +# FreeBSD 8859-5 +ru_RU.ISO_8859-5=ISO-8859-5 +ru_SU.ISO_8859-5=ISO-8859-5 +# FreeBSD Russian +ru_SU.KOI8-R=KOI8-R +# FreeBSD Ukrainian +uk_UA.KOI8-U=KOI8-U +# Solaris +en_US.UTF-8=UTF-8 +# Solaris +en_US.UTF-8@euro=UTF-8 +# AIX +#En_US=IBM-850 +english.iso88591=ISO-8859-1 +es=ISO-8859-1 +# Solaris +es.ISO8859-15=ISO-8859-15 +# Solaris +es.ISO8859-15@euro=ISO-8859-15 +# Solaris +es.UTF-8=UTF-8 +# Solaris +es.UTF-8@euro=UTF-8 +es_ES=ISO-8859-1 +es_ES.ISO8859-15=ISO-8859-15 +es_ES.ISO8859-15@euro=ISO-8859-15 +es_AR.ISO8859-1=ISO-8859-1 +es_BO.ISO8859-1=ISO-8859-1 +es_CL.ISO8859-1=ISO-8859-1 +es_CO.ISO8859-1=ISO-8859-1 +es_CR.ISO8859-1=ISO-8859-1 +es_EC.ISO8859-1=ISO-8859-1 +es_GT.ISO8859-1=ISO-8859-1 +es_MX.ISO8859-1=ISO-8859-1 +es_NI.ISO8859-1=ISO-8859-1 +es_PA.ISO8859-1=ISO-8859-1 +es_PE.ISO8859-1=ISO-8859-1 +es_PY.ISO8859-1=ISO-8859-1 +es_SV.ISO8859-1=ISO-8859-1 +es_UY.ISO8859-1=ISO-8859-1 +es_VE.ISO8859-1=ISO-8859-1 +# HP +es_ES.iso885915=ISO-8859-15 +# HP +es_ES.iso885915@euro=ISO-8859-15 +es_ES.88591=ISO-8859-1 +es_ES.ISO8859-1=ISO-8859-1 +# AIX +#En_ES=IBM-850 +# Solaris +et_EE.ISO8859-15=ISO-8859-15 +# AIX +#Et_ET=IBM-922 +# AIX +ET_ET=UTF-8 +fi=ISO-8859-1 +# Solaris +fi.ISO8859-15=ISO-8859-15 +# Solaris +fi.ISO8859-15@euro=ISO-8859-15 +fi_FI=ISO-8859-1 +fi_FI.88591=ISO-8859-1 +fi_FI.ISO8859-1=ISO-8859-1 +fi_FI.ISO8859-15=ISO-8859-15 +fi_FI.ISO8859-15@euro=ISO-8859-15 +# HP +fi_FI.iso885915@euro=ISO-8859-15 +# AIX +#Fi_ES=IBM-850 +finnish.iso88591=ISO-8859-1 +fr=ISO-8859-1 +# Solaris +fr.ISO8859-15=ISO-8859-15 +# Solaris +fr.ISO8859-15@euro=ISO-8859-15 +# Solaris +fr.UTF-8=UTF-8 +# Solaris +fr.UTF-8@euro=UTF-8 +fr_BE=ISO-8859-1 +# Solaris +fr_BE.ISO8859-15=ISO-8859-15 +# Solaris +fr_BE.ISO8859-15@euro=ISO-8859-15 +fr_BE.88591=ISO-8859-1 +fr_BE.ISO8859-1=ISO-8859-1 +fr_BE.iso8859=ISO-8859-1 +# AIX +#Fr_BE=IBM-850 +fr_CA=ISO-8859-1 +fr_CA.88591=ISO-8859-1 +fr_CA.iso8859=ISO-8859-1 +# HP +fr_CA.iso885915@euro=ISO-8859-15 +fr_CA.ISO8859-1=ISO-8859-1 +# AIX +#Fr_CA=IBM-850 +fr_CH=ISO-8859-1 +fr_CH.88591=ISO-8859-1 +fr_CH.iso8859=ISO-8859-1 +fr_CH.ISO8859-1=ISO-8859-1 +# Solaris +fr_FR.ISO8859-15=ISO-8859-15 +fr_FR.ISO8859-15@euro=ISO-8859-15 +# AIX +#Fr_CH=IBM-850 +fr_FR=ISO-8859-1 +fr_FR.88591=ISO-8859-1 +fr_FR.iso8859=ISO-8859-1 +# HP +fr_FR.iso885915=ISO-8859-15 +# HP +fr_FR.iso885915@euro=ISO-8859-15 +fr_FR.ISO8859-1=ISO-8859-1 +# AIX +#Fr_FR=IBM-850 +french.iso88591=ISO-8859-1 +german.iso88591=ISO-8859-1 +# Solaris +he_HE=ISO-8859-8 +he_IL=ISO-8859-8 +hr_HR.ISO8859-2=ISO-8859-2 +# AIX +hr_HR=ISO-8859-2 +hu_HU=ISO-8859-2 +hu_HU.88592=ISO-8859-2 +hu_HU.ISO8859-2=ISO-8859-2 +hungarian=ISO-8859-2 +icelandic.iso88591=ISO-8859-1 +iso_8859_1=ISO-8859-1 +is=ISO-8859-1 +is_IS=ISO-8859-1 +is_IS.88591=ISO-8859-1 +is_IS.ISO8859-1=ISO-8859-1 +# HP +is_IS.iso885915@euro=ISO-8859-15 +# AIX +#Is_IS=IBM-850 +it=ISO-8859-1 +# Solaris +it.ISO8859-15=ISO-8859-15 +# Solaris +it.ISO8859-15@euro=ISO-8859-15 +# Solaris +it.UTF-8=UTF-8 +# Solaris +it.UTF-8@euro=UTF-8 +it_IT.ISO8859-15=ISO-8859-15 +it_IT.ISO8859-15@euro=ISO-8859-15 +# AIX +#It_IT=IBM-850 +italian.iso8859-1=ISO-8859-1 +it_CH=ISO-8859-1 +it_IT=ISO-8859-1 +it_IT.88591=ISO-8859-1 +it_IT.ISO8859-1=ISO-8859-1 +# HP +it_IT.iso885915=ISO-8859-15 +# HP +it_IT.iso885915@euro=ISO-8859-15 +# AIX +iw_IL=ISO-8859-8 +# AIX +#Iw_IL=IBM-856 +ja=EUC-JP +Ja_JP.IBM-932=Shift_JIS +Ja_JP=Shift_JIS +japanese=EUC-JP +japanese.euc=EUC-JP +ja_JP=EUC-JP +# Solaris +ja_JP.UTF-8=UTF-8 +# Solaris +ja_JP.UTF-8@euro=UTF-8 +ja_JP.EUC=EUC-JP +ja_JP.eucJP=EUC-JP +ja_JP.SJIS=Shift_JIS +ja_JP.PCK=Shift_JIS +ja_JP.IBM-eucJP=EUC-JP +ja_JP.mscode=Shift_JIS +ja_JP.ujis=EUC-JP +katakana=Shift_JIS +ko=EUC-KR +ko_KR=EUC-KR +# Solaris +ko_KR.UTF-8=UTF-8 +# Solaris +ko_KR.UTF-8@euro=UTF-8 +ko_KR.euc=EUC-KR +ko_KR.euckr=EUC-KR +ko_KR.eucKR=EUC-KR +ko_KR.IBM-eucKR=EUC-KR +ko_KR.EUC=EUC-KR +ko.UTF-8=UTF-8 +korean=EUC-KR +# Solaris +lt_LT.ISO8859-13=ISO-8859-13 +# AIX +#Lt_LT=IBM-921 +# AIX +LT_LT=UTF-8 +# Solaris +lv_LV.ISO8859-13=ISO-8859-13 +# AIX +#Lt_LV=IBM-921 +# AIX +LT_LV=UTF-8 +# Solaris +mk_MK.ISO8859-5=ISO-8859-5 +# AIX +mk_MK=ISO-8859-5 +nl=ISO-8859-1 +# Solaris +nl.ISO8859-15=ISO-8859-15 +# Solaris +nl.ISO8859-15@euro=ISO-8859-15 +nl_BE=ISO-8859-1 +# Solaris +nl_BE.ISO8859-15=ISO-8859-15 +# Solaris +nl_BE.ISO8859-15@euro=ISO-8859-15 +nl_BE.88591=ISO-8859-1 +nl_BE.ISO8859-1=ISO-8859-1 +# Solaris +nl_NL.ISO8859-15=ISO-8859-15 +nl_NL.ISO8859-15@euro=ISO-8859-15 +# AIX +#NL_BE=IBM-850 +nl_NL=ISO-8859-1 +nl_NL.88591=ISO-8859-1 +nl_NL.ISO8859-1=ISO-8859-1 +# HP +nl_NL.iso885915@euro=ISO-8859-15 +# AIX +#NL_NL=IBM-850 +no=ISO-8859-1 +no_NO=ISO-8859-1 +no_NO.88591=ISO-8859-1 +no_NO.ISO8859-1=ISO-8859-1 +# Solaris +no_NO.ISO8859-1@bokmal=ISO-8859-1 +no_NO.ISO8859-1@nynorsk=ISO-8859-1 +# HP +no_NO.iso885915@euro=ISO-8859-15 +# AIX +#No_NO=IBM-850 +norwegian.iso88591=ISO-8859-1 +pl=ISO-8859-2 +pl_PL=ISO-8859-2 +pl_PL.88592=ISO-8859-2 +pl_PL.ISO8859-2=ISO-8859-2 +polish=ISO-8859-2 +portuguese.iso88591=ISO-8859-1 +pt=ISO-8859-1 +# Solaris +pt.ISO8859-15=ISO-8859-15 +# Solaris +pt.ISO8859-15@euro=ISO-8859-15 +# Solaris +pt_BR.ISO8859-1=ISO-8859-1 +pt_PT.ISO8859-15=ISO-8859-15 +pt_PT.ISO8859-15@euro=ISO-8859-15 +# AIX +#Pt.PT=IBM-850 +pt_PT=ISO-8859-1 +pt_PT.88591=ISO-8859-1 +# HP +pt_PT.iso885915@euro=ISO-8859-15 +pt_PT.ISO8859-1=ISO-8859-1 +# Solaris +ro_RO.ISO8859-2=ISO-8859-2 +# AIX +ro_RO=ISO-8859-5 +# Solaris +#ru_RU.ANSI1251= ??? ANSI-1251 ??? +ru_RU.ISO8859-5=ISO-8859-5 +# AIX +ru_RU=ISO-8859-5 +ru_RU.KOI8-R=KOI8-R +# RedHat 7 reported by Garaschenko Slava