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