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