"Fossies" - the Fresh Open Source Software Archive

Member "gnuastro-0.8/bootstrapped/tests/localename.c" (28 Dec 2018, 100929 Bytes) of package /linux/privat/gnuastro-0.8.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "localename.c": 0.7_vs_0.8.

    1 /* Determine name of the currently selected locale.
    2    Copyright (C) 1995-2018 Free Software Foundation, Inc.
    3 
    4    This program is free software: you can redistribute it and/or modify
    5    it under the terms of the GNU General Public License as published by
    6    the Free Software Foundation; either version 3 of the License, or
    7    (at your option) 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
   12    GNU General Public License for more details.
   13 
   14    You should have received a copy of the GNU General Public License
   15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   16 
   17 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
   18 /* Native Windows code written by Tor Lillqvist <tml@iki.fi>.  */
   19 /* Mac OS X code written by Bruno Haible <bruno@clisp.org>.  */
   20 
   21 #include <config.h>
   22 
   23 /* Specification.  */
   24 #ifdef IN_LIBINTL
   25 # include "gettextP.h"
   26 #else
   27 # include "localename.h"
   28 #endif
   29 
   30 #include <limits.h>
   31 #include <stddef.h>
   32 #include <stdlib.h>
   33 #include <locale.h>
   34 #include <string.h>
   35 
   36 #include "flexmember.h"
   37 
   38 /* We cannot support uselocale() on platforms where the locale_t type is fake.
   39    See intl-thread-locale.m4 for details.  */
   40 #if HAVE_WORKING_USELOCALE && !HAVE_FAKE_LOCALES
   41 # define HAVE_GOOD_USELOCALE 1
   42 #endif
   43 
   44 #if HAVE_GOOD_USELOCALE
   45 /* Mac OS X 10.5 defines the locale_t type in <xlocale.h>.  */
   46 # if defined __APPLE__ && defined __MACH__
   47 #  include <xlocale.h>
   48 # endif
   49 # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || (defined __linux__ && HAVE_LANGINFO_H) || defined __CYGWIN__
   50 #  include <langinfo.h>
   51 # endif
   52 # if !defined IN_LIBINTL
   53 #  include "glthread/lock.h"
   54 # endif
   55 # if defined __sun
   56 #  if HAVE_GETLOCALENAME_L
   57 /* Solaris >= 12.  */
   58 extern char * getlocalename_l(int, locale_t);
   59 #  elif HAVE_SOLARIS114_LOCALES
   60 #   include <sys/localedef.h>
   61 #  endif
   62 # endif
   63 # if HAVE_NAMELESS_LOCALES
   64 #  include <errno.h>
   65 #  include "localename-table.h"
   66 # endif
   67 #endif
   68 
   69 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
   70 # include <CoreFoundation/CFString.h>
   71 # if HAVE_CFLOCALECOPYCURRENT
   72 #  include <CoreFoundation/CFLocale.h>
   73 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
   74 #  include <CoreFoundation/CFPreferences.h>
   75 # endif
   76 #endif
   77 
   78 #if defined _WIN32 && !defined __CYGWIN__
   79 # define WINDOWS_NATIVE
   80 # if !defined IN_LIBINTL
   81 #  include "glthread/lock.h"
   82 # endif
   83 #endif
   84 
   85 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
   86 # define WIN32_LEAN_AND_MEAN
   87 # include <windows.h>
   88 # include <winnls.h>
   89 /* List of language codes, sorted by value:
   90    0x01 LANG_ARABIC
   91    0x02 LANG_BULGARIAN
   92    0x03 LANG_CATALAN
   93    0x04 LANG_CHINESE
   94    0x05 LANG_CZECH
   95    0x06 LANG_DANISH
   96    0x07 LANG_GERMAN
   97    0x08 LANG_GREEK
   98    0x09 LANG_ENGLISH
   99    0x0a LANG_SPANISH
  100    0x0b LANG_FINNISH
  101    0x0c LANG_FRENCH
  102    0x0d LANG_HEBREW
  103    0x0e LANG_HUNGARIAN
  104    0x0f LANG_ICELANDIC
  105    0x10 LANG_ITALIAN
  106    0x11 LANG_JAPANESE
  107    0x12 LANG_KOREAN
  108    0x13 LANG_DUTCH
  109    0x14 LANG_NORWEGIAN
  110    0x15 LANG_POLISH
  111    0x16 LANG_PORTUGUESE
  112    0x17 LANG_ROMANSH
  113    0x18 LANG_ROMANIAN
  114    0x19 LANG_RUSSIAN
  115    0x1a LANG_CROATIAN == LANG_SERBIAN
  116    0x1b LANG_SLOVAK
  117    0x1c LANG_ALBANIAN
  118    0x1d LANG_SWEDISH
  119    0x1e LANG_THAI
  120    0x1f LANG_TURKISH
  121    0x20 LANG_URDU
  122    0x21 LANG_INDONESIAN
  123    0x22 LANG_UKRAINIAN
  124    0x23 LANG_BELARUSIAN
  125    0x24 LANG_SLOVENIAN
  126    0x25 LANG_ESTONIAN
  127    0x26 LANG_LATVIAN
  128    0x27 LANG_LITHUANIAN
  129    0x28 LANG_TAJIK
  130    0x29 LANG_FARSI
  131    0x2a LANG_VIETNAMESE
  132    0x2b LANG_ARMENIAN
  133    0x2c LANG_AZERI
  134    0x2d LANG_BASQUE
  135    0x2e LANG_SORBIAN
  136    0x2f LANG_MACEDONIAN
  137    0x30 LANG_SUTU
  138    0x31 LANG_TSONGA
  139    0x32 LANG_TSWANA
  140    0x33 LANG_VENDA
  141    0x34 LANG_XHOSA
  142    0x35 LANG_ZULU
  143    0x36 LANG_AFRIKAANS
  144    0x37 LANG_GEORGIAN
  145    0x38 LANG_FAEROESE
  146    0x39 LANG_HINDI
  147    0x3a LANG_MALTESE
  148    0x3b LANG_SAMI
  149    0x3c LANG_GAELIC
  150    0x3d LANG_YIDDISH
  151    0x3e LANG_MALAY
  152    0x3f LANG_KAZAK
  153    0x40 LANG_KYRGYZ
  154    0x41 LANG_SWAHILI
  155    0x42 LANG_TURKMEN
  156    0x43 LANG_UZBEK
  157    0x44 LANG_TATAR
  158    0x45 LANG_BENGALI
  159    0x46 LANG_PUNJABI
  160    0x47 LANG_GUJARATI
  161    0x48 LANG_ORIYA
  162    0x49 LANG_TAMIL
  163    0x4a LANG_TELUGU
  164    0x4b LANG_KANNADA
  165    0x4c LANG_MALAYALAM
  166    0x4d LANG_ASSAMESE
  167    0x4e LANG_MARATHI
  168    0x4f LANG_SANSKRIT
  169    0x50 LANG_MONGOLIAN
  170    0x51 LANG_TIBETAN
  171    0x52 LANG_WELSH
  172    0x53 LANG_CAMBODIAN
  173    0x54 LANG_LAO
  174    0x55 LANG_BURMESE
  175    0x56 LANG_GALICIAN
  176    0x57 LANG_KONKANI
  177    0x58 LANG_MANIPURI
  178    0x59 LANG_SINDHI
  179    0x5a LANG_SYRIAC
  180    0x5b LANG_SINHALESE
  181    0x5c LANG_CHEROKEE
  182    0x5d LANG_INUKTITUT
  183    0x5e LANG_AMHARIC
  184    0x5f LANG_TAMAZIGHT
  185    0x60 LANG_KASHMIRI
  186    0x61 LANG_NEPALI
  187    0x62 LANG_FRISIAN
  188    0x63 LANG_PASHTO
  189    0x64 LANG_TAGALOG
  190    0x65 LANG_DIVEHI
  191    0x66 LANG_EDO
  192    0x67 LANG_FULFULDE
  193    0x68 LANG_HAUSA
  194    0x69 LANG_IBIBIO
  195    0x6a LANG_YORUBA
  196    0x6d LANG_BASHKIR
  197    0x6e LANG_LUXEMBOURGISH
  198    0x6f LANG_GREENLANDIC
  199    0x70 LANG_IGBO
  200    0x71 LANG_KANURI
  201    0x72 LANG_OROMO
  202    0x73 LANG_TIGRINYA
  203    0x74 LANG_GUARANI
  204    0x75 LANG_HAWAIIAN
  205    0x76 LANG_LATIN
  206    0x77 LANG_SOMALI
  207    0x78 LANG_YI
  208    0x79 LANG_PAPIAMENTU
  209    0x7a LANG_MAPUDUNGUN
  210    0x7c LANG_MOHAWK
  211    0x7e LANG_BRETON
  212    0x82 LANG_OCCITAN
  213    0x83 LANG_CORSICAN
  214    0x84 LANG_ALSATIAN
  215    0x85 LANG_YAKUT
  216    0x86 LANG_KICHE
  217    0x87 LANG_KINYARWANDA
  218    0x88 LANG_WOLOF
  219    0x8c LANG_DARI
  220    0x91 LANG_SCOTTISH_GAELIC
  221 */
  222 /* Mingw headers don't have latest language and sublanguage codes.  */
  223 # ifndef LANG_AFRIKAANS
  224 # define LANG_AFRIKAANS 0x36
  225 # endif
  226 # ifndef LANG_ALBANIAN
  227 # define LANG_ALBANIAN 0x1c
  228 # endif
  229 # ifndef LANG_ALSATIAN
  230 # define LANG_ALSATIAN 0x84
  231 # endif
  232 # ifndef LANG_AMHARIC
  233 # define LANG_AMHARIC 0x5e
  234 # endif
  235 # ifndef LANG_ARABIC
  236 # define LANG_ARABIC 0x01
  237 # endif
  238 # ifndef LANG_ARMENIAN
  239 # define LANG_ARMENIAN 0x2b
  240 # endif
  241 # ifndef LANG_ASSAMESE
  242 # define LANG_ASSAMESE 0x4d
  243 # endif
  244 # ifndef LANG_AZERI
  245 # define LANG_AZERI 0x2c
  246 # endif
  247 # ifndef LANG_BASHKIR
  248 # define LANG_BASHKIR 0x6d
  249 # endif
  250 # ifndef LANG_BASQUE
  251 # define LANG_BASQUE 0x2d
  252 # endif
  253 # ifndef LANG_BELARUSIAN
  254 # define LANG_BELARUSIAN 0x23
  255 # endif
  256 # ifndef LANG_BENGALI
  257 # define LANG_BENGALI 0x45
  258 # endif
  259 # ifndef LANG_BRETON
  260 # define LANG_BRETON 0x7e
  261 # endif
  262 # ifndef LANG_BURMESE
  263 # define LANG_BURMESE 0x55
  264 # endif
  265 # ifndef LANG_CAMBODIAN
  266 # define LANG_CAMBODIAN 0x53
  267 # endif
  268 # ifndef LANG_CATALAN
  269 # define LANG_CATALAN 0x03
  270 # endif
  271 # ifndef LANG_CHEROKEE
  272 # define LANG_CHEROKEE 0x5c
  273 # endif
  274 # ifndef LANG_CORSICAN
  275 # define LANG_CORSICAN 0x83
  276 # endif
  277 # ifndef LANG_DARI
  278 # define LANG_DARI 0x8c
  279 # endif
  280 # ifndef LANG_DIVEHI
  281 # define LANG_DIVEHI 0x65
  282 # endif
  283 # ifndef LANG_EDO
  284 # define LANG_EDO 0x66
  285 # endif
  286 # ifndef LANG_ESTONIAN
  287 # define LANG_ESTONIAN 0x25
  288 # endif
  289 # ifndef LANG_FAEROESE
  290 # define LANG_FAEROESE 0x38
  291 # endif
  292 # ifndef LANG_FARSI
  293 # define LANG_FARSI 0x29
  294 # endif
  295 # ifndef LANG_FRISIAN
  296 # define LANG_FRISIAN 0x62
  297 # endif
  298 # ifndef LANG_FULFULDE
  299 # define LANG_FULFULDE 0x67
  300 # endif
  301 # ifndef LANG_GAELIC
  302 # define LANG_GAELIC 0x3c
  303 # endif
  304 # ifndef LANG_GALICIAN
  305 # define LANG_GALICIAN 0x56
  306 # endif
  307 # ifndef LANG_GEORGIAN
  308 # define LANG_GEORGIAN 0x37
  309 # endif
  310 # ifndef LANG_GREENLANDIC
  311 # define LANG_GREENLANDIC 0x6f
  312 # endif
  313 # ifndef LANG_GUARANI
  314 # define LANG_GUARANI 0x74
  315 # endif
  316 # ifndef LANG_GUJARATI
  317 # define LANG_GUJARATI 0x47
  318 # endif
  319 # ifndef LANG_HAUSA
  320 # define LANG_HAUSA 0x68
  321 # endif
  322 # ifndef LANG_HAWAIIAN
  323 # define LANG_HAWAIIAN 0x75
  324 # endif
  325 # ifndef LANG_HEBREW
  326 # define LANG_HEBREW 0x0d
  327 # endif
  328 # ifndef LANG_HINDI
  329 # define LANG_HINDI 0x39
  330 # endif
  331 # ifndef LANG_IBIBIO
  332 # define LANG_IBIBIO 0x69
  333 # endif
  334 # ifndef LANG_IGBO
  335 # define LANG_IGBO 0x70
  336 # endif
  337 # ifndef LANG_INDONESIAN
  338 # define LANG_INDONESIAN 0x21
  339 # endif
  340 # ifndef LANG_INUKTITUT
  341 # define LANG_INUKTITUT 0x5d
  342 # endif
  343 # ifndef LANG_KANNADA
  344 # define LANG_KANNADA 0x4b
  345 # endif
  346 # ifndef LANG_KANURI
  347 # define LANG_KANURI 0x71
  348 # endif
  349 # ifndef LANG_KASHMIRI
  350 # define LANG_KASHMIRI 0x60
  351 # endif
  352 # ifndef LANG_KAZAK
  353 # define LANG_KAZAK 0x3f
  354 # endif
  355 # ifndef LANG_KICHE
  356 # define LANG_KICHE 0x86
  357 # endif
  358 # ifndef LANG_KINYARWANDA
  359 # define LANG_KINYARWANDA 0x87
  360 # endif
  361 # ifndef LANG_KONKANI
  362 # define LANG_KONKANI 0x57
  363 # endif
  364 # ifndef LANG_KYRGYZ
  365 # define LANG_KYRGYZ 0x40
  366 # endif
  367 # ifndef LANG_LAO
  368 # define LANG_LAO 0x54
  369 # endif
  370 # ifndef LANG_LATIN
  371 # define LANG_LATIN 0x76
  372 # endif
  373 # ifndef LANG_LATVIAN
  374 # define LANG_LATVIAN 0x26
  375 # endif
  376 # ifndef LANG_LITHUANIAN
  377 # define LANG_LITHUANIAN 0x27
  378 # endif
  379 # ifndef LANG_LUXEMBOURGISH
  380 # define LANG_LUXEMBOURGISH 0x6e
  381 # endif
  382 # ifndef LANG_MACEDONIAN
  383 # define LANG_MACEDONIAN 0x2f
  384 # endif
  385 # ifndef LANG_MALAY
  386 # define LANG_MALAY 0x3e
  387 # endif
  388 # ifndef LANG_MALAYALAM
  389 # define LANG_MALAYALAM 0x4c
  390 # endif
  391 # ifndef LANG_MALTESE
  392 # define LANG_MALTESE 0x3a
  393 # endif
  394 # ifndef LANG_MANIPURI
  395 # define LANG_MANIPURI 0x58
  396 # endif
  397 # ifndef LANG_MAORI
  398 # define LANG_MAORI 0x81
  399 # endif
  400 # ifndef LANG_MAPUDUNGUN
  401 # define LANG_MAPUDUNGUN 0x7a
  402 # endif
  403 # ifndef LANG_MARATHI
  404 # define LANG_MARATHI 0x4e
  405 # endif
  406 # ifndef LANG_MOHAWK
  407 # define LANG_MOHAWK 0x7c
  408 # endif
  409 # ifndef LANG_MONGOLIAN
  410 # define LANG_MONGOLIAN 0x50
  411 # endif
  412 # ifndef LANG_NEPALI
  413 # define LANG_NEPALI 0x61
  414 # endif
  415 # ifndef LANG_OCCITAN
  416 # define LANG_OCCITAN 0x82
  417 # endif
  418 # ifndef LANG_ORIYA
  419 # define LANG_ORIYA 0x48
  420 # endif
  421 # ifndef LANG_OROMO
  422 # define LANG_OROMO 0x72
  423 # endif
  424 # ifndef LANG_PAPIAMENTU
  425 # define LANG_PAPIAMENTU 0x79
  426 # endif
  427 # ifndef LANG_PASHTO
  428 # define LANG_PASHTO 0x63
  429 # endif
  430 # ifndef LANG_PUNJABI
  431 # define LANG_PUNJABI 0x46
  432 # endif
  433 # ifndef LANG_QUECHUA
  434 # define LANG_QUECHUA 0x6b
  435 # endif
  436 # ifndef LANG_ROMANSH
  437 # define LANG_ROMANSH 0x17
  438 # endif
  439 # ifndef LANG_SAMI
  440 # define LANG_SAMI 0x3b
  441 # endif
  442 # ifndef LANG_SANSKRIT
  443 # define LANG_SANSKRIT 0x4f
  444 # endif
  445 # ifndef LANG_SCOTTISH_GAELIC
  446 # define LANG_SCOTTISH_GAELIC 0x91
  447 # endif
  448 # ifndef LANG_SERBIAN
  449 # define LANG_SERBIAN 0x1a
  450 # endif
  451 # ifndef LANG_SINDHI
  452 # define LANG_SINDHI 0x59
  453 # endif
  454 # ifndef LANG_SINHALESE
  455 # define LANG_SINHALESE 0x5b
  456 # endif
  457 # ifndef LANG_SLOVAK
  458 # define LANG_SLOVAK 0x1b
  459 # endif
  460 # ifndef LANG_SOMALI
  461 # define LANG_SOMALI 0x77
  462 # endif
  463 # ifndef LANG_SORBIAN
  464 # define LANG_SORBIAN 0x2e
  465 # endif
  466 # ifndef LANG_SOTHO
  467 # define LANG_SOTHO 0x6c
  468 # endif
  469 # ifndef LANG_SUTU
  470 # define LANG_SUTU 0x30
  471 # endif
  472 # ifndef LANG_SWAHILI
  473 # define LANG_SWAHILI 0x41
  474 # endif
  475 # ifndef LANG_SYRIAC
  476 # define LANG_SYRIAC 0x5a
  477 # endif
  478 # ifndef LANG_TAGALOG
  479 # define LANG_TAGALOG 0x64
  480 # endif
  481 # ifndef LANG_TAJIK
  482 # define LANG_TAJIK 0x28
  483 # endif
  484 # ifndef LANG_TAMAZIGHT
  485 # define LANG_TAMAZIGHT 0x5f
  486 # endif
  487 # ifndef LANG_TAMIL
  488 # define LANG_TAMIL 0x49
  489 # endif
  490 # ifndef LANG_TATAR
  491 # define LANG_TATAR 0x44
  492 # endif
  493 # ifndef LANG_TELUGU
  494 # define LANG_TELUGU 0x4a
  495 # endif
  496 # ifndef LANG_THAI
  497 # define LANG_THAI 0x1e
  498 # endif
  499 # ifndef LANG_TIBETAN
  500 # define LANG_TIBETAN 0x51
  501 # endif
  502 # ifndef LANG_TIGRINYA
  503 # define LANG_TIGRINYA 0x73
  504 # endif
  505 # ifndef LANG_TSONGA
  506 # define LANG_TSONGA 0x31
  507 # endif
  508 # ifndef LANG_TSWANA
  509 # define LANG_TSWANA 0x32
  510 # endif
  511 # ifndef LANG_TURKMEN
  512 # define LANG_TURKMEN 0x42
  513 # endif
  514 # ifndef LANG_UIGHUR
  515 # define LANG_UIGHUR 0x80
  516 # endif
  517 # ifndef LANG_UKRAINIAN
  518 # define LANG_UKRAINIAN 0x22
  519 # endif
  520 # ifndef LANG_URDU
  521 # define LANG_URDU 0x20
  522 # endif
  523 # ifndef LANG_UZBEK
  524 # define LANG_UZBEK 0x43
  525 # endif
  526 # ifndef LANG_VENDA
  527 # define LANG_VENDA 0x33
  528 # endif
  529 # ifndef LANG_VIETNAMESE
  530 # define LANG_VIETNAMESE 0x2a
  531 # endif
  532 # ifndef LANG_WELSH
  533 # define LANG_WELSH 0x52
  534 # endif
  535 # ifndef LANG_WOLOF
  536 # define LANG_WOLOF 0x88
  537 # endif
  538 # ifndef LANG_XHOSA
  539 # define LANG_XHOSA 0x34
  540 # endif
  541 # ifndef LANG_YAKUT
  542 # define LANG_YAKUT 0x85
  543 # endif
  544 # ifndef LANG_YI
  545 # define LANG_YI 0x78
  546 # endif
  547 # ifndef LANG_YIDDISH
  548 # define LANG_YIDDISH 0x3d
  549 # endif
  550 # ifndef LANG_YORUBA
  551 # define LANG_YORUBA 0x6a
  552 # endif
  553 # ifndef LANG_ZULU
  554 # define LANG_ZULU 0x35
  555 # endif
  556 # ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
  557 # define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
  558 # endif
  559 # ifndef SUBLANG_ALBANIAN_ALBANIA
  560 # define SUBLANG_ALBANIAN_ALBANIA 0x01
  561 # endif
  562 # ifndef SUBLANG_ALSATIAN_FRANCE
  563 # define SUBLANG_ALSATIAN_FRANCE 0x01
  564 # endif
  565 # ifndef SUBLANG_AMHARIC_ETHIOPIA
  566 # define SUBLANG_AMHARIC_ETHIOPIA 0x01
  567 # endif
  568 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
  569 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
  570 # endif
  571 # ifndef SUBLANG_ARABIC_IRAQ
  572 # define SUBLANG_ARABIC_IRAQ 0x02
  573 # endif
  574 # ifndef SUBLANG_ARABIC_EGYPT
  575 # define SUBLANG_ARABIC_EGYPT 0x03
  576 # endif
  577 # ifndef SUBLANG_ARABIC_LIBYA
  578 # define SUBLANG_ARABIC_LIBYA 0x04
  579 # endif
  580 # ifndef SUBLANG_ARABIC_ALGERIA
  581 # define SUBLANG_ARABIC_ALGERIA 0x05
  582 # endif
  583 # ifndef SUBLANG_ARABIC_MOROCCO
  584 # define SUBLANG_ARABIC_MOROCCO 0x06
  585 # endif
  586 # ifndef SUBLANG_ARABIC_TUNISIA
  587 # define SUBLANG_ARABIC_TUNISIA 0x07
  588 # endif
  589 # ifndef SUBLANG_ARABIC_OMAN
  590 # define SUBLANG_ARABIC_OMAN 0x08
  591 # endif
  592 # ifndef SUBLANG_ARABIC_YEMEN
  593 # define SUBLANG_ARABIC_YEMEN 0x09
  594 # endif
  595 # ifndef SUBLANG_ARABIC_SYRIA
  596 # define SUBLANG_ARABIC_SYRIA 0x0a
  597 # endif
  598 # ifndef SUBLANG_ARABIC_JORDAN
  599 # define SUBLANG_ARABIC_JORDAN 0x0b
  600 # endif
  601 # ifndef SUBLANG_ARABIC_LEBANON
  602 # define SUBLANG_ARABIC_LEBANON 0x0c
  603 # endif
  604 # ifndef SUBLANG_ARABIC_KUWAIT
  605 # define SUBLANG_ARABIC_KUWAIT 0x0d
  606 # endif
  607 # ifndef SUBLANG_ARABIC_UAE
  608 # define SUBLANG_ARABIC_UAE 0x0e
  609 # endif
  610 # ifndef SUBLANG_ARABIC_BAHRAIN
  611 # define SUBLANG_ARABIC_BAHRAIN 0x0f
  612 # endif
  613 # ifndef SUBLANG_ARABIC_QATAR
  614 # define SUBLANG_ARABIC_QATAR 0x10
  615 # endif
  616 # ifndef SUBLANG_ARMENIAN_ARMENIA
  617 # define SUBLANG_ARMENIAN_ARMENIA 0x01
  618 # endif
  619 # ifndef SUBLANG_ASSAMESE_INDIA
  620 # define SUBLANG_ASSAMESE_INDIA 0x01
  621 # endif
  622 # ifndef SUBLANG_AZERI_LATIN
  623 # define SUBLANG_AZERI_LATIN 0x01
  624 # endif
  625 # ifndef SUBLANG_AZERI_CYRILLIC
  626 # define SUBLANG_AZERI_CYRILLIC 0x02
  627 # endif
  628 # ifndef SUBLANG_BASHKIR_RUSSIA
  629 # define SUBLANG_BASHKIR_RUSSIA 0x01
  630 # endif
  631 # ifndef SUBLANG_BASQUE_BASQUE
  632 # define SUBLANG_BASQUE_BASQUE 0x01
  633 # endif
  634 # ifndef SUBLANG_BELARUSIAN_BELARUS
  635 # define SUBLANG_BELARUSIAN_BELARUS 0x01
  636 # endif
  637 # ifndef SUBLANG_BENGALI_INDIA
  638 # define SUBLANG_BENGALI_INDIA 0x01
  639 # endif
  640 # ifndef SUBLANG_BENGALI_BANGLADESH
  641 # define SUBLANG_BENGALI_BANGLADESH 0x02
  642 # endif
  643 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
  644 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
  645 # endif
  646 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
  647 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
  648 # endif
  649 # ifndef SUBLANG_BRETON_FRANCE
  650 # define SUBLANG_BRETON_FRANCE 0x01
  651 # endif
  652 # ifndef SUBLANG_BULGARIAN_BULGARIA
  653 # define SUBLANG_BULGARIAN_BULGARIA 0x01
  654 # endif
  655 # ifndef SUBLANG_CAMBODIAN_CAMBODIA
  656 # define SUBLANG_CAMBODIAN_CAMBODIA 0x01
  657 # endif
  658 # ifndef SUBLANG_CATALAN_SPAIN
  659 # define SUBLANG_CATALAN_SPAIN 0x01
  660 # endif
  661 # ifndef SUBLANG_CORSICAN_FRANCE
  662 # define SUBLANG_CORSICAN_FRANCE 0x01
  663 # endif
  664 # ifndef SUBLANG_CROATIAN_CROATIA
  665 # define SUBLANG_CROATIAN_CROATIA 0x01
  666 # endif
  667 # ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
  668 # define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
  669 # endif
  670 # ifndef SUBLANG_CHINESE_MACAU
  671 # define SUBLANG_CHINESE_MACAU 0x05
  672 # endif
  673 # ifndef SUBLANG_CZECH_CZECH_REPUBLIC
  674 # define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
  675 # endif
  676 # ifndef SUBLANG_DANISH_DENMARK
  677 # define SUBLANG_DANISH_DENMARK 0x01
  678 # endif
  679 # ifndef SUBLANG_DARI_AFGHANISTAN
  680 # define SUBLANG_DARI_AFGHANISTAN 0x01
  681 # endif
  682 # ifndef SUBLANG_DIVEHI_MALDIVES
  683 # define SUBLANG_DIVEHI_MALDIVES 0x01
  684 # endif
  685 # ifndef SUBLANG_DUTCH_SURINAM
  686 # define SUBLANG_DUTCH_SURINAM 0x03
  687 # endif
  688 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
  689 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
  690 # endif
  691 # ifndef SUBLANG_ENGLISH_JAMAICA
  692 # define SUBLANG_ENGLISH_JAMAICA 0x08
  693 # endif
  694 # ifndef SUBLANG_ENGLISH_CARIBBEAN
  695 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
  696 # endif
  697 # ifndef SUBLANG_ENGLISH_BELIZE
  698 # define SUBLANG_ENGLISH_BELIZE 0x0a
  699 # endif
  700 # ifndef SUBLANG_ENGLISH_TRINIDAD
  701 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
  702 # endif
  703 # ifndef SUBLANG_ENGLISH_ZIMBABWE
  704 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
  705 # endif
  706 # ifndef SUBLANG_ENGLISH_PHILIPPINES
  707 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
  708 # endif
  709 # ifndef SUBLANG_ENGLISH_INDONESIA
  710 # define SUBLANG_ENGLISH_INDONESIA 0x0e
  711 # endif
  712 # ifndef SUBLANG_ENGLISH_HONGKONG
  713 # define SUBLANG_ENGLISH_HONGKONG 0x0f
  714 # endif
  715 # ifndef SUBLANG_ENGLISH_INDIA
  716 # define SUBLANG_ENGLISH_INDIA 0x10
  717 # endif
  718 # ifndef SUBLANG_ENGLISH_MALAYSIA
  719 # define SUBLANG_ENGLISH_MALAYSIA 0x11
  720 # endif
  721 # ifndef SUBLANG_ENGLISH_SINGAPORE
  722 # define SUBLANG_ENGLISH_SINGAPORE 0x12
  723 # endif
  724 # ifndef SUBLANG_ESTONIAN_ESTONIA
  725 # define SUBLANG_ESTONIAN_ESTONIA 0x01
  726 # endif
  727 # ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
  728 # define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
  729 # endif
  730 # ifndef SUBLANG_FARSI_IRAN
  731 # define SUBLANG_FARSI_IRAN 0x01
  732 # endif
  733 # ifndef SUBLANG_FINNISH_FINLAND
  734 # define SUBLANG_FINNISH_FINLAND 0x01
  735 # endif
  736 # ifndef SUBLANG_FRENCH_LUXEMBOURG
  737 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
  738 # endif
  739 # ifndef SUBLANG_FRENCH_MONACO
  740 # define SUBLANG_FRENCH_MONACO 0x06
  741 # endif
  742 # ifndef SUBLANG_FRENCH_WESTINDIES
  743 # define SUBLANG_FRENCH_WESTINDIES 0x07
  744 # endif
  745 # ifndef SUBLANG_FRENCH_REUNION
  746 # define SUBLANG_FRENCH_REUNION 0x08
  747 # endif
  748 # ifndef SUBLANG_FRENCH_CONGO
  749 # define SUBLANG_FRENCH_CONGO 0x09
  750 # endif
  751 # ifndef SUBLANG_FRENCH_SENEGAL
  752 # define SUBLANG_FRENCH_SENEGAL 0x0a
  753 # endif
  754 # ifndef SUBLANG_FRENCH_CAMEROON
  755 # define SUBLANG_FRENCH_CAMEROON 0x0b
  756 # endif
  757 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
  758 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
  759 # endif
  760 # ifndef SUBLANG_FRENCH_MALI
  761 # define SUBLANG_FRENCH_MALI 0x0d
  762 # endif
  763 # ifndef SUBLANG_FRENCH_MOROCCO
  764 # define SUBLANG_FRENCH_MOROCCO 0x0e
  765 # endif
  766 # ifndef SUBLANG_FRENCH_HAITI
  767 # define SUBLANG_FRENCH_HAITI 0x0f
  768 # endif
  769 # ifndef SUBLANG_FRISIAN_NETHERLANDS
  770 # define SUBLANG_FRISIAN_NETHERLANDS 0x01
  771 # endif
  772 # ifndef SUBLANG_GALICIAN_SPAIN
  773 # define SUBLANG_GALICIAN_SPAIN 0x01
  774 # endif
  775 # ifndef SUBLANG_GEORGIAN_GEORGIA
  776 # define SUBLANG_GEORGIAN_GEORGIA 0x01
  777 # endif
  778 # ifndef SUBLANG_GERMAN_LUXEMBOURG
  779 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
  780 # endif
  781 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
  782 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
  783 # endif
  784 # ifndef SUBLANG_GREEK_GREECE
  785 # define SUBLANG_GREEK_GREECE 0x01
  786 # endif
  787 # ifndef SUBLANG_GREENLANDIC_GREENLAND
  788 # define SUBLANG_GREENLANDIC_GREENLAND 0x01
  789 # endif
  790 # ifndef SUBLANG_GUJARATI_INDIA
  791 # define SUBLANG_GUJARATI_INDIA 0x01
  792 # endif
  793 # ifndef SUBLANG_HAUSA_NIGERIA_LATIN
  794 # define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
  795 # endif
  796 # ifndef SUBLANG_HEBREW_ISRAEL
  797 # define SUBLANG_HEBREW_ISRAEL 0x01
  798 # endif
  799 # ifndef SUBLANG_HINDI_INDIA
  800 # define SUBLANG_HINDI_INDIA 0x01
  801 # endif
  802 # ifndef SUBLANG_HUNGARIAN_HUNGARY
  803 # define SUBLANG_HUNGARIAN_HUNGARY 0x01
  804 # endif
  805 # ifndef SUBLANG_ICELANDIC_ICELAND
  806 # define SUBLANG_ICELANDIC_ICELAND 0x01
  807 # endif
  808 # ifndef SUBLANG_IGBO_NIGERIA
  809 # define SUBLANG_IGBO_NIGERIA 0x01
  810 # endif
  811 # ifndef SUBLANG_INDONESIAN_INDONESIA
  812 # define SUBLANG_INDONESIAN_INDONESIA 0x01
  813 # endif
  814 # ifndef SUBLANG_INUKTITUT_CANADA
  815 # define SUBLANG_INUKTITUT_CANADA 0x01
  816 # endif
  817 # undef SUBLANG_INUKTITUT_CANADA_LATIN
  818 # define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
  819 # undef SUBLANG_IRISH_IRELAND
  820 # define SUBLANG_IRISH_IRELAND 0x02
  821 # ifndef SUBLANG_JAPANESE_JAPAN
  822 # define SUBLANG_JAPANESE_JAPAN 0x01
  823 # endif
  824 # ifndef SUBLANG_KANNADA_INDIA
  825 # define SUBLANG_KANNADA_INDIA 0x01
  826 # endif
  827 # ifndef SUBLANG_KASHMIRI_INDIA
  828 # define SUBLANG_KASHMIRI_INDIA 0x02
  829 # endif
  830 # ifndef SUBLANG_KAZAK_KAZAKHSTAN
  831 # define SUBLANG_KAZAK_KAZAKHSTAN 0x01
  832 # endif
  833 # ifndef SUBLANG_KICHE_GUATEMALA
  834 # define SUBLANG_KICHE_GUATEMALA 0x01
  835 # endif
  836 # ifndef SUBLANG_KINYARWANDA_RWANDA
  837 # define SUBLANG_KINYARWANDA_RWANDA 0x01
  838 # endif
  839 # ifndef SUBLANG_KONKANI_INDIA
  840 # define SUBLANG_KONKANI_INDIA 0x01
  841 # endif
  842 # ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
  843 # define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
  844 # endif
  845 # ifndef SUBLANG_LAO_LAOS
  846 # define SUBLANG_LAO_LAOS 0x01
  847 # endif
  848 # ifndef SUBLANG_LATVIAN_LATVIA
  849 # define SUBLANG_LATVIAN_LATVIA 0x01
  850 # endif
  851 # ifndef SUBLANG_LITHUANIAN_LITHUANIA
  852 # define SUBLANG_LITHUANIAN_LITHUANIA 0x01
  853 # endif
  854 # undef SUBLANG_LOWER_SORBIAN_GERMANY
  855 # define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
  856 # ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
  857 # define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
  858 # endif
  859 # ifndef SUBLANG_MACEDONIAN_MACEDONIA
  860 # define SUBLANG_MACEDONIAN_MACEDONIA 0x01
  861 # endif
  862 # ifndef SUBLANG_MALAY_MALAYSIA
  863 # define SUBLANG_MALAY_MALAYSIA 0x01
  864 # endif
  865 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
  866 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
  867 # endif
  868 # ifndef SUBLANG_MALAYALAM_INDIA
  869 # define SUBLANG_MALAYALAM_INDIA 0x01
  870 # endif
  871 # ifndef SUBLANG_MALTESE_MALTA
  872 # define SUBLANG_MALTESE_MALTA 0x01
  873 # endif
  874 # ifndef SUBLANG_MAORI_NEW_ZEALAND
  875 # define SUBLANG_MAORI_NEW_ZEALAND 0x01
  876 # endif
  877 # ifndef SUBLANG_MAPUDUNGUN_CHILE
  878 # define SUBLANG_MAPUDUNGUN_CHILE 0x01
  879 # endif
  880 # ifndef SUBLANG_MARATHI_INDIA
  881 # define SUBLANG_MARATHI_INDIA 0x01
  882 # endif
  883 # ifndef SUBLANG_MOHAWK_CANADA
  884 # define SUBLANG_MOHAWK_CANADA 0x01
  885 # endif
  886 # ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
  887 # define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
  888 # endif
  889 # ifndef SUBLANG_MONGOLIAN_PRC
  890 # define SUBLANG_MONGOLIAN_PRC 0x02
  891 # endif
  892 # ifndef SUBLANG_NEPALI_NEPAL
  893 # define SUBLANG_NEPALI_NEPAL 0x01
  894 # endif
  895 # ifndef SUBLANG_NEPALI_INDIA
  896 # define SUBLANG_NEPALI_INDIA 0x02
  897 # endif
  898 # ifndef SUBLANG_OCCITAN_FRANCE
  899 # define SUBLANG_OCCITAN_FRANCE 0x01
  900 # endif
  901 # ifndef SUBLANG_ORIYA_INDIA
  902 # define SUBLANG_ORIYA_INDIA 0x01
  903 # endif
  904 # ifndef SUBLANG_PASHTO_AFGHANISTAN
  905 # define SUBLANG_PASHTO_AFGHANISTAN 0x01
  906 # endif
  907 # ifndef SUBLANG_POLISH_POLAND
  908 # define SUBLANG_POLISH_POLAND 0x01
  909 # endif
  910 # ifndef SUBLANG_PUNJABI_INDIA
  911 # define SUBLANG_PUNJABI_INDIA 0x01
  912 # endif
  913 # ifndef SUBLANG_PUNJABI_PAKISTAN
  914 # define SUBLANG_PUNJABI_PAKISTAN 0x02
  915 # endif
  916 # ifndef SUBLANG_QUECHUA_BOLIVIA
  917 # define SUBLANG_QUECHUA_BOLIVIA 0x01
  918 # endif
  919 # ifndef SUBLANG_QUECHUA_ECUADOR
  920 # define SUBLANG_QUECHUA_ECUADOR 0x02
  921 # endif
  922 # ifndef SUBLANG_QUECHUA_PERU
  923 # define SUBLANG_QUECHUA_PERU 0x03
  924 # endif
  925 # ifndef SUBLANG_ROMANIAN_ROMANIA
  926 # define SUBLANG_ROMANIAN_ROMANIA 0x01
  927 # endif
  928 # ifndef SUBLANG_ROMANIAN_MOLDOVA
  929 # define SUBLANG_ROMANIAN_MOLDOVA 0x02
  930 # endif
  931 # ifndef SUBLANG_ROMANSH_SWITZERLAND
  932 # define SUBLANG_ROMANSH_SWITZERLAND 0x01
  933 # endif
  934 # ifndef SUBLANG_RUSSIAN_RUSSIA
  935 # define SUBLANG_RUSSIAN_RUSSIA 0x01
  936 # endif
  937 # ifndef SUBLANG_RUSSIAN_MOLDAVIA
  938 # define SUBLANG_RUSSIAN_MOLDAVIA 0x02
  939 # endif
  940 # ifndef SUBLANG_SAMI_NORTHERN_NORWAY
  941 # define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
  942 # endif
  943 # ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
  944 # define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
  945 # endif
  946 # ifndef SUBLANG_SAMI_NORTHERN_FINLAND
  947 # define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
  948 # endif
  949 # ifndef SUBLANG_SAMI_LULE_NORWAY
  950 # define SUBLANG_SAMI_LULE_NORWAY 0x04
  951 # endif
  952 # ifndef SUBLANG_SAMI_LULE_SWEDEN
  953 # define SUBLANG_SAMI_LULE_SWEDEN 0x05
  954 # endif
  955 # ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
  956 # define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
  957 # endif
  958 # ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
  959 # define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
  960 # endif
  961 # undef SUBLANG_SAMI_SKOLT_FINLAND
  962 # define SUBLANG_SAMI_SKOLT_FINLAND 0x08
  963 # undef SUBLANG_SAMI_INARI_FINLAND
  964 # define SUBLANG_SAMI_INARI_FINLAND 0x09
  965 # ifndef SUBLANG_SANSKRIT_INDIA
  966 # define SUBLANG_SANSKRIT_INDIA 0x01
  967 # endif
  968 # ifndef SUBLANG_SERBIAN_LATIN
  969 # define SUBLANG_SERBIAN_LATIN 0x02
  970 # endif
  971 # ifndef SUBLANG_SERBIAN_CYRILLIC
  972 # define SUBLANG_SERBIAN_CYRILLIC 0x03
  973 # endif
  974 # ifndef SUBLANG_SINDHI_INDIA
  975 # define SUBLANG_SINDHI_INDIA 0x01
  976 # endif
  977 # undef SUBLANG_SINDHI_PAKISTAN
  978 # define SUBLANG_SINDHI_PAKISTAN 0x02
  979 # ifndef SUBLANG_SINDHI_AFGHANISTAN
  980 # define SUBLANG_SINDHI_AFGHANISTAN 0x02
  981 # endif
  982 # ifndef SUBLANG_SINHALESE_SRI_LANKA
  983 # define SUBLANG_SINHALESE_SRI_LANKA 0x01
  984 # endif
  985 # ifndef SUBLANG_SLOVAK_SLOVAKIA
  986 # define SUBLANG_SLOVAK_SLOVAKIA 0x01
  987 # endif
  988 # ifndef SUBLANG_SLOVENIAN_SLOVENIA
  989 # define SUBLANG_SLOVENIAN_SLOVENIA 0x01
  990 # endif
  991 # ifndef SUBLANG_SOTHO_SOUTH_AFRICA
  992 # define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
  993 # endif
  994 # ifndef SUBLANG_SPANISH_GUATEMALA
  995 # define SUBLANG_SPANISH_GUATEMALA 0x04
  996 # endif
  997 # ifndef SUBLANG_SPANISH_COSTA_RICA
  998 # define SUBLANG_SPANISH_COSTA_RICA 0x05
  999 # endif
 1000 # ifndef SUBLANG_SPANISH_PANAMA
 1001 # define SUBLANG_SPANISH_PANAMA 0x06
 1002 # endif
 1003 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
 1004 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
 1005 # endif
 1006 # ifndef SUBLANG_SPANISH_VENEZUELA
 1007 # define SUBLANG_SPANISH_VENEZUELA 0x08
 1008 # endif
 1009 # ifndef SUBLANG_SPANISH_COLOMBIA
 1010 # define SUBLANG_SPANISH_COLOMBIA 0x09
 1011 # endif
 1012 # ifndef SUBLANG_SPANISH_PERU
 1013 # define SUBLANG_SPANISH_PERU 0x0a
 1014 # endif
 1015 # ifndef SUBLANG_SPANISH_ARGENTINA
 1016 # define SUBLANG_SPANISH_ARGENTINA 0x0b
 1017 # endif
 1018 # ifndef SUBLANG_SPANISH_ECUADOR
 1019 # define SUBLANG_SPANISH_ECUADOR 0x0c
 1020 # endif
 1021 # ifndef SUBLANG_SPANISH_CHILE
 1022 # define SUBLANG_SPANISH_CHILE 0x0d
 1023 # endif
 1024 # ifndef SUBLANG_SPANISH_URUGUAY
 1025 # define SUBLANG_SPANISH_URUGUAY 0x0e
 1026 # endif
 1027 # ifndef SUBLANG_SPANISH_PARAGUAY
 1028 # define SUBLANG_SPANISH_PARAGUAY 0x0f
 1029 # endif
 1030 # ifndef SUBLANG_SPANISH_BOLIVIA
 1031 # define SUBLANG_SPANISH_BOLIVIA 0x10
 1032 # endif
 1033 # ifndef SUBLANG_SPANISH_EL_SALVADOR
 1034 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
 1035 # endif
 1036 # ifndef SUBLANG_SPANISH_HONDURAS
 1037 # define SUBLANG_SPANISH_HONDURAS 0x12
 1038 # endif
 1039 # ifndef SUBLANG_SPANISH_NICARAGUA
 1040 # define SUBLANG_SPANISH_NICARAGUA 0x13
 1041 # endif
 1042 # ifndef SUBLANG_SPANISH_PUERTO_RICO
 1043 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
 1044 # endif
 1045 # ifndef SUBLANG_SPANISH_US
 1046 # define SUBLANG_SPANISH_US 0x15
 1047 # endif
 1048 # ifndef SUBLANG_SWAHILI_KENYA
 1049 # define SUBLANG_SWAHILI_KENYA 0x01
 1050 # endif
 1051 # ifndef SUBLANG_SWEDISH_SWEDEN
 1052 # define SUBLANG_SWEDISH_SWEDEN 0x01
 1053 # endif
 1054 # ifndef SUBLANG_SWEDISH_FINLAND
 1055 # define SUBLANG_SWEDISH_FINLAND 0x02
 1056 # endif
 1057 # ifndef SUBLANG_SYRIAC_SYRIA
 1058 # define SUBLANG_SYRIAC_SYRIA 0x01
 1059 # endif
 1060 # ifndef SUBLANG_TAGALOG_PHILIPPINES
 1061 # define SUBLANG_TAGALOG_PHILIPPINES 0x01
 1062 # endif
 1063 # ifndef SUBLANG_TAJIK_TAJIKISTAN
 1064 # define SUBLANG_TAJIK_TAJIKISTAN 0x01
 1065 # endif
 1066 # ifndef SUBLANG_TAMAZIGHT_ARABIC
 1067 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
 1068 # endif
 1069 # ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
 1070 # define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
 1071 # endif
 1072 # ifndef SUBLANG_TAMIL_INDIA
 1073 # define SUBLANG_TAMIL_INDIA 0x01
 1074 # endif
 1075 # ifndef SUBLANG_TATAR_RUSSIA
 1076 # define SUBLANG_TATAR_RUSSIA 0x01
 1077 # endif
 1078 # ifndef SUBLANG_TELUGU_INDIA
 1079 # define SUBLANG_TELUGU_INDIA 0x01
 1080 # endif
 1081 # ifndef SUBLANG_THAI_THAILAND
 1082 # define SUBLANG_THAI_THAILAND 0x01
 1083 # endif
 1084 # ifndef SUBLANG_TIBETAN_PRC
 1085 # define SUBLANG_TIBETAN_PRC 0x01
 1086 # endif
 1087 # undef SUBLANG_TIBETAN_BHUTAN
 1088 # define SUBLANG_TIBETAN_BHUTAN 0x02
 1089 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
 1090 # define SUBLANG_TIGRINYA_ETHIOPIA 0x01
 1091 # endif
 1092 # ifndef SUBLANG_TIGRINYA_ERITREA
 1093 # define SUBLANG_TIGRINYA_ERITREA 0x02
 1094 # endif
 1095 # ifndef SUBLANG_TSWANA_SOUTH_AFRICA
 1096 # define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
 1097 # endif
 1098 # ifndef SUBLANG_TURKISH_TURKEY
 1099 # define SUBLANG_TURKISH_TURKEY 0x01
 1100 # endif
 1101 # ifndef SUBLANG_TURKMEN_TURKMENISTAN
 1102 # define SUBLANG_TURKMEN_TURKMENISTAN 0x01
 1103 # endif
 1104 # ifndef SUBLANG_UIGHUR_PRC
 1105 # define SUBLANG_UIGHUR_PRC 0x01
 1106 # endif
 1107 # ifndef SUBLANG_UKRAINIAN_UKRAINE
 1108 # define SUBLANG_UKRAINIAN_UKRAINE 0x01
 1109 # endif
 1110 # ifndef SUBLANG_UPPER_SORBIAN_GERMANY
 1111 # define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
 1112 # endif
 1113 # ifndef SUBLANG_URDU_PAKISTAN
 1114 # define SUBLANG_URDU_PAKISTAN 0x01
 1115 # endif
 1116 # ifndef SUBLANG_URDU_INDIA
 1117 # define SUBLANG_URDU_INDIA 0x02
 1118 # endif
 1119 # ifndef SUBLANG_UZBEK_LATIN
 1120 # define SUBLANG_UZBEK_LATIN 0x01
 1121 # endif
 1122 # ifndef SUBLANG_UZBEK_CYRILLIC
 1123 # define SUBLANG_UZBEK_CYRILLIC 0x02
 1124 # endif
 1125 # ifndef SUBLANG_VIETNAMESE_VIETNAM
 1126 # define SUBLANG_VIETNAMESE_VIETNAM 0x01
 1127 # endif
 1128 # ifndef SUBLANG_WELSH_UNITED_KINGDOM
 1129 # define SUBLANG_WELSH_UNITED_KINGDOM 0x01
 1130 # endif
 1131 # ifndef SUBLANG_WOLOF_SENEGAL
 1132 # define SUBLANG_WOLOF_SENEGAL 0x01
 1133 # endif
 1134 # ifndef SUBLANG_XHOSA_SOUTH_AFRICA
 1135 # define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
 1136 # endif
 1137 # ifndef SUBLANG_YAKUT_RUSSIA
 1138 # define SUBLANG_YAKUT_RUSSIA 0x01
 1139 # endif
 1140 # ifndef SUBLANG_YI_PRC
 1141 # define SUBLANG_YI_PRC 0x01
 1142 # endif
 1143 # ifndef SUBLANG_YORUBA_NIGERIA
 1144 # define SUBLANG_YORUBA_NIGERIA 0x01
 1145 # endif
 1146 # ifndef SUBLANG_ZULU_SOUTH_AFRICA
 1147 # define SUBLANG_ZULU_SOUTH_AFRICA 0x01
 1148 # endif
 1149 /* GetLocaleInfoA operations.  */
 1150 # ifndef LOCALE_SNAME
 1151 # define LOCALE_SNAME 0x5c
 1152 # endif
 1153 # ifndef LOCALE_NAME_MAX_LENGTH
 1154 # define LOCALE_NAME_MAX_LENGTH 85
 1155 # endif
 1156 #endif
 1157 
 1158 
 1159 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
 1160 /* Mac OS X 10.4 or newer */
 1161 
 1162 /* Canonicalize a Mac OS X locale name to a Unix locale name.
 1163    NAME is a sufficiently large buffer.
 1164    On input, it contains the Mac OS X locale name.
 1165    On output, it contains the Unix locale name.  */
 1166 # if !defined IN_LIBINTL
 1167 static
 1168 # endif
 1169 void
 1170 gl_locale_name_canonicalize (char *name)
 1171 {
 1172   /* This conversion is based on a posting by
 1173      Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
 1174      https://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
 1175 
 1176   /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
 1177      ISO 3166) names.  Prior to Mac OS X 10.3, there is no API for doing this.
 1178      Therefore we do it ourselves, using a table based on the results of the
 1179      Mac OS X 10.3.8 function
 1180      CFLocaleCreateCanonicalLocaleIdentifierFromString().  */
 1181   typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
 1182           legacy_entry;
 1183   static const legacy_entry legacy_table[] = {
 1184     { "Afrikaans",             "af" },
 1185     { "Albanian",              "sq" },
 1186     { "Amharic",               "am" },
 1187     { "Arabic",                "ar" },
 1188     { "Armenian",              "hy" },
 1189     { "Assamese",              "as" },
 1190     { "Aymara",                "ay" },
 1191     { "Azerbaijani",           "az" },
 1192     { "Basque",                "eu" },
 1193     { "Belarusian",            "be" },
 1194     { "Belorussian",           "be" },
 1195     { "Bengali",               "bn" },
 1196     { "Brazilian Portugese",   "pt_BR" },
 1197     { "Brazilian Portuguese",  "pt_BR" },
 1198     { "Breton",                "br" },
 1199     { "Bulgarian",             "bg" },
 1200     { "Burmese",               "my" },
 1201     { "Byelorussian",          "be" },
 1202     { "Catalan",               "ca" },
 1203     { "Chewa",                 "ny" },
 1204     { "Chichewa",              "ny" },
 1205     { "Chinese",               "zh" },
 1206     { "Chinese, Simplified",   "zh_CN" },
 1207     { "Chinese, Traditional",  "zh_TW" },
 1208     { "Chinese, Tradtional",   "zh_TW" },
 1209     { "Croatian",              "hr" },
 1210     { "Czech",                 "cs" },
 1211     { "Danish",                "da" },
 1212     { "Dutch",                 "nl" },
 1213     { "Dzongkha",              "dz" },
 1214     { "English",               "en" },
 1215     { "Esperanto",             "eo" },
 1216     { "Estonian",              "et" },
 1217     { "Faroese",               "fo" },
 1218     { "Farsi",                 "fa" },
 1219     { "Finnish",               "fi" },
 1220     { "Flemish",               "nl_BE" },
 1221     { "French",                "fr" },
 1222     { "Galician",              "gl" },
 1223     { "Gallegan",              "gl" },
 1224     { "Georgian",              "ka" },
 1225     { "German",                "de" },
 1226     { "Greek",                 "el" },
 1227     { "Greenlandic",           "kl" },
 1228     { "Guarani",               "gn" },
 1229     { "Gujarati",              "gu" },
 1230     { "Hawaiian",              "haw" }, /* Yes, "haw", not "cpe".  */
 1231     { "Hebrew",                "he" },
 1232     { "Hindi",                 "hi" },
 1233     { "Hungarian",             "hu" },
 1234     { "Icelandic",             "is" },
 1235     { "Indonesian",            "id" },
 1236     { "Inuktitut",             "iu" },
 1237     { "Irish",                 "ga" },
 1238     { "Italian",               "it" },
 1239     { "Japanese",              "ja" },
 1240     { "Javanese",              "jv" },
 1241     { "Kalaallisut",           "kl" },
 1242     { "Kannada",               "kn" },
 1243     { "Kashmiri",              "ks" },
 1244     { "Kazakh",                "kk" },
 1245     { "Khmer",                 "km" },
 1246     { "Kinyarwanda",           "rw" },
 1247     { "Kirghiz",               "ky" },
 1248     { "Korean",                "ko" },
 1249     { "Kurdish",               "ku" },
 1250     { "Latin",                 "la" },
 1251     { "Latvian",               "lv" },
 1252     { "Lithuanian",            "lt" },
 1253     { "Macedonian",            "mk" },
 1254     { "Malagasy",              "mg" },
 1255     { "Malay",                 "ms" },
 1256     { "Malayalam",             "ml" },
 1257     { "Maltese",               "mt" },
 1258     { "Manx",                  "gv" },
 1259     { "Marathi",               "mr" },
 1260     { "Moldavian",             "mo" },
 1261     { "Mongolian",             "mn" },
 1262     { "Nepali",                "ne" },
 1263     { "Norwegian",             "nb" }, /* Yes, "nb", not the obsolete "no".  */
 1264     { "Nyanja",                "ny" },
 1265     { "Nynorsk",               "nn" },
 1266     { "Oriya",                 "or" },
 1267     { "Oromo",                 "om" },
 1268     { "Panjabi",               "pa" },
 1269     { "Pashto",                "ps" },
 1270     { "Persian",               "fa" },
 1271     { "Polish",                "pl" },
 1272     { "Portuguese",            "pt" },
 1273     { "Portuguese, Brazilian", "pt_BR" },
 1274     { "Punjabi",               "pa" },
 1275     { "Pushto",                "ps" },
 1276     { "Quechua",               "qu" },
 1277     { "Romanian",              "ro" },
 1278     { "Ruanda",                "rw" },
 1279     { "Rundi",                 "rn" },
 1280     { "Russian",               "ru" },
 1281     { "Sami",                  "se_NO" }, /* Not just "se".  */
 1282     { "Sanskrit",              "sa" },
 1283     { "Scottish",              "gd" },
 1284     { "Serbian",               "sr" },
 1285     { "Simplified Chinese",    "zh_CN" },
 1286     { "Sindhi",                "sd" },
 1287     { "Sinhalese",             "si" },
 1288     { "Slovak",                "sk" },
 1289     { "Slovenian",             "sl" },
 1290     { "Somali",                "so" },
 1291     { "Spanish",               "es" },
 1292     { "Sundanese",             "su" },
 1293     { "Swahili",               "sw" },
 1294     { "Swedish",               "sv" },
 1295     { "Tagalog",               "tl" },
 1296     { "Tajik",                 "tg" },
 1297     { "Tajiki",                "tg" },
 1298     { "Tamil",                 "ta" },
 1299     { "Tatar",                 "tt" },
 1300     { "Telugu",                "te" },
 1301     { "Thai",                  "th" },
 1302     { "Tibetan",               "bo" },
 1303     { "Tigrinya",              "ti" },
 1304     { "Tongan",                "to" },
 1305     { "Traditional Chinese",   "zh_TW" },
 1306     { "Turkish",               "tr" },
 1307     { "Turkmen",               "tk" },
 1308     { "Uighur",                "ug" },
 1309     { "Ukrainian",             "uk" },
 1310     { "Urdu",                  "ur" },
 1311     { "Uzbek",                 "uz" },
 1312     { "Vietnamese",            "vi" },
 1313     { "Welsh",                 "cy" },
 1314     { "Yiddish",               "yi" }
 1315   };
 1316 
 1317   /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
 1318      to Unix (ISO 639 and ISO 3166) names.  */
 1319   typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
 1320           langtag_entry;
 1321   static const langtag_entry langtag_table[] = {
 1322     /* Mac OS X has "az-Arab", "az-Cyrl", "az-Latn".
 1323        The default script for az on Unix is Latin.  */
 1324     { "az-Latn", "az" },
 1325     /* Mac OS X has "bs-Cyrl", "bs-Latn".
 1326        The default script for bs on Unix is Latin.  */
 1327     { "bs-Latn", "bs" },
 1328     /* Mac OS X has "ga-dots".  Does not yet exist on Unix.  */
 1329     { "ga-dots", "ga" },
 1330     /* Mac OS X has "kk-Cyrl".
 1331        The default script for kk on Unix is Cyrillic.  */
 1332     { "kk-Cyrl", "kk" },
 1333     /* Mac OS X has "mn-Cyrl", "mn-Mong".
 1334        The default script for mn on Unix is Cyrillic.  */
 1335     { "mn-Cyrl", "mn" },
 1336     /* Mac OS X has "ms-Arab", "ms-Latn".
 1337        The default script for ms on Unix is Latin.  */
 1338     { "ms-Latn", "ms" },
 1339     /* Mac OS X has "pa-Arab", "pa-Guru".
 1340        Country codes are used to distinguish these on Unix.  */
 1341     { "pa-Arab", "pa_PK" },
 1342     { "pa-Guru", "pa_IN" },
 1343     /* Mac OS X has "shi-Latn", "shi-Tfng".  Does not yet exist on Unix.  */
 1344     /* Mac OS X has "sr-Cyrl", "sr-Latn".
 1345        The default script for sr on Unix is Cyrillic.  */
 1346     { "sr-Cyrl", "sr" },
 1347     /* Mac OS X has "tg-Cyrl".
 1348        The default script for tg on Unix is Cyrillic.  */
 1349     { "tg-Cyrl", "tg" },
 1350     /* Mac OS X has "tk-Cyrl".
 1351        The default script for tk on Unix is Cyrillic.  */
 1352     { "tk-Cyrl", "tk" },
 1353     /* Mac OS X has "tt-Cyrl".
 1354        The default script for tt on Unix is Cyrillic.  */
 1355     { "tt-Cyrl", "tt" },
 1356     /* Mac OS X has "uz-Arab", "uz-Cyrl", "uz-Latn".
 1357        The default script for uz on Unix is Latin.  */
 1358     { "uz-Latn", "uz" },
 1359     /* Mac OS X has "vai-Latn", "vai-Vaii".  Does not yet exist on Unix.  */
 1360     /* Mac OS X has "yue-Hans", "yue-Hant".
 1361        The default script for yue on Unix is Simplified Han.  */
 1362     { "yue-Hans", "yue" },
 1363     /* Mac OS X has "zh-Hans", "zh-Hant".
 1364        Country codes are used to distinguish these on Unix.  */
 1365     { "zh-Hans", "zh_CN" },
 1366     { "zh-Hant", "zh_TW" }
 1367   };
 1368 
 1369   /* Convert script names (ISO 15924) to Unix conventions.
 1370      See https://www.unicode.org/iso15924/iso15924-codes.html  */
 1371   typedef struct { const char script[4+1]; const char unixy[9+1]; }
 1372           script_entry;
 1373   static const script_entry script_table[] = {
 1374     { "Arab", "arabic" },
 1375     { "Cyrl", "cyrillic" },
 1376     { "Latn", "latin" },
 1377     { "Mong", "mongolian" }
 1378   };
 1379 
 1380   /* Step 1: Convert using legacy_table.  */
 1381   if (name[0] >= 'A' && name[0] <= 'Z')
 1382     {
 1383       unsigned int i1, i2;
 1384       i1 = 0;
 1385       i2 = sizeof (legacy_table) / sizeof (legacy_entry);
 1386       while (i2 - i1 > 1)
 1387         {
 1388           /* At this point we know that if name occurs in legacy_table,
 1389              its index must be >= i1 and < i2.  */
 1390           unsigned int i = (i1 + i2) >> 1;
 1391           const legacy_entry *p = &legacy_table[i];
 1392           if (strcmp (name, p->legacy) < 0)
 1393             i2 = i;
 1394           else
 1395             i1 = i;
 1396         }
 1397       if (strcmp (name, legacy_table[i1].legacy) == 0)
 1398         {
 1399           strcpy (name, legacy_table[i1].unixy);
 1400           return;
 1401         }
 1402     }
 1403 
 1404   /* Step 2: Convert using langtag_table and script_table.  */
 1405   if (strlen (name) == 7 && name[2] == '-')
 1406     {
 1407       unsigned int i1, i2;
 1408       i1 = 0;
 1409       i2 = sizeof (langtag_table) / sizeof (langtag_entry);
 1410       while (i2 - i1 > 1)
 1411         {
 1412           /* At this point we know that if name occurs in langtag_table,
 1413              its index must be >= i1 and < i2.  */
 1414           unsigned int i = (i1 + i2) >> 1;
 1415           const langtag_entry *p = &langtag_table[i];
 1416           if (strcmp (name, p->langtag) < 0)
 1417             i2 = i;
 1418           else
 1419             i1 = i;
 1420         }
 1421       if (strcmp (name, langtag_table[i1].langtag) == 0)
 1422         {
 1423           strcpy (name, langtag_table[i1].unixy);
 1424           return;
 1425         }
 1426 
 1427       i1 = 0;
 1428       i2 = sizeof (script_table) / sizeof (script_entry);
 1429       while (i2 - i1 > 1)
 1430         {
 1431           /* At this point we know that if (name + 3) occurs in script_table,
 1432              its index must be >= i1 and < i2.  */
 1433           unsigned int i = (i1 + i2) >> 1;
 1434           const script_entry *p = &script_table[i];
 1435           if (strcmp (name + 3, p->script) < 0)
 1436             i2 = i;
 1437           else
 1438             i1 = i;
 1439         }
 1440       if (strcmp (name + 3, script_table[i1].script) == 0)
 1441         {
 1442           name[2] = '@';
 1443           strcpy (name + 3, script_table[i1].unixy);
 1444           return;
 1445         }
 1446     }
 1447 
 1448   /* Step 3: Convert new-style dash to Unix underscore. */
 1449   {
 1450     char *p;
 1451     for (p = name; *p != '\0'; p++)
 1452       if (*p == '-')
 1453         *p = '_';
 1454   }
 1455 }
 1456 
 1457 #endif
 1458 
 1459 
 1460 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
 1461 
 1462 /* Canonicalize a Windows native locale name to a Unix locale name.
 1463    NAME is a sufficiently large buffer.
 1464    On input, it contains the Windows locale name.
 1465    On output, it contains the Unix locale name.  */
 1466 # if !defined IN_LIBINTL
 1467 static
 1468 # endif
 1469 void
 1470 gl_locale_name_canonicalize (char *name)
 1471 {
 1472   /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
 1473      "zh-Hant".  */
 1474   char *p;
 1475 
 1476   for (p = name; *p != '\0'; p++)
 1477     if (*p == '-')
 1478       {
 1479         *p = '_';
 1480         p++;
 1481         for (; *p != '\0'; p++)
 1482           {
 1483             if (*p >= 'a' && *p <= 'z')
 1484               *p += 'A' - 'a';
 1485             if (*p == '-')
 1486               {
 1487                 *p = '\0';
 1488                 return;
 1489               }
 1490           }
 1491         return;
 1492       }
 1493 }
 1494 
 1495 # if !defined IN_LIBINTL
 1496 static
 1497 # endif
 1498 const char *
 1499 gl_locale_name_from_win32_LANGID (LANGID langid)
 1500 {
 1501   /* Activate the new code only when the GETTEXT_MUI environment variable is
 1502      set, for the time being, since the new code is not well tested.  */
 1503   if (getenv ("GETTEXT_MUI") != NULL)
 1504     {
 1505       static char namebuf[256];
 1506 
 1507       /* Query the system's notion of locale name.
 1508          On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
 1509          But we don't need to support systems that are so old.  */
 1510       if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
 1511                           namebuf, sizeof (namebuf) - 1))
 1512         {
 1513           /* Convert it to a Unix locale name.  */
 1514           gl_locale_name_canonicalize (namebuf);
 1515           return namebuf;
 1516         }
 1517     }
 1518   /* Internet Explorer has an LCID to RFC3066 name mapping stored in
 1519      HKEY_CLASSES_ROOT\Mime\Database\Rfc1766.  But we better don't use that
 1520      since IE's i18n subsystem is known to be inconsistent with the native
 1521      Windows base (e.g. they have different character conversion facilities
 1522      that produce different results).  */
 1523   /* Use our own table.  */
 1524   {
 1525     int primary, sub;
 1526 
 1527     /* Split into language and territory part.  */
 1528     primary = PRIMARYLANGID (langid);
 1529     sub = SUBLANGID (langid);
 1530 
 1531     /* Dispatch on language.
 1532        See also https://www.unicode.org/unicode/onlinedat/languages.html .
 1533        For details about languages, see https://www.ethnologue.com/ .  */
 1534     switch (primary)
 1535       {
 1536       case LANG_AFRIKAANS:
 1537         switch (sub)
 1538           {
 1539           case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
 1540           }
 1541         return "af";
 1542       case LANG_ALBANIAN:
 1543         switch (sub)
 1544           {
 1545           case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
 1546           }
 1547         return "sq";
 1548       case LANG_ALSATIAN:
 1549         switch (sub)
 1550           {
 1551           case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
 1552           }
 1553         return "gsw";
 1554       case LANG_AMHARIC:
 1555         switch (sub)
 1556           {
 1557           case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
 1558           }
 1559         return "am";
 1560       case LANG_ARABIC:
 1561         switch (sub)
 1562           {
 1563           case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
 1564           case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
 1565           case SUBLANG_ARABIC_EGYPT: return "ar_EG";
 1566           case SUBLANG_ARABIC_LIBYA: return "ar_LY";
 1567           case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
 1568           case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
 1569           case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
 1570           case SUBLANG_ARABIC_OMAN: return "ar_OM";
 1571           case SUBLANG_ARABIC_YEMEN: return "ar_YE";
 1572           case SUBLANG_ARABIC_SYRIA: return "ar_SY";
 1573           case SUBLANG_ARABIC_JORDAN: return "ar_JO";
 1574           case SUBLANG_ARABIC_LEBANON: return "ar_LB";
 1575           case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
 1576           case SUBLANG_ARABIC_UAE: return "ar_AE";
 1577           case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
 1578           case SUBLANG_ARABIC_QATAR: return "ar_QA";
 1579           }
 1580         return "ar";
 1581       case LANG_ARMENIAN:
 1582         switch (sub)
 1583           {
 1584           case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
 1585           }
 1586         return "hy";
 1587       case LANG_ASSAMESE:
 1588         switch (sub)
 1589           {
 1590           case SUBLANG_ASSAMESE_INDIA: return "as_IN";
 1591           }
 1592         return "as";
 1593       case LANG_AZERI:
 1594         switch (sub)
 1595           {
 1596           /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
 1597           case 0x1e: return "az@latin";
 1598           case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
 1599           case 0x1d: return "az@cyrillic";
 1600           case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
 1601           }
 1602         return "az";
 1603       case LANG_BASHKIR:
 1604         switch (sub)
 1605           {
 1606           case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
 1607           }
 1608         return "ba";
 1609       case LANG_BASQUE:
 1610         switch (sub)
 1611           {
 1612           case SUBLANG_BASQUE_BASQUE: return "eu_ES";
 1613           }
 1614         return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
 1615       case LANG_BELARUSIAN:
 1616         switch (sub)
 1617           {
 1618           case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
 1619           }
 1620         return "be";
 1621       case LANG_BENGALI:
 1622         switch (sub)
 1623           {
 1624           case SUBLANG_BENGALI_INDIA: return "bn_IN";
 1625           case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
 1626           }
 1627         return "bn";
 1628       case LANG_BRETON:
 1629         switch (sub)
 1630           {
 1631           case SUBLANG_BRETON_FRANCE: return "br_FR";
 1632           }
 1633         return "br";
 1634       case LANG_BULGARIAN:
 1635         switch (sub)
 1636           {
 1637           case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
 1638           }
 1639         return "bg";
 1640       case LANG_BURMESE:
 1641         switch (sub)
 1642           {
 1643           case SUBLANG_DEFAULT: return "my_MM";
 1644           }
 1645         return "my";
 1646       case LANG_CAMBODIAN:
 1647         switch (sub)
 1648           {
 1649           case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
 1650           }
 1651         return "km";
 1652       case LANG_CATALAN:
 1653         switch (sub)
 1654           {
 1655           case SUBLANG_CATALAN_SPAIN: return "ca_ES";
 1656           }
 1657         return "ca";
 1658       case LANG_CHEROKEE:
 1659         switch (sub)
 1660           {
 1661           case SUBLANG_DEFAULT: return "chr_US";
 1662           }
 1663         return "chr";
 1664       case LANG_CHINESE:
 1665         switch (sub)
 1666           {
 1667           case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
 1668           case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
 1669           case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
 1670           case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
 1671           case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
 1672           }
 1673         return "zh";
 1674       case LANG_CORSICAN:
 1675         switch (sub)
 1676           {
 1677           case SUBLANG_CORSICAN_FRANCE: return "co_FR";
 1678           }
 1679         return "co";
 1680       case LANG_CROATIAN:      /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
 1681                                 * What used to be called Serbo-Croatian
 1682                                 * should really now be two separate
 1683                                 * languages because of political reasons.
 1684                                 * (Says tml, who knows nothing about Serbian
 1685                                 * or Croatian.)
 1686                                 * (I can feel those flames coming already.)
 1687                                 */
 1688         switch (sub)
 1689           {
 1690           /* Croatian */
 1691           case 0x00: return "hr";
 1692           case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
 1693           case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
 1694           /* Serbian */
 1695           case 0x1f: return "sr";
 1696           case 0x1c: return "sr"; /* latin */
 1697           case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
 1698           case 0x09: return "sr_RS"; /* latin */
 1699           case 0x0b: return "sr_ME"; /* latin */
 1700           case 0x06: return "sr_BA"; /* latin */
 1701           case 0x1b: return "sr@cyrillic";
 1702           case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
 1703           case 0x0a: return "sr_RS@cyrillic";
 1704           case 0x0c: return "sr_ME@cyrillic";
 1705           case 0x07: return "sr_BA@cyrillic";
 1706           /* Bosnian */
 1707           case 0x1e: return "bs";
 1708           case 0x1a: return "bs"; /* latin */
 1709           case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
 1710           case 0x19: return "bs@cyrillic";
 1711           case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
 1712           }
 1713         return "hr";
 1714       case LANG_CZECH:
 1715         switch (sub)
 1716           {
 1717           case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
 1718           }
 1719         return "cs";
 1720       case LANG_DANISH:
 1721         switch (sub)
 1722           {
 1723           case SUBLANG_DANISH_DENMARK: return "da_DK";
 1724           }
 1725         return "da";
 1726       case LANG_DARI:
 1727         /* FIXME: Adjust this when such locales appear on Unix.  */
 1728         switch (sub)
 1729           {
 1730           case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
 1731           }
 1732         return "prs";
 1733       case LANG_DIVEHI:
 1734         switch (sub)
 1735           {
 1736           case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
 1737           }
 1738         return "dv";
 1739       case LANG_DUTCH:
 1740         switch (sub)
 1741           {
 1742           case SUBLANG_DUTCH: return "nl_NL";
 1743           case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
 1744           case SUBLANG_DUTCH_SURINAM: return "nl_SR";
 1745           }
 1746         return "nl";
 1747       case LANG_EDO:
 1748         switch (sub)
 1749           {
 1750           case SUBLANG_DEFAULT: return "bin_NG";
 1751           }
 1752         return "bin";
 1753       case LANG_ENGLISH:
 1754         switch (sub)
 1755           {
 1756           /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
 1757            * English was the language spoken in England.
 1758            * Oh well.
 1759            */
 1760           case SUBLANG_ENGLISH_US: return "en_US";
 1761           case SUBLANG_ENGLISH_UK: return "en_GB";
 1762           case SUBLANG_ENGLISH_AUS: return "en_AU";
 1763           case SUBLANG_ENGLISH_CAN: return "en_CA";
 1764           case SUBLANG_ENGLISH_NZ: return "en_NZ";
 1765           case SUBLANG_ENGLISH_EIRE: return "en_IE";
 1766           case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
 1767           case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
 1768           case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
 1769           case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
 1770           case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
 1771           case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
 1772           case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
 1773           case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
 1774           case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
 1775           case SUBLANG_ENGLISH_INDIA: return "en_IN";
 1776           case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
 1777           case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
 1778           }
 1779         return "en";
 1780       case LANG_ESTONIAN:
 1781         switch (sub)
 1782           {
 1783           case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
 1784           }
 1785         return "et";
 1786       case LANG_FAEROESE:
 1787         switch (sub)
 1788           {
 1789           case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
 1790           }
 1791         return "fo";
 1792       case LANG_FARSI:
 1793         switch (sub)
 1794           {
 1795           case SUBLANG_FARSI_IRAN: return "fa_IR";
 1796           }
 1797         return "fa";
 1798       case LANG_FINNISH:
 1799         switch (sub)
 1800           {
 1801           case SUBLANG_FINNISH_FINLAND: return "fi_FI";
 1802           }
 1803         return "fi";
 1804       case LANG_FRENCH:
 1805         switch (sub)
 1806           {
 1807           case SUBLANG_FRENCH: return "fr_FR";
 1808           case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
 1809           case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
 1810           case SUBLANG_FRENCH_SWISS: return "fr_CH";
 1811           case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
 1812           case SUBLANG_FRENCH_MONACO: return "fr_MC";
 1813           case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
 1814           case SUBLANG_FRENCH_REUNION: return "fr_RE";
 1815           case SUBLANG_FRENCH_CONGO: return "fr_CG";
 1816           case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
 1817           case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
 1818           case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
 1819           case SUBLANG_FRENCH_MALI: return "fr_ML";
 1820           case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
 1821           case SUBLANG_FRENCH_HAITI: return "fr_HT";
 1822           }
 1823         return "fr";
 1824       case LANG_FRISIAN:
 1825         switch (sub)
 1826           {
 1827           case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
 1828           }
 1829         return "fy";
 1830       case LANG_FULFULDE:
 1831         /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin.  */
 1832         switch (sub)
 1833           {
 1834           case SUBLANG_DEFAULT: return "ff_NG";
 1835           }
 1836         return "ff";
 1837       case LANG_GAELIC:
 1838         switch (sub)
 1839           {
 1840           case 0x01: /* SCOTTISH */
 1841             /* old, superseded by LANG_SCOTTISH_GAELIC */
 1842             return "gd_GB";
 1843           case SUBLANG_IRISH_IRELAND: return "ga_IE";
 1844           }
 1845         return "ga";
 1846       case LANG_GALICIAN:
 1847         switch (sub)
 1848           {
 1849           case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
 1850           }
 1851         return "gl";
 1852       case LANG_GEORGIAN:
 1853         switch (sub)
 1854           {
 1855           case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
 1856           }
 1857         return "ka";
 1858       case LANG_GERMAN:
 1859         switch (sub)
 1860           {
 1861           case SUBLANG_GERMAN: return "de_DE";
 1862           case SUBLANG_GERMAN_SWISS: return "de_CH";
 1863           case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
 1864           case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
 1865           case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
 1866           }
 1867         return "de";
 1868       case LANG_GREEK:
 1869         switch (sub)
 1870           {
 1871           case SUBLANG_GREEK_GREECE: return "el_GR";
 1872           }
 1873         return "el";
 1874       case LANG_GREENLANDIC:
 1875         switch (sub)
 1876           {
 1877           case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
 1878           }
 1879         return "kl";
 1880       case LANG_GUARANI:
 1881         switch (sub)
 1882           {
 1883           case SUBLANG_DEFAULT: return "gn_PY";
 1884           }
 1885         return "gn";
 1886       case LANG_GUJARATI:
 1887         switch (sub)
 1888           {
 1889           case SUBLANG_GUJARATI_INDIA: return "gu_IN";
 1890           }
 1891         return "gu";
 1892       case LANG_HAUSA:
 1893         switch (sub)
 1894           {
 1895           case 0x1f: return "ha";
 1896           case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
 1897           }
 1898         return "ha";
 1899       case LANG_HAWAIIAN:
 1900         /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
 1901            or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
 1902         switch (sub)
 1903           {
 1904           case SUBLANG_DEFAULT: return "cpe_US";
 1905           }
 1906         return "cpe";
 1907       case LANG_HEBREW:
 1908         switch (sub)
 1909           {
 1910           case SUBLANG_HEBREW_ISRAEL: return "he_IL";
 1911           }
 1912         return "he";
 1913       case LANG_HINDI:
 1914         switch (sub)
 1915           {
 1916           case SUBLANG_HINDI_INDIA: return "hi_IN";
 1917           }
 1918         return "hi";
 1919       case LANG_HUNGARIAN:
 1920         switch (sub)
 1921           {
 1922           case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
 1923           }
 1924         return "hu";
 1925       case LANG_IBIBIO:
 1926         switch (sub)
 1927           {
 1928           case SUBLANG_DEFAULT: return "nic_NG";
 1929           }
 1930         return "nic";
 1931       case LANG_ICELANDIC:
 1932         switch (sub)
 1933           {
 1934           case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
 1935           }
 1936         return "is";
 1937       case LANG_IGBO:
 1938         switch (sub)
 1939           {
 1940           case SUBLANG_IGBO_NIGERIA: return "ig_NG";
 1941           }
 1942         return "ig";
 1943       case LANG_INDONESIAN:
 1944         switch (sub)
 1945           {
 1946           case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
 1947           }
 1948         return "id";
 1949       case LANG_INUKTITUT:
 1950         switch (sub)
 1951           {
 1952           case 0x1e: return "iu"; /* syllabic */
 1953           case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
 1954           case 0x1f: return "iu@latin";
 1955           case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
 1956           }
 1957         return "iu";
 1958       case LANG_ITALIAN:
 1959         switch (sub)
 1960           {
 1961           case SUBLANG_ITALIAN: return "it_IT";
 1962           case SUBLANG_ITALIAN_SWISS: return "it_CH";
 1963           }
 1964         return "it";
 1965       case LANG_JAPANESE:
 1966         switch (sub)
 1967           {
 1968           case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
 1969           }
 1970         return "ja";
 1971       case LANG_KANNADA:
 1972         switch (sub)
 1973           {
 1974           case SUBLANG_KANNADA_INDIA: return "kn_IN";
 1975           }
 1976         return "kn";
 1977       case LANG_KANURI:
 1978         switch (sub)
 1979           {
 1980           case SUBLANG_DEFAULT: return "kr_NG";
 1981           }
 1982         return "kr";
 1983       case LANG_KASHMIRI:
 1984         switch (sub)
 1985           {
 1986           case SUBLANG_DEFAULT: return "ks_PK";
 1987           case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
 1988           }
 1989         return "ks";
 1990       case LANG_KAZAK:
 1991         switch (sub)
 1992           {
 1993           case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
 1994           }
 1995         return "kk";
 1996       case LANG_KICHE:
 1997         /* FIXME: Adjust this when such locales appear on Unix.  */
 1998         switch (sub)
 1999           {
 2000           case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
 2001           }
 2002         return "qut";
 2003       case LANG_KINYARWANDA:
 2004         switch (sub)
 2005           {
 2006           case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
 2007           }
 2008         return "rw";
 2009       case LANG_KONKANI:
 2010         /* FIXME: Adjust this when such locales appear on Unix.  */
 2011         switch (sub)
 2012           {
 2013           case SUBLANG_KONKANI_INDIA: return "kok_IN";
 2014           }
 2015         return "kok";
 2016       case LANG_KOREAN:
 2017         switch (sub)
 2018           {
 2019           case SUBLANG_DEFAULT: return "ko_KR";
 2020           }
 2021         return "ko";
 2022       case LANG_KYRGYZ:
 2023         switch (sub)
 2024           {
 2025           case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
 2026           }
 2027         return "ky";
 2028       case LANG_LAO:
 2029         switch (sub)
 2030           {
 2031           case SUBLANG_LAO_LAOS: return "lo_LA";
 2032           }
 2033         return "lo";
 2034       case LANG_LATIN:
 2035         switch (sub)
 2036           {
 2037           case SUBLANG_DEFAULT: return "la_VA";
 2038           }
 2039         return "la";
 2040       case LANG_LATVIAN:
 2041         switch (sub)
 2042           {
 2043           case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
 2044           }
 2045         return "lv";
 2046       case LANG_LITHUANIAN:
 2047         switch (sub)
 2048           {
 2049           case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
 2050           }
 2051         return "lt";
 2052       case LANG_LUXEMBOURGISH:
 2053         switch (sub)
 2054           {
 2055           case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
 2056           }
 2057         return "lb";
 2058       case LANG_MACEDONIAN:
 2059         switch (sub)
 2060           {
 2061           case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
 2062           }
 2063         return "mk";
 2064       case LANG_MALAY:
 2065         switch (sub)
 2066           {
 2067           case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
 2068           case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
 2069           }
 2070         return "ms";
 2071       case LANG_MALAYALAM:
 2072         switch (sub)
 2073           {
 2074           case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
 2075           }
 2076         return "ml";
 2077       case LANG_MALTESE:
 2078         switch (sub)
 2079           {
 2080           case SUBLANG_MALTESE_MALTA: return "mt_MT";
 2081           }
 2082         return "mt";
 2083       case LANG_MANIPURI:
 2084         /* FIXME: Adjust this when such locales appear on Unix.  */
 2085         switch (sub)
 2086           {
 2087           case SUBLANG_DEFAULT: return "mni_IN";
 2088           }
 2089         return "mni";
 2090       case LANG_MAORI:
 2091         switch (sub)
 2092           {
 2093           case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
 2094           }
 2095         return "mi";
 2096       case LANG_MAPUDUNGUN:
 2097         switch (sub)
 2098           {
 2099           case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
 2100           }
 2101         return "arn";
 2102       case LANG_MARATHI:
 2103         switch (sub)
 2104           {
 2105           case SUBLANG_MARATHI_INDIA: return "mr_IN";
 2106           }
 2107         return "mr";
 2108       case LANG_MOHAWK:
 2109         switch (sub)
 2110           {
 2111           case SUBLANG_MOHAWK_CANADA: return "moh_CA";
 2112           }
 2113         return "moh";
 2114       case LANG_MONGOLIAN:
 2115         switch (sub)
 2116           {
 2117           case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
 2118           case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
 2119           }
 2120         return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
 2121       case LANG_NEPALI:
 2122         switch (sub)
 2123           {
 2124           case SUBLANG_NEPALI_NEPAL: return "ne_NP";
 2125           case SUBLANG_NEPALI_INDIA: return "ne_IN";
 2126           }
 2127         return "ne";
 2128       case LANG_NORWEGIAN:
 2129         switch (sub)
 2130           {
 2131           case 0x1f: return "nb";
 2132           case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
 2133           case 0x1e: return "nn";
 2134           case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
 2135           }
 2136         return "no";
 2137       case LANG_OCCITAN:
 2138         switch (sub)
 2139           {
 2140           case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
 2141           }
 2142         return "oc";
 2143       case LANG_ORIYA:
 2144         switch (sub)
 2145           {
 2146           case SUBLANG_ORIYA_INDIA: return "or_IN";
 2147           }
 2148         return "or";
 2149       case LANG_OROMO:
 2150         switch (sub)
 2151           {
 2152           case SUBLANG_DEFAULT: return "om_ET";
 2153           }
 2154         return "om";
 2155       case LANG_PAPIAMENTU:
 2156         switch (sub)
 2157           {
 2158           case SUBLANG_DEFAULT: return "pap_AN";
 2159           }
 2160         return "pap";
 2161       case LANG_PASHTO:
 2162         switch (sub)
 2163           {
 2164           case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
 2165           }
 2166         return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
 2167       case LANG_POLISH:
 2168         switch (sub)
 2169           {
 2170           case SUBLANG_POLISH_POLAND: return "pl_PL";
 2171           }
 2172         return "pl";
 2173       case LANG_PORTUGUESE:
 2174         switch (sub)
 2175           {
 2176           /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
 2177              Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
 2178           case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
 2179           case SUBLANG_PORTUGUESE: return "pt_PT";
 2180           }
 2181         return "pt";
 2182       case LANG_PUNJABI:
 2183         switch (sub)
 2184           {
 2185           case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
 2186           case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
 2187           }
 2188         return "pa";
 2189       case LANG_QUECHUA:
 2190         /* Note: Microsoft uses the non-ISO language code "quz".  */
 2191         switch (sub)
 2192           {
 2193           case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
 2194           case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
 2195           case SUBLANG_QUECHUA_PERU: return "qu_PE";
 2196           }
 2197         return "qu";
 2198       case LANG_ROMANIAN:
 2199         switch (sub)
 2200           {
 2201           case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
 2202           case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
 2203           }
 2204         return "ro";
 2205       case LANG_ROMANSH:
 2206         switch (sub)
 2207           {
 2208           case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
 2209           }
 2210         return "rm";
 2211       case LANG_RUSSIAN:
 2212         switch (sub)
 2213           {
 2214           case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
 2215           case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
 2216           }
 2217         return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
 2218       case LANG_SAMI:
 2219         switch (sub)
 2220           {
 2221           /* Northern Sami */
 2222           case 0x00: return "se";
 2223           case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
 2224           case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
 2225           case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
 2226           /* Lule Sami */
 2227           case 0x1f: return "smj";
 2228           case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
 2229           case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
 2230           /* Southern Sami */
 2231           case 0x1e: return "sma";
 2232           case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
 2233           case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
 2234           /* Skolt Sami */
 2235           case 0x1d: return "sms";
 2236           case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
 2237           /* Inari Sami */
 2238           case 0x1c: return "smn";
 2239           case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
 2240           }
 2241         return "se"; /* or "smi"? */
 2242       case LANG_SANSKRIT:
 2243         switch (sub)
 2244           {
 2245           case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
 2246           }
 2247         return "sa";
 2248       case LANG_SCOTTISH_GAELIC:
 2249         switch (sub)
 2250           {
 2251           case SUBLANG_DEFAULT: return "gd_GB";
 2252           }
 2253         return "gd";
 2254       case LANG_SINDHI:
 2255         switch (sub)
 2256           {
 2257           case SUBLANG_SINDHI_INDIA: return "sd_IN";
 2258           case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
 2259           /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
 2260           }
 2261         return "sd";
 2262       case LANG_SINHALESE:
 2263         switch (sub)
 2264           {
 2265           case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
 2266           }
 2267         return "si";
 2268       case LANG_SLOVAK:
 2269         switch (sub)
 2270           {
 2271           case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
 2272           }
 2273         return "sk";
 2274       case LANG_SLOVENIAN:
 2275         switch (sub)
 2276           {
 2277           case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
 2278           }
 2279         return "sl";
 2280       case LANG_SOMALI:
 2281         switch (sub)
 2282           {
 2283           case SUBLANG_DEFAULT: return "so_SO";
 2284           }
 2285         return "so";
 2286       case LANG_SORBIAN:
 2287         /* FIXME: Adjust this when such locales appear on Unix.  */
 2288         switch (sub)
 2289           {
 2290           /* Upper Sorbian */
 2291           case 0x00: return "hsb";
 2292           case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
 2293           /* Lower Sorbian */
 2294           case 0x1f: return "dsb";
 2295           case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
 2296           }
 2297         return "wen";
 2298       case LANG_SOTHO:
 2299         /* <https://msdn.microsoft.com/en-us/library/dd318693.aspx> calls
 2300            it "Sesotho sa Leboa"; according to
 2301            <https://www.ethnologue.com/show_language.asp?code=nso>
 2302            <https://www.ethnologue.com/show_language.asp?code=sot>
 2303            it's the same as Northern Sotho.  */
 2304         switch (sub)
 2305           {
 2306           case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
 2307           }
 2308         return "nso";
 2309       case LANG_SPANISH:
 2310         switch (sub)
 2311           {
 2312           case SUBLANG_SPANISH: return "es_ES";
 2313           case SUBLANG_SPANISH_MEXICAN: return "es_MX";
 2314           case SUBLANG_SPANISH_MODERN:
 2315             return "es_ES@modern";      /* not seen on Unix */
 2316           case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
 2317           case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
 2318           case SUBLANG_SPANISH_PANAMA: return "es_PA";
 2319           case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
 2320           case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
 2321           case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
 2322           case SUBLANG_SPANISH_PERU: return "es_PE";
 2323           case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
 2324           case SUBLANG_SPANISH_ECUADOR: return "es_EC";
 2325           case SUBLANG_SPANISH_CHILE: return "es_CL";
 2326           case SUBLANG_SPANISH_URUGUAY: return "es_UY";
 2327           case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
 2328           case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
 2329           case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
 2330           case SUBLANG_SPANISH_HONDURAS: return "es_HN";
 2331           case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
 2332           case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
 2333           case SUBLANG_SPANISH_US: return "es_US";
 2334           }
 2335         return "es";
 2336       case LANG_SUTU:
 2337         switch (sub)
 2338           {
 2339           case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
 2340           }
 2341         return "bnt";
 2342       case LANG_SWAHILI:
 2343         switch (sub)
 2344           {
 2345           case SUBLANG_SWAHILI_KENYA: return "sw_KE";
 2346           }
 2347         return "sw";
 2348       case LANG_SWEDISH:
 2349         switch (sub)
 2350           {
 2351           case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
 2352           case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
 2353           }
 2354         return "sv";
 2355       case LANG_SYRIAC:
 2356         switch (sub)
 2357           {
 2358           case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language.  */
 2359           }
 2360         return "syr";
 2361       case LANG_TAGALOG:
 2362         switch (sub)
 2363           {
 2364           case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
 2365           }
 2366         return "tl"; /* or "fil"? */
 2367       case LANG_TAJIK:
 2368         switch (sub)
 2369           {
 2370           case 0x1f: return "tg";
 2371           case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
 2372           }
 2373         return "tg";
 2374       case LANG_TAMAZIGHT:
 2375         /* Note: Microsoft uses the non-ISO language code "tmz".  */
 2376         switch (sub)
 2377           {
 2378           /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
 2379           case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
 2380           case 0x1f: return "ber@latin";
 2381           case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
 2382           }
 2383         return "ber";
 2384       case LANG_TAMIL:
 2385         switch (sub)
 2386           {
 2387           case SUBLANG_TAMIL_INDIA: return "ta_IN";
 2388           }
 2389         return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
 2390       case LANG_TATAR:
 2391         switch (sub)
 2392           {
 2393           case SUBLANG_TATAR_RUSSIA: return "tt_RU";
 2394           }
 2395         return "tt";
 2396       case LANG_TELUGU:
 2397         switch (sub)
 2398           {
 2399           case SUBLANG_TELUGU_INDIA: return "te_IN";
 2400           }
 2401         return "te";
 2402       case LANG_THAI:
 2403         switch (sub)
 2404           {
 2405           case SUBLANG_THAI_THAILAND: return "th_TH";
 2406           }
 2407         return "th";
 2408       case LANG_TIBETAN:
 2409         switch (sub)
 2410           {
 2411           case SUBLANG_TIBETAN_PRC:
 2412             /* Most Tibetans would not like "bo_CN".  But Tibet does not yet
 2413                have a country code of its own.  */
 2414             return "bo";
 2415           case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
 2416           }
 2417         return "bo";
 2418       case LANG_TIGRINYA:
 2419         switch (sub)
 2420           {
 2421           case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
 2422           case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
 2423           }
 2424         return "ti";
 2425       case LANG_TSONGA:
 2426         switch (sub)
 2427           {
 2428           case SUBLANG_DEFAULT: return "ts_ZA";
 2429           }
 2430         return "ts";
 2431       case LANG_TSWANA:
 2432         /* Spoken in South Africa, Botswana.  */
 2433         switch (sub)
 2434           {
 2435           case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
 2436           }
 2437         return "tn";
 2438       case LANG_TURKISH:
 2439         switch (sub)
 2440           {
 2441           case SUBLANG_TURKISH_TURKEY: return "tr_TR";
 2442           }
 2443         return "tr";
 2444       case LANG_TURKMEN:
 2445         switch (sub)
 2446           {
 2447           case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
 2448           }
 2449         return "tk";
 2450       case LANG_UIGHUR:
 2451         switch (sub)
 2452           {
 2453           case SUBLANG_UIGHUR_PRC: return "ug_CN";
 2454           }
 2455         return "ug";
 2456       case LANG_UKRAINIAN:
 2457         switch (sub)
 2458           {
 2459           case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
 2460           }
 2461         return "uk";
 2462       case LANG_URDU:
 2463         switch (sub)
 2464           {
 2465           case SUBLANG_URDU_PAKISTAN: return "ur_PK";
 2466           case SUBLANG_URDU_INDIA: return "ur_IN";
 2467           }
 2468         return "ur";
 2469       case LANG_UZBEK:
 2470         switch (sub)
 2471           {
 2472           case 0x1f: return "uz";
 2473           case SUBLANG_UZBEK_LATIN: return "uz_UZ";
 2474           case 0x1e: return "uz@cyrillic";
 2475           case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
 2476           }
 2477         return "uz";
 2478       case LANG_VENDA:
 2479         switch (sub)
 2480           {
 2481           case SUBLANG_DEFAULT: return "ve_ZA";
 2482           }
 2483         return "ve";
 2484       case LANG_VIETNAMESE:
 2485         switch (sub)
 2486           {
 2487           case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
 2488           }
 2489         return "vi";
 2490       case LANG_WELSH:
 2491         switch (sub)
 2492           {
 2493           case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
 2494           }
 2495         return "cy";
 2496       case LANG_WOLOF:
 2497         switch (sub)
 2498           {
 2499           case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
 2500           }
 2501         return "wo";
 2502       case LANG_XHOSA:
 2503         switch (sub)
 2504           {
 2505           case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
 2506           }
 2507         return "xh";
 2508       case LANG_YAKUT:
 2509         switch (sub)
 2510           {
 2511           case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
 2512           }
 2513         return "sah";
 2514       case LANG_YI:
 2515         switch (sub)
 2516           {
 2517           case SUBLANG_YI_PRC: return "ii_CN";
 2518           }
 2519         return "ii";
 2520       case LANG_YIDDISH:
 2521         switch (sub)
 2522           {
 2523           case SUBLANG_DEFAULT: return "yi_IL";
 2524           }
 2525         return "yi";
 2526       case LANG_YORUBA:
 2527         switch (sub)
 2528           {
 2529           case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
 2530           }
 2531         return "yo";
 2532       case LANG_ZULU:
 2533         switch (sub)
 2534           {
 2535           case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
 2536           }
 2537         return "zu";
 2538       default: return "C";
 2539       }
 2540   }
 2541 }
 2542 
 2543 # if !defined IN_LIBINTL
 2544 static
 2545 # endif
 2546 const char *
 2547 gl_locale_name_from_win32_LCID (LCID lcid)
 2548 {
 2549   LANGID langid;
 2550 
 2551   /* Strip off the sorting rules, keep only the language part.  */
 2552   langid = LANGIDFROMLCID (lcid);
 2553 
 2554   return gl_locale_name_from_win32_LANGID (langid);
 2555 }
 2556 
 2557 # ifdef WINDOWS_NATIVE
 2558 
 2559 /* Two variables to interface between get_lcid and the EnumLocales
 2560    callback function below.  */
 2561 static LCID found_lcid;
 2562 static char lname[LC_MAX * (LOCALE_NAME_MAX_LENGTH + 1) + 1];
 2563 
 2564 /* Callback function for EnumLocales.  */
 2565 static BOOL CALLBACK
 2566 enum_locales_fn (LPTSTR locale_num_str)
 2567 {
 2568   char *endp;
 2569   char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
 2570   LCID try_lcid = strtoul (locale_num_str, &endp, 16);
 2571 
 2572   if (GetLocaleInfo (try_lcid, LOCALE_SENGLANGUAGE,
 2573                     locval, LOCALE_NAME_MAX_LENGTH))
 2574     {
 2575       strcat (locval, "_");
 2576       if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
 2577                         locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
 2578        {
 2579          size_t locval_len = strlen (locval);
 2580 
 2581          if (strncmp (locval, lname, locval_len) == 0
 2582              && (lname[locval_len] == '.'
 2583                  || lname[locval_len] == '\0'))
 2584            {
 2585              found_lcid = try_lcid;
 2586              return FALSE;
 2587            }
 2588        }
 2589     }
 2590   return TRUE;
 2591 }
 2592 
 2593 /* This lock protects the get_lcid against multiple simultaneous calls.  */
 2594 gl_lock_define_initialized(static, get_lcid_lock)
 2595 
 2596 /* Return the Locale ID (LCID) number given the locale's name, a
 2597    string, in LOCALE_NAME.  This works by enumerating all the locales
 2598    supported by the system, until we find one whose name matches
 2599    LOCALE_NAME.  */
 2600 static LCID
 2601 get_lcid (const char *locale_name)
 2602 {
 2603   /* A simple cache.  */
 2604   static LCID last_lcid;
 2605   static char last_locale[1000];
 2606 
 2607   /* Lock while looking for an LCID, to protect access to static
 2608      variables: last_lcid, last_locale, found_lcid, and lname.  */
 2609   gl_lock_lock (get_lcid_lock);
 2610   if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
 2611     {
 2612       gl_lock_unlock (get_lcid_lock);
 2613       return last_lcid;
 2614     }
 2615   strncpy (lname, locale_name, sizeof (lname) - 1);
 2616   lname[sizeof (lname) - 1] = '\0';
 2617   found_lcid = 0;
 2618   EnumSystemLocales (enum_locales_fn, LCID_SUPPORTED);
 2619   if (found_lcid > 0)
 2620     {
 2621       last_lcid = found_lcid;
 2622       strcpy (last_locale, locale_name);
 2623     }
 2624   gl_lock_unlock (get_lcid_lock);
 2625   return found_lcid;
 2626 }
 2627 
 2628 # endif
 2629 #endif
 2630 
 2631 
 2632 #if HAVE_GOOD_USELOCALE /* glibc, Mac OS X, FreeBSD >= 9.1, Cygwin >= 2.6,
 2633                            Solaris 11 OpenIndiana, or Solaris >= 11.4  */
 2634 
 2635 /* Simple hash set of strings.  We don't want to drag in lots of hash table
 2636    code here.  */
 2637 
 2638 # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
 2639 
 2640 /* A hash function for NUL-terminated char* strings using
 2641    the method described by Bruno Haible.
 2642    See https://www.haible.de/bruno/hashfunc.html.  */
 2643 static size_t _GL_ATTRIBUTE_PURE
 2644 string_hash (const void *x)
 2645 {
 2646   const char *s = (const char *) x;
 2647   size_t h = 0;
 2648 
 2649   for (; *s; s++)
 2650     h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
 2651 
 2652   return h;
 2653 }
 2654 
 2655 /* A hash table of fixed size.  Multiple threads can access it read-only
 2656    simultaneously, but only one thread can insert into it at the same time.  */
 2657 
 2658 /* A node in a hash bucket collision list.  */
 2659 struct struniq_hash_node
 2660   {
 2661     struct struniq_hash_node * volatile next;
 2662     char contents[FLEXIBLE_ARRAY_MEMBER];
 2663   };
 2664 
 2665 # define STRUNIQ_HASH_TABLE_SIZE 257
 2666 static struct struniq_hash_node * volatile struniq_hash_table[STRUNIQ_HASH_TABLE_SIZE]
 2667   /* = { NULL, ..., NULL } */;
 2668 
 2669 /* This lock protects the struniq_hash_table against multiple simultaneous
 2670    insertions.  */
 2671 gl_lock_define_initialized(static, struniq_lock)
 2672 
 2673 /* Store a copy of the given string in a string pool with indefinite extent.
 2674    Return a pointer to this copy.  */
 2675 static const char *
 2676 struniq (const char *string)
 2677 {
 2678   size_t hashcode = string_hash (string);
 2679   size_t slot = hashcode % STRUNIQ_HASH_TABLE_SIZE;
 2680   size_t size;
 2681   struct struniq_hash_node *new_node;
 2682   struct struniq_hash_node *p;
 2683   for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
 2684     if (strcmp (p->contents, string) == 0)
 2685       return p->contents;
 2686   size = strlen (string) + 1;
 2687   new_node =
 2688     (struct struniq_hash_node *)
 2689     malloc (FLEXSIZEOF (struct struniq_hash_node, contents, size));
 2690   if (new_node == NULL)
 2691     /* Out of memory.  Return a statically allocated string.  */
 2692     return "C";
 2693   memcpy (new_node->contents, string, size);
 2694   /* Lock while inserting new_node.  */
 2695   gl_lock_lock (struniq_lock);
 2696   /* Check whether another thread already added the string while we were
 2697      waiting on the lock.  */
 2698   for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
 2699     if (strcmp (p->contents, string) == 0)
 2700       {
 2701         free (new_node);
 2702         new_node = p;
 2703         goto done;
 2704       }
 2705   /* Really insert new_node into the hash table.  Fill new_node entirely first,
 2706      because other threads may be iterating over the linked list.  */
 2707   new_node->next = struniq_hash_table[slot];
 2708   struniq_hash_table[slot] = new_node;
 2709  done:
 2710   /* Unlock after new_node is inserted.  */
 2711   gl_lock_unlock (struniq_lock);
 2712   return new_node->contents;
 2713 }
 2714 
 2715 #endif
 2716 
 2717 
 2718 #if HAVE_GOOD_USELOCALE && HAVE_NAMELESS_LOCALES
 2719 
 2720 /* The 'locale_t' object does not contain the names of the locale categories.
 2721    We have to associate them with the object through a hash table.
 2722    The hash table is defined in localename-table.[hc].  */
 2723 
 2724 /* Returns the name of a given locale category in a given locale_t object,
 2725    allocated as a string with indefinite extent.  */
 2726 static const char *
 2727 get_locale_t_name (int category, locale_t locale)
 2728 {
 2729   if (locale == LC_GLOBAL_LOCALE)
 2730     {
 2731       /* Query the global locale.  */
 2732       const char *name = setlocale (category, NULL);
 2733       if (name != NULL)
 2734         return struniq (name);
 2735       else
 2736         /* Should normally not happen.  */
 2737         return "";
 2738     }
 2739   else
 2740     {
 2741       /* Look up the names in the hash table.  */
 2742       size_t hashcode = locale_hash_function (locale);
 2743       size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
 2744       /* If the locale was not found in the table, return "".  This can
 2745          happen if the application uses the original newlocale()/duplocale()
 2746          functions instead of the overridden ones.  */
 2747       const char *name = "";
 2748       struct locale_hash_node *p;
 2749       /* Lock while looking up the hash node.  */
 2750       gl_rwlock_rdlock (locale_lock);
 2751       for (p = locale_hash_table[slot]; p != NULL; p = p->next)
 2752         if (p->locale == locale)
 2753           {
 2754             name = p->names.category_name[category];
 2755             break;
 2756           }
 2757       gl_rwlock_unlock (locale_lock);
 2758       return name;
 2759     }
 2760 }
 2761 
 2762 # if !(defined newlocale && defined duplocale && defined freelocale)
 2763 #  error "newlocale, duplocale, freelocale not being replaced as expected!"
 2764 # endif
 2765 
 2766 /* newlocale() override.  */
 2767 locale_t
 2768 newlocale (int category_mask, const char *name, locale_t base)
 2769 #undef newlocale
 2770 {
 2771   struct locale_categories_names names;
 2772   struct locale_hash_node *node;
 2773   locale_t result;
 2774 
 2775   /* Make sure name has indefinite extent.  */
 2776   if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK
 2777         | LC_MONETARY_MASK | LC_MESSAGES_MASK)
 2778        & category_mask) != 0)
 2779     name = struniq (name);
 2780 
 2781   /* Determine the category names of the result.  */
 2782   if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK
 2783         | LC_MONETARY_MASK | LC_MESSAGES_MASK)
 2784        & ~category_mask) == 0)
 2785     {
 2786       /* Use name, ignore base.  */
 2787       int category;
 2788 
 2789       name = struniq (name);
 2790       for (category = 0; category < 6; category++)
 2791         names.category_name[category] = name;
 2792     }
 2793   else
 2794     {
 2795       /* Use base, possibly also name.  */
 2796       if (base == NULL)
 2797         {
 2798           int category;
 2799 
 2800           for (category = 0; category < 6; category++)
 2801             {
 2802               int mask;
 2803 
 2804               switch (category)
 2805                 {
 2806                 case LC_CTYPE:
 2807                   mask = LC_CTYPE_MASK;
 2808                   break;
 2809                 case LC_NUMERIC:
 2810                   mask = LC_NUMERIC_MASK;
 2811                   break;
 2812                 case LC_TIME:
 2813                   mask = LC_TIME_MASK;
 2814                   break;
 2815                 case LC_COLLATE:
 2816                   mask = LC_COLLATE_MASK;
 2817                   break;
 2818                 case LC_MONETARY:
 2819                   mask = LC_MONETARY_MASK;
 2820                   break;
 2821                 case LC_MESSAGES:
 2822                   mask = LC_MESSAGES_MASK;
 2823                   break;
 2824                 default:
 2825                   abort ();
 2826                 }
 2827               names.category_name[category] =
 2828                 ((mask & category_mask) != 0 ? name : "C");
 2829             }
 2830         }
 2831       else if (base == LC_GLOBAL_LOCALE)
 2832         {
 2833           int category;
 2834 
 2835           for (category = 0; category < 6; category++)
 2836             {
 2837               int mask;
 2838 
 2839               switch (category)
 2840                 {
 2841                 case LC_CTYPE:
 2842                   mask = LC_CTYPE_MASK;
 2843                   break;
 2844                 case LC_NUMERIC:
 2845                   mask = LC_NUMERIC_MASK;
 2846                   break;
 2847                 case LC_TIME:
 2848                   mask = LC_TIME_MASK;
 2849                   break;
 2850                 case LC_COLLATE:
 2851                   mask = LC_COLLATE_MASK;
 2852                   break;
 2853                 case LC_MONETARY:
 2854                   mask = LC_MONETARY_MASK;
 2855                   break;
 2856                 case LC_MESSAGES:
 2857                   mask = LC_MESSAGES_MASK;
 2858                   break;
 2859                 default:
 2860                   abort ();
 2861                 }
 2862               names.category_name[category] =
 2863                 ((mask & category_mask) != 0
 2864                  ? name
 2865                  : get_locale_t_name (category, LC_GLOBAL_LOCALE));
 2866             }
 2867         }
 2868       else
 2869         {
 2870           /* Look up the names of base in the hash table.  Like multiple calls
 2871              of get_locale_t_name, but locking only once.  */
 2872           struct locale_hash_node *p;
 2873           int category;
 2874 
 2875           /* Lock while looking up the hash node.  */
 2876           gl_rwlock_rdlock (locale_lock);
 2877           for (p = locale_hash_table[locale_hash_function (base) % LOCALE_HASH_TABLE_SIZE];
 2878                p != NULL;
 2879                p = p->next)
 2880             if (p->locale == base)
 2881               break;
 2882 
 2883           for (category = 0; category < 6; category++)
 2884             {
 2885               int mask;
 2886 
 2887               switch (category)
 2888                 {
 2889                 case LC_CTYPE:
 2890                   mask = LC_CTYPE_MASK;
 2891                   break;
 2892                 case LC_NUMERIC:
 2893                   mask = LC_NUMERIC_MASK;
 2894                   break;
 2895                 case LC_TIME:
 2896                   mask = LC_TIME_MASK;
 2897                   break;
 2898                 case LC_COLLATE:
 2899                   mask = LC_COLLATE_MASK;
 2900                   break;
 2901                 case LC_MONETARY:
 2902                   mask = LC_MONETARY_MASK;
 2903                   break;
 2904                 case LC_MESSAGES:
 2905                   mask = LC_MESSAGES_MASK;
 2906                   break;
 2907                 default:
 2908                   abort ();
 2909                 }
 2910               names.category_name[category] =
 2911                 ((mask & category_mask) != 0
 2912                  ? name
 2913                  : (p != NULL ? p->names.category_name[category] : ""));
 2914             }
 2915 
 2916           gl_rwlock_unlock (locale_lock);
 2917         }
 2918     }
 2919 
 2920   node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node));
 2921   if (node == NULL)
 2922     /* errno is set to ENOMEM.  */
 2923     return NULL;
 2924 
 2925   result = newlocale (category_mask, name, base);
 2926   if (result == NULL)
 2927     {
 2928       int saved_errno = errno;
 2929       free (node);
 2930       errno = saved_errno;
 2931       return NULL;
 2932     }
 2933 
 2934   /* Fill the hash node.  */
 2935   node->locale = result;
 2936   node->names = names;
 2937 
 2938   /* Insert it in the hash table.  */
 2939   {
 2940     size_t hashcode = locale_hash_function (result);
 2941     size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
 2942     struct locale_hash_node *p;
 2943 
 2944     /* Lock while inserting the new node.  */
 2945     gl_rwlock_wrlock (locale_lock);
 2946     for (p = locale_hash_table[slot]; p != NULL; p = p->next)
 2947       if (p->locale == result)
 2948         {
 2949           /* This can happen if the application uses the original freelocale()
 2950              function instead of the overridden one.  */
 2951           p->names = node->names;
 2952           break;
 2953         }
 2954     if (p == NULL)
 2955       {
 2956         node->next = locale_hash_table[slot];
 2957         locale_hash_table[slot] = node;
 2958       }
 2959 
 2960     gl_rwlock_unlock (locale_lock);
 2961 
 2962     if (p != NULL)
 2963       free (node);
 2964   }
 2965 
 2966   return result;
 2967 }
 2968 
 2969 /* duplocale() override.  */
 2970 locale_t
 2971 duplocale (locale_t locale)
 2972 #undef duplocale
 2973 {
 2974   struct locale_hash_node *node;
 2975   locale_t result;
 2976 
 2977   if (locale == NULL)
 2978     /* Invalid argument.  */
 2979     abort ();
 2980 
 2981   node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node));
 2982   if (node == NULL)
 2983     /* errno is set to ENOMEM.  */
 2984     return NULL;
 2985 
 2986   result = duplocale (locale);
 2987   if (result == NULL)
 2988     {
 2989       int saved_errno = errno;
 2990       free (node);
 2991       errno = saved_errno;
 2992       return NULL;
 2993     }
 2994 
 2995   /* Fill the hash node.  */
 2996   node->locale = result;
 2997   if (locale == LC_GLOBAL_LOCALE)
 2998     {
 2999       int category;
 3000 
 3001       for (category = 0; category < 6; category++)
 3002         node->names.category_name[category] =
 3003           get_locale_t_name (category, LC_GLOBAL_LOCALE);
 3004 
 3005       /* Lock before inserting the new node.  */
 3006       gl_rwlock_wrlock (locale_lock);
 3007     }
 3008   else
 3009     {
 3010       struct locale_hash_node *p;
 3011 
 3012       /* Lock once, for the lookup and the insertion.  */
 3013       gl_rwlock_wrlock (locale_lock);
 3014 
 3015       for (p = locale_hash_table[locale_hash_function (locale) % LOCALE_HASH_TABLE_SIZE];
 3016            p != NULL;
 3017            p = p->next)
 3018         if (p->locale == locale)
 3019           break;
 3020       if (p != NULL)
 3021         node->names = p->names;
 3022       else
 3023         {
 3024           /* This can happen if the application uses the original
 3025              newlocale()/duplocale() functions instead of the overridden
 3026              ones.  */
 3027           int category;
 3028 
 3029           for (category = 0; category < 6; category++)
 3030             node->names.category_name[category] = "";
 3031         }
 3032     }
 3033 
 3034   /* Insert it in the hash table.  */
 3035   {
 3036     size_t hashcode = locale_hash_function (result);
 3037     size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
 3038     struct locale_hash_node *p;
 3039 
 3040     for (p = locale_hash_table[slot]; p != NULL; p = p->next)
 3041       if (p->locale == result)
 3042         {
 3043           /* This can happen if the application uses the original freelocale()
 3044              function instead of the overridden one.  */
 3045           p->names = node->names;
 3046           break;
 3047         }
 3048     if (p == NULL)
 3049       {
 3050         node->next = locale_hash_table[slot];
 3051         locale_hash_table[slot] = node;
 3052       }
 3053 
 3054     gl_rwlock_unlock (locale_lock);
 3055 
 3056     if (p != NULL)
 3057       free (node);
 3058   }
 3059 
 3060   return result;
 3061 }
 3062 
 3063 /* freelocale() override.  */
 3064 void
 3065 freelocale (locale_t locale)
 3066 #undef freelocale
 3067 {
 3068   if (locale == NULL || locale == LC_GLOBAL_LOCALE)
 3069     /* Invalid argument.  */
 3070     abort ();
 3071 
 3072   {
 3073     size_t hashcode = locale_hash_function (locale);
 3074     size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
 3075     struct locale_hash_node *found;
 3076     struct locale_hash_node **p;
 3077 
 3078     found = NULL;
 3079     /* Lock while removing the hash node.  */
 3080     gl_rwlock_wrlock (locale_lock);
 3081     for (p = &locale_hash_table[slot]; *p != NULL; p = &(*p)->next)
 3082       if ((*p)->locale == locale)
 3083         {
 3084           found = *p;
 3085           *p = (*p)->next;
 3086           break;
 3087         }
 3088     gl_rwlock_unlock (locale_lock);
 3089     free (found);
 3090   }
 3091 
 3092   freelocale (locale);
 3093 }
 3094 
 3095 #endif
 3096 
 3097 
 3098 #if defined IN_LIBINTL || HAVE_GOOD_USELOCALE
 3099 
 3100 /* Like gl_locale_name_thread, except that the result is not in storage of
 3101    indefinite extent.  */
 3102 # if !defined IN_LIBINTL
 3103 static
 3104 # endif
 3105 const char *
 3106 gl_locale_name_thread_unsafe (int category, const char *categoryname)
 3107 {
 3108 # if HAVE_GOOD_USELOCALE
 3109   {
 3110     locale_t thread_locale = uselocale (NULL);
 3111     if (thread_locale != LC_GLOBAL_LOCALE)
 3112       {
 3113 #  if __GLIBC__ >= 2 && !defined __UCLIBC__
 3114         /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
 3115            glibc < 2.12.
 3116            See <https://sourceware.org/bugzilla/show_bug.cgi?id=10968>.  */
 3117         const char *name =
 3118           nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
 3119         if (name[0] == '\0')
 3120           /* Fallback code for glibc < 2.4, which did not implement
 3121              nl_langinfo (_NL_LOCALE_NAME (category)).  */
 3122           name = thread_locale->__names[category];
 3123         return name;
 3124 #  elif defined __linux__ && HAVE_LANGINFO_H && defined NL_LOCALE_NAME
 3125         /* musl libc */
 3126         return nl_langinfo_l (NL_LOCALE_NAME (category), thread_locale);
 3127 #  elif (defined __FreeBSD__ || defined __DragonFly__) || (defined __APPLE__ && defined __MACH__)
 3128         /* FreeBSD, Mac OS X */
 3129         int mask;
 3130 
 3131         switch (category)
 3132           {
 3133           case LC_CTYPE:
 3134             mask = LC_CTYPE_MASK;
 3135             break;
 3136           case LC_NUMERIC:
 3137             mask = LC_NUMERIC_MASK;
 3138             break;
 3139           case LC_TIME:
 3140             mask = LC_TIME_MASK;
 3141             break;
 3142           case LC_COLLATE:
 3143             mask = LC_COLLATE_MASK;
 3144             break;
 3145           case LC_MONETARY:
 3146             mask = LC_MONETARY_MASK;
 3147             break;
 3148           case LC_MESSAGES:
 3149             mask = LC_MESSAGES_MASK;
 3150             break;
 3151           default: /* We shouldn't get here.  */
 3152             return "";
 3153           }
 3154         return querylocale (mask, thread_locale);
 3155 #  elif defined __sun
 3156 #   if HAVE_GETLOCALENAME_L
 3157         /* Solaris >= 12.  */
 3158         return getlocalename_l (category, thread_locale);
 3159 #   elif HAVE_SOLARIS114_LOCALES
 3160         /* Solaris >= 11.4.  */
 3161         void *lcp = (*thread_locale)->core.data->lcp;
 3162         if (lcp != NULL)
 3163           switch (category)
 3164             {
 3165             case LC_CTYPE:
 3166             case LC_NUMERIC:
 3167             case LC_TIME:
 3168             case LC_COLLATE:
 3169             case LC_MONETARY:
 3170             case LC_MESSAGES:
 3171               return ((const char * const *) lcp)[category];
 3172             default: /* We shouldn't get here.  */
 3173               return "";
 3174             }
 3175 #   elif HAVE_NAMELESS_LOCALES
 3176         return get_locale_t_name (category, thread_locale);
 3177 #   else
 3178         /* Solaris 11 OpenIndiana.
 3179            For the internal structure of locale objects, see
 3180            https://github.com/OpenIndiana/illumos-gate/blob/master/usr/src/lib/libc/port/locale/localeimpl.h  */
 3181         switch (category)
 3182           {
 3183           case LC_CTYPE:
 3184           case LC_NUMERIC:
 3185           case LC_TIME:
 3186           case LC_COLLATE:
 3187           case LC_MONETARY:
 3188           case LC_MESSAGES:
 3189             return ((const char * const *) thread_locale)[category];
 3190           default: /* We shouldn't get here.  */
 3191             return "";
 3192           }
 3193 #   endif
 3194 #  elif defined __CYGWIN__
 3195         /* Cygwin < 2.6 lacks uselocale and thread-local locales altogether.
 3196            Cygwin <= 2.6.1 lacks NL_LOCALE_NAME, requiring peeking inside
 3197            an opaque struct.  */
 3198 #   ifdef NL_LOCALE_NAME
 3199         return nl_langinfo_l (NL_LOCALE_NAME (category), thread_locale);
 3200 #   else
 3201         /* FIXME: Remove when we can assume new-enough Cygwin.  */
 3202         struct __locale_t {
 3203           char categories[7][32];
 3204         };
 3205         return ((struct __locale_t *) thread_locale)->categories[category];
 3206 #   endif
 3207 #  elif defined __ANDROID__
 3208         return MB_CUR_MAX == 4 ? "C.UTF-8" : "C";
 3209 #  endif
 3210       }
 3211   }
 3212 # endif
 3213   return NULL;
 3214 }
 3215 
 3216 #endif
 3217 
 3218 const char *
 3219 gl_locale_name_thread (int category, const char *categoryname)
 3220 {
 3221 #if HAVE_GOOD_USELOCALE
 3222   const char *name = gl_locale_name_thread_unsafe (category, categoryname);
 3223   if (name != NULL)
 3224     return struniq (name);
 3225 #endif
 3226   /* On WINDOWS_NATIVE, don't use GetThreadLocale() here, because when
 3227      SetThreadLocale has not been called - which is a very frequent case -
 3228      the value of GetThreadLocale() ignores past calls to 'setlocale'.  */
 3229   return NULL;
 3230 }
 3231 
 3232 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
 3233    "Directs 'setlocale()' to query 'category' and return the current
 3234     setting of 'local'."
 3235    However it does not specify the exact format.  Neither do SUSV2 and
 3236    ISO C 99.  So we can use this feature only on selected systems (e.g.
 3237    those using GNU C Library).  */
 3238 #if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
 3239 # define HAVE_LOCALE_NULL
 3240 #endif
 3241 
 3242 const char *
 3243 gl_locale_name_posix (int category, const char *categoryname)
 3244 {
 3245 #if defined WINDOWS_NATIVE
 3246   if (LC_MIN <= category && category <= LC_MAX)
 3247     {
 3248       const char *locname = setlocale (category, NULL);
 3249       LCID lcid;
 3250 
 3251       /* If CATEGORY is LC_ALL, the result might be a semi-colon
 3252         separated list of locales.  We need only one, so we take the
 3253         one corresponding to LC_CTYPE, as the most important for
 3254         character translations.  */
 3255       if (category == LC_ALL && strchr (locname, ';'))
 3256         locname = setlocale (LC_CTYPE, NULL);
 3257 
 3258       /* Convert locale name to LCID.  We don't want to use
 3259          LocaleNameToLCID because (a) it is only available since Vista,
 3260          and (b) it doesn't accept locale names returned by 'setlocale'.  */
 3261       lcid = get_lcid (locname);
 3262 
 3263       if (lcid > 0)
 3264         return gl_locale_name_from_win32_LCID (lcid);
 3265     }
 3266 #endif
 3267   {
 3268     const char *locname;
 3269 
 3270     /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
 3271        On some systems this can be done by the 'setlocale' function itself.  */
 3272 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
 3273     locname = setlocale (category, NULL);
 3274 #else
 3275     /* On other systems we ignore what setlocale reports and instead look at the
 3276        environment variables directly.  This is necessary
 3277          1. on systems which have a facility for customizing the default locale
 3278             (Mac OS X, native Windows, Cygwin) and where the system's setlocale()
 3279             function ignores this default locale (Mac OS X, Cygwin), in two cases:
 3280             a. when the user missed to use the setlocale() override from libintl
 3281                (for example by not including <libintl.h>),
 3282             b. when setlocale supports only the "C" locale, such as on Cygwin
 3283                1.5.x.  In this case even the override from libintl cannot help.
 3284          2. on all systems where setlocale supports only the "C" locale.  */
 3285     /* Strictly speaking, it is a POSIX violation to look at the environment
 3286        variables regardless whether setlocale has been called or not.  POSIX
 3287        says:
 3288            "For C-language programs, the POSIX locale shall be the
 3289             default locale when the setlocale() function is not called."
 3290        But we assume that all programs that use internationalized APIs call
 3291        setlocale (LC_ALL, "").  */
 3292     locname = gl_locale_name_environ (category, categoryname);
 3293 #endif
 3294     /* Convert the locale name from the format returned by setlocale() or found
 3295        in the environment variables to the XPG syntax.  */
 3296 #if defined WINDOWS_NATIVE
 3297     {
 3298       /* Convert locale name to LCID.  We don't want to use
 3299          LocaleNameToLCID because (a) it is only available since Vista,
 3300          and (b) it doesn't accept locale names returned by 'setlocale'.  */
 3301       LCID lcid = get_lcid (locname);
 3302 
 3303       if (lcid > 0)
 3304         return gl_locale_name_from_win32_LCID (lcid);
 3305     }
 3306 #endif
 3307     return locname;
 3308   }
 3309 }
 3310 
 3311 const char *
 3312 gl_locale_name_environ (int category, const char *categoryname)
 3313 {
 3314   const char *retval;
 3315 
 3316   /* Setting of LC_ALL overrides all other.  */
 3317   retval = getenv ("LC_ALL");
 3318   if (retval != NULL && retval[0] != '\0')
 3319     return retval;
 3320   /* Next comes the name of the desired category.  */
 3321   retval = getenv (categoryname);
 3322   if (retval != NULL && retval[0] != '\0')
 3323     return retval;
 3324   /* Last possibility is the LANG environment variable.  */
 3325   retval = getenv ("LANG");
 3326   if (retval != NULL && retval[0] != '\0')
 3327     {
 3328 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
 3329       /* Mac OS X 10.2 or newer.
 3330          Ignore invalid LANG value set by the Terminal application.  */
 3331       if (strcmp (retval, "UTF-8") != 0)
 3332 #endif
 3333 #if defined __CYGWIN__
 3334       /* Cygwin.
 3335          Ignore dummy LANG value set by ~/.profile.  */
 3336       if (strcmp (retval, "C.UTF-8") != 0)
 3337 #endif
 3338         return retval;
 3339     }
 3340 
 3341   return NULL;
 3342 }
 3343 
 3344 const char *
 3345 gl_locale_name_default (void)
 3346 {
 3347   /* POSIX:2001 says:
 3348      "All implementations shall define a locale as the default locale, to be
 3349       invoked when no environment variables are set, or set to the empty
 3350       string.  This default locale can be the POSIX locale or any other
 3351       implementation-defined locale.  Some implementations may provide
 3352       facilities for local installation administrators to set the default
 3353       locale, customizing it for each location.  POSIX:2001 does not require
 3354       such a facility.
 3355 
 3356      The systems with such a facility are Mac OS X and Windows: They provide a
 3357      GUI that allows the user to choose a locale.
 3358        - On Mac OS X, by default, none of LC_* or LANG are set.  Starting with
 3359          Mac OS X 10.4 or 10.5, LANG is set for processes launched by the
 3360          'Terminal' application (but sometimes to an incorrect value "UTF-8").
 3361          When no environment variable is set, setlocale (LC_ALL, "") uses the
 3362          "C" locale.
 3363        - On native Windows, by default, none of LC_* or LANG are set.
 3364          When no environment variable is set, setlocale (LC_ALL, "") uses the
 3365          locale chosen by the user.
 3366        - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
 3367          When no environment variable is set, setlocale (LC_ALL, "") uses the
 3368          "C" locale.
 3369        - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
 3370          ~/.profile is executed.
 3371          When no environment variable is set, setlocale (LC_ALL, "") uses the
 3372          "C.UTF-8" locale, which operates in the same way as the "C" locale.
 3373   */
 3374 
 3375 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WINDOWS_NATIVE || defined __CYGWIN__)
 3376 
 3377   /* The system does not have a way of setting the locale, other than the
 3378      POSIX specified environment variables.  We use C as default locale.  */
 3379   return "C";
 3380 
 3381 #else
 3382 
 3383   /* Return an XPG style locale name language[_territory][@modifier].
 3384      Don't even bother determining the codeset; it's not useful in this
 3385      context, because message catalogs are not specific to a single
 3386      codeset.  */
 3387 
 3388 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
 3389   /* Mac OS X 10.4 or newer */
 3390   {
 3391     /* Cache the locale name, since CoreFoundation calls are expensive.  */
 3392     static const char *cached_localename;
 3393 
 3394     if (cached_localename == NULL)
 3395       {
 3396         char namebuf[256];
 3397 #  if HAVE_CFLOCALECOPYCURRENT /* Mac OS X 10.5 or newer */
 3398         CFLocaleRef locale = CFLocaleCopyCurrent ();
 3399         CFStringRef name = CFLocaleGetIdentifier (locale);
 3400 #  elif HAVE_CFPREFERENCESCOPYAPPVALUE /* Mac OS X 10.4 or newer */
 3401         CFTypeRef value =
 3402           CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
 3403                                      kCFPreferencesCurrentApplication);
 3404         if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
 3405           {
 3406             CFStringRef name = (CFStringRef)value;
 3407 #  endif
 3408 
 3409             if (CFStringGetCString (name, namebuf, sizeof (namebuf),
 3410                                     kCFStringEncodingASCII))
 3411               {
 3412                 gl_locale_name_canonicalize (namebuf);
 3413                 cached_localename = strdup (namebuf);
 3414               }
 3415 
 3416 #  if HAVE_CFLOCALECOPYCURRENT /* Mac OS X 10.5 or newer */
 3417         CFRelease (locale);
 3418 #  elif HAVE_CFPREFERENCESCOPYAPPVALUE /* Mac OS X 10.4 or newer */
 3419           }
 3420 #  endif
 3421         if (cached_localename == NULL)
 3422           cached_localename = "C";
 3423       }
 3424     return cached_localename;
 3425   }
 3426 
 3427 # endif
 3428 
 3429 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
 3430   {
 3431     LCID lcid;
 3432 
 3433     /* Use native Windows API locale ID.  */
 3434     lcid = GetThreadLocale ();
 3435 
 3436     return gl_locale_name_from_win32_LCID (lcid);
 3437   }
 3438 # endif
 3439 #endif
 3440 }
 3441 
 3442 /* Determine the current locale's name, and canonicalize it into XPG syntax
 3443      language[_territory][.codeset][@modifier]
 3444    The codeset part in the result is not reliable; the locale_charset()
 3445    should be used for codeset information instead.
 3446    The result must not be freed; it is statically allocated.  */
 3447 
 3448 const char *
 3449 gl_locale_name (int category, const char *categoryname)
 3450 {
 3451   const char *retval;
 3452 
 3453   retval = gl_locale_name_thread (category, categoryname);
 3454   if (retval != NULL)
 3455     return retval;
 3456 
 3457   retval = gl_locale_name_posix (category, categoryname);
 3458   if (retval != NULL)
 3459     return retval;
 3460 
 3461   return gl_locale_name_default ();
 3462 }