(root)/
findutils-4.9.0/
gnulib-tests/
localename.c
       1  /* Determine name of the currently selected locale.
       2     Copyright (C) 1995-2022 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 Lesser General Public License as published by
       6     the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
      18  /* Native Windows code written by Tor Lillqvist <tml@iki.fi>.  */
      19  /* Mac OS X code written by Bruno Haible <bruno@clisp.org>.  */
      20  
      21  #include <config.h>
      22  
      23  /* Specification.  */
      24  #include "localename.h"
      25  
      26  #include <limits.h>
      27  #include <stdbool.h>
      28  #include <stddef.h>
      29  #include <stdlib.h>
      30  #include <locale.h>
      31  #include <string.h>
      32  
      33  #include "flexmember.h"
      34  #include "setlocale_null.h"
      35  #include "thread-optim.h"
      36  
      37  #if HAVE_GOOD_USELOCALE
      38  /* Mac OS X 10.5 defines the locale_t type in <xlocale.h>.  */
      39  # if defined __APPLE__ && defined __MACH__
      40  #  include <xlocale.h>
      41  # endif
      42  # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || (defined __linux__ && HAVE_LANGINFO_H) || defined __CYGWIN__
      43  #  include <langinfo.h>
      44  # endif
      45  # include "glthread/lock.h"
      46  # if defined __sun
      47  #  if HAVE_GETLOCALENAME_L
      48  /* Solaris >= 12.  */
      49  extern char * getlocalename_l(int, locale_t);
      50  #  elif HAVE_SOLARIS114_LOCALES
      51  #   include <sys/localedef.h>
      52  #  endif
      53  # endif
      54  # if HAVE_NAMELESS_LOCALES
      55  #  include "localename-table.h"
      56  # endif
      57  #endif
      58  
      59  #if HAVE_CFPREFERENCESCOPYAPPVALUE
      60  # include <CoreFoundation/CFString.h>
      61  # include <CoreFoundation/CFPreferences.h>
      62  #endif
      63  
      64  #if defined _WIN32 && !defined __CYGWIN__
      65  # define WINDOWS_NATIVE
      66  # include "glthread/lock.h"
      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  /* Don't assume that UNICODE is not defined.  */
    1141  # undef GetLocaleInfo
    1142  # define GetLocaleInfo GetLocaleInfoA
    1143  # undef EnumSystemLocales
    1144  # define EnumSystemLocales EnumSystemLocalesA
    1145  #endif
    1146  
    1147  /* We want to use the system's setlocale() function here, not the gnulib
    1148     override.  */
    1149  #undef setlocale
    1150  
    1151  
    1152  #if HAVE_CFPREFERENCESCOPYAPPVALUE
    1153  /* Mac OS X 10.4 or newer */
    1154  
    1155  /* Canonicalize a Mac OS X locale name to a Unix locale name.
    1156     NAME is a sufficiently large buffer.
    1157     On input, it contains the Mac OS X locale name.
    1158     On output, it contains the Unix locale name.  */
    1159  # if !defined IN_LIBINTL
    1160  static
    1161  # endif
    1162  void
    1163  gl_locale_name_canonicalize (char *name)
    1164  {
    1165    /* This conversion is based on a posting by
    1166       Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
    1167       https://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
    1168  
    1169    /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
    1170       ISO 3166) names.  Prior to Mac OS X 10.3, there is no API for doing this.
    1171       Therefore we do it ourselves, using a table based on the results of the
    1172       Mac OS X 10.3.8 function
    1173       CFLocaleCreateCanonicalLocaleIdentifierFromString().  */
    1174    typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
    1175            legacy_entry;
    1176    static const legacy_entry legacy_table[] = {
    1177      { "Afrikaans",             "af" },
    1178      { "Albanian",              "sq" },
    1179      { "Amharic",               "am" },
    1180      { "Arabic",                "ar" },
    1181      { "Armenian",              "hy" },
    1182      { "Assamese",              "as" },
    1183      { "Aymara",                "ay" },
    1184      { "Azerbaijani",           "az" },
    1185      { "Basque",                "eu" },
    1186      { "Belarusian",            "be" },
    1187      { "Belorussian",           "be" },
    1188      { "Bengali",               "bn" },
    1189      { "Brazilian Portugese",   "pt_BR" },
    1190      { "Brazilian Portuguese",  "pt_BR" },
    1191      { "Breton",                "br" },
    1192      { "Bulgarian",             "bg" },
    1193      { "Burmese",               "my" },
    1194      { "Byelorussian",          "be" },
    1195      { "Catalan",               "ca" },
    1196      { "Chewa",                 "ny" },
    1197      { "Chichewa",              "ny" },
    1198      { "Chinese",               "zh" },
    1199      { "Chinese, Simplified",   "zh_CN" },
    1200      { "Chinese, Traditional",  "zh_TW" },
    1201      { "Chinese, Tradtional",   "zh_TW" },
    1202      { "Croatian",              "hr" },
    1203      { "Czech",                 "cs" },
    1204      { "Danish",                "da" },
    1205      { "Dutch",                 "nl" },
    1206      { "Dzongkha",              "dz" },
    1207      { "English",               "en" },
    1208      { "Esperanto",             "eo" },
    1209      { "Estonian",              "et" },
    1210      { "Faroese",               "fo" },
    1211      { "Farsi",                 "fa" },
    1212      { "Finnish",               "fi" },
    1213      { "Flemish",               "nl_BE" },
    1214      { "French",                "fr" },
    1215      { "Galician",              "gl" },
    1216      { "Gallegan",              "gl" },
    1217      { "Georgian",              "ka" },
    1218      { "German",                "de" },
    1219      { "Greek",                 "el" },
    1220      { "Greenlandic",           "kl" },
    1221      { "Guarani",               "gn" },
    1222      { "Gujarati",              "gu" },
    1223      { "Hawaiian",              "haw" }, /* Yes, "haw", not "cpe".  */
    1224      { "Hebrew",                "he" },
    1225      { "Hindi",                 "hi" },
    1226      { "Hungarian",             "hu" },
    1227      { "Icelandic",             "is" },
    1228      { "Indonesian",            "id" },
    1229      { "Inuktitut",             "iu" },
    1230      { "Irish",                 "ga" },
    1231      { "Italian",               "it" },
    1232      { "Japanese",              "ja" },
    1233      { "Javanese",              "jv" },
    1234      { "Kalaallisut",           "kl" },
    1235      { "Kannada",               "kn" },
    1236      { "Kashmiri",              "ks" },
    1237      { "Kazakh",                "kk" },
    1238      { "Khmer",                 "km" },
    1239      { "Kinyarwanda",           "rw" },
    1240      { "Kirghiz",               "ky" },
    1241      { "Korean",                "ko" },
    1242      { "Kurdish",               "ku" },
    1243      { "Latin",                 "la" },
    1244      { "Latvian",               "lv" },
    1245      { "Lithuanian",            "lt" },
    1246      { "Macedonian",            "mk" },
    1247      { "Malagasy",              "mg" },
    1248      { "Malay",                 "ms" },
    1249      { "Malayalam",             "ml" },
    1250      { "Maltese",               "mt" },
    1251      { "Manx",                  "gv" },
    1252      { "Marathi",               "mr" },
    1253      { "Moldavian",             "mo" },
    1254      { "Mongolian",             "mn" },
    1255      { "Nepali",                "ne" },
    1256      { "Norwegian",             "nb" }, /* Yes, "nb", not the obsolete "no".  */
    1257      { "Nyanja",                "ny" },
    1258      { "Nynorsk",               "nn" },
    1259      { "Oriya",                 "or" },
    1260      { "Oromo",                 "om" },
    1261      { "Panjabi",               "pa" },
    1262      { "Pashto",                "ps" },
    1263      { "Persian",               "fa" },
    1264      { "Polish",                "pl" },
    1265      { "Portuguese",            "pt" },
    1266      { "Portuguese, Brazilian", "pt_BR" },
    1267      { "Punjabi",               "pa" },
    1268      { "Pushto",                "ps" },
    1269      { "Quechua",               "qu" },
    1270      { "Romanian",              "ro" },
    1271      { "Ruanda",                "rw" },
    1272      { "Rundi",                 "rn" },
    1273      { "Russian",               "ru" },
    1274      { "Sami",                  "se_NO" }, /* Not just "se".  */
    1275      { "Sanskrit",              "sa" },
    1276      { "Scottish",              "gd" },
    1277      { "Serbian",               "sr" },
    1278      { "Simplified Chinese",    "zh_CN" },
    1279      { "Sindhi",                "sd" },
    1280      { "Sinhalese",             "si" },
    1281      { "Slovak",                "sk" },
    1282      { "Slovenian",             "sl" },
    1283      { "Somali",                "so" },
    1284      { "Spanish",               "es" },
    1285      { "Sundanese",             "su" },
    1286      { "Swahili",               "sw" },
    1287      { "Swedish",               "sv" },
    1288      { "Tagalog",               "tl" },
    1289      { "Tajik",                 "tg" },
    1290      { "Tajiki",                "tg" },
    1291      { "Tamil",                 "ta" },
    1292      { "Tatar",                 "tt" },
    1293      { "Telugu",                "te" },
    1294      { "Thai",                  "th" },
    1295      { "Tibetan",               "bo" },
    1296      { "Tigrinya",              "ti" },
    1297      { "Tongan",                "to" },
    1298      { "Traditional Chinese",   "zh_TW" },
    1299      { "Turkish",               "tr" },
    1300      { "Turkmen",               "tk" },
    1301      { "Uighur",                "ug" },
    1302      { "Ukrainian",             "uk" },
    1303      { "Urdu",                  "ur" },
    1304      { "Uzbek",                 "uz" },
    1305      { "Vietnamese",            "vi" },
    1306      { "Welsh",                 "cy" },
    1307      { "Yiddish",               "yi" }
    1308    };
    1309  
    1310    /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
    1311       to Unix (ISO 639 and ISO 3166) names.  */
    1312    typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
    1313            langtag_entry;
    1314    static const langtag_entry langtag_table[] = {
    1315      /* Mac OS X has "az-Arab", "az-Cyrl", "az-Latn".
    1316         The default script for az on Unix is Latin.  */
    1317      { "az-Latn", "az" },
    1318      /* Mac OS X has "bs-Cyrl", "bs-Latn".
    1319         The default script for bs on Unix is Latin.  */
    1320      { "bs-Latn", "bs" },
    1321      /* Mac OS X has "ga-dots".  Does not yet exist on Unix.  */
    1322      { "ga-dots", "ga" },
    1323      /* Mac OS X has "kk-Cyrl".
    1324         The default script for kk on Unix is Cyrillic.  */
    1325      { "kk-Cyrl", "kk" },
    1326      /* Mac OS X has "mn-Cyrl", "mn-Mong".
    1327         The default script for mn on Unix is Cyrillic.  */
    1328      { "mn-Cyrl", "mn" },
    1329      /* Mac OS X has "ms-Arab", "ms-Latn".
    1330         The default script for ms on Unix is Latin.  */
    1331      { "ms-Latn", "ms" },
    1332      /* Mac OS X has "pa-Arab", "pa-Guru".
    1333         Country codes are used to distinguish these on Unix.  */
    1334      { "pa-Arab", "pa_PK" },
    1335      { "pa-Guru", "pa_IN" },
    1336      /* Mac OS X has "shi-Latn", "shi-Tfng".  Does not yet exist on Unix.  */
    1337      /* Mac OS X has "sr-Cyrl", "sr-Latn".
    1338         The default script for sr on Unix is Cyrillic.  */
    1339      { "sr-Cyrl", "sr" },
    1340      /* Mac OS X has "tg-Cyrl".
    1341         The default script for tg on Unix is Cyrillic.  */
    1342      { "tg-Cyrl", "tg" },
    1343      /* Mac OS X has "tk-Cyrl".
    1344         The default script for tk on Unix is Cyrillic.  */
    1345      { "tk-Cyrl", "tk" },
    1346      /* Mac OS X has "tt-Cyrl".
    1347         The default script for tt on Unix is Cyrillic.  */
    1348      { "tt-Cyrl", "tt" },
    1349      /* Mac OS X has "uz-Arab", "uz-Cyrl", "uz-Latn".
    1350         The default script for uz on Unix is Latin.  */
    1351      { "uz-Latn", "uz" },
    1352      /* Mac OS X has "vai-Latn", "vai-Vaii".  Does not yet exist on Unix.  */
    1353      /* Mac OS X has "yue-Hans", "yue-Hant".
    1354         The default script for yue on Unix is Simplified Han.  */
    1355      { "yue-Hans", "yue" },
    1356      /* Mac OS X has "zh-Hans", "zh-Hant".
    1357         Country codes are used to distinguish these on Unix.  */
    1358      { "zh-Hans", "zh_CN" },
    1359      { "zh-Hant", "zh_TW" }
    1360    };
    1361  
    1362    /* Convert script names (ISO 15924) to Unix conventions.
    1363       See https://www.unicode.org/iso15924/iso15924-codes.html  */
    1364    typedef struct { const char script[4+1]; const char unixy[9+1]; }
    1365            script_entry;
    1366    static const script_entry script_table[] = {
    1367      { "Arab", "arabic" },
    1368      { "Cyrl", "cyrillic" },
    1369      { "Latn", "latin" },
    1370      { "Mong", "mongolian" }
    1371    };
    1372  
    1373    /* Step 1: Convert using legacy_table.  */
    1374    if (name[0] >= 'A' && name[0] <= 'Z')
    1375      {
    1376        unsigned int i1, i2;
    1377        i1 = 0;
    1378        i2 = sizeof (legacy_table) / sizeof (legacy_entry);
    1379        while (i2 - i1 > 1)
    1380          {
    1381            /* At this point we know that if name occurs in legacy_table,
    1382               its index must be >= i1 and < i2.  */
    1383            unsigned int i = (i1 + i2) >> 1;
    1384            const legacy_entry *p = &legacy_table[i];
    1385            if (strcmp (name, p->legacy) < 0)
    1386              i2 = i;
    1387            else
    1388              i1 = i;
    1389          }
    1390        if (strcmp (name, legacy_table[i1].legacy) == 0)
    1391          {
    1392            strcpy (name, legacy_table[i1].unixy);
    1393            return;
    1394          }
    1395      }
    1396  
    1397    /* Step 2: Convert using langtag_table and script_table.  */
    1398    if (strlen (name) == 7 && name[2] == '-')
    1399      {
    1400        unsigned int i1, i2;
    1401        i1 = 0;
    1402        i2 = sizeof (langtag_table) / sizeof (langtag_entry);
    1403        while (i2 - i1 > 1)
    1404          {
    1405            /* At this point we know that if name occurs in langtag_table,
    1406               its index must be >= i1 and < i2.  */
    1407            unsigned int i = (i1 + i2) >> 1;
    1408            const langtag_entry *p = &langtag_table[i];
    1409            if (strcmp (name, p->langtag) < 0)
    1410              i2 = i;
    1411            else
    1412              i1 = i;
    1413          }
    1414        if (strcmp (name, langtag_table[i1].langtag) == 0)
    1415          {
    1416            strcpy (name, langtag_table[i1].unixy);
    1417            return;
    1418          }
    1419  
    1420        i1 = 0;
    1421        i2 = sizeof (script_table) / sizeof (script_entry);
    1422        while (i2 - i1 > 1)
    1423          {
    1424            /* At this point we know that if (name + 3) occurs in script_table,
    1425               its index must be >= i1 and < i2.  */
    1426            unsigned int i = (i1 + i2) >> 1;
    1427            const script_entry *p = &script_table[i];
    1428            if (strcmp (name + 3, p->script) < 0)
    1429              i2 = i;
    1430            else
    1431              i1 = i;
    1432          }
    1433        if (strcmp (name + 3, script_table[i1].script) == 0)
    1434          {
    1435            name[2] = '@';
    1436            strcpy (name + 3, script_table[i1].unixy);
    1437            return;
    1438          }
    1439      }
    1440  
    1441    /* Step 3: Convert new-style dash to Unix underscore. */
    1442    {
    1443      char *p;
    1444      for (p = name; *p != '\0'; p++)
    1445        if (*p == '-')
    1446          *p = '_';
    1447    }
    1448  }
    1449  
    1450  #endif
    1451  
    1452  
    1453  #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
    1454  
    1455  /* Canonicalize a Windows native locale name to a Unix locale name.
    1456     NAME is a sufficiently large buffer.
    1457     On input, it contains the Windows locale name.
    1458     On output, it contains the Unix locale name.  */
    1459  # if !defined IN_LIBINTL
    1460  static
    1461  # endif
    1462  void
    1463  gl_locale_name_canonicalize (char *name)
    1464  {
    1465    /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
    1466       "zh-Hant".  */
    1467    char *p;
    1468  
    1469    for (p = name; *p != '\0'; p++)
    1470      if (*p == '-')
    1471        {
    1472          *p = '_';
    1473          p++;
    1474          for (; *p != '\0'; p++)
    1475            {
    1476              if (*p >= 'a' && *p <= 'z')
    1477                *p += 'A' - 'a';
    1478              if (*p == '-')
    1479                {
    1480                  *p = '\0';
    1481                  return;
    1482                }
    1483            }
    1484          return;
    1485        }
    1486  }
    1487  
    1488  # if !defined IN_LIBINTL
    1489  static
    1490  # endif
    1491  const char *
    1492  gl_locale_name_from_win32_LANGID (LANGID langid)
    1493  {
    1494    /* Activate the new code only when the GETTEXT_MUI environment variable is
    1495       set, for the time being, since the new code is not well tested.  */
    1496    if (getenv ("GETTEXT_MUI") != NULL)
    1497      {
    1498        static char namebuf[256];
    1499  
    1500        /* Query the system's notion of locale name.
    1501           On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
    1502           But we don't need to support systems that are so old.  */
    1503        if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
    1504                            namebuf, sizeof (namebuf) - 1))
    1505          {
    1506            /* Convert it to a Unix locale name.  */
    1507            gl_locale_name_canonicalize (namebuf);
    1508            return namebuf;
    1509          }
    1510      }
    1511    /* Internet Explorer has an LCID to RFC3066 name mapping stored in
    1512       HKEY_CLASSES_ROOT\Mime\Database\Rfc1766.  But we better don't use that
    1513       since IE's i18n subsystem is known to be inconsistent with the native
    1514       Windows base (e.g. they have different character conversion facilities
    1515       that produce different results).  */
    1516    /* Use our own table.  */
    1517    {
    1518      int primary, sub;
    1519  
    1520      /* Split into language and territory part.  */
    1521      primary = PRIMARYLANGID (langid);
    1522      sub = SUBLANGID (langid);
    1523  
    1524      /* Dispatch on language.
    1525         See also https://www.unicode.org/unicode/onlinedat/languages.html .
    1526         For details about languages, see https://www.ethnologue.com/ .  */
    1527      switch (primary)
    1528        {
    1529        case LANG_AFRIKAANS:
    1530          switch (sub)
    1531            {
    1532            case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
    1533            }
    1534          return "af";
    1535        case LANG_ALBANIAN:
    1536          switch (sub)
    1537            {
    1538            case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
    1539            }
    1540          return "sq";
    1541        case LANG_ALSATIAN:
    1542          switch (sub)
    1543            {
    1544            case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
    1545            }
    1546          return "gsw";
    1547        case LANG_AMHARIC:
    1548          switch (sub)
    1549            {
    1550            case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
    1551            }
    1552          return "am";
    1553        case LANG_ARABIC:
    1554          switch (sub)
    1555            {
    1556            case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
    1557            case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
    1558            case SUBLANG_ARABIC_EGYPT: return "ar_EG";
    1559            case SUBLANG_ARABIC_LIBYA: return "ar_LY";
    1560            case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
    1561            case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
    1562            case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
    1563            case SUBLANG_ARABIC_OMAN: return "ar_OM";
    1564            case SUBLANG_ARABIC_YEMEN: return "ar_YE";
    1565            case SUBLANG_ARABIC_SYRIA: return "ar_SY";
    1566            case SUBLANG_ARABIC_JORDAN: return "ar_JO";
    1567            case SUBLANG_ARABIC_LEBANON: return "ar_LB";
    1568            case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
    1569            case SUBLANG_ARABIC_UAE: return "ar_AE";
    1570            case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
    1571            case SUBLANG_ARABIC_QATAR: return "ar_QA";
    1572            }
    1573          return "ar";
    1574        case LANG_ARMENIAN:
    1575          switch (sub)
    1576            {
    1577            case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
    1578            }
    1579          return "hy";
    1580        case LANG_ASSAMESE:
    1581          switch (sub)
    1582            {
    1583            case SUBLANG_ASSAMESE_INDIA: return "as_IN";
    1584            }
    1585          return "as";
    1586        case LANG_AZERI:
    1587          switch (sub)
    1588            {
    1589            /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
    1590            case 0x1e: return "az@latin";
    1591            case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
    1592            case 0x1d: return "az@cyrillic";
    1593            case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
    1594            }
    1595          return "az";
    1596        case LANG_BASHKIR:
    1597          switch (sub)
    1598            {
    1599            case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
    1600            }
    1601          return "ba";
    1602        case LANG_BASQUE:
    1603          switch (sub)
    1604            {
    1605            case SUBLANG_BASQUE_BASQUE: return "eu_ES";
    1606            }
    1607          return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
    1608        case LANG_BELARUSIAN:
    1609          switch (sub)
    1610            {
    1611            case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
    1612            }
    1613          return "be";
    1614        case LANG_BENGALI:
    1615          switch (sub)
    1616            {
    1617            case SUBLANG_BENGALI_INDIA: return "bn_IN";
    1618            case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
    1619            }
    1620          return "bn";
    1621        case LANG_BRETON:
    1622          switch (sub)
    1623            {
    1624            case SUBLANG_BRETON_FRANCE: return "br_FR";
    1625            }
    1626          return "br";
    1627        case LANG_BULGARIAN:
    1628          switch (sub)
    1629            {
    1630            case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
    1631            }
    1632          return "bg";
    1633        case LANG_BURMESE:
    1634          switch (sub)
    1635            {
    1636            case SUBLANG_DEFAULT: return "my_MM";
    1637            }
    1638          return "my";
    1639        case LANG_CAMBODIAN:
    1640          switch (sub)
    1641            {
    1642            case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
    1643            }
    1644          return "km";
    1645        case LANG_CATALAN:
    1646          switch (sub)
    1647            {
    1648            case SUBLANG_CATALAN_SPAIN: return "ca_ES";
    1649            }
    1650          return "ca";
    1651        case LANG_CHEROKEE:
    1652          switch (sub)
    1653            {
    1654            case SUBLANG_DEFAULT: return "chr_US";
    1655            }
    1656          return "chr";
    1657        case LANG_CHINESE:
    1658          switch (sub)
    1659            {
    1660            case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
    1661            case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
    1662            case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
    1663            case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
    1664            case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
    1665            }
    1666          return "zh";
    1667        case LANG_CORSICAN:
    1668          switch (sub)
    1669            {
    1670            case SUBLANG_CORSICAN_FRANCE: return "co_FR";
    1671            }
    1672          return "co";
    1673        case LANG_CROATIAN:      /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
    1674                                  * What used to be called Serbo-Croatian
    1675                                  * should really now be two separate
    1676                                  * languages because of political reasons.
    1677                                  * (Says tml, who knows nothing about Serbian
    1678                                  * or Croatian.)
    1679                                  * (I can feel those flames coming already.)
    1680                                  */
    1681          switch (sub)
    1682            {
    1683            /* Croatian */
    1684            case 0x00: return "hr";
    1685            case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
    1686            case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
    1687            /* Serbian */
    1688            case 0x1f: return "sr";
    1689            case 0x1c: return "sr"; /* latin */
    1690            case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
    1691            case 0x09: return "sr_RS"; /* latin */
    1692            case 0x0b: return "sr_ME"; /* latin */
    1693            case 0x06: return "sr_BA"; /* latin */
    1694            case 0x1b: return "sr@cyrillic";
    1695            case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
    1696            case 0x0a: return "sr_RS@cyrillic";
    1697            case 0x0c: return "sr_ME@cyrillic";
    1698            case 0x07: return "sr_BA@cyrillic";
    1699            /* Bosnian */
    1700            case 0x1e: return "bs";
    1701            case 0x1a: return "bs"; /* latin */
    1702            case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
    1703            case 0x19: return "bs@cyrillic";
    1704            case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
    1705            }
    1706          return "hr";
    1707        case LANG_CZECH:
    1708          switch (sub)
    1709            {
    1710            case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
    1711            }
    1712          return "cs";
    1713        case LANG_DANISH:
    1714          switch (sub)
    1715            {
    1716            case SUBLANG_DANISH_DENMARK: return "da_DK";
    1717            }
    1718          return "da";
    1719        case LANG_DARI:
    1720          /* FIXME: Adjust this when such locales appear on Unix.  */
    1721          switch (sub)
    1722            {
    1723            case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
    1724            }
    1725          return "prs";
    1726        case LANG_DIVEHI:
    1727          switch (sub)
    1728            {
    1729            case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
    1730            }
    1731          return "dv";
    1732        case LANG_DUTCH:
    1733          switch (sub)
    1734            {
    1735            case SUBLANG_DUTCH: return "nl_NL";
    1736            case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
    1737            case SUBLANG_DUTCH_SURINAM: return "nl_SR";
    1738            }
    1739          return "nl";
    1740        case LANG_EDO:
    1741          switch (sub)
    1742            {
    1743            case SUBLANG_DEFAULT: return "bin_NG";
    1744            }
    1745          return "bin";
    1746        case LANG_ENGLISH:
    1747          switch (sub)
    1748            {
    1749            /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
    1750             * English was the language spoken in England.
    1751             * Oh well.
    1752             */
    1753            case SUBLANG_ENGLISH_US: return "en_US";
    1754            case SUBLANG_ENGLISH_UK: return "en_GB";
    1755            case SUBLANG_ENGLISH_AUS: return "en_AU";
    1756            case SUBLANG_ENGLISH_CAN: return "en_CA";
    1757            case SUBLANG_ENGLISH_NZ: return "en_NZ";
    1758            case SUBLANG_ENGLISH_EIRE: return "en_IE";
    1759            case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
    1760            case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
    1761            case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
    1762            case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
    1763            case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
    1764            case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
    1765            case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
    1766            case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
    1767            case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
    1768            case SUBLANG_ENGLISH_INDIA: return "en_IN";
    1769            case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
    1770            case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
    1771            }
    1772          return "en";
    1773        case LANG_ESTONIAN:
    1774          switch (sub)
    1775            {
    1776            case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
    1777            }
    1778          return "et";
    1779        case LANG_FAEROESE:
    1780          switch (sub)
    1781            {
    1782            case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
    1783            }
    1784          return "fo";
    1785        case LANG_FARSI:
    1786          switch (sub)
    1787            {
    1788            case SUBLANG_FARSI_IRAN: return "fa_IR";
    1789            }
    1790          return "fa";
    1791        case LANG_FINNISH:
    1792          switch (sub)
    1793            {
    1794            case SUBLANG_FINNISH_FINLAND: return "fi_FI";
    1795            }
    1796          return "fi";
    1797        case LANG_FRENCH:
    1798          switch (sub)
    1799            {
    1800            case SUBLANG_FRENCH: return "fr_FR";
    1801            case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
    1802            case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
    1803            case SUBLANG_FRENCH_SWISS: return "fr_CH";
    1804            case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
    1805            case SUBLANG_FRENCH_MONACO: return "fr_MC";
    1806            case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
    1807            case SUBLANG_FRENCH_REUNION: return "fr_RE";
    1808            case SUBLANG_FRENCH_CONGO: return "fr_CG";
    1809            case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
    1810            case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
    1811            case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
    1812            case SUBLANG_FRENCH_MALI: return "fr_ML";
    1813            case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
    1814            case SUBLANG_FRENCH_HAITI: return "fr_HT";
    1815            }
    1816          return "fr";
    1817        case LANG_FRISIAN:
    1818          switch (sub)
    1819            {
    1820            case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
    1821            }
    1822          return "fy";
    1823        case LANG_FULFULDE:
    1824          /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin.  */
    1825          switch (sub)
    1826            {
    1827            case SUBLANG_DEFAULT: return "ff_NG";
    1828            }
    1829          return "ff";
    1830        case LANG_GAELIC:
    1831          switch (sub)
    1832            {
    1833            case 0x01: /* SCOTTISH */
    1834              /* old, superseded by LANG_SCOTTISH_GAELIC */
    1835              return "gd_GB";
    1836            case SUBLANG_IRISH_IRELAND: return "ga_IE";
    1837            }
    1838          return "ga";
    1839        case LANG_GALICIAN:
    1840          switch (sub)
    1841            {
    1842            case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
    1843            }
    1844          return "gl";
    1845        case LANG_GEORGIAN:
    1846          switch (sub)
    1847            {
    1848            case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
    1849            }
    1850          return "ka";
    1851        case LANG_GERMAN:
    1852          switch (sub)
    1853            {
    1854            case SUBLANG_GERMAN: return "de_DE";
    1855            case SUBLANG_GERMAN_SWISS: return "de_CH";
    1856            case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
    1857            case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
    1858            case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
    1859            }
    1860          return "de";
    1861        case LANG_GREEK:
    1862          switch (sub)
    1863            {
    1864            case SUBLANG_GREEK_GREECE: return "el_GR";
    1865            }
    1866          return "el";
    1867        case LANG_GREENLANDIC:
    1868          switch (sub)
    1869            {
    1870            case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
    1871            }
    1872          return "kl";
    1873        case LANG_GUARANI:
    1874          switch (sub)
    1875            {
    1876            case SUBLANG_DEFAULT: return "gn_PY";
    1877            }
    1878          return "gn";
    1879        case LANG_GUJARATI:
    1880          switch (sub)
    1881            {
    1882            case SUBLANG_GUJARATI_INDIA: return "gu_IN";
    1883            }
    1884          return "gu";
    1885        case LANG_HAUSA:
    1886          switch (sub)
    1887            {
    1888            case 0x1f: return "ha";
    1889            case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
    1890            }
    1891          return "ha";
    1892        case LANG_HAWAIIAN:
    1893          /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
    1894             or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
    1895          switch (sub)
    1896            {
    1897            case SUBLANG_DEFAULT: return "cpe_US";
    1898            }
    1899          return "cpe";
    1900        case LANG_HEBREW:
    1901          switch (sub)
    1902            {
    1903            case SUBLANG_HEBREW_ISRAEL: return "he_IL";
    1904            }
    1905          return "he";
    1906        case LANG_HINDI:
    1907          switch (sub)
    1908            {
    1909            case SUBLANG_HINDI_INDIA: return "hi_IN";
    1910            }
    1911          return "hi";
    1912        case LANG_HUNGARIAN:
    1913          switch (sub)
    1914            {
    1915            case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
    1916            }
    1917          return "hu";
    1918        case LANG_IBIBIO:
    1919          switch (sub)
    1920            {
    1921            case SUBLANG_DEFAULT: return "nic_NG";
    1922            }
    1923          return "nic";
    1924        case LANG_ICELANDIC:
    1925          switch (sub)
    1926            {
    1927            case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
    1928            }
    1929          return "is";
    1930        case LANG_IGBO:
    1931          switch (sub)
    1932            {
    1933            case SUBLANG_IGBO_NIGERIA: return "ig_NG";
    1934            }
    1935          return "ig";
    1936        case LANG_INDONESIAN:
    1937          switch (sub)
    1938            {
    1939            case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
    1940            }
    1941          return "id";
    1942        case LANG_INUKTITUT:
    1943          switch (sub)
    1944            {
    1945            case 0x1e: return "iu"; /* syllabic */
    1946            case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
    1947            case 0x1f: return "iu@latin";
    1948            case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
    1949            }
    1950          return "iu";
    1951        case LANG_ITALIAN:
    1952          switch (sub)
    1953            {
    1954            case SUBLANG_ITALIAN: return "it_IT";
    1955            case SUBLANG_ITALIAN_SWISS: return "it_CH";
    1956            }
    1957          return "it";
    1958        case LANG_JAPANESE:
    1959          switch (sub)
    1960            {
    1961            case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
    1962            }
    1963          return "ja";
    1964        case LANG_KANNADA:
    1965          switch (sub)
    1966            {
    1967            case SUBLANG_KANNADA_INDIA: return "kn_IN";
    1968            }
    1969          return "kn";
    1970        case LANG_KANURI:
    1971          switch (sub)
    1972            {
    1973            case SUBLANG_DEFAULT: return "kr_NG";
    1974            }
    1975          return "kr";
    1976        case LANG_KASHMIRI:
    1977          switch (sub)
    1978            {
    1979            case SUBLANG_DEFAULT: return "ks_PK";
    1980            case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
    1981            }
    1982          return "ks";
    1983        case LANG_KAZAK:
    1984          switch (sub)
    1985            {
    1986            case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
    1987            }
    1988          return "kk";
    1989        case LANG_KICHE:
    1990          /* FIXME: Adjust this when such locales appear on Unix.  */
    1991          switch (sub)
    1992            {
    1993            case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
    1994            }
    1995          return "qut";
    1996        case LANG_KINYARWANDA:
    1997          switch (sub)
    1998            {
    1999            case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
    2000            }
    2001          return "rw";
    2002        case LANG_KONKANI:
    2003          /* FIXME: Adjust this when such locales appear on Unix.  */
    2004          switch (sub)
    2005            {
    2006            case SUBLANG_KONKANI_INDIA: return "kok_IN";
    2007            }
    2008          return "kok";
    2009        case LANG_KOREAN:
    2010          switch (sub)
    2011            {
    2012            case SUBLANG_DEFAULT: return "ko_KR";
    2013            }
    2014          return "ko";
    2015        case LANG_KYRGYZ:
    2016          switch (sub)
    2017            {
    2018            case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
    2019            }
    2020          return "ky";
    2021        case LANG_LAO:
    2022          switch (sub)
    2023            {
    2024            case SUBLANG_LAO_LAOS: return "lo_LA";
    2025            }
    2026          return "lo";
    2027        case LANG_LATIN:
    2028          switch (sub)
    2029            {
    2030            case SUBLANG_DEFAULT: return "la_VA";
    2031            }
    2032          return "la";
    2033        case LANG_LATVIAN:
    2034          switch (sub)
    2035            {
    2036            case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
    2037            }
    2038          return "lv";
    2039        case LANG_LITHUANIAN:
    2040          switch (sub)
    2041            {
    2042            case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
    2043            }
    2044          return "lt";
    2045        case LANG_LUXEMBOURGISH:
    2046          switch (sub)
    2047            {
    2048            case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
    2049            }
    2050          return "lb";
    2051        case LANG_MACEDONIAN:
    2052          switch (sub)
    2053            {
    2054            case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
    2055            }
    2056          return "mk";
    2057        case LANG_MALAY:
    2058          switch (sub)
    2059            {
    2060            case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
    2061            case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
    2062            }
    2063          return "ms";
    2064        case LANG_MALAYALAM:
    2065          switch (sub)
    2066            {
    2067            case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
    2068            }
    2069          return "ml";
    2070        case LANG_MALTESE:
    2071          switch (sub)
    2072            {
    2073            case SUBLANG_MALTESE_MALTA: return "mt_MT";
    2074            }
    2075          return "mt";
    2076        case LANG_MANIPURI:
    2077          /* FIXME: Adjust this when such locales appear on Unix.  */
    2078          switch (sub)
    2079            {
    2080            case SUBLANG_DEFAULT: return "mni_IN";
    2081            }
    2082          return "mni";
    2083        case LANG_MAORI:
    2084          switch (sub)
    2085            {
    2086            case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
    2087            }
    2088          return "mi";
    2089        case LANG_MAPUDUNGUN:
    2090          switch (sub)
    2091            {
    2092            case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
    2093            }
    2094          return "arn";
    2095        case LANG_MARATHI:
    2096          switch (sub)
    2097            {
    2098            case SUBLANG_MARATHI_INDIA: return "mr_IN";
    2099            }
    2100          return "mr";
    2101        case LANG_MOHAWK:
    2102          switch (sub)
    2103            {
    2104            case SUBLANG_MOHAWK_CANADA: return "moh_CA";
    2105            }
    2106          return "moh";
    2107        case LANG_MONGOLIAN:
    2108          switch (sub)
    2109            {
    2110            case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
    2111            case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
    2112            }
    2113          return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
    2114        case LANG_NEPALI:
    2115          switch (sub)
    2116            {
    2117            case SUBLANG_NEPALI_NEPAL: return "ne_NP";
    2118            case SUBLANG_NEPALI_INDIA: return "ne_IN";
    2119            }
    2120          return "ne";
    2121        case LANG_NORWEGIAN:
    2122          switch (sub)
    2123            {
    2124            case 0x1f: return "nb";
    2125            case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
    2126            case 0x1e: return "nn";
    2127            case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
    2128            }
    2129          return "no";
    2130        case LANG_OCCITAN:
    2131          switch (sub)
    2132            {
    2133            case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
    2134            }
    2135          return "oc";
    2136        case LANG_ORIYA:
    2137          switch (sub)
    2138            {
    2139            case SUBLANG_ORIYA_INDIA: return "or_IN";
    2140            }
    2141          return "or";
    2142        case LANG_OROMO:
    2143          switch (sub)
    2144            {
    2145            case SUBLANG_DEFAULT: return "om_ET";
    2146            }
    2147          return "om";
    2148        case LANG_PAPIAMENTU:
    2149          switch (sub)
    2150            {
    2151            case SUBLANG_DEFAULT: return "pap_AN";
    2152            }
    2153          return "pap";
    2154        case LANG_PASHTO:
    2155          switch (sub)
    2156            {
    2157            case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
    2158            }
    2159          return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
    2160        case LANG_POLISH:
    2161          switch (sub)
    2162            {
    2163            case SUBLANG_POLISH_POLAND: return "pl_PL";
    2164            }
    2165          return "pl";
    2166        case LANG_PORTUGUESE:
    2167          switch (sub)
    2168            {
    2169            /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
    2170               Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
    2171            case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
    2172            case SUBLANG_PORTUGUESE: return "pt_PT";
    2173            }
    2174          return "pt";
    2175        case LANG_PUNJABI:
    2176          switch (sub)
    2177            {
    2178            case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
    2179            case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
    2180            }
    2181          return "pa";
    2182        case LANG_QUECHUA:
    2183          /* Note: Microsoft uses the non-ISO language code "quz".  */
    2184          switch (sub)
    2185            {
    2186            case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
    2187            case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
    2188            case SUBLANG_QUECHUA_PERU: return "qu_PE";
    2189            }
    2190          return "qu";
    2191        case LANG_ROMANIAN:
    2192          switch (sub)
    2193            {
    2194            case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
    2195            case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
    2196            }
    2197          return "ro";
    2198        case LANG_ROMANSH:
    2199          switch (sub)
    2200            {
    2201            case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
    2202            }
    2203          return "rm";
    2204        case LANG_RUSSIAN:
    2205          switch (sub)
    2206            {
    2207            case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
    2208            case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
    2209            }
    2210          return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
    2211        case LANG_SAMI:
    2212          switch (sub)
    2213            {
    2214            /* Northern Sami */
    2215            case 0x00: return "se";
    2216            case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
    2217            case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
    2218            case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
    2219            /* Lule Sami */
    2220            case 0x1f: return "smj";
    2221            case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
    2222            case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
    2223            /* Southern Sami */
    2224            case 0x1e: return "sma";
    2225            case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
    2226            case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
    2227            /* Skolt Sami */
    2228            case 0x1d: return "sms";
    2229            case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
    2230            /* Inari Sami */
    2231            case 0x1c: return "smn";
    2232            case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
    2233            }
    2234          return "se"; /* or "smi"? */
    2235        case LANG_SANSKRIT:
    2236          switch (sub)
    2237            {
    2238            case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
    2239            }
    2240          return "sa";
    2241        case LANG_SCOTTISH_GAELIC:
    2242          switch (sub)
    2243            {
    2244            case SUBLANG_DEFAULT: return "gd_GB";
    2245            }
    2246          return "gd";
    2247        case LANG_SINDHI:
    2248          switch (sub)
    2249            {
    2250            case SUBLANG_SINDHI_INDIA: return "sd_IN";
    2251            case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
    2252            /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
    2253            }
    2254          return "sd";
    2255        case LANG_SINHALESE:
    2256          switch (sub)
    2257            {
    2258            case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
    2259            }
    2260          return "si";
    2261        case LANG_SLOVAK:
    2262          switch (sub)
    2263            {
    2264            case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
    2265            }
    2266          return "sk";
    2267        case LANG_SLOVENIAN:
    2268          switch (sub)
    2269            {
    2270            case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
    2271            }
    2272          return "sl";
    2273        case LANG_SOMALI:
    2274          switch (sub)
    2275            {
    2276            case SUBLANG_DEFAULT: return "so_SO";
    2277            }
    2278          return "so";
    2279        case LANG_SORBIAN:
    2280          /* FIXME: Adjust this when such locales appear on Unix.  */
    2281          switch (sub)
    2282            {
    2283            /* Upper Sorbian */
    2284            case 0x00: return "hsb";
    2285            case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
    2286            /* Lower Sorbian */
    2287            case 0x1f: return "dsb";
    2288            case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
    2289            }
    2290          return "wen";
    2291        case LANG_SOTHO:
    2292          /* <https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifier-constants-and-strings>
    2293             calls it "Sesotho sa Leboa"; according to
    2294             <https://www.ethnologue.com/show_language.asp?code=nso>
    2295             <https://www.ethnologue.com/show_language.asp?code=sot>
    2296             it's the same as Northern Sotho.  */
    2297          switch (sub)
    2298            {
    2299            case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
    2300            }
    2301          return "nso";
    2302        case LANG_SPANISH:
    2303          switch (sub)
    2304            {
    2305            case SUBLANG_SPANISH: return "es_ES";
    2306            case SUBLANG_SPANISH_MEXICAN: return "es_MX";
    2307            case SUBLANG_SPANISH_MODERN:
    2308              return "es_ES@modern";      /* not seen on Unix */
    2309            case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
    2310            case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
    2311            case SUBLANG_SPANISH_PANAMA: return "es_PA";
    2312            case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
    2313            case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
    2314            case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
    2315            case SUBLANG_SPANISH_PERU: return "es_PE";
    2316            case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
    2317            case SUBLANG_SPANISH_ECUADOR: return "es_EC";
    2318            case SUBLANG_SPANISH_CHILE: return "es_CL";
    2319            case SUBLANG_SPANISH_URUGUAY: return "es_UY";
    2320            case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
    2321            case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
    2322            case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
    2323            case SUBLANG_SPANISH_HONDURAS: return "es_HN";
    2324            case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
    2325            case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
    2326            case SUBLANG_SPANISH_US: return "es_US";
    2327            }
    2328          return "es";
    2329        case LANG_SUTU:
    2330          switch (sub)
    2331            {
    2332            case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
    2333            }
    2334          return "bnt";
    2335        case LANG_SWAHILI:
    2336          switch (sub)
    2337            {
    2338            case SUBLANG_SWAHILI_KENYA: return "sw_KE";
    2339            }
    2340          return "sw";
    2341        case LANG_SWEDISH:
    2342          switch (sub)
    2343            {
    2344            case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
    2345            case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
    2346            }
    2347          return "sv";
    2348        case LANG_SYRIAC:
    2349          switch (sub)
    2350            {
    2351            case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language.  */
    2352            }
    2353          return "syr";
    2354        case LANG_TAGALOG:
    2355          switch (sub)
    2356            {
    2357            case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
    2358            }
    2359          return "tl"; /* or "fil"? */
    2360        case LANG_TAJIK:
    2361          switch (sub)
    2362            {
    2363            case 0x1f: return "tg";
    2364            case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
    2365            }
    2366          return "tg";
    2367        case LANG_TAMAZIGHT:
    2368          /* Note: Microsoft uses the non-ISO language code "tmz".  */
    2369          switch (sub)
    2370            {
    2371            /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
    2372            case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
    2373            case 0x1f: return "ber@latin";
    2374            case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
    2375            }
    2376          return "ber";
    2377        case LANG_TAMIL:
    2378          switch (sub)
    2379            {
    2380            case SUBLANG_TAMIL_INDIA: return "ta_IN";
    2381            }
    2382          return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
    2383        case LANG_TATAR:
    2384          switch (sub)
    2385            {
    2386            case SUBLANG_TATAR_RUSSIA: return "tt_RU";
    2387            }
    2388          return "tt";
    2389        case LANG_TELUGU:
    2390          switch (sub)
    2391            {
    2392            case SUBLANG_TELUGU_INDIA: return "te_IN";
    2393            }
    2394          return "te";
    2395        case LANG_THAI:
    2396          switch (sub)
    2397            {
    2398            case SUBLANG_THAI_THAILAND: return "th_TH";
    2399            }
    2400          return "th";
    2401        case LANG_TIBETAN:
    2402          switch (sub)
    2403            {
    2404            case SUBLANG_TIBETAN_PRC:
    2405              /* Most Tibetans would not like "bo_CN".  But Tibet does not yet
    2406                 have a country code of its own.  */
    2407              return "bo";
    2408            case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
    2409            }
    2410          return "bo";
    2411        case LANG_TIGRINYA:
    2412          switch (sub)
    2413            {
    2414            case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
    2415            case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
    2416            }
    2417          return "ti";
    2418        case LANG_TSONGA:
    2419          switch (sub)
    2420            {
    2421            case SUBLANG_DEFAULT: return "ts_ZA";
    2422            }
    2423          return "ts";
    2424        case LANG_TSWANA:
    2425          /* Spoken in South Africa, Botswana.  */
    2426          switch (sub)
    2427            {
    2428            case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
    2429            }
    2430          return "tn";
    2431        case LANG_TURKISH:
    2432          switch (sub)
    2433            {
    2434            case SUBLANG_TURKISH_TURKEY: return "tr_TR";
    2435            }
    2436          return "tr";
    2437        case LANG_TURKMEN:
    2438          switch (sub)
    2439            {
    2440            case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
    2441            }
    2442          return "tk";
    2443        case LANG_UIGHUR:
    2444          switch (sub)
    2445            {
    2446            case SUBLANG_UIGHUR_PRC: return "ug_CN";
    2447            }
    2448          return "ug";
    2449        case LANG_UKRAINIAN:
    2450          switch (sub)
    2451            {
    2452            case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
    2453            }
    2454          return "uk";
    2455        case LANG_URDU:
    2456          switch (sub)
    2457            {
    2458            case SUBLANG_URDU_PAKISTAN: return "ur_PK";
    2459            case SUBLANG_URDU_INDIA: return "ur_IN";
    2460            }
    2461          return "ur";
    2462        case LANG_UZBEK:
    2463          switch (sub)
    2464            {
    2465            case 0x1f: return "uz";
    2466            case SUBLANG_UZBEK_LATIN: return "uz_UZ";
    2467            case 0x1e: return "uz@cyrillic";
    2468            case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
    2469            }
    2470          return "uz";
    2471        case LANG_VENDA:
    2472          switch (sub)
    2473            {
    2474            case SUBLANG_DEFAULT: return "ve_ZA";
    2475            }
    2476          return "ve";
    2477        case LANG_VIETNAMESE:
    2478          switch (sub)
    2479            {
    2480            case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
    2481            }
    2482          return "vi";
    2483        case LANG_WELSH:
    2484          switch (sub)
    2485            {
    2486            case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
    2487            }
    2488          return "cy";
    2489        case LANG_WOLOF:
    2490          switch (sub)
    2491            {
    2492            case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
    2493            }
    2494          return "wo";
    2495        case LANG_XHOSA:
    2496          switch (sub)
    2497            {
    2498            case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
    2499            }
    2500          return "xh";
    2501        case LANG_YAKUT:
    2502          switch (sub)
    2503            {
    2504            case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
    2505            }
    2506          return "sah";
    2507        case LANG_YI:
    2508          switch (sub)
    2509            {
    2510            case SUBLANG_YI_PRC: return "ii_CN";
    2511            }
    2512          return "ii";
    2513        case LANG_YIDDISH:
    2514          switch (sub)
    2515            {
    2516            case SUBLANG_DEFAULT: return "yi_IL";
    2517            }
    2518          return "yi";
    2519        case LANG_YORUBA:
    2520          switch (sub)
    2521            {
    2522            case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
    2523            }
    2524          return "yo";
    2525        case LANG_ZULU:
    2526          switch (sub)
    2527            {
    2528            case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
    2529            }
    2530          return "zu";
    2531        default: return "C";
    2532        }
    2533    }
    2534  }
    2535  
    2536  # if !defined IN_LIBINTL
    2537  static
    2538  # endif
    2539  const char *
    2540  gl_locale_name_from_win32_LCID (LCID lcid)
    2541  {
    2542    LANGID langid;
    2543  
    2544    /* Strip off the sorting rules, keep only the language part.  */
    2545    langid = LANGIDFROMLCID (lcid);
    2546  
    2547    return gl_locale_name_from_win32_LANGID (langid);
    2548  }
    2549  
    2550  # ifdef WINDOWS_NATIVE
    2551  
    2552  /* Two variables to interface between get_lcid and the EnumLocales
    2553     callback function below.  */
    2554  static LCID found_lcid;
    2555  static char lname[LC_MAX * (LOCALE_NAME_MAX_LENGTH + 1) + 1];
    2556  
    2557  /* Callback function for EnumLocales.  */
    2558  static BOOL CALLBACK
    2559  enum_locales_fn (LPSTR locale_num_str)
    2560  {
    2561    char *endp;
    2562    char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
    2563    LCID try_lcid = strtoul (locale_num_str, &endp, 16);
    2564  
    2565    if (GetLocaleInfo (try_lcid, LOCALE_SENGLANGUAGE,
    2566                      locval, LOCALE_NAME_MAX_LENGTH))
    2567      {
    2568        strcat (locval, "_");
    2569        if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
    2570                          locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
    2571         {
    2572           size_t locval_len = strlen (locval);
    2573  
    2574           if (strncmp (locval, lname, locval_len) == 0
    2575               && (lname[locval_len] == '.'
    2576                   || lname[locval_len] == '\0'))
    2577             {
    2578               found_lcid = try_lcid;
    2579               return FALSE;
    2580             }
    2581         }
    2582      }
    2583    return TRUE;
    2584  }
    2585  
    2586  /* This lock protects the get_lcid against multiple simultaneous calls.  */
    2587  gl_lock_define_initialized(static, get_lcid_lock)
    2588  
    2589  /* Return the Locale ID (LCID) number given the locale's name, a
    2590     string, in LOCALE_NAME.  This works by enumerating all the locales
    2591     supported by the system, until we find one whose name matches
    2592     LOCALE_NAME.  */
    2593  static LCID
    2594  get_lcid (const char *locale_name)
    2595  {
    2596    /* A simple cache.  */
    2597    static LCID last_lcid;
    2598    static char last_locale[1000];
    2599  
    2600    /* Lock while looking for an LCID, to protect access to static
    2601       variables: last_lcid, last_locale, found_lcid, and lname.  */
    2602    gl_lock_lock (get_lcid_lock);
    2603    if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
    2604      {
    2605        gl_lock_unlock (get_lcid_lock);
    2606        return last_lcid;
    2607      }
    2608    strncpy (lname, locale_name, sizeof (lname) - 1);
    2609    lname[sizeof (lname) - 1] = '\0';
    2610    found_lcid = 0;
    2611    EnumSystemLocales (enum_locales_fn, LCID_SUPPORTED);
    2612    if (found_lcid > 0)
    2613      {
    2614        last_lcid = found_lcid;
    2615        strcpy (last_locale, locale_name);
    2616      }
    2617    gl_lock_unlock (get_lcid_lock);
    2618    return found_lcid;
    2619  }
    2620  
    2621  # endif
    2622  #endif
    2623  
    2624  
    2625  #if HAVE_GOOD_USELOCALE /* glibc, Mac OS X, FreeBSD >= 9.1, Cygwin >= 2.6,
    2626                             Solaris 11 OpenIndiana, or Solaris >= 11.4  */
    2627  
    2628  /* Simple hash set of strings.  We don't want to drag in lots of hash table
    2629     code here.  */
    2630  
    2631  # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
    2632  
    2633  /* A hash function for NUL-terminated char* strings using
    2634     the method described by Bruno Haible.
    2635     See https://www.haible.de/bruno/hashfunc.html.  */
    2636  static size_t _GL_ATTRIBUTE_PURE
    2637  string_hash (const void *x)
    2638  {
    2639    const char *s = (const char *) x;
    2640    size_t h = 0;
    2641  
    2642    for (; *s; s++)
    2643      h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
    2644  
    2645    return h;
    2646  }
    2647  
    2648  /* A hash table of fixed size.  Multiple threads can access it read-only
    2649     simultaneously, but only one thread can insert into it at the same time.  */
    2650  
    2651  /* A node in a hash bucket collision list.  */
    2652  struct struniq_hash_node
    2653    {
    2654      struct struniq_hash_node * volatile next;
    2655      char contents[FLEXIBLE_ARRAY_MEMBER];
    2656    };
    2657  
    2658  # define STRUNIQ_HASH_TABLE_SIZE 257
    2659  static struct struniq_hash_node * volatile struniq_hash_table[STRUNIQ_HASH_TABLE_SIZE]
    2660    /* = { NULL, ..., NULL } */;
    2661  
    2662  /* This lock protects the struniq_hash_table against multiple simultaneous
    2663     insertions.  */
    2664  gl_lock_define_initialized(static, struniq_lock)
    2665  
    2666  /* Store a copy of the given string in a string pool with indefinite extent.
    2667     Return a pointer to this copy.  */
    2668  static const char *
    2669  struniq (const char *string)
    2670  {
    2671    size_t hashcode = string_hash (string);
    2672    size_t slot = hashcode % STRUNIQ_HASH_TABLE_SIZE;
    2673    size_t size;
    2674    struct struniq_hash_node *new_node;
    2675    struct struniq_hash_node *p;
    2676    for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
    2677      if (strcmp (p->contents, string) == 0)
    2678        return p->contents;
    2679    size = strlen (string) + 1;
    2680    new_node =
    2681      (struct struniq_hash_node *)
    2682      malloc (FLEXSIZEOF (struct struniq_hash_node, contents, size));
    2683    if (new_node == NULL)
    2684      /* Out of memory.  Return a statically allocated string.  */
    2685      return "C";
    2686    memcpy (new_node->contents, string, size);
    2687    {
    2688      bool mt = gl_multithreaded ();
    2689      /* Lock while inserting new_node.  */
    2690      if (mt) gl_lock_lock (struniq_lock);
    2691      /* Check whether another thread already added the string while we were
    2692         waiting on the lock.  */
    2693      for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
    2694        if (strcmp (p->contents, string) == 0)
    2695          {
    2696            free (new_node);
    2697            new_node = p;
    2698            goto done;
    2699          }
    2700      /* Really insert new_node into the hash table.  Fill new_node entirely
    2701         first, because other threads may be iterating over the linked list.  */
    2702      new_node->next = struniq_hash_table[slot];
    2703      struniq_hash_table[slot] = new_node;
    2704     done:
    2705      /* Unlock after new_node is inserted.  */
    2706      if (mt) gl_lock_unlock (struniq_lock);
    2707    }
    2708    return new_node->contents;
    2709  }
    2710  
    2711  #endif
    2712  
    2713  
    2714  #if LOCALENAME_ENHANCE_LOCALE_FUNCS
    2715  
    2716  /* The 'locale_t' object does not contain the names of the locale categories.
    2717     We have to associate them with the object through a hash table.
    2718     The hash table is defined in localename-table.[hc].  */
    2719  
    2720  /* Returns the name of a given locale category in a given locale_t object,
    2721     allocated as a string with indefinite extent.  */
    2722  static const char *
    2723  get_locale_t_name (int category, locale_t locale)
    2724  {
    2725    if (locale == LC_GLOBAL_LOCALE)
    2726      {
    2727        /* Query the global locale.  */
    2728        const char *name = setlocale_null (category);
    2729        if (name != NULL)
    2730          return struniq (name);
    2731        else
    2732          /* Should normally not happen.  */
    2733          return "";
    2734      }
    2735    else
    2736      {
    2737        /* Look up the names in the hash table.  */
    2738        size_t hashcode = locale_hash_function (locale);
    2739        size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
    2740        /* If the locale was not found in the table, return "".  This can
    2741           happen if the application uses the original newlocale()/duplocale()
    2742           functions instead of the overridden ones.  */
    2743        const char *name = "";
    2744        struct locale_hash_node *p;
    2745        /* Lock while looking up the hash node.  */
    2746        gl_rwlock_rdlock (locale_lock);
    2747        for (p = locale_hash_table[slot]; p != NULL; p = p->next)
    2748          if (p->locale == locale)
    2749            {
    2750              name = p->names.category_name[category];
    2751              break;
    2752            }
    2753        gl_rwlock_unlock (locale_lock);
    2754        return name;
    2755      }
    2756  }
    2757  
    2758  # if !(defined newlocale && defined duplocale && defined freelocale)
    2759  #  error "newlocale, duplocale, freelocale not being replaced as expected!"
    2760  # endif
    2761  
    2762  /* newlocale() override.  */
    2763  locale_t
    2764  newlocale (int category_mask, const char *name, locale_t base)
    2765  #undef newlocale
    2766  {
    2767    struct locale_categories_names names;
    2768    struct locale_hash_node *node;
    2769    locale_t result;
    2770  
    2771    /* Make sure name has indefinite extent.  */
    2772    if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK
    2773          | LC_MONETARY_MASK | LC_MESSAGES_MASK)
    2774         & category_mask) != 0)
    2775      name = struniq (name);
    2776  
    2777    /* Determine the category names of the result.  */
    2778    if (((LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK
    2779          | LC_MONETARY_MASK | LC_MESSAGES_MASK)
    2780         & ~category_mask) == 0)
    2781      {
    2782        /* Use name, ignore base.  */
    2783        int category;
    2784  
    2785        name = struniq (name);
    2786        for (category = 0; category < 6; category++)
    2787          names.category_name[category] = name;
    2788      }
    2789    else
    2790      {
    2791        /* Use base, possibly also name.  */
    2792        if (base == NULL)
    2793          {
    2794            int category;
    2795  
    2796            for (category = 0; category < 6; category++)
    2797              {
    2798                int mask;
    2799  
    2800                switch (category)
    2801                  {
    2802                  case LC_CTYPE:
    2803                    mask = LC_CTYPE_MASK;
    2804                    break;
    2805                  case LC_NUMERIC:
    2806                    mask = LC_NUMERIC_MASK;
    2807                    break;
    2808                  case LC_TIME:
    2809                    mask = LC_TIME_MASK;
    2810                    break;
    2811                  case LC_COLLATE:
    2812                    mask = LC_COLLATE_MASK;
    2813                    break;
    2814                  case LC_MONETARY:
    2815                    mask = LC_MONETARY_MASK;
    2816                    break;
    2817                  case LC_MESSAGES:
    2818                    mask = LC_MESSAGES_MASK;
    2819                    break;
    2820                  default:
    2821                    abort ();
    2822                  }
    2823                names.category_name[category] =
    2824                  ((mask & category_mask) != 0 ? name : "C");
    2825              }
    2826          }
    2827        else if (base == LC_GLOBAL_LOCALE)
    2828          {
    2829            int category;
    2830  
    2831            for (category = 0; category < 6; category++)
    2832              {
    2833                int mask;
    2834  
    2835                switch (category)
    2836                  {
    2837                  case LC_CTYPE:
    2838                    mask = LC_CTYPE_MASK;
    2839                    break;
    2840                  case LC_NUMERIC:
    2841                    mask = LC_NUMERIC_MASK;
    2842                    break;
    2843                  case LC_TIME:
    2844                    mask = LC_TIME_MASK;
    2845                    break;
    2846                  case LC_COLLATE:
    2847                    mask = LC_COLLATE_MASK;
    2848                    break;
    2849                  case LC_MONETARY:
    2850                    mask = LC_MONETARY_MASK;
    2851                    break;
    2852                  case LC_MESSAGES:
    2853                    mask = LC_MESSAGES_MASK;
    2854                    break;
    2855                  default:
    2856                    abort ();
    2857                  }
    2858                names.category_name[category] =
    2859                  ((mask & category_mask) != 0
    2860                   ? name
    2861                   : get_locale_t_name (category, LC_GLOBAL_LOCALE));
    2862              }
    2863          }
    2864        else
    2865          {
    2866            /* Look up the names of base in the hash table.  Like multiple calls
    2867               of get_locale_t_name, but locking only once.  */
    2868            struct locale_hash_node *p;
    2869            int category;
    2870  
    2871            /* Lock while looking up the hash node.  */
    2872            gl_rwlock_rdlock (locale_lock);
    2873            for (p = locale_hash_table[locale_hash_function (base) % LOCALE_HASH_TABLE_SIZE];
    2874                 p != NULL;
    2875                 p = p->next)
    2876              if (p->locale == base)
    2877                break;
    2878  
    2879            for (category = 0; category < 6; category++)
    2880              {
    2881                int mask;
    2882  
    2883                switch (category)
    2884                  {
    2885                  case LC_CTYPE:
    2886                    mask = LC_CTYPE_MASK;
    2887                    break;
    2888                  case LC_NUMERIC:
    2889                    mask = LC_NUMERIC_MASK;
    2890                    break;
    2891                  case LC_TIME:
    2892                    mask = LC_TIME_MASK;
    2893                    break;
    2894                  case LC_COLLATE:
    2895                    mask = LC_COLLATE_MASK;
    2896                    break;
    2897                  case LC_MONETARY:
    2898                    mask = LC_MONETARY_MASK;
    2899                    break;
    2900                  case LC_MESSAGES:
    2901                    mask = LC_MESSAGES_MASK;
    2902                    break;
    2903                  default:
    2904                    abort ();
    2905                  }
    2906                names.category_name[category] =
    2907                  ((mask & category_mask) != 0
    2908                   ? name
    2909                   : (p != NULL ? p->names.category_name[category] : ""));
    2910              }
    2911  
    2912            gl_rwlock_unlock (locale_lock);
    2913          }
    2914      }
    2915  
    2916    node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node));
    2917    if (node == NULL)
    2918      /* errno is set to ENOMEM.  */
    2919      return NULL;
    2920  
    2921    result = newlocale (category_mask, name, base);
    2922    if (result == NULL)
    2923      {
    2924        free (node);
    2925        return NULL;
    2926      }
    2927  
    2928    /* Fill the hash node.  */
    2929    node->locale = result;
    2930    node->names = names;
    2931  
    2932    /* Insert it in the hash table.  */
    2933    {
    2934      size_t hashcode = locale_hash_function (result);
    2935      size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
    2936      struct locale_hash_node *p;
    2937  
    2938      /* Lock while inserting the new node.  */
    2939      gl_rwlock_wrlock (locale_lock);
    2940      for (p = locale_hash_table[slot]; p != NULL; p = p->next)
    2941        if (p->locale == result)
    2942          {
    2943            /* This can happen if the application uses the original freelocale()
    2944               function instead of the overridden one.  */
    2945            p->names = node->names;
    2946            break;
    2947          }
    2948      if (p == NULL)
    2949        {
    2950          node->next = locale_hash_table[slot];
    2951          locale_hash_table[slot] = node;
    2952        }
    2953  
    2954      gl_rwlock_unlock (locale_lock);
    2955  
    2956      if (p != NULL)
    2957        free (node);
    2958    }
    2959  
    2960    return result;
    2961  }
    2962  
    2963  /* duplocale() override.  */
    2964  locale_t
    2965  duplocale (locale_t locale)
    2966  #undef duplocale
    2967  {
    2968    struct locale_hash_node *node;
    2969    locale_t result;
    2970  
    2971    if (locale == NULL)
    2972      /* Invalid argument.  */
    2973      abort ();
    2974  
    2975    node = (struct locale_hash_node *) malloc (sizeof (struct locale_hash_node));
    2976    if (node == NULL)
    2977      /* errno is set to ENOMEM.  */
    2978      return NULL;
    2979  
    2980    result = duplocale (locale);
    2981    if (result == NULL)
    2982      {
    2983        free (node);
    2984        return NULL;
    2985      }
    2986  
    2987    /* Fill the hash node.  */
    2988    node->locale = result;
    2989    if (locale == LC_GLOBAL_LOCALE)
    2990      {
    2991        int category;
    2992  
    2993        for (category = 0; category < 6; category++)
    2994          node->names.category_name[category] =
    2995            get_locale_t_name (category, LC_GLOBAL_LOCALE);
    2996  
    2997        /* Lock before inserting the new node.  */
    2998        gl_rwlock_wrlock (locale_lock);
    2999      }
    3000    else
    3001      {
    3002        struct locale_hash_node *p;
    3003  
    3004        /* Lock once, for the lookup and the insertion.  */
    3005        gl_rwlock_wrlock (locale_lock);
    3006  
    3007        for (p = locale_hash_table[locale_hash_function (locale) % LOCALE_HASH_TABLE_SIZE];
    3008             p != NULL;
    3009             p = p->next)
    3010          if (p->locale == locale)
    3011            break;
    3012        if (p != NULL)
    3013          node->names = p->names;
    3014        else
    3015          {
    3016            /* This can happen if the application uses the original
    3017               newlocale()/duplocale() functions instead of the overridden
    3018               ones.  */
    3019            int category;
    3020  
    3021            for (category = 0; category < 6; category++)
    3022              node->names.category_name[category] = "";
    3023          }
    3024      }
    3025  
    3026    /* Insert it in the hash table.  */
    3027    {
    3028      size_t hashcode = locale_hash_function (result);
    3029      size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
    3030      struct locale_hash_node *p;
    3031  
    3032      for (p = locale_hash_table[slot]; p != NULL; p = p->next)
    3033        if (p->locale == result)
    3034          {
    3035            /* This can happen if the application uses the original freelocale()
    3036               function instead of the overridden one.  */
    3037            p->names = node->names;
    3038            break;
    3039          }
    3040      if (p == NULL)
    3041        {
    3042          node->next = locale_hash_table[slot];
    3043          locale_hash_table[slot] = node;
    3044        }
    3045  
    3046      gl_rwlock_unlock (locale_lock);
    3047  
    3048      if (p != NULL)
    3049        free (node);
    3050    }
    3051  
    3052    return result;
    3053  }
    3054  
    3055  /* freelocale() override.  */
    3056  void
    3057  freelocale (locale_t locale)
    3058  #undef freelocale
    3059  {
    3060    if (locale == NULL || locale == LC_GLOBAL_LOCALE)
    3061      /* Invalid argument.  */
    3062      abort ();
    3063  
    3064    {
    3065      size_t hashcode = locale_hash_function (locale);
    3066      size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE;
    3067      struct locale_hash_node *found;
    3068      struct locale_hash_node **p;
    3069  
    3070      found = NULL;
    3071      /* Lock while removing the hash node.  */
    3072      gl_rwlock_wrlock (locale_lock);
    3073      for (p = &locale_hash_table[slot]; *p != NULL; p = &(*p)->next)
    3074        if ((*p)->locale == locale)
    3075          {
    3076            found = *p;
    3077            *p = (*p)->next;
    3078            break;
    3079          }
    3080      gl_rwlock_unlock (locale_lock);
    3081      free (found);
    3082    }
    3083  
    3084    freelocale (locale);
    3085  }
    3086  
    3087  #endif
    3088  
    3089  
    3090  #if defined IN_LIBINTL || HAVE_GOOD_USELOCALE
    3091  
    3092  /* Like gl_locale_name_thread, except that the result is not in storage of
    3093     indefinite extent.  */
    3094  # if !defined IN_LIBINTL
    3095  static
    3096  # endif
    3097  const char *
    3098  gl_locale_name_thread_unsafe (int category, _GL_UNUSED const char *categoryname)
    3099  {
    3100  # if HAVE_GOOD_USELOCALE
    3101    {
    3102      locale_t thread_locale = uselocale (NULL);
    3103      if (thread_locale != LC_GLOBAL_LOCALE)
    3104        {
    3105  #  if __GLIBC__ >= 2 && !defined __UCLIBC__
    3106          /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
    3107             glibc < 2.12.
    3108             See <https://sourceware.org/bugzilla/show_bug.cgi?id=10968>.  */
    3109          const char *name =
    3110            nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
    3111          if (name[0] == '\0')
    3112            /* Fallback code for glibc < 2.4, which did not implement
    3113               nl_langinfo (_NL_LOCALE_NAME (category)).  */
    3114            name = thread_locale->__names[category];
    3115          return name;
    3116  #  elif defined __linux__ && HAVE_LANGINFO_H && defined NL_LOCALE_NAME
    3117          /* musl libc */
    3118          return nl_langinfo_l (NL_LOCALE_NAME (category), thread_locale);
    3119  #  elif (defined __FreeBSD__ || defined __DragonFly__) || (defined __APPLE__ && defined __MACH__)
    3120          /* FreeBSD, Mac OS X */
    3121          int mask;
    3122  
    3123          switch (category)
    3124            {
    3125            case LC_CTYPE:
    3126              mask = LC_CTYPE_MASK;
    3127              break;
    3128            case LC_NUMERIC:
    3129              mask = LC_NUMERIC_MASK;
    3130              break;
    3131            case LC_TIME:
    3132              mask = LC_TIME_MASK;
    3133              break;
    3134            case LC_COLLATE:
    3135              mask = LC_COLLATE_MASK;
    3136              break;
    3137            case LC_MONETARY:
    3138              mask = LC_MONETARY_MASK;
    3139              break;
    3140            case LC_MESSAGES:
    3141              mask = LC_MESSAGES_MASK;
    3142              break;
    3143            default: /* We shouldn't get here.  */
    3144              return "";
    3145            }
    3146          return querylocale (mask, thread_locale);
    3147  #  elif defined __sun
    3148  #   if HAVE_GETLOCALENAME_L
    3149          /* Solaris >= 12.  */
    3150          return getlocalename_l (category, thread_locale);
    3151  #   elif HAVE_SOLARIS114_LOCALES
    3152          /* Solaris >= 11.4.  */
    3153          void *lcp = (*thread_locale)->core.data->lcp;
    3154          if (lcp != NULL)
    3155            switch (category)
    3156              {
    3157              case LC_CTYPE:
    3158              case LC_NUMERIC:
    3159              case LC_TIME:
    3160              case LC_COLLATE:
    3161              case LC_MONETARY:
    3162              case LC_MESSAGES:
    3163                return ((const char * const *) lcp)[category];
    3164              default: /* We shouldn't get here.  */
    3165                return "";
    3166              }
    3167  #   elif HAVE_NAMELESS_LOCALES
    3168          return get_locale_t_name (category, thread_locale);
    3169  #   else
    3170          /* Solaris 11 OpenIndiana.
    3171             For the internal structure of locale objects, see
    3172             https://github.com/OpenIndiana/illumos-gate/blob/master/usr/src/lib/libc/port/locale/localeimpl.h  */
    3173          switch (category)
    3174            {
    3175            case LC_CTYPE:
    3176            case LC_NUMERIC:
    3177            case LC_TIME:
    3178            case LC_COLLATE:
    3179            case LC_MONETARY:
    3180            case LC_MESSAGES:
    3181              return ((const char * const *) thread_locale)[category];
    3182            default: /* We shouldn't get here.  */
    3183              return "";
    3184            }
    3185  #   endif
    3186  #  elif defined _AIX && HAVE_NAMELESS_LOCALES
    3187          return get_locale_t_name (category, thread_locale);
    3188  #  elif defined __CYGWIN__
    3189          /* Cygwin < 2.6 lacks uselocale and thread-local locales altogether.
    3190             Cygwin <= 2.6.1 lacks NL_LOCALE_NAME, requiring peeking inside
    3191             an opaque struct.  */
    3192  #   ifdef NL_LOCALE_NAME
    3193          return nl_langinfo_l (NL_LOCALE_NAME (category), thread_locale);
    3194  #   else
    3195          /* FIXME: Remove when we can assume new-enough Cygwin.  */
    3196          struct __locale_t {
    3197            char categories[7][32];
    3198          };
    3199          return ((struct __locale_t *) thread_locale)->categories[category];
    3200  #   endif
    3201  #  elif defined __ANDROID__
    3202          return MB_CUR_MAX == 4 ? "C.UTF-8" : "C";
    3203  #  endif
    3204        }
    3205    }
    3206  # endif
    3207    return NULL;
    3208  }
    3209  
    3210  #endif
    3211  
    3212  const char *
    3213  gl_locale_name_thread (int category, _GL_UNUSED const char *categoryname)
    3214  {
    3215  #if HAVE_GOOD_USELOCALE
    3216    const char *name = gl_locale_name_thread_unsafe (category, categoryname);
    3217    if (name != NULL)
    3218      return struniq (name);
    3219  #endif
    3220    /* On WINDOWS_NATIVE, don't use GetThreadLocale() here, because when
    3221       SetThreadLocale has not been called - which is a very frequent case -
    3222       the value of GetThreadLocale() ignores past calls to 'setlocale'.  */
    3223    return NULL;
    3224  }
    3225  
    3226  /* XPG3 defines the result of 'setlocale (category, NULL)' as:
    3227     "Directs 'setlocale()' to query 'category' and return the current
    3228      setting of 'local'."
    3229     However it does not specify the exact format.  Neither do SUSV2 and
    3230     ISO C 99.  So we can use this feature only on selected systems (e.g.
    3231     those using GNU C Library).  */
    3232  #if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
    3233  # define HAVE_LOCALE_NULL
    3234  #endif
    3235  
    3236  const char *
    3237  gl_locale_name_posix (int category, _GL_UNUSED const char *categoryname)
    3238  {
    3239  #if defined WINDOWS_NATIVE
    3240    if (LC_MIN <= category && category <= LC_MAX)
    3241      {
    3242        const char *locname =
    3243          /* setlocale_null (category) is identical to setlocale (category, NULL)
    3244             on this platform.  */
    3245          setlocale (category, NULL);
    3246  
    3247        /* Convert locale name to LCID.  We don't want to use
    3248           LocaleNameToLCID because (a) it is only available since Vista,
    3249           and (b) it doesn't accept locale names returned by 'setlocale'.  */
    3250        LCID lcid = get_lcid (locname);
    3251  
    3252        if (lcid > 0)
    3253          return gl_locale_name_from_win32_LCID (lcid);
    3254      }
    3255  #endif
    3256    {
    3257      const char *locname;
    3258  
    3259      /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
    3260         On some systems this can be done by the 'setlocale' function itself.  */
    3261  #if defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
    3262      locname = setlocale_null (category);
    3263  #else
    3264      /* On other systems we ignore what setlocale reports and instead look at the
    3265         environment variables directly.  This is necessary
    3266           1. on systems which have a facility for customizing the default locale
    3267              (Mac OS X, native Windows, Cygwin) and where the system's setlocale()
    3268              function ignores this default locale (Mac OS X, Cygwin), in two cases:
    3269              a. when the user missed to use the setlocale() override from libintl
    3270                 (for example by not including <libintl.h>),
    3271              b. when setlocale supports only the "C" locale, such as on Cygwin
    3272                 1.5.x.  In this case even the override from libintl cannot help.
    3273           2. on all systems where setlocale supports only the "C" locale.  */
    3274      /* Strictly speaking, it is a POSIX violation to look at the environment
    3275         variables regardless whether setlocale has been called or not.  POSIX
    3276         says:
    3277             "For C-language programs, the POSIX locale shall be the
    3278              default locale when the setlocale() function is not called."
    3279         But we assume that all programs that use internationalized APIs call
    3280         setlocale (LC_ALL, "").  */
    3281      locname = gl_locale_name_environ (category, categoryname);
    3282  #endif
    3283      /* Convert the locale name from the format returned by setlocale() or found
    3284         in the environment variables to the XPG syntax.  */
    3285  #if defined WINDOWS_NATIVE
    3286      if (locname != NULL)
    3287        {
    3288          /* Convert locale name to LCID.  We don't want to use
    3289             LocaleNameToLCID because (a) it is only available since Vista,
    3290             and (b) it doesn't accept locale names returned by 'setlocale'.  */
    3291          LCID lcid = get_lcid (locname);
    3292  
    3293          if (lcid > 0)
    3294            return gl_locale_name_from_win32_LCID (lcid);
    3295        }
    3296  #endif
    3297      return locname;
    3298    }
    3299  }
    3300  
    3301  const char *
    3302  gl_locale_name_environ (_GL_UNUSED int category, const char *categoryname)
    3303  {
    3304    const char *retval;
    3305  
    3306    /* Setting of LC_ALL overrides all other.  */
    3307    retval = getenv ("LC_ALL");
    3308    if (retval != NULL && retval[0] != '\0')
    3309      return retval;
    3310    /* Next comes the name of the desired category.  */
    3311    retval = getenv (categoryname);
    3312    if (retval != NULL && retval[0] != '\0')
    3313      return retval;
    3314    /* Last possibility is the LANG environment variable.  */
    3315    retval = getenv ("LANG");
    3316    if (retval != NULL && retval[0] != '\0')
    3317      {
    3318  #if HAVE_CFPREFERENCESCOPYAPPVALUE
    3319        /* Mac OS X 10.2 or newer.
    3320           Ignore invalid LANG value set by the Terminal application.  */
    3321        if (strcmp (retval, "UTF-8") != 0)
    3322  #endif
    3323  #if defined __CYGWIN__
    3324        /* Cygwin.
    3325           Ignore dummy LANG value set by ~/.profile.  */
    3326        if (strcmp (retval, "C.UTF-8") != 0)
    3327  #endif
    3328          return retval;
    3329      }
    3330  
    3331    return NULL;
    3332  }
    3333  
    3334  const char *
    3335  gl_locale_name_default (void)
    3336  {
    3337    /* POSIX:2001 says:
    3338       "All implementations shall define a locale as the default locale, to be
    3339        invoked when no environment variables are set, or set to the empty
    3340        string.  This default locale can be the POSIX locale or any other
    3341        implementation-defined locale.  Some implementations may provide
    3342        facilities for local installation administrators to set the default
    3343        locale, customizing it for each location.  POSIX:2001 does not require
    3344        such a facility.
    3345  
    3346       The systems with such a facility are Mac OS X and Windows: They provide a
    3347       GUI that allows the user to choose a locale.
    3348         - On Mac OS X, by default, none of LC_* or LANG are set.  Starting with
    3349           Mac OS X 10.4 or 10.5, LANG is set for processes launched by the
    3350           'Terminal' application (but sometimes to an incorrect value "UTF-8").
    3351           When no environment variable is set, setlocale (LC_ALL, "") uses the
    3352           "C" locale.
    3353         - On native Windows, by default, none of LC_* or LANG are set.
    3354           When no environment variable is set, setlocale (LC_ALL, "") uses the
    3355           locale chosen by the user.
    3356         - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
    3357           When no environment variable is set, setlocale (LC_ALL, "") uses the
    3358           "C" locale.
    3359         - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
    3360           ~/.profile is executed.
    3361           When no environment variable is set, setlocale (LC_ALL, "") uses the
    3362           "C.UTF-8" locale, which operates in the same way as the "C" locale.
    3363    */
    3364  
    3365  #if !(HAVE_CFPREFERENCESCOPYAPPVALUE || defined WINDOWS_NATIVE || defined __CYGWIN__)
    3366  
    3367    /* The system does not have a way of setting the locale, other than the
    3368       POSIX specified environment variables.  We use C as default locale.  */
    3369    return "C";
    3370  
    3371  #else
    3372  
    3373    /* Return an XPG style locale name language[_territory][@modifier].
    3374       Don't even bother determining the codeset; it's not useful in this
    3375       context, because message catalogs are not specific to a single
    3376       codeset.  */
    3377  
    3378  # if HAVE_CFPREFERENCESCOPYAPPVALUE
    3379    /* Mac OS X 10.4 or newer */
    3380    /* Don't use the API introduced in Mac OS X 10.5, CFLocaleCopyCurrent,
    3381       because in macOS 10.13.4 it has the following behaviour:
    3382       When two or more languages are specified in the
    3383       "System Preferences > Language & Region > Preferred Languages" panel,
    3384       it returns en_CC where CC is the territory (even when English is not among
    3385       the preferred languages!).  What we want instead is what
    3386       CFLocaleCopyCurrent returned in earlier macOS releases and what
    3387       CFPreferencesCopyAppValue still returns, namely ll_CC where ll is the
    3388       first among the preferred languages and CC is the territory.  */
    3389    {
    3390      /* Cache the locale name, since CoreFoundation calls are expensive.  */
    3391      static const char *cached_localename;
    3392  
    3393      if (cached_localename == NULL)
    3394        {
    3395          char namebuf[256];
    3396          CFTypeRef value =
    3397            CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
    3398                                       kCFPreferencesCurrentApplication);
    3399          if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
    3400            {
    3401              CFStringRef name = (CFStringRef)value;
    3402  
    3403              if (CFStringGetCString (name, namebuf, sizeof (namebuf),
    3404                                      kCFStringEncodingASCII))
    3405                {
    3406                  gl_locale_name_canonicalize (namebuf);
    3407                  cached_localename = strdup (namebuf);
    3408                }
    3409            }
    3410          if (cached_localename == NULL)
    3411            cached_localename = "C";
    3412        }
    3413      return cached_localename;
    3414    }
    3415  
    3416  # endif
    3417  
    3418  # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
    3419    {
    3420      LCID lcid;
    3421  
    3422      /* Use native Windows API locale ID.  */
    3423      lcid = GetThreadLocale ();
    3424  
    3425      return gl_locale_name_from_win32_LCID (lcid);
    3426    }
    3427  # endif
    3428  #endif
    3429  }
    3430  
    3431  /* Determine the current locale's name, and canonicalize it into XPG syntax
    3432       language[_territory][.codeset][@modifier]
    3433     The codeset part in the result is not reliable; the locale_charset()
    3434     should be used for codeset information instead.
    3435     The result must not be freed; it is statically allocated.  */
    3436  
    3437  const char *
    3438  gl_locale_name (int category, const char *categoryname)
    3439  {
    3440    const char *retval;
    3441  
    3442    retval = gl_locale_name_thread (category, categoryname);
    3443    if (retval != NULL)
    3444      return retval;
    3445  
    3446    retval = gl_locale_name_posix (category, categoryname);
    3447    if (retval != NULL)
    3448      return retval;
    3449  
    3450    return gl_locale_name_default ();
    3451  }