Home | History | Annotate | Line # | Download | only in intl
      1 /* Determine the current selected locale.
      2    Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc.
      3 
      4    This program is free software; you can redistribute it and/or modify it
      5    under the terms of the GNU Library General Public License as published
      6    by the Free Software Foundation; either version 2, or (at your option)
      7    any later version.
      8 
      9    This program is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12    Library General Public License for more details.
     13 
     14    You should have received a copy of the GNU Library General Public
     15    License along with this program; if not, write to the Free Software
     16    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
     17    USA.  */
     18 
     19 /* Written by Ulrich Drepper <drepper (at) gnu.org>, 1995.  */
     20 /* Win32 code written by Tor Lillqvist <tml (at) iki.fi>.  */
     21 
     22 #ifdef HAVE_CONFIG_H
     23 # include <config.h>
     24 #endif
     25 
     26 #include <stdlib.h>
     27 #include <locale.h>
     28 
     29 #if defined _WIN32 || defined __WIN32__
     30 # undef WIN32   /* avoid warning on mingw32 */
     31 # define WIN32
     32 #endif
     33 
     34 #ifdef WIN32
     35 # define WIN32_LEAN_AND_MEAN
     36 # include <windows.h>
     37 /* Mingw headers don't have latest language and sublanguage codes.  */
     38 # ifndef LANG_AFRIKAANS
     39 # define LANG_AFRIKAANS 0x36
     40 # endif
     41 # ifndef LANG_ALBANIAN
     42 # define LANG_ALBANIAN 0x1c
     43 # endif
     44 # ifndef LANG_ARABIC
     45 # define LANG_ARABIC 0x01
     46 # endif
     47 # ifndef LANG_ARMENIAN
     48 # define LANG_ARMENIAN 0x2b
     49 # endif
     50 # ifndef LANG_ASSAMESE
     51 # define LANG_ASSAMESE 0x4d
     52 # endif
     53 # ifndef LANG_AZERI
     54 # define LANG_AZERI 0x2c
     55 # endif
     56 # ifndef LANG_BASQUE
     57 # define LANG_BASQUE 0x2d
     58 # endif
     59 # ifndef LANG_BELARUSIAN
     60 # define LANG_BELARUSIAN 0x23
     61 # endif
     62 # ifndef LANG_BENGALI
     63 # define LANG_BENGALI 0x45
     64 # endif
     65 # ifndef LANG_CATALAN
     66 # define LANG_CATALAN 0x03
     67 # endif
     68 # ifndef LANG_DIVEHI
     69 # define LANG_DIVEHI 0x65
     70 # endif
     71 # ifndef LANG_ESTONIAN
     72 # define LANG_ESTONIAN 0x25
     73 # endif
     74 # ifndef LANG_FAEROESE
     75 # define LANG_FAEROESE 0x38
     76 # endif
     77 # ifndef LANG_FARSI
     78 # define LANG_FARSI 0x29
     79 # endif
     80 # ifndef LANG_GALICIAN
     81 # define LANG_GALICIAN 0x56
     82 # endif
     83 # ifndef LANG_GEORGIAN
     84 # define LANG_GEORGIAN 0x37
     85 # endif
     86 # ifndef LANG_GUJARATI
     87 # define LANG_GUJARATI 0x47
     88 # endif
     89 # ifndef LANG_HEBREW
     90 # define LANG_HEBREW 0x0d
     91 # endif
     92 # ifndef LANG_HINDI
     93 # define LANG_HINDI 0x39
     94 # endif
     95 # ifndef LANG_INDONESIAN
     96 # define LANG_INDONESIAN 0x21
     97 # endif
     98 # ifndef LANG_KANNADA
     99 # define LANG_KANNADA 0x4b
    100 # endif
    101 # ifndef LANG_KASHMIRI
    102 # define LANG_KASHMIRI 0x60
    103 # endif
    104 # ifndef LANG_KAZAK
    105 # define LANG_KAZAK 0x3f
    106 # endif
    107 # ifndef LANG_KONKANI
    108 # define LANG_KONKANI 0x57
    109 # endif
    110 # ifndef LANG_KYRGYZ
    111 # define LANG_KYRGYZ 0x40
    112 # endif
    113 # ifndef LANG_LATVIAN
    114 # define LANG_LATVIAN 0x26
    115 # endif
    116 # ifndef LANG_LITHUANIAN
    117 # define LANG_LITHUANIAN 0x27
    118 # endif
    119 # ifndef LANG_MACEDONIAN
    120 # define LANG_MACEDONIAN 0x2f
    121 # endif
    122 # ifndef LANG_MALAY
    123 # define LANG_MALAY 0x3e
    124 # endif
    125 # ifndef LANG_MALAYALAM
    126 # define LANG_MALAYALAM 0x4c
    127 # endif
    128 # ifndef LANG_MANIPURI
    129 # define LANG_MANIPURI 0x58
    130 # endif
    131 # ifndef LANG_MARATHI
    132 # define LANG_MARATHI 0x4e
    133 # endif
    134 # ifndef LANG_MONGOLIAN
    135 # define LANG_MONGOLIAN 0x50
    136 # endif
    137 # ifndef LANG_NEPALI
    138 # define LANG_NEPALI 0x61
    139 # endif
    140 # ifndef LANG_ORIYA
    141 # define LANG_ORIYA 0x48
    142 # endif
    143 # ifndef LANG_PUNJABI
    144 # define LANG_PUNJABI 0x46
    145 # endif
    146 # ifndef LANG_SANSKRIT
    147 # define LANG_SANSKRIT 0x4f
    148 # endif
    149 # ifndef LANG_SERBIAN
    150 # define LANG_SERBIAN 0x1a
    151 # endif
    152 # ifndef LANG_SINDHI
    153 # define LANG_SINDHI 0x59
    154 # endif
    155 # ifndef LANG_SLOVAK
    156 # define LANG_SLOVAK 0x1b
    157 # endif
    158 # ifndef LANG_SORBIAN
    159 # define LANG_SORBIAN 0x2e
    160 # endif
    161 # ifndef LANG_SWAHILI
    162 # define LANG_SWAHILI 0x41
    163 # endif
    164 # ifndef LANG_SYRIAC
    165 # define LANG_SYRIAC 0x5a
    166 # endif
    167 # ifndef LANG_TAMIL
    168 # define LANG_TAMIL 0x49
    169 # endif
    170 # ifndef LANG_TATAR
    171 # define LANG_TATAR 0x44
    172 # endif
    173 # ifndef LANG_TELUGU
    174 # define LANG_TELUGU 0x4a
    175 # endif
    176 # ifndef LANG_THAI
    177 # define LANG_THAI 0x1e
    178 # endif
    179 # ifndef LANG_UKRAINIAN
    180 # define LANG_UKRAINIAN 0x22
    181 # endif
    182 # ifndef LANG_URDU
    183 # define LANG_URDU 0x20
    184 # endif
    185 # ifndef LANG_UZBEK
    186 # define LANG_UZBEK 0x43
    187 # endif
    188 # ifndef LANG_VIETNAMESE
    189 # define LANG_VIETNAMESE 0x2a
    190 # endif
    191 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
    192 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
    193 # endif
    194 # ifndef SUBLANG_ARABIC_IRAQ
    195 # define SUBLANG_ARABIC_IRAQ 0x02
    196 # endif
    197 # ifndef SUBLANG_ARABIC_EGYPT
    198 # define SUBLANG_ARABIC_EGYPT 0x03
    199 # endif
    200 # ifndef SUBLANG_ARABIC_LIBYA
    201 # define SUBLANG_ARABIC_LIBYA 0x04
    202 # endif
    203 # ifndef SUBLANG_ARABIC_ALGERIA
    204 # define SUBLANG_ARABIC_ALGERIA 0x05
    205 # endif
    206 # ifndef SUBLANG_ARABIC_MOROCCO
    207 # define SUBLANG_ARABIC_MOROCCO 0x06
    208 # endif
    209 # ifndef SUBLANG_ARABIC_TUNISIA
    210 # define SUBLANG_ARABIC_TUNISIA 0x07
    211 # endif
    212 # ifndef SUBLANG_ARABIC_OMAN
    213 # define SUBLANG_ARABIC_OMAN 0x08
    214 # endif
    215 # ifndef SUBLANG_ARABIC_YEMEN
    216 # define SUBLANG_ARABIC_YEMEN 0x09
    217 # endif
    218 # ifndef SUBLANG_ARABIC_SYRIA
    219 # define SUBLANG_ARABIC_SYRIA 0x0a
    220 # endif
    221 # ifndef SUBLANG_ARABIC_JORDAN
    222 # define SUBLANG_ARABIC_JORDAN 0x0b
    223 # endif
    224 # ifndef SUBLANG_ARABIC_LEBANON
    225 # define SUBLANG_ARABIC_LEBANON 0x0c
    226 # endif
    227 # ifndef SUBLANG_ARABIC_KUWAIT
    228 # define SUBLANG_ARABIC_KUWAIT 0x0d
    229 # endif
    230 # ifndef SUBLANG_ARABIC_UAE
    231 # define SUBLANG_ARABIC_UAE 0x0e
    232 # endif
    233 # ifndef SUBLANG_ARABIC_BAHRAIN
    234 # define SUBLANG_ARABIC_BAHRAIN 0x0f
    235 # endif
    236 # ifndef SUBLANG_ARABIC_QATAR
    237 # define SUBLANG_ARABIC_QATAR 0x10
    238 # endif
    239 # ifndef SUBLANG_AZERI_LATIN
    240 # define SUBLANG_AZERI_LATIN 0x01
    241 # endif
    242 # ifndef SUBLANG_AZERI_CYRILLIC
    243 # define SUBLANG_AZERI_CYRILLIC 0x02
    244 # endif
    245 # ifndef SUBLANG_CHINESE_MACAU
    246 # define SUBLANG_CHINESE_MACAU 0x05
    247 # endif
    248 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
    249 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
    250 # endif
    251 # ifndef SUBLANG_ENGLISH_JAMAICA
    252 # define SUBLANG_ENGLISH_JAMAICA 0x08
    253 # endif
    254 # ifndef SUBLANG_ENGLISH_CARIBBEAN
    255 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
    256 # endif
    257 # ifndef SUBLANG_ENGLISH_BELIZE
    258 # define SUBLANG_ENGLISH_BELIZE 0x0a
    259 # endif
    260 # ifndef SUBLANG_ENGLISH_TRINIDAD
    261 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
    262 # endif
    263 # ifndef SUBLANG_ENGLISH_ZIMBABWE
    264 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
    265 # endif
    266 # ifndef SUBLANG_ENGLISH_PHILIPPINES
    267 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
    268 # endif
    269 # ifndef SUBLANG_FRENCH_LUXEMBOURG
    270 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
    271 # endif
    272 # ifndef SUBLANG_FRENCH_MONACO
    273 # define SUBLANG_FRENCH_MONACO 0x06
    274 # endif
    275 # ifndef SUBLANG_GERMAN_LUXEMBOURG
    276 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
    277 # endif
    278 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
    279 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
    280 # endif
    281 # ifndef SUBLANG_KASHMIRI_INDIA
    282 # define SUBLANG_KASHMIRI_INDIA 0x02
    283 # endif
    284 # ifndef SUBLANG_MALAY_MALAYSIA
    285 # define SUBLANG_MALAY_MALAYSIA 0x01
    286 # endif
    287 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
    288 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
    289 # endif
    290 # ifndef SUBLANG_NEPALI_INDIA
    291 # define SUBLANG_NEPALI_INDIA 0x02
    292 # endif
    293 # ifndef SUBLANG_SERBIAN_LATIN
    294 # define SUBLANG_SERBIAN_LATIN 0x02
    295 # endif
    296 # ifndef SUBLANG_SERBIAN_CYRILLIC
    297 # define SUBLANG_SERBIAN_CYRILLIC 0x03
    298 # endif
    299 # ifndef SUBLANG_SPANISH_GUATEMALA
    300 # define SUBLANG_SPANISH_GUATEMALA 0x04
    301 # endif
    302 # ifndef SUBLANG_SPANISH_COSTA_RICA
    303 # define SUBLANG_SPANISH_COSTA_RICA 0x05
    304 # endif
    305 # ifndef SUBLANG_SPANISH_PANAMA
    306 # define SUBLANG_SPANISH_PANAMA 0x06
    307 # endif
    308 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
    309 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
    310 # endif
    311 # ifndef SUBLANG_SPANISH_VENEZUELA
    312 # define SUBLANG_SPANISH_VENEZUELA 0x08
    313 # endif
    314 # ifndef SUBLANG_SPANISH_COLOMBIA
    315 # define SUBLANG_SPANISH_COLOMBIA 0x09
    316 # endif
    317 # ifndef SUBLANG_SPANISH_PERU
    318 # define SUBLANG_SPANISH_PERU 0x0a
    319 # endif
    320 # ifndef SUBLANG_SPANISH_ARGENTINA
    321 # define SUBLANG_SPANISH_ARGENTINA 0x0b
    322 # endif
    323 # ifndef SUBLANG_SPANISH_ECUADOR
    324 # define SUBLANG_SPANISH_ECUADOR 0x0c
    325 # endif
    326 # ifndef SUBLANG_SPANISH_CHILE
    327 # define SUBLANG_SPANISH_CHILE 0x0d
    328 # endif
    329 # ifndef SUBLANG_SPANISH_URUGUAY
    330 # define SUBLANG_SPANISH_URUGUAY 0x0e
    331 # endif
    332 # ifndef SUBLANG_SPANISH_PARAGUAY
    333 # define SUBLANG_SPANISH_PARAGUAY 0x0f
    334 # endif
    335 # ifndef SUBLANG_SPANISH_BOLIVIA
    336 # define SUBLANG_SPANISH_BOLIVIA 0x10
    337 # endif
    338 # ifndef SUBLANG_SPANISH_EL_SALVADOR
    339 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
    340 # endif
    341 # ifndef SUBLANG_SPANISH_HONDURAS
    342 # define SUBLANG_SPANISH_HONDURAS 0x12
    343 # endif
    344 # ifndef SUBLANG_SPANISH_NICARAGUA
    345 # define SUBLANG_SPANISH_NICARAGUA 0x13
    346 # endif
    347 # ifndef SUBLANG_SPANISH_PUERTO_RICO
    348 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
    349 # endif
    350 # ifndef SUBLANG_SWEDISH_FINLAND
    351 # define SUBLANG_SWEDISH_FINLAND 0x02
    352 # endif
    353 # ifndef SUBLANG_URDU_PAKISTAN
    354 # define SUBLANG_URDU_PAKISTAN 0x01
    355 # endif
    356 # ifndef SUBLANG_URDU_INDIA
    357 # define SUBLANG_URDU_INDIA 0x02
    358 # endif
    359 # ifndef SUBLANG_UZBEK_LATIN
    360 # define SUBLANG_UZBEK_LATIN 0x01
    361 # endif
    362 # ifndef SUBLANG_UZBEK_CYRILLIC
    363 # define SUBLANG_UZBEK_CYRILLIC 0x02
    364 # endif
    365 #endif
    366 
    367 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
    368    "Directs 'setlocale()' to query 'category' and return the current
    369     setting of 'local'."
    370    However it does not specify the exact format.  Neither do SUSV2 and
    371    ISO C 99.  So we can use this feature only on selected systems (e.g.
    372    those using GNU C Library).  */
    373 #if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
    374 # define HAVE_LOCALE_NULL
    375 #endif
    376 
    377 /* Determine the current locale's name, and canonicalize it into XPG syntax
    378      language[_territory[.codeset]][@modifier]
    379    The codeset part in the result is not reliable; the locale_charset()
    380    should be used for codeset information instead.
    381    The result must not be freed; it is statically allocated.  */
    382 
    383 const char *
    384 _nl_locale_name (category, categoryname)
    385      int category;
    386      const char *categoryname;
    387 {
    388   const char *retval;
    389 
    390 #ifndef WIN32
    391 
    392   /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
    393      On some systems this can be done by the 'setlocale' function itself.  */
    394 # if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
    395   retval = setlocale (category, NULL);
    396 # else
    397   /* Setting of LC_ALL overwrites all other.  */
    398   retval = getenv ("LC_ALL");
    399   if (retval == NULL || retval[0] == '\0')
    400     {
    401       /* Next comes the name of the desired category.  */
    402       retval = getenv (categoryname);
    403       if (retval == NULL || retval[0] == '\0')
    404 	{
    405 	  /* Last possibility is the LANG environment variable.  */
    406 	  retval = getenv ("LANG");
    407 	  if (retval == NULL || retval[0] == '\0')
    408 	    /* We use C as the default domain.  POSIX says this is
    409 	       implementation defined.  */
    410 	    retval = "C";
    411 	}
    412     }
    413 # endif
    414 
    415   return retval;
    416 
    417 #else /* WIN32 */
    418 
    419   /* Return an XPG style locale name language[_territory][@modifier].
    420      Don't even bother determining the codeset; it's not useful in this
    421      context, because message catalogs are not specific to a single
    422      codeset.  */
    423 
    424   LCID lcid;
    425   LANGID langid;
    426   int primary, sub;
    427 
    428   /* Let the user override the system settings through environment
    429      variables, as on POSIX systems.  */
    430   retval = getenv ("LC_ALL");
    431   if (retval != NULL && retval[0] != '\0')
    432     return retval;
    433   retval = getenv (categoryname);
    434   if (retval != NULL && retval[0] != '\0')
    435     return retval;
    436   retval = getenv ("LANG");
    437   if (retval != NULL && retval[0] != '\0')
    438     return retval;
    439 
    440   /* Use native Win32 API locale ID.  */
    441   lcid = GetThreadLocale ();
    442 
    443   /* Strip off the sorting rules, keep only the language part.  */
    444   langid = LANGIDFROMLCID (lcid);
    445 
    446   /* Split into language and territory part.  */
    447   primary = PRIMARYLANGID (langid);
    448   sub = SUBLANGID (langid);
    449 
    450   /* Dispatch on language.
    451      See also http://www.unicode.org/unicode/onlinedat/languages.html .
    452      For details about languages, see http://www.ethnologue.com/ .  */
    453   switch (primary)
    454     {
    455     case LANG_AFRIKAANS: return "af_ZA";
    456     case LANG_ALBANIAN: return "sq_AL";
    457     case 0x5e: /* AMHARIC */ return "am_ET";
    458     case LANG_ARABIC:
    459       switch (sub)
    460 	{
    461 	case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
    462 	case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
    463 	case SUBLANG_ARABIC_EGYPT: return "ar_EG";
    464 	case SUBLANG_ARABIC_LIBYA: return "ar_LY";
    465 	case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
    466 	case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
    467 	case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
    468 	case SUBLANG_ARABIC_OMAN: return "ar_OM";
    469 	case SUBLANG_ARABIC_YEMEN: return "ar_YE";
    470 	case SUBLANG_ARABIC_SYRIA: return "ar_SY";
    471 	case SUBLANG_ARABIC_JORDAN: return "ar_JO";
    472 	case SUBLANG_ARABIC_LEBANON: return "ar_LB";
    473 	case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
    474 	case SUBLANG_ARABIC_UAE: return "ar_AE";
    475 	case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
    476 	case SUBLANG_ARABIC_QATAR: return "ar_QA";
    477 	}
    478       return "ar";
    479     case LANG_ARMENIAN: return "hy_AM";
    480     case LANG_ASSAMESE: return "as_IN";
    481     case LANG_AZERI:
    482       switch (sub)
    483 	{
    484 	/* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
    485 	case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
    486 	case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
    487 	}
    488       return "az";
    489     case LANG_BASQUE:
    490       return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
    491     case LANG_BELARUSIAN: return "be_BY";
    492     case LANG_BENGALI: return "bn_IN";
    493     case LANG_BULGARIAN: return "bg_BG";
    494     case 0x55: /* BURMESE */ return "my_MM";
    495     case 0x53: /* CAMBODIAN */ return "km_KH";
    496     case LANG_CATALAN: return "ca_ES";
    497     case 0x5c: /* CHEROKEE */ return "chr_US";
    498     case LANG_CHINESE:
    499       switch (sub)
    500 	{
    501 	case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
    502 	case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
    503 	case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
    504 	case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
    505 	case SUBLANG_CHINESE_MACAU: return "zh_MO";
    506 	}
    507       return "zh";
    508     case LANG_CROATIAN:		/* LANG_CROATIAN == LANG_SERBIAN
    509 				 * What used to be called Serbo-Croatian
    510 				 * should really now be two separate
    511 				 * languages because of political reasons.
    512 				 * (Says tml, who knows nothing about Serbian
    513 				 * or Croatian.)
    514 				 * (I can feel those flames coming already.)
    515 				 */
    516       switch (sub)
    517 	{
    518 	case SUBLANG_DEFAULT: return "hr_HR";
    519 	case SUBLANG_SERBIAN_LATIN: return "sr_YU";
    520 	case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic";
    521 	}
    522       return "hr";
    523     case LANG_CZECH: return "cs_CZ";
    524     case LANG_DANISH: return "da_DK";
    525     case LANG_DIVEHI: return "div_MV";
    526     case LANG_DUTCH:
    527       switch (sub)
    528 	{
    529 	case SUBLANG_DUTCH: return "nl_NL";
    530 	case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
    531 	}
    532       return "nl";
    533     case 0x66: /* EDO */ return "bin_NG";
    534     case LANG_ENGLISH:
    535       switch (sub)
    536 	{
    537 	/* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
    538 	 * English was the language spoken in England.
    539 	 * Oh well.
    540 	 */
    541 	case SUBLANG_ENGLISH_US: return "en_US";
    542 	case SUBLANG_ENGLISH_UK: return "en_GB";
    543 	case SUBLANG_ENGLISH_AUS: return "en_AU";
    544 	case SUBLANG_ENGLISH_CAN: return "en_CA";
    545 	case SUBLANG_ENGLISH_NZ: return "en_NZ";
    546 	case SUBLANG_ENGLISH_EIRE: return "en_IE";
    547 	case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
    548 	case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
    549 	case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
    550 	case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
    551 	case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
    552 	case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
    553 	case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
    554 	}
    555       return "en";
    556     case LANG_ESTONIAN: return "et_EE";
    557     case LANG_FAEROESE: return "fo_FO";
    558     case LANG_FARSI: return "fa_IR";
    559     case LANG_FINNISH: return "fi_FI";
    560     case LANG_FRENCH:
    561       switch (sub)
    562 	{
    563 	case SUBLANG_FRENCH: return "fr_FR";
    564 	case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
    565 	case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
    566 	case SUBLANG_FRENCH_SWISS: return "fr_CH";
    567 	case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
    568 	case SUBLANG_FRENCH_MONACO: return "fr_MC";
    569 	}
    570       return "fr";
    571     case 0x62: /* FRISIAN */ return "fy_NL";
    572     case 0x67: /* FULFULDE */ return "ful_NG";
    573     case 0x3c: /* GAELIC */
    574       switch (sub)
    575 	{
    576 	case 0x01: /* SCOTTISH */ return "gd_GB";
    577 	case 0x02: /* IRISH */ return "ga_IE";
    578 	}
    579       return "C";
    580     case LANG_GALICIAN: return "gl_ES";
    581     case LANG_GEORGIAN: return "ka_GE";
    582     case LANG_GERMAN:
    583       switch (sub)
    584 	{
    585 	case SUBLANG_GERMAN: return "de_DE";
    586 	case SUBLANG_GERMAN_SWISS: return "de_CH";
    587 	case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
    588 	case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
    589 	case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
    590 	}
    591       return "de";
    592     case LANG_GREEK: return "el_GR";
    593     case 0x74: /* GUARANI */ return "gn_PY";
    594     case LANG_GUJARATI: return "gu_IN";
    595     case 0x68: /* HAUSA */ return "ha_NG";
    596     case 0x75: /* HAWAIIAN */
    597       /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
    598 	 or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
    599       return "cpe_US";
    600     case LANG_HEBREW: return "he_IL";
    601     case LANG_HINDI: return "hi_IN";
    602     case LANG_HUNGARIAN: return "hu_HU";
    603     case 0x69: /* IBIBIO */ return "nic_NG";
    604     case LANG_ICELANDIC: return "is_IS";
    605     case 0x70: /* IGBO */ return "ibo_NG";
    606     case LANG_INDONESIAN: return "id_ID";
    607     case 0x5d: /* INUKTITUT */ return "iu_CA";
    608     case LANG_ITALIAN:
    609       switch (sub)
    610 	{
    611 	case SUBLANG_ITALIAN: return "it_IT";
    612 	case SUBLANG_ITALIAN_SWISS: return "it_CH";
    613 	}
    614       return "it";
    615     case LANG_JAPANESE: return "ja_JP";
    616     case LANG_KANNADA: return "kn_IN";
    617     case 0x71: /* KANURI */ return "kau_NG";
    618     case LANG_KASHMIRI:
    619       switch (sub)
    620 	{
    621 	case SUBLANG_DEFAULT: return "ks_PK";
    622 	case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
    623 	}
    624       return "ks";
    625     case LANG_KAZAK: return "kk_KZ";
    626     case LANG_KONKANI:
    627       /* FIXME: Adjust this when such locales appear on Unix.  */
    628       return "kok_IN";
    629     case LANG_KOREAN: return "ko_KR";
    630     case LANG_KYRGYZ: return "ky_KG";
    631     case 0x54: /* LAO */ return "lo_LA";
    632     case 0x76: /* LATIN */ return "la_VA";
    633     case LANG_LATVIAN: return "lv_LV";
    634     case LANG_LITHUANIAN: return "lt_LT";
    635     case LANG_MACEDONIAN: return "mk_MK";
    636     case LANG_MALAY:
    637       switch (sub)
    638 	{
    639 	case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
    640 	case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
    641 	}
    642       return "ms";
    643     case LANG_MALAYALAM: return "ml_IN";
    644     case 0x3a: /* MALTESE */ return "mt_MT";
    645     case LANG_MANIPURI:
    646       /* FIXME: Adjust this when such locales appear on Unix.  */
    647       return "mni_IN";
    648     case LANG_MARATHI: return "mr_IN";
    649     case LANG_MONGOLIAN:
    650       return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
    651     case LANG_NEPALI:
    652       switch (sub)
    653 	{
    654 	case SUBLANG_DEFAULT: return "ne_NP";
    655 	case SUBLANG_NEPALI_INDIA: return "ne_IN";
    656 	}
    657       return "ne";
    658     case LANG_NORWEGIAN:
    659       switch (sub)
    660 	{
    661 	case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO";
    662 	case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
    663 	}
    664       return "no";
    665     case LANG_ORIYA: return "or_IN";
    666     case 0x72: /* OROMO */ return "om_ET";
    667     case 0x79: /* PAPIAMENTU */ return "pap_AN";
    668     case 0x63: /* PASHTO */
    669       return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
    670     case LANG_POLISH: return "pl_PL";
    671     case LANG_PORTUGUESE:
    672       switch (sub)
    673 	{
    674 	case SUBLANG_PORTUGUESE: return "pt_PT";
    675 	/* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
    676 	   Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
    677 	case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
    678 	}
    679       return "pt";
    680     case LANG_PUNJABI: return "pa_IN";
    681     case 0x17: /* RHAETO-ROMANCE */ return "rm_CH";
    682     case LANG_ROMANIAN: return "ro_RO";
    683     case LANG_RUSSIAN:
    684       return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA".  */
    685     case 0x3b: /* SAMI */ return "se_NO";
    686     case LANG_SANSKRIT: return "sa_IN";
    687     case LANG_SINDHI: return "sd";
    688     case 0x5b: /* SINHALESE */ return "si_LK";
    689     case LANG_SLOVAK: return "sk_SK";
    690     case LANG_SLOVENIAN: return "sl_SI";
    691     case 0x77: /* SOMALI */ return "so_SO";
    692     case LANG_SORBIAN:
    693       /* FIXME: Adjust this when such locales appear on Unix.  */
    694       return "wen_DE";
    695     case LANG_SPANISH:
    696       switch (sub)
    697 	{
    698 	case SUBLANG_SPANISH: return "es_ES";
    699 	case SUBLANG_SPANISH_MEXICAN: return "es_MX";
    700 	case SUBLANG_SPANISH_MODERN:
    701 	  return "es_ES@modern";	/* not seen on Unix */
    702 	case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
    703 	case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
    704 	case SUBLANG_SPANISH_PANAMA: return "es_PA";
    705 	case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
    706 	case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
    707 	case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
    708 	case SUBLANG_SPANISH_PERU: return "es_PE";
    709 	case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
    710 	case SUBLANG_SPANISH_ECUADOR: return "es_EC";
    711 	case SUBLANG_SPANISH_CHILE: return "es_CL";
    712 	case SUBLANG_SPANISH_URUGUAY: return "es_UY";
    713 	case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
    714 	case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
    715 	case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
    716 	case SUBLANG_SPANISH_HONDURAS: return "es_HN";
    717 	case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
    718 	case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
    719 	}
    720       return "es";
    721     case 0x30: /* SUTU */ return "bnt_TZ";
    722     case LANG_SWAHILI: return "sw_KE";
    723     case LANG_SWEDISH:
    724       switch (sub)
    725 	{
    726 	case SUBLANG_DEFAULT: return "sv_SE";
    727 	case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
    728 	}
    729       return "sv";
    730     case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
    731     case 0x64: /* TAGALOG */ return "tl_PH";
    732     case 0x28: /* TAJIK */ return "tg_TJ";
    733     case 0x5f: /* TAMAZIGHT */ return "ber_MA";
    734     case LANG_TAMIL:
    735       return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
    736     case LANG_TATAR: return "tt_RU";
    737     case LANG_TELUGU: return "te_IN";
    738     case LANG_THAI: return "th_TH";
    739     case 0x51: /* TIBETAN */ return "bo_CN";
    740     case 0x73: /* TIGRINYA */ return "ti_ET";
    741     case 0x31: /* TSONGA */ return "ts_ZA";
    742     case LANG_TURKISH: return "tr_TR";
    743     case 0x42: /* TURKMEN */ return "tk_TM";
    744     case LANG_UKRAINIAN: return "uk_UA";
    745     case LANG_URDU:
    746       switch (sub)
    747 	{
    748 	case SUBLANG_URDU_PAKISTAN: return "ur_PK";
    749 	case SUBLANG_URDU_INDIA: return "ur_IN";
    750 	}
    751       return "ur";
    752     case LANG_UZBEK:
    753       switch (sub)
    754 	{
    755 	/* FIXME: Adjust this when Uzbek locales appear on Unix.  */
    756 	case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin";
    757 	case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
    758 	}
    759       return "uz";
    760     case 0x33: /* VENDA */ return "ven_ZA";
    761     case LANG_VIETNAMESE: return "vi_VN";
    762     case 0x52: /* WELSH */ return "cy_GB";
    763     case 0x34: /* XHOSA */ return "xh_ZA";
    764     case 0x78: /* YI */ return "sit_CN";
    765     case 0x3d: /* YIDDISH */ return "yi_IL";
    766     case 0x6a: /* YORUBA */ return "yo_NG";
    767     case 0x35: /* ZULU */ return "zu_ZA";
    768     default: return "C";
    769     }
    770 
    771 #endif
    772 }
    773