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