intl/locale/src/unix/nsPosixLocale.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nscore.h"
     7 #include "nsString.h"
     8 #include "nsPosixLocale.h"
     9 #include "prprf.h"
    10 #include "plstr.h"
    11 #include "nsReadableUtils.h"
    13 static bool
    14 ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator);
    16 nsresult 
    17 nsPosixLocale::GetPlatformLocale(const nsAString& locale, nsACString& posixLocale)
    18 {
    19   char  country_code[MAX_COUNTRY_CODE_LEN+1];
    20   char  lang_code[MAX_LANGUAGE_CODE_LEN+1];
    21   char  extra[MAX_EXTRA_LEN+1];
    22   char  posix_locale[MAX_LOCALE_LEN+1];
    23   NS_LossyConvertUTF16toASCII xp_locale(locale);
    25   if (!xp_locale.IsEmpty()) {
    26     if (!ParseLocaleString(xp_locale.get(),lang_code,country_code,extra,'-')) {
    27 //      strncpy(posixLocale,"C",length);
    28       posixLocale = xp_locale;  // use xp locale if parse failed
    29       return NS_OK;
    30     }
    32     if (*country_code) {
    33       if (*extra) {
    34         PR_snprintf(posix_locale,sizeof(posix_locale),"%s_%s.%s",lang_code,country_code,extra);
    35       }
    36       else {
    37         PR_snprintf(posix_locale,sizeof(posix_locale),"%s_%s",lang_code,country_code);
    38       }
    39     }
    40     else {
    41       if (*extra) {
    42         PR_snprintf(posix_locale,sizeof(posix_locale),"%s.%s",lang_code,extra);
    43       }
    44       else {
    45         PR_snprintf(posix_locale,sizeof(posix_locale),"%s",lang_code);
    46       }
    47     }
    49     posixLocale = posix_locale;
    50     return NS_OK;
    51   }
    53   return NS_ERROR_FAILURE;
    54 }
    56 nsresult
    57 nsPosixLocale::GetXPLocale(const char* posixLocale, nsAString& locale)
    58 {
    59   char  country_code[MAX_COUNTRY_CODE_LEN+1];
    60   char  lang_code[MAX_LANGUAGE_CODE_LEN+1];
    61   char  extra[MAX_EXTRA_LEN+1];
    62   char  posix_locale[MAX_LOCALE_LEN+1];
    64   if (posixLocale!=nullptr) {
    65     if (strcmp(posixLocale,"C")==0 || strcmp(posixLocale,"POSIX")==0) {
    66       locale.AssignLiteral("en-US");
    67       return NS_OK;
    68     }
    69     if (!ParseLocaleString(posixLocale,lang_code,country_code,extra,'_')) {
    70 //      * locale = "x-user-defined";
    71       // use posix if parse failed
    72       CopyASCIItoUTF16(nsDependentCString(posixLocale), locale);
    73       return NS_OK;
    74     }
    76     // Special case: substitute "nb" (Norwegian Bokmal) for macrolanguage
    77     // code "no" (Norwegian)
    78     if (nsDependentCString(lang_code).LowerCaseEqualsLiteral("no")) {
    79       lang_code[1] = 'b';
    80     }
    82     if (*country_code) {
    83       PR_snprintf(posix_locale,sizeof(posix_locale),"%s-%s",lang_code,country_code);
    84     } 
    85     else {
    86       PR_snprintf(posix_locale,sizeof(posix_locale),"%s",lang_code);
    87     }
    89     CopyASCIItoUTF16(nsDependentCString(posix_locale), locale);
    90     return NS_OK;
    92   }
    94     return NS_ERROR_FAILURE;
    96 }
    98 //
    99 // returns false/true depending on if it was of the form LL-CC.Extra
   100 static bool
   101 ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator)
   102 {
   103   const char *src = locale_string;
   104   char modifier[MAX_EXTRA_LEN+1];
   105   char *dest;
   106   int dest_space, len;
   108   *language = '\0';
   109   *country = '\0';
   110   *extra = '\0';
   111   if (strlen(locale_string) < 2) {
   112     return(false);
   113   }
   115   //
   116   // parse the language part
   117   //
   118   dest = language;
   119   dest_space = MAX_LANGUAGE_CODE_LEN;
   120   while ((*src) && (isalpha(*src)) && (dest_space--)) {
   121     *dest++ = tolower(*src++);
   122   }
   123   *dest = '\0';
   124   len = dest - language;
   125   if ((len != 2) && (len != 3)) {
   126     NS_ASSERTION((len == 2) || (len == 3), "language code too short");
   127     NS_ASSERTION(len < 3, "reminder: verify we can handle 3+ character language code in all parts of the system; eg: language packs");
   128     *language = '\0';
   129     return(false);
   130   }
   132   // check if all done
   133   if (*src == '\0') {
   134     return(true);
   135   }
   137   if ((*src != '_') && (*src != '-') && (*src != '.') && (*src != '@')) {
   138     NS_ASSERTION(isalpha(*src), "language code too long");
   139     NS_ASSERTION(!isalpha(*src), "unexpected language/country separator");
   140     *language = '\0';
   141     return(false);
   142   }
   144   //
   145   // parse the country part
   146   //
   147   if ((*src == '_') || (*src == '-')) { 
   148     src++;
   149     dest = country;
   150     dest_space = MAX_COUNTRY_CODE_LEN;
   151     while ((*src) && (isalpha(*src)) && (dest_space--)) {
   152       *dest++ = toupper(*src++);
   153     }
   154     *dest = '\0';
   155     len = dest - country;
   156     if (len != 2) {
   157       NS_ASSERTION(len == 2, "unexpected country code length");
   158       *language = '\0';
   159       *country = '\0';
   160       return(false);
   161     }
   162   }
   164   // check if all done
   165   if (*src == '\0') {
   166     return(true);
   167   }
   169   if ((*src != '.') && (*src != '@')) {
   170     NS_ASSERTION(isalpha(*src), "country code too long");
   171     NS_ASSERTION(!isalpha(*src), "unexpected country/extra separator");
   172     *language = '\0';
   173     *country = '\0';
   174     return(false);
   175   }
   177   //
   178   // handle the extra part
   179   //
   180   if (*src == '.') { 
   181     src++;  // move past the extra part separator
   182     dest = extra;
   183     dest_space = MAX_EXTRA_LEN;
   184     while ((*src) && (*src != '@') && (dest_space--)) {
   185       *dest++ = *src++;
   186     }
   187     *dest = '\0';
   188     len = dest - extra;
   189     if (len < 1) {
   190       NS_ASSERTION(len > 0, "found country/extra separator but no extra code");
   191       *language = '\0';
   192       *country = '\0';
   193       *extra = '\0';
   194       return(false);
   195     }
   196   }
   198   // check if all done
   199   if (*src == '\0') {
   200     return(true);
   201   }
   203   //
   204   // handle the modifier part
   205   //
   207   if (*src == '@') { 
   208     src++;  // move past the modifier separator
   209     NS_ASSERTION(strcmp("euro",src) == 0, "found non euro modifier");
   210     dest = modifier;
   211     dest_space = MAX_EXTRA_LEN;
   212     while ((*src) && (dest_space--)) {
   213       *dest++ = *src++;
   214     }
   215     *dest = '\0';
   216     len = dest - modifier;
   217     if (len < 1) {
   218       NS_ASSERTION(len > 0, "found modifier separator but no modifier code");
   219       *language = '\0';
   220       *country = '\0';
   221       *extra = '\0';
   222       *modifier = '\0';
   223       return(false);
   224     }
   225   }
   227   // check if all done
   228   if (*src == '\0') {
   229     return(true);
   230   }
   232   NS_ASSERTION(*src == '\0', "extra/modifier code too long");
   233   *language = '\0';
   234   *country = '\0';
   235   *extra = '\0';
   237   return(false);
   238 }

mercurial