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