LCOV - code coverage report
Current view: top level - lib/gltests - localename.c (source / functions) Hit Total Coverage
Test: GNU Libidn Lines: 57 65 87.7 %
Date: 2016-07-20 19:34:35 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11