*** empty log message ***
[m17n/m17n-im-config.git] / intl / localename.c
1 /* Determine the current selected locale.
2    Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU Library General Public License as published
6    by the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17    USA.  */
18
19 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995.  */
20 /* Win32 code written by Tor Lillqvist <tml@iki.fi>.  */
21 /* MacOS X code written by Bruno Haible <bruno@clisp.org>.  */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <locale.h>
29
30 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
31 # include <string.h>
32 # include <CFString.h>
33 # if HAVE_CFLOCALECOPYCURRENT
34 #  include <CFLocale.h>
35 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
36 #  include <CFPreferences.h>
37 # endif
38 #endif
39
40 #if defined _WIN32 || defined __WIN32__
41 # undef WIN32   /* avoid warning on mingw32 */
42 # define WIN32
43 #endif
44
45 #ifdef WIN32
46 # define WIN32_LEAN_AND_MEAN
47 # include <windows.h>
48 /* List of language codes, sorted by value:
49    0x01 LANG_ARABIC
50    0x02 LANG_BULGARIAN
51    0x03 LANG_CATALAN
52    0x04 LANG_CHINESE
53    0x05 LANG_CZECH
54    0x06 LANG_DANISH
55    0x07 LANG_GERMAN
56    0x08 LANG_GREEK
57    0x09 LANG_ENGLISH
58    0x0a LANG_SPANISH
59    0x0b LANG_FINNISH
60    0x0c LANG_FRENCH
61    0x0d LANG_HEBREW
62    0x0e LANG_HUNGARIAN
63    0x0f LANG_ICELANDIC
64    0x10 LANG_ITALIAN
65    0x11 LANG_JAPANESE
66    0x12 LANG_KOREAN
67    0x13 LANG_DUTCH
68    0x14 LANG_NORWEGIAN
69    0x15 LANG_POLISH
70    0x16 LANG_PORTUGUESE
71    0x17 LANG_RHAETO_ROMANCE
72    0x18 LANG_ROMANIAN
73    0x19 LANG_RUSSIAN
74    0x1a LANG_CROATIAN == LANG_SERBIAN
75    0x1b LANG_SLOVAK
76    0x1c LANG_ALBANIAN
77    0x1d LANG_SWEDISH
78    0x1e LANG_THAI
79    0x1f LANG_TURKISH
80    0x20 LANG_URDU
81    0x21 LANG_INDONESIAN
82    0x22 LANG_UKRAINIAN
83    0x23 LANG_BELARUSIAN
84    0x24 LANG_SLOVENIAN
85    0x25 LANG_ESTONIAN
86    0x26 LANG_LATVIAN
87    0x27 LANG_LITHUANIAN
88    0x28 LANG_TAJIK
89    0x29 LANG_FARSI
90    0x2a LANG_VIETNAMESE
91    0x2b LANG_ARMENIAN
92    0x2c LANG_AZERI
93    0x2d LANG_BASQUE
94    0x2e LANG_SORBIAN
95    0x2f LANG_MACEDONIAN
96    0x30 LANG_SUTU
97    0x31 LANG_TSONGA
98    0x32 LANG_TSWANA
99    0x33 LANG_VENDA
100    0x34 LANG_XHOSA
101    0x35 LANG_ZULU
102    0x36 LANG_AFRIKAANS
103    0x37 LANG_GEORGIAN
104    0x38 LANG_FAEROESE
105    0x39 LANG_HINDI
106    0x3a LANG_MALTESE
107    0x3b LANG_SAAMI
108    0x3c LANG_GAELIC
109    0x3d LANG_YIDDISH
110    0x3e LANG_MALAY
111    0x3f LANG_KAZAK
112    0x40 LANG_KYRGYZ
113    0x41 LANG_SWAHILI
114    0x42 LANG_TURKMEN
115    0x43 LANG_UZBEK
116    0x44 LANG_TATAR
117    0x45 LANG_BENGALI
118    0x46 LANG_PUNJABI
119    0x47 LANG_GUJARATI
120    0x48 LANG_ORIYA
121    0x49 LANG_TAMIL
122    0x4a LANG_TELUGU
123    0x4b LANG_KANNADA
124    0x4c LANG_MALAYALAM
125    0x4d LANG_ASSAMESE
126    0x4e LANG_MARATHI
127    0x4f LANG_SANSKRIT
128    0x50 LANG_MONGOLIAN
129    0x51 LANG_TIBETAN
130    0x52 LANG_WELSH
131    0x53 LANG_CAMBODIAN
132    0x54 LANG_LAO
133    0x55 LANG_BURMESE
134    0x56 LANG_GALICIAN
135    0x57 LANG_KONKANI
136    0x58 LANG_MANIPURI
137    0x59 LANG_SINDHI
138    0x5a LANG_SYRIAC
139    0x5b LANG_SINHALESE
140    0x5c LANG_CHEROKEE
141    0x5d LANG_INUKTITUT
142    0x5e LANG_AMHARIC
143    0x5f LANG_TAMAZIGHT
144    0x60 LANG_KASHMIRI
145    0x61 LANG_NEPALI
146    0x62 LANG_FRISIAN
147    0x63 LANG_PASHTO
148    0x64 LANG_TAGALOG
149    0x65 LANG_DIVEHI
150    0x66 LANG_EDO
151    0x67 LANG_FULFULDE
152    0x68 LANG_HAUSA
153    0x69 LANG_IBIBIO
154    0x6a LANG_YORUBA
155    0x70 LANG_IGBO
156    0x71 LANG_KANURI
157    0x72 LANG_OROMO
158    0x73 LANG_TIGRINYA
159    0x74 LANG_GUARANI
160    0x75 LANG_HAWAIIAN
161    0x76 LANG_LATIN
162    0x77 LANG_SOMALI
163    0x78 LANG_YI
164    0x79 LANG_PAPIAMENTU
165 */
166 /* Mingw headers don't have latest language and sublanguage codes.  */
167 # ifndef LANG_AFRIKAANS
168 # define LANG_AFRIKAANS 0x36
169 # endif
170 # ifndef LANG_ALBANIAN
171 # define LANG_ALBANIAN 0x1c
172 # endif
173 # ifndef LANG_AMHARIC
174 # define LANG_AMHARIC 0x5e
175 # endif
176 # ifndef LANG_ARABIC
177 # define LANG_ARABIC 0x01
178 # endif
179 # ifndef LANG_ARMENIAN
180 # define LANG_ARMENIAN 0x2b
181 # endif
182 # ifndef LANG_ASSAMESE
183 # define LANG_ASSAMESE 0x4d
184 # endif
185 # ifndef LANG_AZERI
186 # define LANG_AZERI 0x2c
187 # endif
188 # ifndef LANG_BASQUE
189 # define LANG_BASQUE 0x2d
190 # endif
191 # ifndef LANG_BELARUSIAN
192 # define LANG_BELARUSIAN 0x23
193 # endif
194 # ifndef LANG_BENGALI
195 # define LANG_BENGALI 0x45
196 # endif
197 # ifndef LANG_BURMESE
198 # define LANG_BURMESE 0x55
199 # endif
200 # ifndef LANG_CAMBODIAN
201 # define LANG_CAMBODIAN 0x53
202 # endif
203 # ifndef LANG_CATALAN
204 # define LANG_CATALAN 0x03
205 # endif
206 # ifndef LANG_CHEROKEE
207 # define LANG_CHEROKEE 0x5c
208 # endif
209 # ifndef LANG_DIVEHI
210 # define LANG_DIVEHI 0x65
211 # endif
212 # ifndef LANG_EDO
213 # define LANG_EDO 0x66
214 # endif
215 # ifndef LANG_ESTONIAN
216 # define LANG_ESTONIAN 0x25
217 # endif
218 # ifndef LANG_FAEROESE
219 # define LANG_FAEROESE 0x38
220 # endif
221 # ifndef LANG_FARSI
222 # define LANG_FARSI 0x29
223 # endif
224 # ifndef LANG_FRISIAN
225 # define LANG_FRISIAN 0x62
226 # endif
227 # ifndef LANG_FULFULDE
228 # define LANG_FULFULDE 0x67
229 # endif
230 # ifndef LANG_GAELIC
231 # define LANG_GAELIC 0x3c
232 # endif
233 # ifndef LANG_GALICIAN
234 # define LANG_GALICIAN 0x56
235 # endif
236 # ifndef LANG_GEORGIAN
237 # define LANG_GEORGIAN 0x37
238 # endif
239 # ifndef LANG_GUARANI
240 # define LANG_GUARANI 0x74
241 # endif
242 # ifndef LANG_GUJARATI
243 # define LANG_GUJARATI 0x47
244 # endif
245 # ifndef LANG_HAUSA
246 # define LANG_HAUSA 0x68
247 # endif
248 # ifndef LANG_HAWAIIAN
249 # define LANG_HAWAIIAN 0x75
250 # endif
251 # ifndef LANG_HEBREW
252 # define LANG_HEBREW 0x0d
253 # endif
254 # ifndef LANG_HINDI
255 # define LANG_HINDI 0x39
256 # endif
257 # ifndef LANG_IBIBIO
258 # define LANG_IBIBIO 0x69
259 # endif
260 # ifndef LANG_IGBO
261 # define LANG_IGBO 0x70
262 # endif
263 # ifndef LANG_INDONESIAN
264 # define LANG_INDONESIAN 0x21
265 # endif
266 # ifndef LANG_INUKTITUT
267 # define LANG_INUKTITUT 0x5d
268 # endif
269 # ifndef LANG_KANNADA
270 # define LANG_KANNADA 0x4b
271 # endif
272 # ifndef LANG_KANURI
273 # define LANG_KANURI 0x71
274 # endif
275 # ifndef LANG_KASHMIRI
276 # define LANG_KASHMIRI 0x60
277 # endif
278 # ifndef LANG_KAZAK
279 # define LANG_KAZAK 0x3f
280 # endif
281 # ifndef LANG_KONKANI
282 # define LANG_KONKANI 0x57
283 # endif
284 # ifndef LANG_KYRGYZ
285 # define LANG_KYRGYZ 0x40
286 # endif
287 # ifndef LANG_LAO
288 # define LANG_LAO 0x54
289 # endif
290 # ifndef LANG_LATIN
291 # define LANG_LATIN 0x76
292 # endif
293 # ifndef LANG_LATVIAN
294 # define LANG_LATVIAN 0x26
295 # endif
296 # ifndef LANG_LITHUANIAN
297 # define LANG_LITHUANIAN 0x27
298 # endif
299 # ifndef LANG_MACEDONIAN
300 # define LANG_MACEDONIAN 0x2f
301 # endif
302 # ifndef LANG_MALAY
303 # define LANG_MALAY 0x3e
304 # endif
305 # ifndef LANG_MALAYALAM
306 # define LANG_MALAYALAM 0x4c
307 # endif
308 # ifndef LANG_MALTESE
309 # define LANG_MALTESE 0x3a
310 # endif
311 # ifndef LANG_MANIPURI
312 # define LANG_MANIPURI 0x58
313 # endif
314 # ifndef LANG_MARATHI
315 # define LANG_MARATHI 0x4e
316 # endif
317 # ifndef LANG_MONGOLIAN
318 # define LANG_MONGOLIAN 0x50
319 # endif
320 # ifndef LANG_NEPALI
321 # define LANG_NEPALI 0x61
322 # endif
323 # ifndef LANG_ORIYA
324 # define LANG_ORIYA 0x48
325 # endif
326 # ifndef LANG_OROMO
327 # define LANG_OROMO 0x72
328 # endif
329 # ifndef LANG_PAPIAMENTU
330 # define LANG_PAPIAMENTU 0x79
331 # endif
332 # ifndef LANG_PASHTO
333 # define LANG_PASHTO 0x63
334 # endif
335 # ifndef LANG_PUNJABI
336 # define LANG_PUNJABI 0x46
337 # endif
338 # ifndef LANG_RHAETO_ROMANCE
339 # define LANG_RHAETO_ROMANCE 0x17
340 # endif
341 # ifndef LANG_SAAMI
342 # define LANG_SAAMI 0x3b
343 # endif
344 # ifndef LANG_SANSKRIT
345 # define LANG_SANSKRIT 0x4f
346 # endif
347 # ifndef LANG_SERBIAN
348 # define LANG_SERBIAN 0x1a
349 # endif
350 # ifndef LANG_SINDHI
351 # define LANG_SINDHI 0x59
352 # endif
353 # ifndef LANG_SINHALESE
354 # define LANG_SINHALESE 0x5b
355 # endif
356 # ifndef LANG_SLOVAK
357 # define LANG_SLOVAK 0x1b
358 # endif
359 # ifndef LANG_SOMALI
360 # define LANG_SOMALI 0x77
361 # endif
362 # ifndef LANG_SORBIAN
363 # define LANG_SORBIAN 0x2e
364 # endif
365 # ifndef LANG_SUTU
366 # define LANG_SUTU 0x30
367 # endif
368 # ifndef LANG_SWAHILI
369 # define LANG_SWAHILI 0x41
370 # endif
371 # ifndef LANG_SYRIAC
372 # define LANG_SYRIAC 0x5a
373 # endif
374 # ifndef LANG_TAGALOG
375 # define LANG_TAGALOG 0x64
376 # endif
377 # ifndef LANG_TAJIK
378 # define LANG_TAJIK 0x28
379 # endif
380 # ifndef LANG_TAMAZIGHT
381 # define LANG_TAMAZIGHT 0x5f
382 # endif
383 # ifndef LANG_TAMIL
384 # define LANG_TAMIL 0x49
385 # endif
386 # ifndef LANG_TATAR
387 # define LANG_TATAR 0x44
388 # endif
389 # ifndef LANG_TELUGU
390 # define LANG_TELUGU 0x4a
391 # endif
392 # ifndef LANG_THAI
393 # define LANG_THAI 0x1e
394 # endif
395 # ifndef LANG_TIBETAN
396 # define LANG_TIBETAN 0x51
397 # endif
398 # ifndef LANG_TIGRINYA
399 # define LANG_TIGRINYA 0x73
400 # endif
401 # ifndef LANG_TSONGA
402 # define LANG_TSONGA 0x31
403 # endif
404 # ifndef LANG_TSWANA
405 # define LANG_TSWANA 0x32
406 # endif
407 # ifndef LANG_TURKMEN
408 # define LANG_TURKMEN 0x42
409 # endif
410 # ifndef LANG_UKRAINIAN
411 # define LANG_UKRAINIAN 0x22
412 # endif
413 # ifndef LANG_URDU
414 # define LANG_URDU 0x20
415 # endif
416 # ifndef LANG_UZBEK
417 # define LANG_UZBEK 0x43
418 # endif
419 # ifndef LANG_VENDA
420 # define LANG_VENDA 0x33
421 # endif
422 # ifndef LANG_VIETNAMESE
423 # define LANG_VIETNAMESE 0x2a
424 # endif
425 # ifndef LANG_WELSH
426 # define LANG_WELSH 0x52
427 # endif
428 # ifndef LANG_XHOSA
429 # define LANG_XHOSA 0x34
430 # endif
431 # ifndef LANG_YI
432 # define LANG_YI 0x78
433 # endif
434 # ifndef LANG_YIDDISH
435 # define LANG_YIDDISH 0x3d
436 # endif
437 # ifndef LANG_YORUBA
438 # define LANG_YORUBA 0x6a
439 # endif
440 # ifndef LANG_ZULU
441 # define LANG_ZULU 0x35
442 # endif
443 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
444 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
445 # endif
446 # ifndef SUBLANG_ARABIC_IRAQ
447 # define SUBLANG_ARABIC_IRAQ 0x02
448 # endif
449 # ifndef SUBLANG_ARABIC_EGYPT
450 # define SUBLANG_ARABIC_EGYPT 0x03
451 # endif
452 # ifndef SUBLANG_ARABIC_LIBYA
453 # define SUBLANG_ARABIC_LIBYA 0x04
454 # endif
455 # ifndef SUBLANG_ARABIC_ALGERIA
456 # define SUBLANG_ARABIC_ALGERIA 0x05
457 # endif
458 # ifndef SUBLANG_ARABIC_MOROCCO
459 # define SUBLANG_ARABIC_MOROCCO 0x06
460 # endif
461 # ifndef SUBLANG_ARABIC_TUNISIA
462 # define SUBLANG_ARABIC_TUNISIA 0x07
463 # endif
464 # ifndef SUBLANG_ARABIC_OMAN
465 # define SUBLANG_ARABIC_OMAN 0x08
466 # endif
467 # ifndef SUBLANG_ARABIC_YEMEN
468 # define SUBLANG_ARABIC_YEMEN 0x09
469 # endif
470 # ifndef SUBLANG_ARABIC_SYRIA
471 # define SUBLANG_ARABIC_SYRIA 0x0a
472 # endif
473 # ifndef SUBLANG_ARABIC_JORDAN
474 # define SUBLANG_ARABIC_JORDAN 0x0b
475 # endif
476 # ifndef SUBLANG_ARABIC_LEBANON
477 # define SUBLANG_ARABIC_LEBANON 0x0c
478 # endif
479 # ifndef SUBLANG_ARABIC_KUWAIT
480 # define SUBLANG_ARABIC_KUWAIT 0x0d
481 # endif
482 # ifndef SUBLANG_ARABIC_UAE
483 # define SUBLANG_ARABIC_UAE 0x0e
484 # endif
485 # ifndef SUBLANG_ARABIC_BAHRAIN
486 # define SUBLANG_ARABIC_BAHRAIN 0x0f
487 # endif
488 # ifndef SUBLANG_ARABIC_QATAR
489 # define SUBLANG_ARABIC_QATAR 0x10
490 # endif
491 # ifndef SUBLANG_AZERI_LATIN
492 # define SUBLANG_AZERI_LATIN 0x01
493 # endif
494 # ifndef SUBLANG_AZERI_CYRILLIC
495 # define SUBLANG_AZERI_CYRILLIC 0x02
496 # endif
497 # ifndef SUBLANG_BENGALI_INDIA
498 # define SUBLANG_BENGALI_INDIA 0x00
499 # endif
500 # ifndef SUBLANG_BENGALI_BANGLADESH
501 # define SUBLANG_BENGALI_BANGLADESH 0x01
502 # endif
503 # ifndef SUBLANG_CHINESE_MACAU
504 # define SUBLANG_CHINESE_MACAU 0x05
505 # endif
506 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
507 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
508 # endif
509 # ifndef SUBLANG_ENGLISH_JAMAICA
510 # define SUBLANG_ENGLISH_JAMAICA 0x08
511 # endif
512 # ifndef SUBLANG_ENGLISH_CARIBBEAN
513 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
514 # endif
515 # ifndef SUBLANG_ENGLISH_BELIZE
516 # define SUBLANG_ENGLISH_BELIZE 0x0a
517 # endif
518 # ifndef SUBLANG_ENGLISH_TRINIDAD
519 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
520 # endif
521 # ifndef SUBLANG_ENGLISH_ZIMBABWE
522 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
523 # endif
524 # ifndef SUBLANG_ENGLISH_PHILIPPINES
525 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
526 # endif
527 # ifndef SUBLANG_ENGLISH_INDONESIA
528 # define SUBLANG_ENGLISH_INDONESIA 0x0e
529 # endif
530 # ifndef SUBLANG_ENGLISH_HONGKONG
531 # define SUBLANG_ENGLISH_HONGKONG 0x0f
532 # endif
533 # ifndef SUBLANG_ENGLISH_INDIA
534 # define SUBLANG_ENGLISH_INDIA 0x10
535 # endif
536 # ifndef SUBLANG_ENGLISH_MALAYSIA
537 # define SUBLANG_ENGLISH_MALAYSIA 0x11
538 # endif
539 # ifndef SUBLANG_ENGLISH_SINGAPORE
540 # define SUBLANG_ENGLISH_SINGAPORE 0x12
541 # endif
542 # ifndef SUBLANG_FRENCH_LUXEMBOURG
543 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
544 # endif
545 # ifndef SUBLANG_FRENCH_MONACO
546 # define SUBLANG_FRENCH_MONACO 0x06
547 # endif
548 # ifndef SUBLANG_FRENCH_WESTINDIES
549 # define SUBLANG_FRENCH_WESTINDIES 0x07
550 # endif
551 # ifndef SUBLANG_FRENCH_REUNION
552 # define SUBLANG_FRENCH_REUNION 0x08
553 # endif
554 # ifndef SUBLANG_FRENCH_CONGO
555 # define SUBLANG_FRENCH_CONGO 0x09
556 # endif
557 # ifndef SUBLANG_FRENCH_SENEGAL
558 # define SUBLANG_FRENCH_SENEGAL 0x0a
559 # endif
560 # ifndef SUBLANG_FRENCH_CAMEROON
561 # define SUBLANG_FRENCH_CAMEROON 0x0b
562 # endif
563 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
564 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
565 # endif
566 # ifndef SUBLANG_FRENCH_MALI
567 # define SUBLANG_FRENCH_MALI 0x0d
568 # endif
569 # ifndef SUBLANG_FRENCH_MOROCCO
570 # define SUBLANG_FRENCH_MOROCCO 0x0e
571 # endif
572 # ifndef SUBLANG_FRENCH_HAITI
573 # define SUBLANG_FRENCH_HAITI 0x0f
574 # endif
575 # ifndef SUBLANG_GERMAN_LUXEMBOURG
576 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
577 # endif
578 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
579 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
580 # endif
581 # ifndef SUBLANG_KASHMIRI_INDIA
582 # define SUBLANG_KASHMIRI_INDIA 0x02
583 # endif
584 # ifndef SUBLANG_MALAY_MALAYSIA
585 # define SUBLANG_MALAY_MALAYSIA 0x01
586 # endif
587 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
588 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
589 # endif
590 # ifndef SUBLANG_NEPALI_INDIA
591 # define SUBLANG_NEPALI_INDIA 0x02
592 # endif
593 # ifndef SUBLANG_PUNJABI_INDIA
594 # define SUBLANG_PUNJABI_INDIA 0x00
595 # endif
596 # ifndef SUBLANG_PUNJABI_PAKISTAN
597 # define SUBLANG_PUNJABI_PAKISTAN 0x01
598 # endif
599 # ifndef SUBLANG_ROMANIAN_ROMANIA
600 # define SUBLANG_ROMANIAN_ROMANIA 0x00
601 # endif
602 # ifndef SUBLANG_ROMANIAN_MOLDOVA
603 # define SUBLANG_ROMANIAN_MOLDOVA 0x01
604 # endif
605 # ifndef SUBLANG_SERBIAN_LATIN
606 # define SUBLANG_SERBIAN_LATIN 0x02
607 # endif
608 # ifndef SUBLANG_SERBIAN_CYRILLIC
609 # define SUBLANG_SERBIAN_CYRILLIC 0x03
610 # endif
611 # ifndef SUBLANG_SINDHI_INDIA
612 # define SUBLANG_SINDHI_INDIA 0x00
613 # endif
614 # ifndef SUBLANG_SINDHI_PAKISTAN
615 # define SUBLANG_SINDHI_PAKISTAN 0x01
616 # endif
617 # ifndef SUBLANG_SPANISH_GUATEMALA
618 # define SUBLANG_SPANISH_GUATEMALA 0x04
619 # endif
620 # ifndef SUBLANG_SPANISH_COSTA_RICA
621 # define SUBLANG_SPANISH_COSTA_RICA 0x05
622 # endif
623 # ifndef SUBLANG_SPANISH_PANAMA
624 # define SUBLANG_SPANISH_PANAMA 0x06
625 # endif
626 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
627 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
628 # endif
629 # ifndef SUBLANG_SPANISH_VENEZUELA
630 # define SUBLANG_SPANISH_VENEZUELA 0x08
631 # endif
632 # ifndef SUBLANG_SPANISH_COLOMBIA
633 # define SUBLANG_SPANISH_COLOMBIA 0x09
634 # endif
635 # ifndef SUBLANG_SPANISH_PERU
636 # define SUBLANG_SPANISH_PERU 0x0a
637 # endif
638 # ifndef SUBLANG_SPANISH_ARGENTINA
639 # define SUBLANG_SPANISH_ARGENTINA 0x0b
640 # endif
641 # ifndef SUBLANG_SPANISH_ECUADOR
642 # define SUBLANG_SPANISH_ECUADOR 0x0c
643 # endif
644 # ifndef SUBLANG_SPANISH_CHILE
645 # define SUBLANG_SPANISH_CHILE 0x0d
646 # endif
647 # ifndef SUBLANG_SPANISH_URUGUAY
648 # define SUBLANG_SPANISH_URUGUAY 0x0e
649 # endif
650 # ifndef SUBLANG_SPANISH_PARAGUAY
651 # define SUBLANG_SPANISH_PARAGUAY 0x0f
652 # endif
653 # ifndef SUBLANG_SPANISH_BOLIVIA
654 # define SUBLANG_SPANISH_BOLIVIA 0x10
655 # endif
656 # ifndef SUBLANG_SPANISH_EL_SALVADOR
657 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
658 # endif
659 # ifndef SUBLANG_SPANISH_HONDURAS
660 # define SUBLANG_SPANISH_HONDURAS 0x12
661 # endif
662 # ifndef SUBLANG_SPANISH_NICARAGUA
663 # define SUBLANG_SPANISH_NICARAGUA 0x13
664 # endif
665 # ifndef SUBLANG_SPANISH_PUERTO_RICO
666 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
667 # endif
668 # ifndef SUBLANG_SWEDISH_FINLAND
669 # define SUBLANG_SWEDISH_FINLAND 0x02
670 # endif
671 # ifndef SUBLANG_TAMAZIGHT_ARABIC
672 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
673 # endif
674 # ifndef SUBLANG_TAMAZIGHT_LATIN
675 # define SUBLANG_TAMAZIGHT_LATIN 0x02
676 # endif
677 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
678 # define SUBLANG_TIGRINYA_ETHIOPIA 0x00
679 # endif
680 # ifndef SUBLANG_TIGRINYA_ERITREA
681 # define SUBLANG_TIGRINYA_ERITREA 0x01
682 # endif
683 # ifndef SUBLANG_URDU_PAKISTAN
684 # define SUBLANG_URDU_PAKISTAN 0x01
685 # endif
686 # ifndef SUBLANG_URDU_INDIA
687 # define SUBLANG_URDU_INDIA 0x02
688 # endif
689 # ifndef SUBLANG_UZBEK_LATIN
690 # define SUBLANG_UZBEK_LATIN 0x01
691 # endif
692 # ifndef SUBLANG_UZBEK_CYRILLIC
693 # define SUBLANG_UZBEK_CYRILLIC 0x02
694 # endif
695 #endif
696
697 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
698 /* MacOS X 10.2 or newer */
699
700 /* Canonicalize a MacOS X locale name to a Unix locale name.
701    NAME is a sufficiently large buffer.
702    On input, it contains the MacOS X locale name.
703    On output, it contains the Unix locale name.  */
704 void
705 _nl_locale_name_canonicalize (char *name)
706 {
707   /* This conversion is based on a posting by
708      Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
709      http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
710
711   /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
712      ISO 3166) names.  Prior to MacOS X 10.3, there is no API for doing this.
713      Therefore we do it ourselves, using a table based on the results of the
714      MacOS X 10.3.8 function
715      CFLocaleCreateCanonicalLocaleIdentifierFromString().  */
716   typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
717           legacy_entry;
718   static const legacy_entry legacy_table[] = {
719     { "Afrikaans",             "af" },
720     { "Albanian",              "sq" },
721     { "Amharic",               "am" },
722     { "Arabic",                "ar" },
723     { "Armenian",              "hy" },
724     { "Assamese",              "as" },
725     { "Aymara",                "ay" },
726     { "Azerbaijani",           "az" },
727     { "Basque",                "eu" },
728     { "Belarusian",            "be" },
729     { "Belorussian",           "be" },
730     { "Bengali",               "bn" },
731     { "Brazilian Portugese",   "pt_BR" },
732     { "Brazilian Portuguese",  "pt_BR" },
733     { "Breton",                "br" },
734     { "Bulgarian",             "bg" },
735     { "Burmese",               "my" },
736     { "Byelorussian",          "be" },
737     { "Catalan",               "ca" },
738     { "Chewa",                 "ny" },
739     { "Chichewa",              "ny" },
740     { "Chinese",               "zh" },
741     { "Chinese, Simplified",   "zh_CN" },
742     { "Chinese, Traditional",  "zh_TW" },
743     { "Chinese, Tradtional",   "zh_TW" },
744     { "Croatian",              "hr" },
745     { "Czech",                 "cs" },
746     { "Danish",                "da" },
747     { "Dutch",                 "nl" },
748     { "Dzongkha",              "dz" },
749     { "English",               "en" },
750     { "Esperanto",             "eo" },
751     { "Estonian",              "et" },
752     { "Faroese",               "fo" },
753     { "Farsi",                 "fa" },
754     { "Finnish",               "fi" },
755     { "Flemish",               "nl_BE" },
756     { "French",                "fr" },
757     { "Galician",              "gl" },
758     { "Gallegan",              "gl" },
759     { "Georgian",              "ka" },
760     { "German",                "de" },
761     { "Greek",                 "el" },
762     { "Greenlandic",           "kl" },
763     { "Guarani",               "gn" },
764     { "Gujarati",              "gu" },
765     { "Hawaiian",              "haw" }, /* Yes, "haw", not "cpe".  */
766     { "Hebrew",                "he" },
767     { "Hindi",                 "hi" },
768     { "Hungarian",             "hu" },
769     { "Icelandic",             "is" },
770     { "Indonesian",            "id" },
771     { "Inuktitut",             "iu" },
772     { "Irish",                 "ga" },
773     { "Italian",               "it" },
774     { "Japanese",              "ja" },
775     { "Javanese",              "jv" },
776     { "Kalaallisut",           "kl" },
777     { "Kannada",               "kn" },
778     { "Kashmiri",              "ks" },
779     { "Kazakh",                "kk" },
780     { "Khmer",                 "km" },
781     { "Kinyarwanda",           "rw" },
782     { "Kirghiz",               "ky" },
783     { "Korean",                "ko" },
784     { "Kurdish",               "ku" },
785     { "Latin",                 "la" },
786     { "Latvian",               "lv" },
787     { "Lithuanian",            "lt" },
788     { "Macedonian",            "mk" },
789     { "Malagasy",              "mg" },
790     { "Malay",                 "ms" },
791     { "Malayalam",             "ml" },
792     { "Maltese",               "mt" },
793     { "Manx",                  "gv" },
794     { "Marathi",               "mr" },
795     { "Moldavian",             "mo" },
796     { "Mongolian",             "mn" },
797     { "Nepali",                "ne" },
798     { "Norwegian",             "nb" }, /* Yes, "nb", not the obsolete "no".  */
799     { "Nyanja",                "ny" },
800     { "Nynorsk",               "nn" },
801     { "Oriya",                 "or" },
802     { "Oromo",                 "om" },
803     { "Panjabi",               "pa" },
804     { "Pashto",                "ps" },
805     { "Persian",               "fa" },
806     { "Polish",                "pl" },
807     { "Portuguese",            "pt" },
808     { "Portuguese, Brazilian", "pt_BR" },
809     { "Punjabi",               "pa" },
810     { "Pushto",                "ps" },
811     { "Quechua",               "qu" },
812     { "Romanian",              "ro" },
813     { "Ruanda",                "rw" },
814     { "Rundi",                 "rn" },
815     { "Russian",               "ru" },
816     { "Sami",                  "se_NO" }, /* Not just "se".  */
817     { "Sanskrit",              "sa" },
818     { "Scottish",              "gd" },
819     { "Serbian",               "sr" },
820     { "Simplified Chinese",    "zh_CN" },
821     { "Sindhi",                "sd" },
822     { "Sinhalese",             "si" },
823     { "Slovak",                "sk" },
824     { "Slovenian",             "sl" },
825     { "Somali",                "so" },
826     { "Spanish",               "es" },
827     { "Sundanese",             "su" },
828     { "Swahili",               "sw" },
829     { "Swedish",               "sv" },
830     { "Tagalog",               "tl" },
831     { "Tajik",                 "tg" },
832     { "Tajiki",                "tg" },
833     { "Tamil",                 "ta" },
834     { "Tatar",                 "tt" },
835     { "Telugu",                "te" },
836     { "Thai",                  "th" },
837     { "Tibetan",               "bo" },
838     { "Tigrinya",              "ti" },
839     { "Tongan",                "to" },
840     { "Traditional Chinese",   "zh_TW" },
841     { "Turkish",               "tr" },
842     { "Turkmen",               "tk" },
843     { "Uighur",                "ug" },
844     { "Ukrainian",             "uk" },
845     { "Urdu",                  "ur" },
846     { "Uzbek",                 "uz" },
847     { "Vietnamese",            "vi" },
848     { "Welsh",                 "cy" },
849     { "Yiddish",               "yi" }
850   };
851
852   /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
853      to Unix (ISO 639 and ISO 3166) names.  */
854   typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
855           langtag_entry;
856   static const langtag_entry langtag_table[] = {
857     /* MacOS X has "az-Arab", "az-Cyrl", "az-Latn".
858        The default script for az on Unix is Latin.  */
859     { "az-Latn", "az" },
860     /* MacOS X has "ga-dots".  Does not yet exist on Unix.  */
861     { "ga-dots", "ga" },
862     /* MacOS X has "kk-Cyrl".  Does not yet exist on Unix.  */
863     /* MacOS X has "mn-Cyrl", "mn-Mong".
864        The default script for mn on Unix is Cyrillic.  */
865     { "mn-Cyrl", "mn" },
866     /* MacOS X has "ms-Arab", "ms-Latn".
867        The default script for ms on Unix is Latin.  */
868     { "ms-Latn", "ms" },
869     /* MacOS X has "tg-Cyrl".
870        The default script for tg on Unix is Cyrillic.  */
871     { "tg-Cyrl", "tg" },
872     /* MacOS X has "tk-Cyrl".  Does not yet exist on Unix.  */
873     /* MacOS X has "tt-Cyrl".
874        The default script for tt on Unix is Cyrillic.  */
875     { "tt-Cyrl", "tt" },
876     /* MacOS X has "zh-Hans", "zh-Hant".
877        Country codes are used to distinguish these on Unix.  */
878     { "zh-Hans", "zh_CN" },
879     { "zh-Hant", "zh_TW" }
880   };
881
882   /* Convert script names (ISO 15924) to Unix conventions.
883      See http://www.unicode.org/iso15924/iso15924-codes.html  */
884   typedef struct { const char script[4+1]; const char unixy[9+1]; }
885           script_entry;
886   static const script_entry script_table[] = {
887     { "Arab", "arabic" },
888     { "Cyrl", "cyrillic" },
889     { "Mong", "mongolian" }
890   };
891
892   /* Step 1: Convert using legacy_table.  */
893   if (name[0] >= 'A' && name[0] <= 'Z')
894     {
895       unsigned int i1, i2;
896       i1 = 0;
897       i2 = sizeof (legacy_table) / sizeof (legacy_entry);
898       while (i2 - i1 > 1)
899         {
900           /* At this point we know that if name occurs in legacy_table,
901              its index must be >= i1 and < i2.  */
902           unsigned int i = (i1 + i2) >> 1;
903           const legacy_entry *p = &legacy_table[i];
904           if (strcmp (name, p->legacy) < 0)
905             i2 = i;
906           else
907             i1 = i;
908         }
909       if (strcmp (name, legacy_table[i1].legacy) == 0)
910         {
911           strcpy (name, legacy_table[i1].unixy);
912           return;
913         }
914     }
915
916   /* Step 2: Convert using langtag_table and script_table.  */
917   if (strlen (name) == 7 && name[2] == '-')
918     {
919       unsigned int i1, i2;
920       i1 = 0;
921       i2 = sizeof (langtag_table) / sizeof (langtag_entry);
922       while (i2 - i1 > 1)
923         {
924           /* At this point we know that if name occurs in langtag_table,
925              its index must be >= i1 and < i2.  */
926           unsigned int i = (i1 + i2) >> 1;
927           const langtag_entry *p = &langtag_table[i];
928           if (strcmp (name, p->langtag) < 0)
929             i2 = i;
930           else
931             i1 = i;
932         }
933       if (strcmp (name, langtag_table[i1].langtag) == 0)
934         {
935           strcpy (name, langtag_table[i1].unixy);
936           return;
937         }
938
939       i1 = 0;
940       i2 = sizeof (script_table) / sizeof (script_entry);
941       while (i2 - i1 > 1)
942         {
943           /* At this point we know that if (name + 3) occurs in script_table,
944              its index must be >= i1 and < i2.  */
945           unsigned int i = (i1 + i2) >> 1;
946           const script_entry *p = &script_table[i];
947           if (strcmp (name + 3, p->script) < 0)
948             i2 = i;
949           else
950             i1 = i;
951         }
952       if (strcmp (name + 3, script_table[i1].script) == 0)
953         {
954           name[2] = '@';
955           strcpy (name + 3, script_table[i1].unixy);
956           return;
957         }
958     }
959
960   /* Step 3: Convert new-style dash to Unix underscore. */
961   {
962     char *p;
963     for (p = name; *p != '\0'; p++)
964       if (*p == '-')
965         *p = '_';
966   }
967 }
968
969 #endif
970
971 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
972    "Directs 'setlocale()' to query 'category' and return the current
973     setting of 'local'."
974    However it does not specify the exact format.  Neither do SUSV2 and
975    ISO C 99.  So we can use this feature only on selected systems (e.g.
976    those using GNU C Library).  */
977 #if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
978 # define HAVE_LOCALE_NULL
979 #endif
980
981 /* Determine the current locale's name, and canonicalize it into XPG syntax
982      language[_territory[.codeset]][@modifier]
983    The codeset part in the result is not reliable; the locale_charset()
984    should be used for codeset information instead.
985    The result must not be freed; it is statically allocated.  */
986
987 const char *
988 _nl_locale_name_posix (int category, const char *categoryname)
989 {
990   /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
991      On some systems this can be done by the 'setlocale' function itself.  */
992 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
993   return setlocale (category, NULL);
994 #else
995   const char *retval;
996
997   /* Setting of LC_ALL overrides all other.  */
998   retval = getenv ("LC_ALL");
999   if (retval != NULL && retval[0] != '\0')
1000     return retval;
1001   /* Next comes the name of the desired category.  */
1002   retval = getenv (categoryname);
1003   if (retval != NULL && retval[0] != '\0')
1004     return retval;
1005   /* Last possibility is the LANG environment variable.  */
1006   retval = getenv ("LANG");
1007   if (retval != NULL && retval[0] != '\0')
1008     return retval;
1009
1010   return NULL;
1011 #endif
1012 }
1013
1014 const char *
1015 _nl_locale_name_default (void)
1016 {
1017   /* POSIX:2001 says:
1018      "All implementations shall define a locale as the default locale, to be
1019       invoked when no environment variables are set, or set to the empty
1020       string.  This default locale can be the POSIX locale or any other
1021       implementation-defined locale.  Some implementations may provide
1022       facilities for local installation administrators to set the default
1023       locale, customizing it for each location.  POSIX:2001 does not require
1024       such a facility.  */
1025
1026 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32))
1027
1028   /* The system does not have a way of setting the locale, other than the
1029      POSIX specified environment variables.  We use C as default locale.  */
1030   return "C";
1031
1032 #else
1033
1034   /* Return an XPG style locale name language[_territory][@modifier].
1035      Don't even bother determining the codeset; it's not useful in this
1036      context, because message catalogs are not specific to a single
1037      codeset.  */
1038
1039 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1040   /* MacOS X 10.2 or newer */
1041   {
1042     /* Cache the locale name, since CoreFoundation calls are expensive.  */
1043     static const char *cached_localename;
1044
1045     if (cached_localename == NULL)
1046       {
1047         char namebuf[256];
1048 #  if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
1049         CFLocaleRef locale = CFLocaleCopyCurrent ();
1050         CFStringRef name = CFLocaleGetIdentifier (locale);
1051
1052         if (CFStringGetCString (name, namebuf, sizeof(namebuf),
1053                                 kCFStringEncodingASCII))
1054           {
1055             _nl_locale_name_canonicalize (namebuf);
1056             cached_localename = strdup (namebuf);
1057           }
1058         CFRelease (locale);
1059 #  elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
1060         CFTypeRef value =
1061           CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
1062                                      kCFPreferencesCurrentApplication);
1063         if (value != NULL
1064             && CFGetTypeID (value) == CFStringGetTypeID ()
1065             && CFStringGetCString ((CFStringRef)value, namebuf, sizeof(namebuf),
1066                                    kCFStringEncodingASCII))
1067           {
1068             _nl_locale_name_canonicalize (namebuf);
1069             cached_localename = strdup (namebuf);
1070           }
1071 #  endif
1072         if (cached_localename == NULL)
1073           cached_localename = "C";
1074       }
1075     return cached_localename;
1076   }
1077
1078 # endif
1079
1080 # if defined(WIN32) /* WIN32 */
1081   {
1082     LCID lcid;
1083     LANGID langid;
1084     int primary, sub;
1085
1086     /* Use native Win32 API locale ID.  */
1087     lcid = GetThreadLocale ();
1088
1089     /* Strip off the sorting rules, keep only the language part.  */
1090     langid = LANGIDFROMLCID (lcid);
1091
1092     /* Split into language and territory part.  */
1093     primary = PRIMARYLANGID (langid);
1094     sub = SUBLANGID (langid);
1095
1096     /* Dispatch on language.
1097        See also http://www.unicode.org/unicode/onlinedat/languages.html .
1098        For details about languages, see http://www.ethnologue.com/ .  */
1099     switch (primary)
1100       {
1101       case LANG_AFRIKAANS: return "af_ZA";
1102       case LANG_ALBANIAN: return "sq_AL";
1103       case LANG_AMHARIC: return "am_ET";
1104       case LANG_ARABIC:
1105         switch (sub)
1106           {
1107           case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
1108           case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
1109           case SUBLANG_ARABIC_EGYPT: return "ar_EG";
1110           case SUBLANG_ARABIC_LIBYA: return "ar_LY";
1111           case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
1112           case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
1113           case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
1114           case SUBLANG_ARABIC_OMAN: return "ar_OM";
1115           case SUBLANG_ARABIC_YEMEN: return "ar_YE";
1116           case SUBLANG_ARABIC_SYRIA: return "ar_SY";
1117           case SUBLANG_ARABIC_JORDAN: return "ar_JO";
1118           case SUBLANG_ARABIC_LEBANON: return "ar_LB";
1119           case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
1120           case SUBLANG_ARABIC_UAE: return "ar_AE";
1121           case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
1122           case SUBLANG_ARABIC_QATAR: return "ar_QA";
1123           }
1124         return "ar";
1125       case LANG_ARMENIAN: return "hy_AM";
1126       case LANG_ASSAMESE: return "as_IN";
1127       case LANG_AZERI:
1128         switch (sub)
1129           {
1130           /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
1131           case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
1132           case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
1133           }
1134         return "az";
1135       case LANG_BASQUE:
1136         switch (sub)
1137           {
1138           case SUBLANG_DEFAULT: return "eu_ES";
1139           }
1140         return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
1141       case LANG_BELARUSIAN: return "be_BY";
1142       case LANG_BENGALI:
1143         switch (sub)
1144           {
1145           case SUBLANG_BENGALI_INDIA: return "bn_IN";
1146           case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
1147           }
1148         return "bn";
1149       case LANG_BULGARIAN: return "bg_BG";
1150       case LANG_BURMESE: return "my_MM";
1151       case LANG_CAMBODIAN: return "km_KH";
1152       case LANG_CATALAN: return "ca_ES";
1153       case LANG_CHEROKEE: return "chr_US";
1154       case LANG_CHINESE:
1155         switch (sub)
1156           {
1157           case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
1158           case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
1159           case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
1160           case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
1161           case SUBLANG_CHINESE_MACAU: return "zh_MO";
1162           }
1163         return "zh";
1164       case LANG_CROATIAN:       /* LANG_CROATIAN == LANG_SERBIAN
1165                                  * What used to be called Serbo-Croatian
1166                                  * should really now be two separate
1167                                  * languages because of political reasons.
1168                                  * (Says tml, who knows nothing about Serbian
1169                                  * or Croatian.)
1170                                  * (I can feel those flames coming already.)
1171                                  */
1172         switch (sub)
1173           {
1174           case SUBLANG_DEFAULT: return "hr_HR";
1175           case SUBLANG_SERBIAN_LATIN: return "sr_CS";
1176           case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
1177           }
1178         return "hr";
1179       case LANG_CZECH: return "cs_CZ";
1180       case LANG_DANISH: return "da_DK";
1181       case LANG_DIVEHI: return "dv_MV";
1182       case LANG_DUTCH:
1183         switch (sub)
1184           {
1185           case SUBLANG_DUTCH: return "nl_NL";
1186           case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
1187           }
1188         return "nl";
1189       case LANG_EDO: return "bin_NG";
1190       case LANG_ENGLISH:
1191         switch (sub)
1192           {
1193           /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1194            * English was the language spoken in England.
1195            * Oh well.
1196            */
1197           case SUBLANG_ENGLISH_US: return "en_US";
1198           case SUBLANG_ENGLISH_UK: return "en_GB";
1199           case SUBLANG_ENGLISH_AUS: return "en_AU";
1200           case SUBLANG_ENGLISH_CAN: return "en_CA";
1201           case SUBLANG_ENGLISH_NZ: return "en_NZ";
1202           case SUBLANG_ENGLISH_EIRE: return "en_IE";
1203           case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
1204           case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
1205           case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
1206           case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
1207           case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
1208           case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
1209           case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
1210           case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
1211           case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
1212           case SUBLANG_ENGLISH_INDIA: return "en_IN";
1213           case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
1214           case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
1215           }
1216         return "en";
1217       case LANG_ESTONIAN: return "et_EE";
1218       case LANG_FAEROESE: return "fo_FO";
1219       case LANG_FARSI: return "fa_IR";
1220       case LANG_FINNISH: return "fi_FI";
1221       case LANG_FRENCH:
1222         switch (sub)
1223           {
1224           case SUBLANG_FRENCH: return "fr_FR";
1225           case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
1226           case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
1227           case SUBLANG_FRENCH_SWISS: return "fr_CH";
1228           case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
1229           case SUBLANG_FRENCH_MONACO: return "fr_MC";
1230           case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
1231           case SUBLANG_FRENCH_REUNION: return "fr_RE";
1232           case SUBLANG_FRENCH_CONGO: return "fr_CG";
1233           case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
1234           case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
1235           case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
1236           case SUBLANG_FRENCH_MALI: return "fr_ML";
1237           case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
1238           case SUBLANG_FRENCH_HAITI: return "fr_HT";
1239           }
1240         return "fr";
1241       case LANG_FRISIAN: return "fy_NL";
1242       case LANG_FULFULDE:
1243         /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin.  */
1244         return "ff_NG";
1245       case LANG_GAELIC:
1246         switch (sub)
1247           {
1248           case 0x01: /* SCOTTISH */ return "gd_GB";
1249           case 0x02: /* IRISH */ return "ga_IE";
1250           }
1251         return "C";
1252       case LANG_GALICIAN: return "gl_ES";
1253       case LANG_GEORGIAN: return "ka_GE";
1254       case LANG_GERMAN:
1255         switch (sub)
1256           {
1257           case SUBLANG_GERMAN: return "de_DE";
1258           case SUBLANG_GERMAN_SWISS: return "de_CH";
1259           case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
1260           case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
1261           case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
1262           }
1263         return "de";
1264       case LANG_GREEK: return "el_GR";
1265       case LANG_GUARANI: return "gn_PY";
1266       case LANG_GUJARATI: return "gu_IN";
1267       case LANG_HAUSA: return "ha_NG";
1268       case LANG_HAWAIIAN:
1269         /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1270            or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
1271         return "cpe_US";
1272       case LANG_HEBREW: return "he_IL";
1273       case LANG_HINDI: return "hi_IN";
1274       case LANG_HUNGARIAN: return "hu_HU";
1275       case LANG_IBIBIO: return "nic_NG";
1276       case LANG_ICELANDIC: return "is_IS";
1277       case LANG_IGBO: return "ig_NG";
1278       case LANG_INDONESIAN: return "id_ID";
1279       case LANG_INUKTITUT: return "iu_CA";
1280       case LANG_ITALIAN:
1281         switch (sub)
1282           {
1283           case SUBLANG_ITALIAN: return "it_IT";
1284           case SUBLANG_ITALIAN_SWISS: return "it_CH";
1285           }
1286         return "it";
1287       case LANG_JAPANESE: return "ja_JP";
1288       case LANG_KANNADA: return "kn_IN";
1289       case LANG_KANURI: return "kr_NG";
1290       case LANG_KASHMIRI:
1291         switch (sub)
1292           {
1293           case SUBLANG_DEFAULT: return "ks_PK";
1294           case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
1295           }
1296         return "ks";
1297       case LANG_KAZAK: return "kk_KZ";
1298       case LANG_KONKANI:
1299         /* FIXME: Adjust this when such locales appear on Unix.  */
1300         return "kok_IN";
1301       case LANG_KOREAN: return "ko_KR";
1302       case LANG_KYRGYZ: return "ky_KG";
1303       case LANG_LAO: return "lo_LA";
1304       case LANG_LATIN: return "la_VA";
1305       case LANG_LATVIAN: return "lv_LV";
1306       case LANG_LITHUANIAN: return "lt_LT";
1307       case LANG_MACEDONIAN: return "mk_MK";
1308       case LANG_MALAY:
1309         switch (sub)
1310           {
1311           case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
1312           case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
1313           }
1314         return "ms";
1315       case LANG_MALAYALAM: return "ml_IN";
1316       case LANG_MALTESE: return "mt_MT";
1317       case LANG_MANIPURI:
1318         /* FIXME: Adjust this when such locales appear on Unix.  */
1319         return "mni_IN";
1320       case LANG_MARATHI: return "mr_IN";
1321       case LANG_MONGOLIAN:
1322         switch (sub)
1323           {
1324           case SUBLANG_DEFAULT: return "mn_MN";
1325           }
1326         return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
1327       case LANG_NEPALI:
1328         switch (sub)
1329           {
1330           case SUBLANG_DEFAULT: return "ne_NP";
1331           case SUBLANG_NEPALI_INDIA: return "ne_IN";
1332           }
1333         return "ne";
1334       case LANG_NORWEGIAN:
1335         switch (sub)
1336           {
1337           case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
1338           case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
1339           }
1340         return "no";
1341       case LANG_ORIYA: return "or_IN";
1342       case LANG_OROMO: return "om_ET";
1343       case LANG_PAPIAMENTU: return "pap_AN";
1344       case LANG_PASHTO:
1345         return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
1346       case LANG_POLISH: return "pl_PL";
1347       case LANG_PORTUGUESE:
1348         switch (sub)
1349           {
1350           case SUBLANG_PORTUGUESE: return "pt_PT";
1351           /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
1352              Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
1353           case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
1354           }
1355         return "pt";
1356       case LANG_PUNJABI:
1357         switch (sub)
1358           {
1359           case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
1360           case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
1361           }
1362         return "pa";
1363       case LANG_RHAETO_ROMANCE: return "rm_CH";
1364       case LANG_ROMANIAN:
1365         switch (sub)
1366           {
1367           case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
1368           case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
1369           }
1370         return "ro";
1371       case LANG_RUSSIAN:
1372         switch (sub)
1373           {
1374           case SUBLANG_DEFAULT: return "ru_RU";
1375           }
1376         return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
1377       case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
1378       case LANG_SANSKRIT: return "sa_IN";
1379       case LANG_SINDHI:
1380         switch (sub)
1381           {
1382           case SUBLANG_SINDHI_INDIA: return "sd_IN";
1383           case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
1384           }
1385         return "sd";
1386       case LANG_SINHALESE: return "si_LK";
1387       case LANG_SLOVAK: return "sk_SK";
1388       case LANG_SLOVENIAN: return "sl_SI";
1389       case LANG_SOMALI: return "so_SO";
1390       case LANG_SORBIAN:
1391         /* FIXME: Adjust this when such locales appear on Unix.  */
1392         return "wen_DE";
1393       case LANG_SPANISH:
1394         switch (sub)
1395           {
1396           case SUBLANG_SPANISH: return "es_ES";
1397           case SUBLANG_SPANISH_MEXICAN: return "es_MX";
1398           case SUBLANG_SPANISH_MODERN:
1399             return "es_ES@modern";      /* not seen on Unix */
1400           case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
1401           case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
1402           case SUBLANG_SPANISH_PANAMA: return "es_PA";
1403           case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
1404           case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
1405           case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
1406           case SUBLANG_SPANISH_PERU: return "es_PE";
1407           case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
1408           case SUBLANG_SPANISH_ECUADOR: return "es_EC";
1409           case SUBLANG_SPANISH_CHILE: return "es_CL";
1410           case SUBLANG_SPANISH_URUGUAY: return "es_UY";
1411           case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
1412           case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
1413           case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
1414           case SUBLANG_SPANISH_HONDURAS: return "es_HN";
1415           case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
1416           case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
1417           }
1418         return "es";
1419       case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
1420       case LANG_SWAHILI: return "sw_KE";
1421       case LANG_SWEDISH:
1422         switch (sub)
1423           {
1424           case SUBLANG_DEFAULT: return "sv_SE";
1425           case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
1426           }
1427         return "sv";
1428       case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
1429       case LANG_TAGALOG: return "tl_PH";
1430       case LANG_TAJIK: return "tg_TJ";
1431       case LANG_TAMAZIGHT:
1432         switch (sub)
1433           {
1434           /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
1435           case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
1436           case SUBLANG_TAMAZIGHT_LATIN: return "ber_MA@latin";
1437           }
1438         return "ber_MA";
1439       case LANG_TAMIL:
1440         switch (sub)
1441           {
1442           case SUBLANG_DEFAULT: return "ta_IN";
1443           }
1444         return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
1445       case LANG_TATAR: return "tt_RU";
1446       case LANG_TELUGU: return "te_IN";
1447       case LANG_THAI: return "th_TH";
1448       case LANG_TIBETAN: return "bo_CN";
1449       case LANG_TIGRINYA:
1450         switch (sub)
1451           {
1452           case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
1453           case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
1454           }
1455         return "ti";
1456       case LANG_TSONGA: return "ts_ZA";
1457       case LANG_TSWANA: return "tn_BW";
1458       case LANG_TURKISH: return "tr_TR";
1459       case LANG_TURKMEN: return "tk_TM";
1460       case LANG_UKRAINIAN: return "uk_UA";
1461       case LANG_URDU:
1462         switch (sub)
1463           {
1464           case SUBLANG_URDU_PAKISTAN: return "ur_PK";
1465           case SUBLANG_URDU_INDIA: return "ur_IN";
1466           }
1467         return "ur";
1468       case LANG_UZBEK:
1469         switch (sub)
1470           {
1471           case SUBLANG_UZBEK_LATIN: return "uz_UZ";
1472           case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
1473           }
1474         return "uz";
1475       case LANG_VENDA: return "ve_ZA";
1476       case LANG_VIETNAMESE: return "vi_VN";
1477       case LANG_WELSH: return "cy_GB";
1478       case LANG_XHOSA: return "xh_ZA";
1479       case LANG_YI: return "sit_CN";
1480       case LANG_YIDDISH: return "yi_IL";
1481       case LANG_YORUBA: return "yo_NG";
1482       case LANG_ZULU: return "zu_ZA";
1483       default: return "C";
1484       }
1485   }
1486 # endif
1487 #endif
1488 }
1489
1490 const char *
1491 _nl_locale_name (int category, const char *categoryname)
1492 {
1493   const char *retval;
1494
1495   retval = _nl_locale_name_posix (category, categoryname);
1496   if (retval != NULL)
1497     return retval;
1498
1499   return _nl_locale_name_default ();
1500 }