VirtualBox

source: kBuild/vendor/grep/2.12/gnulib-tests/localename.c@ 3576

Last change on this file since 3576 was 2595, checked in by bird, 13 years ago

gnu grep version 2.12 (grep-2.12.tar.xz, md5sum=8d2f0346d08b13c18afb81f0e8aa1e2f)

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette