1 /* Determine name of the currently selected locale.
2 Copyright (C) 1995-1999, 2000-2010 Free Software Foundation, Inc.
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)
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.
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,
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>. */
27 # include "gettextP.h"
29 # include "localename.h"
39 /* MacOS X 10.5 defines the locale_t type in <xlocale.h>. */
40 # if defined __APPLE__ && defined __MACH__
43 # include <langinfo.h>
44 # if !defined IN_LIBINTL
45 # include "glthread/lock.h"
49 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
50 # include <CoreFoundation/CFString.h>
51 # if HAVE_CFLOCALECOPYCURRENT
52 # include <CoreFoundation/CFLocale.h>
53 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
54 # include <CoreFoundation/CFPreferences.h>
58 #if defined _WIN32 || defined __WIN32__
62 #if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
63 # define WIN32_LEAN_AND_MEAN
65 /* List of language codes, sorted by value:
91 0x1a LANG_CROATIAN == LANG_SERBIAN
173 0x6e LANG_LUXEMBOURGISH
174 0x6f LANG_GREENLANDIC
193 0x87 LANG_KINYARWANDA
196 0x91 LANG_SCOTTISH_GAELIC
198 /* Mingw headers don't have latest language and sublanguage codes. */
199 # ifndef LANG_AFRIKAANS
200 # define LANG_AFRIKAANS 0x36
202 # ifndef LANG_ALBANIAN
203 # define LANG_ALBANIAN 0x1c
205 # ifndef LANG_ALSATIAN
206 # define LANG_ALSATIAN 0x84
208 # ifndef LANG_AMHARIC
209 # define LANG_AMHARIC 0x5e
212 # define LANG_ARABIC 0x01
214 # ifndef LANG_ARMENIAN
215 # define LANG_ARMENIAN 0x2b
217 # ifndef LANG_ASSAMESE
218 # define LANG_ASSAMESE 0x4d
221 # define LANG_AZERI 0x2c
223 # ifndef LANG_BASHKIR
224 # define LANG_BASHKIR 0x6d
227 # define LANG_BASQUE 0x2d
229 # ifndef LANG_BELARUSIAN
230 # define LANG_BELARUSIAN 0x23
232 # ifndef LANG_BENGALI
233 # define LANG_BENGALI 0x45
236 # define LANG_BRETON 0x7e
238 # ifndef LANG_BURMESE
239 # define LANG_BURMESE 0x55
241 # ifndef LANG_CAMBODIAN
242 # define LANG_CAMBODIAN 0x53
244 # ifndef LANG_CATALAN
245 # define LANG_CATALAN 0x03
247 # ifndef LANG_CHEROKEE
248 # define LANG_CHEROKEE 0x5c
250 # ifndef LANG_CORSICAN
251 # define LANG_CORSICAN 0x83
254 # define LANG_DARI 0x8c
257 # define LANG_DIVEHI 0x65
260 # define LANG_EDO 0x66
262 # ifndef LANG_ESTONIAN
263 # define LANG_ESTONIAN 0x25
265 # ifndef LANG_FAEROESE
266 # define LANG_FAEROESE 0x38
269 # define LANG_FARSI 0x29
271 # ifndef LANG_FRISIAN
272 # define LANG_FRISIAN 0x62
274 # ifndef LANG_FULFULDE
275 # define LANG_FULFULDE 0x67
278 # define LANG_GAELIC 0x3c
280 # ifndef LANG_GALICIAN
281 # define LANG_GALICIAN 0x56
283 # ifndef LANG_GEORGIAN
284 # define LANG_GEORGIAN 0x37
286 # ifndef LANG_GREENLANDIC
287 # define LANG_GREENLANDIC 0x6f
289 # ifndef LANG_GUARANI
290 # define LANG_GUARANI 0x74
292 # ifndef LANG_GUJARATI
293 # define LANG_GUJARATI 0x47
296 # define LANG_HAUSA 0x68
298 # ifndef LANG_HAWAIIAN
299 # define LANG_HAWAIIAN 0x75
302 # define LANG_HEBREW 0x0d
305 # define LANG_HINDI 0x39
308 # define LANG_IBIBIO 0x69
311 # define LANG_IGBO 0x70
313 # ifndef LANG_INDONESIAN
314 # define LANG_INDONESIAN 0x21
316 # ifndef LANG_INUKTITUT
317 # define LANG_INUKTITUT 0x5d
319 # ifndef LANG_KANNADA
320 # define LANG_KANNADA 0x4b
323 # define LANG_KANURI 0x71
325 # ifndef LANG_KASHMIRI
326 # define LANG_KASHMIRI 0x60
329 # define LANG_KAZAK 0x3f
332 # define LANG_KICHE 0x86
334 # ifndef LANG_KINYARWANDA
335 # define LANG_KINYARWANDA 0x87
337 # ifndef LANG_KONKANI
338 # define LANG_KONKANI 0x57
341 # define LANG_KYRGYZ 0x40
344 # define LANG_LAO 0x54
347 # define LANG_LATIN 0x76
349 # ifndef LANG_LATVIAN
350 # define LANG_LATVIAN 0x26
352 # ifndef LANG_LITHUANIAN
353 # define LANG_LITHUANIAN 0x27
355 # ifndef LANG_LUXEMBOURGISH
356 # define LANG_LUXEMBOURGISH 0x6e
358 # ifndef LANG_MACEDONIAN
359 # define LANG_MACEDONIAN 0x2f
362 # define LANG_MALAY 0x3e
364 # ifndef LANG_MALAYALAM
365 # define LANG_MALAYALAM 0x4c
367 # ifndef LANG_MALTESE
368 # define LANG_MALTESE 0x3a
370 # ifndef LANG_MANIPURI
371 # define LANG_MANIPURI 0x58
374 # define LANG_MAORI 0x81
376 # ifndef LANG_MAPUDUNGUN
377 # define LANG_MAPUDUNGUN 0x7a
379 # ifndef LANG_MARATHI
380 # define LANG_MARATHI 0x4e
383 # define LANG_MOHAWK 0x7c
385 # ifndef LANG_MONGOLIAN
386 # define LANG_MONGOLIAN 0x50
389 # define LANG_NEPALI 0x61
391 # ifndef LANG_OCCITAN
392 # define LANG_OCCITAN 0x82
395 # define LANG_ORIYA 0x48
398 # define LANG_OROMO 0x72
400 # ifndef LANG_PAPIAMENTU
401 # define LANG_PAPIAMENTU 0x79
404 # define LANG_PASHTO 0x63
406 # ifndef LANG_PUNJABI
407 # define LANG_PUNJABI 0x46
409 # ifndef LANG_QUECHUA
410 # define LANG_QUECHUA 0x6b
412 # ifndef LANG_ROMANSH
413 # define LANG_ROMANSH 0x17
416 # define LANG_SAMI 0x3b
418 # ifndef LANG_SANSKRIT
419 # define LANG_SANSKRIT 0x4f
421 # ifndef LANG_SCOTTISH_GAELIC
422 # define LANG_SCOTTISH_GAELIC 0x91
424 # ifndef LANG_SERBIAN
425 # define LANG_SERBIAN 0x1a
428 # define LANG_SINDHI 0x59
430 # ifndef LANG_SINHALESE
431 # define LANG_SINHALESE 0x5b
434 # define LANG_SLOVAK 0x1b
437 # define LANG_SOMALI 0x77
439 # ifndef LANG_SORBIAN
440 # define LANG_SORBIAN 0x2e
443 # define LANG_SOTHO 0x6c
446 # define LANG_SUTU 0x30
448 # ifndef LANG_SWAHILI
449 # define LANG_SWAHILI 0x41
452 # define LANG_SYRIAC 0x5a
454 # ifndef LANG_TAGALOG
455 # define LANG_TAGALOG 0x64
458 # define LANG_TAJIK 0x28
460 # ifndef LANG_TAMAZIGHT
461 # define LANG_TAMAZIGHT 0x5f
464 # define LANG_TAMIL 0x49
467 # define LANG_TATAR 0x44
470 # define LANG_TELUGU 0x4a
473 # define LANG_THAI 0x1e
475 # ifndef LANG_TIBETAN
476 # define LANG_TIBETAN 0x51
478 # ifndef LANG_TIGRINYA
479 # define LANG_TIGRINYA 0x73
482 # define LANG_TSONGA 0x31
485 # define LANG_TSWANA 0x32
487 # ifndef LANG_TURKMEN
488 # define LANG_TURKMEN 0x42
491 # define LANG_UIGHUR 0x80
493 # ifndef LANG_UKRAINIAN
494 # define LANG_UKRAINIAN 0x22
497 # define LANG_URDU 0x20
500 # define LANG_UZBEK 0x43
503 # define LANG_VENDA 0x33
505 # ifndef LANG_VIETNAMESE
506 # define LANG_VIETNAMESE 0x2a
509 # define LANG_WELSH 0x52
512 # define LANG_WOLOF 0x88
515 # define LANG_XHOSA 0x34
518 # define LANG_YAKUT 0x85
521 # define LANG_YI 0x78
523 # ifndef LANG_YIDDISH
524 # define LANG_YIDDISH 0x3d
527 # define LANG_YORUBA 0x6a
530 # define LANG_ZULU 0x35
532 # ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
533 # define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
535 # ifndef SUBLANG_ALBANIAN_ALBANIA
536 # define SUBLANG_ALBANIAN_ALBANIA 0x01
538 # ifndef SUBLANG_ALSATIAN_FRANCE
539 # define SUBLANG_ALSATIAN_FRANCE 0x01
541 # ifndef SUBLANG_AMHARIC_ETHIOPIA
542 # define SUBLANG_AMHARIC_ETHIOPIA 0x01
544 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
545 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
547 # ifndef SUBLANG_ARABIC_IRAQ
548 # define SUBLANG_ARABIC_IRAQ 0x02
550 # ifndef SUBLANG_ARABIC_EGYPT
551 # define SUBLANG_ARABIC_EGYPT 0x03
553 # ifndef SUBLANG_ARABIC_LIBYA
554 # define SUBLANG_ARABIC_LIBYA 0x04
556 # ifndef SUBLANG_ARABIC_ALGERIA
557 # define SUBLANG_ARABIC_ALGERIA 0x05
559 # ifndef SUBLANG_ARABIC_MOROCCO
560 # define SUBLANG_ARABIC_MOROCCO 0x06
562 # ifndef SUBLANG_ARABIC_TUNISIA
563 # define SUBLANG_ARABIC_TUNISIA 0x07
565 # ifndef SUBLANG_ARABIC_OMAN
566 # define SUBLANG_ARABIC_OMAN 0x08
568 # ifndef SUBLANG_ARABIC_YEMEN
569 # define SUBLANG_ARABIC_YEMEN 0x09
571 # ifndef SUBLANG_ARABIC_SYRIA
572 # define SUBLANG_ARABIC_SYRIA 0x0a
574 # ifndef SUBLANG_ARABIC_JORDAN
575 # define SUBLANG_ARABIC_JORDAN 0x0b
577 # ifndef SUBLANG_ARABIC_LEBANON
578 # define SUBLANG_ARABIC_LEBANON 0x0c
580 # ifndef SUBLANG_ARABIC_KUWAIT
581 # define SUBLANG_ARABIC_KUWAIT 0x0d
583 # ifndef SUBLANG_ARABIC_UAE
584 # define SUBLANG_ARABIC_UAE 0x0e
586 # ifndef SUBLANG_ARABIC_BAHRAIN
587 # define SUBLANG_ARABIC_BAHRAIN 0x0f
589 # ifndef SUBLANG_ARABIC_QATAR
590 # define SUBLANG_ARABIC_QATAR 0x10
592 # ifndef SUBLANG_ARMENIAN_ARMENIA
593 # define SUBLANG_ARMENIAN_ARMENIA 0x01
595 # ifndef SUBLANG_ASSAMESE_INDIA
596 # define SUBLANG_ASSAMESE_INDIA 0x01
598 # ifndef SUBLANG_AZERI_LATIN
599 # define SUBLANG_AZERI_LATIN 0x01
601 # ifndef SUBLANG_AZERI_CYRILLIC
602 # define SUBLANG_AZERI_CYRILLIC 0x02
604 # ifndef SUBLANG_BASHKIR_RUSSIA
605 # define SUBLANG_BASHKIR_RUSSIA 0x01
607 # ifndef SUBLANG_BASQUE_BASQUE
608 # define SUBLANG_BASQUE_BASQUE 0x01
610 # ifndef SUBLANG_BELARUSIAN_BELARUS
611 # define SUBLANG_BELARUSIAN_BELARUS 0x01
613 # ifndef SUBLANG_BENGALI_INDIA
614 # define SUBLANG_BENGALI_INDIA 0x01
616 # ifndef SUBLANG_BENGALI_BANGLADESH
617 # define SUBLANG_BENGALI_BANGLADESH 0x02
619 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
620 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
622 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
623 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
625 # ifndef SUBLANG_BRETON_FRANCE
626 # define SUBLANG_BRETON_FRANCE 0x01
628 # ifndef SUBLANG_BULGARIAN_BULGARIA
629 # define SUBLANG_BULGARIAN_BULGARIA 0x01
631 # ifndef SUBLANG_CAMBODIAN_CAMBODIA
632 # define SUBLANG_CAMBODIAN_CAMBODIA 0x01
634 # ifndef SUBLANG_CATALAN_SPAIN
635 # define SUBLANG_CATALAN_SPAIN 0x01
637 # ifndef SUBLANG_CORSICAN_FRANCE
638 # define SUBLANG_CORSICAN_FRANCE 0x01
640 # ifndef SUBLANG_CROATIAN_CROATIA
641 # define SUBLANG_CROATIAN_CROATIA 0x01
643 # ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
644 # define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
646 # ifndef SUBLANG_CHINESE_MACAU
647 # define SUBLANG_CHINESE_MACAU 0x05
649 # ifndef SUBLANG_CZECH_CZECH_REPUBLIC
650 # define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
652 # ifndef SUBLANG_DANISH_DENMARK
653 # define SUBLANG_DANISH_DENMARK 0x01
655 # ifndef SUBLANG_DARI_AFGHANISTAN
656 # define SUBLANG_DARI_AFGHANISTAN 0x01
658 # ifndef SUBLANG_DIVEHI_MALDIVES
659 # define SUBLANG_DIVEHI_MALDIVES 0x01
661 # ifndef SUBLANG_DUTCH_SURINAM
662 # define SUBLANG_DUTCH_SURINAM 0x03
664 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
665 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
667 # ifndef SUBLANG_ENGLISH_JAMAICA
668 # define SUBLANG_ENGLISH_JAMAICA 0x08
670 # ifndef SUBLANG_ENGLISH_CARIBBEAN
671 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
673 # ifndef SUBLANG_ENGLISH_BELIZE
674 # define SUBLANG_ENGLISH_BELIZE 0x0a
676 # ifndef SUBLANG_ENGLISH_TRINIDAD
677 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
679 # ifndef SUBLANG_ENGLISH_ZIMBABWE
680 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
682 # ifndef SUBLANG_ENGLISH_PHILIPPINES
683 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
685 # ifndef SUBLANG_ENGLISH_INDONESIA
686 # define SUBLANG_ENGLISH_INDONESIA 0x0e
688 # ifndef SUBLANG_ENGLISH_HONGKONG
689 # define SUBLANG_ENGLISH_HONGKONG 0x0f
691 # ifndef SUBLANG_ENGLISH_INDIA
692 # define SUBLANG_ENGLISH_INDIA 0x10
694 # ifndef SUBLANG_ENGLISH_MALAYSIA
695 # define SUBLANG_ENGLISH_MALAYSIA 0x11
697 # ifndef SUBLANG_ENGLISH_SINGAPORE
698 # define SUBLANG_ENGLISH_SINGAPORE 0x12
700 # ifndef SUBLANG_ESTONIAN_ESTONIA
701 # define SUBLANG_ESTONIAN_ESTONIA 0x01
703 # ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
704 # define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
706 # ifndef SUBLANG_FARSI_IRAN
707 # define SUBLANG_FARSI_IRAN 0x01
709 # ifndef SUBLANG_FINNISH_FINLAND
710 # define SUBLANG_FINNISH_FINLAND 0x01
712 # ifndef SUBLANG_FRENCH_LUXEMBOURG
713 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
715 # ifndef SUBLANG_FRENCH_MONACO
716 # define SUBLANG_FRENCH_MONACO 0x06
718 # ifndef SUBLANG_FRENCH_WESTINDIES
719 # define SUBLANG_FRENCH_WESTINDIES 0x07
721 # ifndef SUBLANG_FRENCH_REUNION
722 # define SUBLANG_FRENCH_REUNION 0x08
724 # ifndef SUBLANG_FRENCH_CONGO
725 # define SUBLANG_FRENCH_CONGO 0x09
727 # ifndef SUBLANG_FRENCH_SENEGAL
728 # define SUBLANG_FRENCH_SENEGAL 0x0a
730 # ifndef SUBLANG_FRENCH_CAMEROON
731 # define SUBLANG_FRENCH_CAMEROON 0x0b
733 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
734 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
736 # ifndef SUBLANG_FRENCH_MALI
737 # define SUBLANG_FRENCH_MALI 0x0d
739 # ifndef SUBLANG_FRENCH_MOROCCO
740 # define SUBLANG_FRENCH_MOROCCO 0x0e
742 # ifndef SUBLANG_FRENCH_HAITI
743 # define SUBLANG_FRENCH_HAITI 0x0f
745 # ifndef SUBLANG_FRISIAN_NETHERLANDS
746 # define SUBLANG_FRISIAN_NETHERLANDS 0x01
748 # ifndef SUBLANG_GALICIAN_SPAIN
749 # define SUBLANG_GALICIAN_SPAIN 0x01
751 # ifndef SUBLANG_GEORGIAN_GEORGIA
752 # define SUBLANG_GEORGIAN_GEORGIA 0x01
754 # ifndef SUBLANG_GERMAN_LUXEMBOURG
755 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
757 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
758 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
760 # ifndef SUBLANG_GREEK_GREECE
761 # define SUBLANG_GREEK_GREECE 0x01
763 # ifndef SUBLANG_GREENLANDIC_GREENLAND
764 # define SUBLANG_GREENLANDIC_GREENLAND 0x01
766 # ifndef SUBLANG_GUJARATI_INDIA
767 # define SUBLANG_GUJARATI_INDIA 0x01
769 # ifndef SUBLANG_HAUSA_NIGERIA_LATIN
770 # define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
772 # ifndef SUBLANG_HEBREW_ISRAEL
773 # define SUBLANG_HEBREW_ISRAEL 0x01
775 # ifndef SUBLANG_HINDI_INDIA
776 # define SUBLANG_HINDI_INDIA 0x01
778 # ifndef SUBLANG_HUNGARIAN_HUNGARY
779 # define SUBLANG_HUNGARIAN_HUNGARY 0x01
781 # ifndef SUBLANG_ICELANDIC_ICELAND
782 # define SUBLANG_ICELANDIC_ICELAND 0x01
784 # ifndef SUBLANG_IGBO_NIGERIA
785 # define SUBLANG_IGBO_NIGERIA 0x01
787 # ifndef SUBLANG_INDONESIAN_INDONESIA
788 # define SUBLANG_INDONESIAN_INDONESIA 0x01
790 # ifndef SUBLANG_INUKTITUT_CANADA
791 # define SUBLANG_INUKTITUT_CANADA 0x01
793 # undef SUBLANG_INUKTITUT_CANADA_LATIN
794 # define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
795 # undef SUBLANG_IRISH_IRELAND
796 # define SUBLANG_IRISH_IRELAND 0x02
797 # ifndef SUBLANG_JAPANESE_JAPAN
798 # define SUBLANG_JAPANESE_JAPAN 0x01
800 # ifndef SUBLANG_KANNADA_INDIA
801 # define SUBLANG_KANNADA_INDIA 0x01
803 # ifndef SUBLANG_KASHMIRI_INDIA
804 # define SUBLANG_KASHMIRI_INDIA 0x02
806 # ifndef SUBLANG_KAZAK_KAZAKHSTAN
807 # define SUBLANG_KAZAK_KAZAKHSTAN 0x01
809 # ifndef SUBLANG_KICHE_GUATEMALA
810 # define SUBLANG_KICHE_GUATEMALA 0x01
812 # ifndef SUBLANG_KINYARWANDA_RWANDA
813 # define SUBLANG_KINYARWANDA_RWANDA 0x01
815 # ifndef SUBLANG_KONKANI_INDIA
816 # define SUBLANG_KONKANI_INDIA 0x01
818 # ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
819 # define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
821 # ifndef SUBLANG_LAO_LAOS
822 # define SUBLANG_LAO_LAOS 0x01
824 # ifndef SUBLANG_LATVIAN_LATVIA
825 # define SUBLANG_LATVIAN_LATVIA 0x01
827 # ifndef SUBLANG_LITHUANIAN_LITHUANIA
828 # define SUBLANG_LITHUANIAN_LITHUANIA 0x01
830 # undef SUBLANG_LOWER_SORBIAN_GERMANY
831 # define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
832 # ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
833 # define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
835 # ifndef SUBLANG_MACEDONIAN_MACEDONIA
836 # define SUBLANG_MACEDONIAN_MACEDONIA 0x01
838 # ifndef SUBLANG_MALAY_MALAYSIA
839 # define SUBLANG_MALAY_MALAYSIA 0x01
841 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
842 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
844 # ifndef SUBLANG_MALAYALAM_INDIA
845 # define SUBLANG_MALAYALAM_INDIA 0x01
847 # ifndef SUBLANG_MALTESE_MALTA
848 # define SUBLANG_MALTESE_MALTA 0x01
850 # ifndef SUBLANG_MAORI_NEW_ZEALAND
851 # define SUBLANG_MAORI_NEW_ZEALAND 0x01
853 # ifndef SUBLANG_MAPUDUNGUN_CHILE
854 # define SUBLANG_MAPUDUNGUN_CHILE 0x01
856 # ifndef SUBLANG_MARATHI_INDIA
857 # define SUBLANG_MARATHI_INDIA 0x01
859 # ifndef SUBLANG_MOHAWK_CANADA
860 # define SUBLANG_MOHAWK_CANADA 0x01
862 # ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
863 # define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
865 # ifndef SUBLANG_MONGOLIAN_PRC
866 # define SUBLANG_MONGOLIAN_PRC 0x02
868 # ifndef SUBLANG_NEPALI_NEPAL
869 # define SUBLANG_NEPALI_NEPAL 0x01
871 # ifndef SUBLANG_NEPALI_INDIA
872 # define SUBLANG_NEPALI_INDIA 0x02
874 # ifndef SUBLANG_OCCITAN_FRANCE
875 # define SUBLANG_OCCITAN_FRANCE 0x01
877 # ifndef SUBLANG_ORIYA_INDIA
878 # define SUBLANG_ORIYA_INDIA 0x01
880 # ifndef SUBLANG_PASHTO_AFGHANISTAN
881 # define SUBLANG_PASHTO_AFGHANISTAN 0x01
883 # ifndef SUBLANG_POLISH_POLAND
884 # define SUBLANG_POLISH_POLAND 0x01
886 # ifndef SUBLANG_PUNJABI_INDIA
887 # define SUBLANG_PUNJABI_INDIA 0x01
889 # ifndef SUBLANG_PUNJABI_PAKISTAN
890 # define SUBLANG_PUNJABI_PAKISTAN 0x02
892 # ifndef SUBLANG_QUECHUA_BOLIVIA
893 # define SUBLANG_QUECHUA_BOLIVIA 0x01
895 # ifndef SUBLANG_QUECHUA_ECUADOR
896 # define SUBLANG_QUECHUA_ECUADOR 0x02
898 # ifndef SUBLANG_QUECHUA_PERU
899 # define SUBLANG_QUECHUA_PERU 0x03
901 # ifndef SUBLANG_ROMANIAN_ROMANIA
902 # define SUBLANG_ROMANIAN_ROMANIA 0x01
904 # ifndef SUBLANG_ROMANIAN_MOLDOVA
905 # define SUBLANG_ROMANIAN_MOLDOVA 0x02
907 # ifndef SUBLANG_ROMANSH_SWITZERLAND
908 # define SUBLANG_ROMANSH_SWITZERLAND 0x01
910 # ifndef SUBLANG_RUSSIAN_RUSSIA
911 # define SUBLANG_RUSSIAN_RUSSIA 0x01
913 # ifndef SUBLANG_RUSSIAN_MOLDAVIA
914 # define SUBLANG_RUSSIAN_MOLDAVIA 0x02
916 # ifndef SUBLANG_SAMI_NORTHERN_NORWAY
917 # define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
919 # ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
920 # define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
922 # ifndef SUBLANG_SAMI_NORTHERN_FINLAND
923 # define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
925 # ifndef SUBLANG_SAMI_LULE_NORWAY
926 # define SUBLANG_SAMI_LULE_NORWAY 0x04
928 # ifndef SUBLANG_SAMI_LULE_SWEDEN
929 # define SUBLANG_SAMI_LULE_SWEDEN 0x05
931 # ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
932 # define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
934 # ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
935 # define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
937 # undef SUBLANG_SAMI_SKOLT_FINLAND
938 # define SUBLANG_SAMI_SKOLT_FINLAND 0x08
939 # undef SUBLANG_SAMI_INARI_FINLAND
940 # define SUBLANG_SAMI_INARI_FINLAND 0x09
941 # ifndef SUBLANG_SANSKRIT_INDIA
942 # define SUBLANG_SANSKRIT_INDIA 0x01
944 # ifndef SUBLANG_SERBIAN_LATIN
945 # define SUBLANG_SERBIAN_LATIN 0x02
947 # ifndef SUBLANG_SERBIAN_CYRILLIC
948 # define SUBLANG_SERBIAN_CYRILLIC 0x03
950 # ifndef SUBLANG_SINDHI_INDIA
951 # define SUBLANG_SINDHI_INDIA 0x01
953 # undef SUBLANG_SINDHI_PAKISTAN
954 # define SUBLANG_SINDHI_PAKISTAN 0x02
955 # ifndef SUBLANG_SINDHI_AFGHANISTAN
956 # define SUBLANG_SINDHI_AFGHANISTAN 0x02
958 # ifndef SUBLANG_SINHALESE_SRI_LANKA
959 # define SUBLANG_SINHALESE_SRI_LANKA 0x01
961 # ifndef SUBLANG_SLOVAK_SLOVAKIA
962 # define SUBLANG_SLOVAK_SLOVAKIA 0x01
964 # ifndef SUBLANG_SLOVENIAN_SLOVENIA
965 # define SUBLANG_SLOVENIAN_SLOVENIA 0x01
967 # ifndef SUBLANG_SOTHO_SOUTH_AFRICA
968 # define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
970 # ifndef SUBLANG_SPANISH_GUATEMALA
971 # define SUBLANG_SPANISH_GUATEMALA 0x04
973 # ifndef SUBLANG_SPANISH_COSTA_RICA
974 # define SUBLANG_SPANISH_COSTA_RICA 0x05
976 # ifndef SUBLANG_SPANISH_PANAMA
977 # define SUBLANG_SPANISH_PANAMA 0x06
979 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
980 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
982 # ifndef SUBLANG_SPANISH_VENEZUELA
983 # define SUBLANG_SPANISH_VENEZUELA 0x08
985 # ifndef SUBLANG_SPANISH_COLOMBIA
986 # define SUBLANG_SPANISH_COLOMBIA 0x09
988 # ifndef SUBLANG_SPANISH_PERU
989 # define SUBLANG_SPANISH_PERU 0x0a
991 # ifndef SUBLANG_SPANISH_ARGENTINA
992 # define SUBLANG_SPANISH_ARGENTINA 0x0b
994 # ifndef SUBLANG_SPANISH_ECUADOR
995 # define SUBLANG_SPANISH_ECUADOR 0x0c
997 # ifndef SUBLANG_SPANISH_CHILE
998 # define SUBLANG_SPANISH_CHILE 0x0d
1000 # ifndef SUBLANG_SPANISH_URUGUAY
1001 # define SUBLANG_SPANISH_URUGUAY 0x0e
1003 # ifndef SUBLANG_SPANISH_PARAGUAY
1004 # define SUBLANG_SPANISH_PARAGUAY 0x0f
1006 # ifndef SUBLANG_SPANISH_BOLIVIA
1007 # define SUBLANG_SPANISH_BOLIVIA 0x10
1009 # ifndef SUBLANG_SPANISH_EL_SALVADOR
1010 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
1012 # ifndef SUBLANG_SPANISH_HONDURAS
1013 # define SUBLANG_SPANISH_HONDURAS 0x12
1015 # ifndef SUBLANG_SPANISH_NICARAGUA
1016 # define SUBLANG_SPANISH_NICARAGUA 0x13
1018 # ifndef SUBLANG_SPANISH_PUERTO_RICO
1019 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
1021 # ifndef SUBLANG_SPANISH_US
1022 # define SUBLANG_SPANISH_US 0x15
1024 # ifndef SUBLANG_SWAHILI_KENYA
1025 # define SUBLANG_SWAHILI_KENYA 0x01
1027 # ifndef SUBLANG_SWEDISH_SWEDEN
1028 # define SUBLANG_SWEDISH_SWEDEN 0x01
1030 # ifndef SUBLANG_SWEDISH_FINLAND
1031 # define SUBLANG_SWEDISH_FINLAND 0x02
1033 # ifndef SUBLANG_SYRIAC_SYRIA
1034 # define SUBLANG_SYRIAC_SYRIA 0x01
1036 # ifndef SUBLANG_TAGALOG_PHILIPPINES
1037 # define SUBLANG_TAGALOG_PHILIPPINES 0x01
1039 # ifndef SUBLANG_TAJIK_TAJIKISTAN
1040 # define SUBLANG_TAJIK_TAJIKISTAN 0x01
1042 # ifndef SUBLANG_TAMAZIGHT_ARABIC
1043 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
1045 # ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
1046 # define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
1048 # ifndef SUBLANG_TAMIL_INDIA
1049 # define SUBLANG_TAMIL_INDIA 0x01
1051 # ifndef SUBLANG_TATAR_RUSSIA
1052 # define SUBLANG_TATAR_RUSSIA 0x01
1054 # ifndef SUBLANG_TELUGU_INDIA
1055 # define SUBLANG_TELUGU_INDIA 0x01
1057 # ifndef SUBLANG_THAI_THAILAND
1058 # define SUBLANG_THAI_THAILAND 0x01
1060 # ifndef SUBLANG_TIBETAN_PRC
1061 # define SUBLANG_TIBETAN_PRC 0x01
1063 # undef SUBLANG_TIBETAN_BHUTAN
1064 # define SUBLANG_TIBETAN_BHUTAN 0x02
1065 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
1066 # define SUBLANG_TIGRINYA_ETHIOPIA 0x01
1068 # ifndef SUBLANG_TIGRINYA_ERITREA
1069 # define SUBLANG_TIGRINYA_ERITREA 0x02
1071 # ifndef SUBLANG_TSWANA_SOUTH_AFRICA
1072 # define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
1074 # ifndef SUBLANG_TURKISH_TURKEY
1075 # define SUBLANG_TURKISH_TURKEY 0x01
1077 # ifndef SUBLANG_TURKMEN_TURKMENISTAN
1078 # define SUBLANG_TURKMEN_TURKMENISTAN 0x01
1080 # ifndef SUBLANG_UIGHUR_PRC
1081 # define SUBLANG_UIGHUR_PRC 0x01
1083 # ifndef SUBLANG_UKRAINIAN_UKRAINE
1084 # define SUBLANG_UKRAINIAN_UKRAINE 0x01
1086 # ifndef SUBLANG_UPPER_SORBIAN_GERMANY
1087 # define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
1089 # ifndef SUBLANG_URDU_PAKISTAN
1090 # define SUBLANG_URDU_PAKISTAN 0x01
1092 # ifndef SUBLANG_URDU_INDIA
1093 # define SUBLANG_URDU_INDIA 0x02
1095 # ifndef SUBLANG_UZBEK_LATIN
1096 # define SUBLANG_UZBEK_LATIN 0x01
1098 # ifndef SUBLANG_UZBEK_CYRILLIC
1099 # define SUBLANG_UZBEK_CYRILLIC 0x02
1101 # ifndef SUBLANG_VIETNAMESE_VIETNAM
1102 # define SUBLANG_VIETNAMESE_VIETNAM 0x01
1104 # ifndef SUBLANG_WELSH_UNITED_KINGDOM
1105 # define SUBLANG_WELSH_UNITED_KINGDOM 0x01
1107 # ifndef SUBLANG_WOLOF_SENEGAL
1108 # define SUBLANG_WOLOF_SENEGAL 0x01
1110 # ifndef SUBLANG_XHOSA_SOUTH_AFRICA
1111 # define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
1113 # ifndef SUBLANG_YAKUT_RUSSIA
1114 # define SUBLANG_YAKUT_RUSSIA 0x01
1116 # ifndef SUBLANG_YI_PRC
1117 # define SUBLANG_YI_PRC 0x01
1119 # ifndef SUBLANG_YORUBA_NIGERIA
1120 # define SUBLANG_YORUBA_NIGERIA 0x01
1122 # ifndef SUBLANG_ZULU_SOUTH_AFRICA
1123 # define SUBLANG_ZULU_SOUTH_AFRICA 0x01
1125 /* GetLocaleInfoA operations. */
1126 # ifndef LOCALE_SNAME
1127 # define LOCALE_SNAME 0x5c
1132 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1133 /* MacOS X 10.2 or newer */
1135 /* Canonicalize a MacOS X locale name to a Unix locale name.
1136 NAME is a sufficiently large buffer.
1137 On input, it contains the MacOS X locale name.
1138 On output, it contains the Unix locale name. */
1139 # if !defined IN_LIBINTL
1143 gl_locale_name_canonicalize (char *name
)
1145 /* This conversion is based on a posting by
1146 Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
1147 http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
1149 /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
1150 ISO 3166) names. Prior to MacOS X 10.3, there is no API for doing this.
1151 Therefore we do it ourselves, using a table based on the results of the
1152 MacOS X 10.3.8 function
1153 CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
1154 typedef struct { const char legacy
[21+1]; const char unixy
[5+1]; }
1156 static const legacy_entry legacy_table
[] = {
1157 { "Afrikaans", "af" },
1158 { "Albanian", "sq" },
1159 { "Amharic", "am" },
1161 { "Armenian", "hy" },
1162 { "Assamese", "as" },
1164 { "Azerbaijani", "az" },
1166 { "Belarusian", "be" },
1167 { "Belorussian", "be" },
1168 { "Bengali", "bn" },
1169 { "Brazilian Portugese", "pt_BR" },
1170 { "Brazilian Portuguese", "pt_BR" },
1172 { "Bulgarian", "bg" },
1173 { "Burmese", "my" },
1174 { "Byelorussian", "be" },
1175 { "Catalan", "ca" },
1177 { "Chichewa", "ny" },
1178 { "Chinese", "zh" },
1179 { "Chinese, Simplified", "zh_CN" },
1180 { "Chinese, Traditional", "zh_TW" },
1181 { "Chinese, Tradtional", "zh_TW" },
1182 { "Croatian", "hr" },
1186 { "Dzongkha", "dz" },
1187 { "English", "en" },
1188 { "Esperanto", "eo" },
1189 { "Estonian", "et" },
1190 { "Faroese", "fo" },
1192 { "Finnish", "fi" },
1193 { "Flemish", "nl_BE" },
1195 { "Galician", "gl" },
1196 { "Gallegan", "gl" },
1197 { "Georgian", "ka" },
1200 { "Greenlandic", "kl" },
1201 { "Guarani", "gn" },
1202 { "Gujarati", "gu" },
1203 { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
1206 { "Hungarian", "hu" },
1207 { "Icelandic", "is" },
1208 { "Indonesian", "id" },
1209 { "Inuktitut", "iu" },
1211 { "Italian", "it" },
1212 { "Japanese", "ja" },
1213 { "Javanese", "jv" },
1214 { "Kalaallisut", "kl" },
1215 { "Kannada", "kn" },
1216 { "Kashmiri", "ks" },
1219 { "Kinyarwanda", "rw" },
1220 { "Kirghiz", "ky" },
1222 { "Kurdish", "ku" },
1224 { "Latvian", "lv" },
1225 { "Lithuanian", "lt" },
1226 { "Macedonian", "mk" },
1227 { "Malagasy", "mg" },
1229 { "Malayalam", "ml" },
1230 { "Maltese", "mt" },
1232 { "Marathi", "mr" },
1233 { "Moldavian", "mo" },
1234 { "Mongolian", "mn" },
1236 { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
1238 { "Nynorsk", "nn" },
1241 { "Panjabi", "pa" },
1243 { "Persian", "fa" },
1245 { "Portuguese", "pt" },
1246 { "Portuguese, Brazilian", "pt_BR" },
1247 { "Punjabi", "pa" },
1249 { "Quechua", "qu" },
1250 { "Romanian", "ro" },
1253 { "Russian", "ru" },
1254 { "Sami", "se_NO" }, /* Not just "se". */
1255 { "Sanskrit", "sa" },
1256 { "Scottish", "gd" },
1257 { "Serbian", "sr" },
1258 { "Simplified Chinese", "zh_CN" },
1260 { "Sinhalese", "si" },
1262 { "Slovenian", "sl" },
1264 { "Spanish", "es" },
1265 { "Sundanese", "su" },
1266 { "Swahili", "sw" },
1267 { "Swedish", "sv" },
1268 { "Tagalog", "tl" },
1275 { "Tibetan", "bo" },
1276 { "Tigrinya", "ti" },
1278 { "Traditional Chinese", "zh_TW" },
1279 { "Turkish", "tr" },
1280 { "Turkmen", "tk" },
1282 { "Ukrainian", "uk" },
1285 { "Vietnamese", "vi" },
1290 /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
1291 to Unix (ISO 639 and ISO 3166) names. */
1292 typedef struct { const char langtag
[7+1]; const char unixy
[12+1]; }
1294 static const langtag_entry langtag_table
[] = {
1295 /* MacOS X has "az-Arab", "az-Cyrl", "az-Latn".
1296 The default script for az on Unix is Latin. */
1297 { "az-Latn", "az" },
1298 /* MacOS X has "ga-dots". Does not yet exist on Unix. */
1299 { "ga-dots", "ga" },
1300 /* MacOS X has "kk-Cyrl". Does not yet exist on Unix. */
1301 /* MacOS X has "mn-Cyrl", "mn-Mong".
1302 The default script for mn on Unix is Cyrillic. */
1303 { "mn-Cyrl", "mn" },
1304 /* MacOS X has "ms-Arab", "ms-Latn".
1305 The default script for ms on Unix is Latin. */
1306 { "ms-Latn", "ms" },
1307 /* MacOS X has "tg-Cyrl".
1308 The default script for tg on Unix is Cyrillic. */
1309 { "tg-Cyrl", "tg" },
1310 /* MacOS X has "tk-Cyrl". Does not yet exist on Unix. */
1311 /* MacOS X has "tt-Cyrl".
1312 The default script for tt on Unix is Cyrillic. */
1313 { "tt-Cyrl", "tt" },
1314 /* MacOS X has "zh-Hans", "zh-Hant".
1315 Country codes are used to distinguish these on Unix. */
1316 { "zh-Hans", "zh_CN" },
1317 { "zh-Hant", "zh_TW" }
1320 /* Convert script names (ISO 15924) to Unix conventions.
1321 See http://www.unicode.org/iso15924/iso15924-codes.html */
1322 typedef struct { const char script
[4+1]; const char unixy
[9+1]; }
1324 static const script_entry script_table
[] = {
1325 { "Arab", "arabic" },
1326 { "Cyrl", "cyrillic" },
1327 { "Mong", "mongolian" }
1330 /* Step 1: Convert using legacy_table. */
1331 if (name
[0] >= 'A' && name
[0] <= 'Z')
1333 unsigned int i1
, i2
;
1335 i2
= sizeof (legacy_table
) / sizeof (legacy_entry
);
1338 /* At this point we know that if name occurs in legacy_table,
1339 its index must be >= i1 and < i2. */
1340 unsigned int i
= (i1
+ i2
) >> 1;
1341 const legacy_entry
*p
= &legacy_table
[i
];
1342 if (strcmp (name
, p
->legacy
) < 0)
1347 if (strcmp (name
, legacy_table
[i1
].legacy
) == 0)
1349 strcpy (name
, legacy_table
[i1
].unixy
);
1354 /* Step 2: Convert using langtag_table and script_table. */
1355 if (strlen (name
) == 7 && name
[2] == '-')
1357 unsigned int i1
, i2
;
1359 i2
= sizeof (langtag_table
) / sizeof (langtag_entry
);
1362 /* At this point we know that if name occurs in langtag_table,
1363 its index must be >= i1 and < i2. */
1364 unsigned int i
= (i1
+ i2
) >> 1;
1365 const langtag_entry
*p
= &langtag_table
[i
];
1366 if (strcmp (name
, p
->langtag
) < 0)
1371 if (strcmp (name
, langtag_table
[i1
].langtag
) == 0)
1373 strcpy (name
, langtag_table
[i1
].unixy
);
1378 i2
= sizeof (script_table
) / sizeof (script_entry
);
1381 /* At this point we know that if (name + 3) occurs in script_table,
1382 its index must be >= i1 and < i2. */
1383 unsigned int i
= (i1
+ i2
) >> 1;
1384 const script_entry
*p
= &script_table
[i
];
1385 if (strcmp (name
+ 3, p
->script
) < 0)
1390 if (strcmp (name
+ 3, script_table
[i1
].script
) == 0)
1393 strcpy (name
+ 3, script_table
[i1
].unixy
);
1398 /* Step 3: Convert new-style dash to Unix underscore. */
1401 for (p
= name
; *p
!= '\0'; p
++)
1410 #if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
1412 /* Canonicalize a Win32 native locale name to a Unix locale name.
1413 NAME is a sufficiently large buffer.
1414 On input, it contains the Win32 locale name.
1415 On output, it contains the Unix locale name. */
1416 # if !defined IN_LIBINTL
1420 gl_locale_name_canonicalize (char *name
)
1422 /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
1426 for (p
= name
; *p
!= '\0'; p
++)
1431 for (; *p
!= '\0'; p
++)
1433 if (*p
>= 'a' && *p
<= 'z')
1445 # if !defined IN_LIBINTL
1449 gl_locale_name_from_win32_LANGID (LANGID langid
)
1451 /* Activate the new code only when the GETTEXT_MUI environment variable is
1452 set, for the time being, since the new code is not well tested. */
1453 if (getenv ("GETTEXT_MUI") != NULL
)
1455 static char namebuf
[256];
1457 /* Query the system's notion of locale name.
1458 On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
1459 But we don't need to support systems that are so old. */
1460 if (GetLocaleInfoA (MAKELCID (langid
, SORT_DEFAULT
), LOCALE_SNAME
,
1461 namebuf
, sizeof (namebuf
) - 1))
1463 /* Convert it to a Unix locale name. */
1464 gl_locale_name_canonicalize (namebuf
);
1468 /* Internet Explorer has an LCID to RFC3066 name mapping stored in
1469 HKEY_CLASSES_ROOT\Mime\Database\Rfc1766. But we better don't use that
1470 since IE's i18n subsystem is known to be inconsistent with the Win32 base
1471 (e.g. they have different character conversion facilities that produce
1472 different results). */
1473 /* Use our own table. */
1477 /* Split into language and territory part. */
1478 primary
= PRIMARYLANGID (langid
);
1479 sub
= SUBLANGID (langid
);
1481 /* Dispatch on language.
1482 See also http://www.unicode.org/unicode/onlinedat/languages.html .
1483 For details about languages, see http://www.ethnologue.com/ . */
1486 case LANG_AFRIKAANS
:
1489 case SUBLANG_AFRIKAANS_SOUTH_AFRICA
: return "af_ZA";
1495 case SUBLANG_ALBANIAN_ALBANIA
: return "sq_AL";
1501 case SUBLANG_ALSATIAN_FRANCE
: return "gsw_FR";
1507 case SUBLANG_AMHARIC_ETHIOPIA
: return "am_ET";
1513 case SUBLANG_ARABIC_SAUDI_ARABIA
: return "ar_SA";
1514 case SUBLANG_ARABIC_IRAQ
: return "ar_IQ";
1515 case SUBLANG_ARABIC_EGYPT
: return "ar_EG";
1516 case SUBLANG_ARABIC_LIBYA
: return "ar_LY";
1517 case SUBLANG_ARABIC_ALGERIA
: return "ar_DZ";
1518 case SUBLANG_ARABIC_MOROCCO
: return "ar_MA";
1519 case SUBLANG_ARABIC_TUNISIA
: return "ar_TN";
1520 case SUBLANG_ARABIC_OMAN
: return "ar_OM";
1521 case SUBLANG_ARABIC_YEMEN
: return "ar_YE";
1522 case SUBLANG_ARABIC_SYRIA
: return "ar_SY";
1523 case SUBLANG_ARABIC_JORDAN
: return "ar_JO";
1524 case SUBLANG_ARABIC_LEBANON
: return "ar_LB";
1525 case SUBLANG_ARABIC_KUWAIT
: return "ar_KW";
1526 case SUBLANG_ARABIC_UAE
: return "ar_AE";
1527 case SUBLANG_ARABIC_BAHRAIN
: return "ar_BH";
1528 case SUBLANG_ARABIC_QATAR
: return "ar_QA";
1534 case SUBLANG_ARMENIAN_ARMENIA
: return "hy_AM";
1540 case SUBLANG_ASSAMESE_INDIA
: return "as_IN";
1546 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
1547 case 0x1e: return "az@latin";
1548 case SUBLANG_AZERI_LATIN
: return "az_AZ@latin";
1549 case 0x1d: return "az@cyrillic";
1550 case SUBLANG_AZERI_CYRILLIC
: return "az_AZ@cyrillic";
1556 case SUBLANG_BASHKIR_RUSSIA
: return "ba_RU";
1562 case SUBLANG_BASQUE_BASQUE
: return "eu_ES";
1564 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
1565 case LANG_BELARUSIAN
:
1568 case SUBLANG_BELARUSIAN_BELARUS
: return "be_BY";
1574 case SUBLANG_BENGALI_INDIA
: return "bn_IN";
1575 case SUBLANG_BENGALI_BANGLADESH
: return "bn_BD";
1581 case SUBLANG_BRETON_FRANCE
: return "br_FR";
1584 case LANG_BULGARIAN
:
1587 case SUBLANG_BULGARIAN_BULGARIA
: return "bg_BG";
1593 case SUBLANG_DEFAULT
: return "my_MM";
1596 case LANG_CAMBODIAN
:
1599 case SUBLANG_CAMBODIAN_CAMBODIA
: return "km_KH";
1605 case SUBLANG_CATALAN_SPAIN
: return "ca_ES";
1611 case SUBLANG_DEFAULT
: return "chr_US";
1617 case SUBLANG_CHINESE_TRADITIONAL
: case 0x1f: return "zh_TW";
1618 case SUBLANG_CHINESE_SIMPLIFIED
: case 0x00: return "zh_CN";
1619 case SUBLANG_CHINESE_HONGKONG
: return "zh_HK"; /* traditional */
1620 case SUBLANG_CHINESE_SINGAPORE
: return "zh_SG"; /* simplified */
1621 case SUBLANG_CHINESE_MACAU
: return "zh_MO"; /* traditional */
1627 case SUBLANG_CORSICAN_FRANCE
: return "co_FR";
1630 case LANG_CROATIAN
: /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
1631 * What used to be called Serbo-Croatian
1632 * should really now be two separate
1633 * languages because of political reasons.
1634 * (Says tml, who knows nothing about Serbian
1636 * (I can feel those flames coming already.)
1641 case 0x00: return "hr";
1642 case SUBLANG_CROATIAN_CROATIA
: return "hr_HR";
1643 case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
: return "hr_BA";
1645 case 0x1f: return "sr";
1646 case 0x1c: return "sr"; /* latin */
1647 case SUBLANG_SERBIAN_LATIN
: return "sr_CS"; /* latin */
1648 case 0x09: return "sr_RS"; /* latin */
1649 case 0x0b: return "sr_ME"; /* latin */
1650 case 0x06: return "sr_BA"; /* latin */
1651 case 0x1b: return "sr@cyrillic";
1652 case SUBLANG_SERBIAN_CYRILLIC
: return "sr_CS@cyrillic";
1653 case 0x0a: return "sr_RS@cyrillic";
1654 case 0x0c: return "sr_ME@cyrillic";
1655 case 0x07: return "sr_BA@cyrillic";
1657 case 0x1e: return "bs";
1658 case 0x1a: return "bs"; /* latin */
1659 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
: return "bs_BA"; /* latin */
1660 case 0x19: return "bs@cyrillic";
1661 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
: return "bs_BA@cyrillic";
1667 case SUBLANG_CZECH_CZECH_REPUBLIC
: return "cs_CZ";
1673 case SUBLANG_DANISH_DENMARK
: return "da_DK";
1677 /* FIXME: Adjust this when such locales appear on Unix. */
1680 case SUBLANG_DARI_AFGHANISTAN
: return "prs_AF";
1686 case SUBLANG_DIVEHI_MALDIVES
: return "dv_MV";
1692 case SUBLANG_DUTCH
: return "nl_NL";
1693 case SUBLANG_DUTCH_BELGIAN
: /* FLEMISH, VLAAMS */ return "nl_BE";
1694 case SUBLANG_DUTCH_SURINAM
: return "nl_SR";
1700 case SUBLANG_DEFAULT
: return "bin_NG";
1706 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1707 * English was the language spoken in England.
1710 case SUBLANG_ENGLISH_US
: return "en_US";
1711 case SUBLANG_ENGLISH_UK
: return "en_GB";
1712 case SUBLANG_ENGLISH_AUS
: return "en_AU";
1713 case SUBLANG_ENGLISH_CAN
: return "en_CA";
1714 case SUBLANG_ENGLISH_NZ
: return "en_NZ";
1715 case SUBLANG_ENGLISH_EIRE
: return "en_IE";
1716 case SUBLANG_ENGLISH_SOUTH_AFRICA
: return "en_ZA";
1717 case SUBLANG_ENGLISH_JAMAICA
: return "en_JM";
1718 case SUBLANG_ENGLISH_CARIBBEAN
: return "en_GD"; /* Grenada? */
1719 case SUBLANG_ENGLISH_BELIZE
: return "en_BZ";
1720 case SUBLANG_ENGLISH_TRINIDAD
: return "en_TT";
1721 case SUBLANG_ENGLISH_ZIMBABWE
: return "en_ZW";
1722 case SUBLANG_ENGLISH_PHILIPPINES
: return "en_PH";
1723 case SUBLANG_ENGLISH_INDONESIA
: return "en_ID";
1724 case SUBLANG_ENGLISH_HONGKONG
: return "en_HK";
1725 case SUBLANG_ENGLISH_INDIA
: return "en_IN";
1726 case SUBLANG_ENGLISH_MALAYSIA
: return "en_MY";
1727 case SUBLANG_ENGLISH_SINGAPORE
: return "en_SG";
1733 case SUBLANG_ESTONIAN_ESTONIA
: return "et_EE";
1739 case SUBLANG_FAEROESE_FAROE_ISLANDS
: return "fo_FO";
1745 case SUBLANG_FARSI_IRAN
: return "fa_IR";
1751 case SUBLANG_FINNISH_FINLAND
: return "fi_FI";
1757 case SUBLANG_FRENCH
: return "fr_FR";
1758 case SUBLANG_FRENCH_BELGIAN
: /* WALLOON */ return "fr_BE";
1759 case SUBLANG_FRENCH_CANADIAN
: return "fr_CA";
1760 case SUBLANG_FRENCH_SWISS
: return "fr_CH";
1761 case SUBLANG_FRENCH_LUXEMBOURG
: return "fr_LU";
1762 case SUBLANG_FRENCH_MONACO
: return "fr_MC";
1763 case SUBLANG_FRENCH_WESTINDIES
: return "fr"; /* Caribbean? */
1764 case SUBLANG_FRENCH_REUNION
: return "fr_RE";
1765 case SUBLANG_FRENCH_CONGO
: return "fr_CG";
1766 case SUBLANG_FRENCH_SENEGAL
: return "fr_SN";
1767 case SUBLANG_FRENCH_CAMEROON
: return "fr_CM";
1768 case SUBLANG_FRENCH_COTEDIVOIRE
: return "fr_CI";
1769 case SUBLANG_FRENCH_MALI
: return "fr_ML";
1770 case SUBLANG_FRENCH_MOROCCO
: return "fr_MA";
1771 case SUBLANG_FRENCH_HAITI
: return "fr_HT";
1777 case SUBLANG_FRISIAN_NETHERLANDS
: return "fy_NL";
1781 /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
1784 case SUBLANG_DEFAULT
: return "ff_NG";
1790 case 0x01: /* SCOTTISH */
1791 /* old, superseded by LANG_SCOTTISH_GAELIC */
1793 case SUBLANG_IRISH_IRELAND
: return "ga_IE";
1799 case SUBLANG_GALICIAN_SPAIN
: return "gl_ES";
1805 case SUBLANG_GEORGIAN_GEORGIA
: return "ka_GE";
1811 case SUBLANG_GERMAN
: return "de_DE";
1812 case SUBLANG_GERMAN_SWISS
: return "de_CH";
1813 case SUBLANG_GERMAN_AUSTRIAN
: return "de_AT";
1814 case SUBLANG_GERMAN_LUXEMBOURG
: return "de_LU";
1815 case SUBLANG_GERMAN_LIECHTENSTEIN
: return "de_LI";
1821 case SUBLANG_GREEK_GREECE
: return "el_GR";
1824 case LANG_GREENLANDIC
:
1827 case SUBLANG_GREENLANDIC_GREENLAND
: return "kl_GL";
1833 case SUBLANG_DEFAULT
: return "gn_PY";
1839 case SUBLANG_GUJARATI_INDIA
: return "gu_IN";
1845 case 0x1f: return "ha";
1846 case SUBLANG_HAUSA_NIGERIA_LATIN
: return "ha_NG";
1850 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1851 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
1854 case SUBLANG_DEFAULT
: return "cpe_US";
1860 case SUBLANG_HEBREW_ISRAEL
: return "he_IL";
1866 case SUBLANG_HINDI_INDIA
: return "hi_IN";
1869 case LANG_HUNGARIAN
:
1872 case SUBLANG_HUNGARIAN_HUNGARY
: return "hu_HU";
1878 case SUBLANG_DEFAULT
: return "nic_NG";
1881 case LANG_ICELANDIC
:
1884 case SUBLANG_ICELANDIC_ICELAND
: return "is_IS";
1890 case SUBLANG_IGBO_NIGERIA
: return "ig_NG";
1893 case LANG_INDONESIAN
:
1896 case SUBLANG_INDONESIAN_INDONESIA
: return "id_ID";
1899 case LANG_INUKTITUT
:
1902 case 0x1e: return "iu"; /* syllabic */
1903 case SUBLANG_INUKTITUT_CANADA
: return "iu_CA"; /* syllabic */
1904 case 0x1f: return "iu@latin";
1905 case SUBLANG_INUKTITUT_CANADA_LATIN
: return "iu_CA@latin";
1911 case SUBLANG_ITALIAN
: return "it_IT";
1912 case SUBLANG_ITALIAN_SWISS
: return "it_CH";
1918 case SUBLANG_JAPANESE_JAPAN
: return "ja_JP";
1924 case SUBLANG_KANNADA_INDIA
: return "kn_IN";
1930 case SUBLANG_DEFAULT
: return "kr_NG";
1936 case SUBLANG_DEFAULT
: return "ks_PK";
1937 case SUBLANG_KASHMIRI_INDIA
: return "ks_IN";
1943 case SUBLANG_KAZAK_KAZAKHSTAN
: return "kk_KZ";
1947 /* FIXME: Adjust this when such locales appear on Unix. */
1950 case SUBLANG_KICHE_GUATEMALA
: return "qut_GT";
1953 case LANG_KINYARWANDA
:
1956 case SUBLANG_KINYARWANDA_RWANDA
: return "rw_RW";
1960 /* FIXME: Adjust this when such locales appear on Unix. */
1963 case SUBLANG_KONKANI_INDIA
: return "kok_IN";
1969 case SUBLANG_DEFAULT
: return "ko_KR";
1975 case SUBLANG_KYRGYZ_KYRGYZSTAN
: return "ky_KG";
1981 case SUBLANG_LAO_LAOS
: return "lo_LA";
1987 case SUBLANG_DEFAULT
: return "la_VA";
1993 case SUBLANG_LATVIAN_LATVIA
: return "lv_LV";
1996 case LANG_LITHUANIAN
:
1999 case SUBLANG_LITHUANIAN_LITHUANIA
: return "lt_LT";
2002 case LANG_LUXEMBOURGISH
:
2005 case SUBLANG_LUXEMBOURGISH_LUXEMBOURG
: return "lb_LU";
2008 case LANG_MACEDONIAN
:
2011 case SUBLANG_MACEDONIAN_MACEDONIA
: return "mk_MK";
2017 case SUBLANG_MALAY_MALAYSIA
: return "ms_MY";
2018 case SUBLANG_MALAY_BRUNEI_DARUSSALAM
: return "ms_BN";
2021 case LANG_MALAYALAM
:
2024 case SUBLANG_MALAYALAM_INDIA
: return "ml_IN";
2030 case SUBLANG_MALTESE_MALTA
: return "mt_MT";
2034 /* FIXME: Adjust this when such locales appear on Unix. */
2037 case SUBLANG_DEFAULT
: return "mni_IN";
2043 case SUBLANG_MAORI_NEW_ZEALAND
: return "mi_NZ";
2046 case LANG_MAPUDUNGUN
:
2049 case SUBLANG_MAPUDUNGUN_CHILE
: return "arn_CL";
2055 case SUBLANG_MARATHI_INDIA
: return "mr_IN";
2061 case SUBLANG_MOHAWK_CANADA
: return "moh_CA";
2064 case LANG_MONGOLIAN
:
2067 case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
: case 0x1e: return "mn_MN";
2068 case SUBLANG_MONGOLIAN_PRC
: case 0x1f: return "mn_CN";
2070 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
2074 case SUBLANG_NEPALI_NEPAL
: return "ne_NP";
2075 case SUBLANG_NEPALI_INDIA
: return "ne_IN";
2078 case LANG_NORWEGIAN
:
2081 case 0x1f: return "nb";
2082 case SUBLANG_NORWEGIAN_BOKMAL
: return "nb_NO";
2083 case 0x1e: return "nn";
2084 case SUBLANG_NORWEGIAN_NYNORSK
: return "nn_NO";
2090 case SUBLANG_OCCITAN_FRANCE
: return "oc_FR";
2096 case SUBLANG_ORIYA_INDIA
: return "or_IN";
2102 case SUBLANG_DEFAULT
: return "om_ET";
2105 case LANG_PAPIAMENTU
:
2108 case SUBLANG_DEFAULT
: return "pap_AN";
2114 case SUBLANG_PASHTO_AFGHANISTAN
: return "ps_AF";
2116 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
2120 case SUBLANG_POLISH_POLAND
: return "pl_PL";
2123 case LANG_PORTUGUESE
:
2126 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
2127 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
2128 case SUBLANG_PORTUGUESE_BRAZILIAN
: return "pt_BR";
2129 case SUBLANG_PORTUGUESE
: return "pt_PT";
2135 case SUBLANG_PUNJABI_INDIA
: return "pa_IN"; /* Gurmukhi script */
2136 case SUBLANG_PUNJABI_PAKISTAN
: return "pa_PK"; /* Arabic script */
2140 /* Note: Microsoft uses the non-ISO language code "quz". */
2143 case SUBLANG_QUECHUA_BOLIVIA
: return "qu_BO";
2144 case SUBLANG_QUECHUA_ECUADOR
: return "qu_EC";
2145 case SUBLANG_QUECHUA_PERU
: return "qu_PE";
2151 case SUBLANG_ROMANIAN_ROMANIA
: return "ro_RO";
2152 case SUBLANG_ROMANIAN_MOLDOVA
: return "ro_MD";
2158 case SUBLANG_ROMANSH_SWITZERLAND
: return "rm_CH";
2164 case SUBLANG_RUSSIAN_RUSSIA
: return "ru_RU";
2165 case SUBLANG_RUSSIAN_MOLDAVIA
: return "ru_MD";
2167 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
2172 case 0x00: return "se";
2173 case SUBLANG_SAMI_NORTHERN_NORWAY
: return "se_NO";
2174 case SUBLANG_SAMI_NORTHERN_SWEDEN
: return "se_SE";
2175 case SUBLANG_SAMI_NORTHERN_FINLAND
: return "se_FI";
2177 case 0x1f: return "smj";
2178 case SUBLANG_SAMI_LULE_NORWAY
: return "smj_NO";
2179 case SUBLANG_SAMI_LULE_SWEDEN
: return "smj_SE";
2181 case 0x1e: return "sma";
2182 case SUBLANG_SAMI_SOUTHERN_NORWAY
: return "sma_NO";
2183 case SUBLANG_SAMI_SOUTHERN_SWEDEN
: return "sma_SE";
2185 case 0x1d: return "sms";
2186 case SUBLANG_SAMI_SKOLT_FINLAND
: return "sms_FI";
2188 case 0x1c: return "smn";
2189 case SUBLANG_SAMI_INARI_FINLAND
: return "smn_FI";
2191 return "se"; /* or "smi"? */
2195 case SUBLANG_SANSKRIT_INDIA
: return "sa_IN";
2198 case LANG_SCOTTISH_GAELIC
:
2201 case SUBLANG_DEFAULT
: return "gd_GB";
2207 case SUBLANG_SINDHI_INDIA
: return "sd_IN";
2208 case SUBLANG_SINDHI_PAKISTAN
: return "sd_PK";
2209 /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
2212 case LANG_SINHALESE
:
2215 case SUBLANG_SINHALESE_SRI_LANKA
: return "si_LK";
2221 case SUBLANG_SLOVAK_SLOVAKIA
: return "sk_SK";
2224 case LANG_SLOVENIAN
:
2227 case SUBLANG_SLOVENIAN_SLOVENIA
: return "sl_SI";
2233 case SUBLANG_DEFAULT
: return "so_SO";
2237 /* FIXME: Adjust this when such locales appear on Unix. */
2241 case 0x00: return "hsb";
2242 case SUBLANG_UPPER_SORBIAN_GERMANY
: return "hsb_DE";
2244 case 0x1f: return "dsb";
2245 case SUBLANG_LOWER_SORBIAN_GERMANY
: return "dsb_DE";
2249 /* <http://www.microsoft.com/globaldev/reference/lcid-all.mspx> calls
2250 it "Sepedi"; according to
2251 <http://www.ethnologue.com/show_language.asp?code=nso>
2252 <http://www.ethnologue.com/show_language.asp?code=sot>
2253 it's the same as Northern Sotho. */
2256 case SUBLANG_SOTHO_SOUTH_AFRICA
: return "nso_ZA";
2262 case SUBLANG_SPANISH
: return "es_ES";
2263 case SUBLANG_SPANISH_MEXICAN
: return "es_MX";
2264 case SUBLANG_SPANISH_MODERN
:
2265 return "es_ES@modern"; /* not seen on Unix */
2266 case SUBLANG_SPANISH_GUATEMALA
: return "es_GT";
2267 case SUBLANG_SPANISH_COSTA_RICA
: return "es_CR";
2268 case SUBLANG_SPANISH_PANAMA
: return "es_PA";
2269 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC
: return "es_DO";
2270 case SUBLANG_SPANISH_VENEZUELA
: return "es_VE";
2271 case SUBLANG_SPANISH_COLOMBIA
: return "es_CO";
2272 case SUBLANG_SPANISH_PERU
: return "es_PE";
2273 case SUBLANG_SPANISH_ARGENTINA
: return "es_AR";
2274 case SUBLANG_SPANISH_ECUADOR
: return "es_EC";
2275 case SUBLANG_SPANISH_CHILE
: return "es_CL";
2276 case SUBLANG_SPANISH_URUGUAY
: return "es_UY";
2277 case SUBLANG_SPANISH_PARAGUAY
: return "es_PY";
2278 case SUBLANG_SPANISH_BOLIVIA
: return "es_BO";
2279 case SUBLANG_SPANISH_EL_SALVADOR
: return "es_SV";
2280 case SUBLANG_SPANISH_HONDURAS
: return "es_HN";
2281 case SUBLANG_SPANISH_NICARAGUA
: return "es_NI";
2282 case SUBLANG_SPANISH_PUERTO_RICO
: return "es_PR";
2283 case SUBLANG_SPANISH_US
: return "es_US";
2289 case SUBLANG_DEFAULT
: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
2295 case SUBLANG_SWAHILI_KENYA
: return "sw_KE";
2301 case SUBLANG_SWEDISH_SWEDEN
: return "sv_SE";
2302 case SUBLANG_SWEDISH_FINLAND
: return "sv_FI";
2308 case SUBLANG_SYRIAC_SYRIA
: return "syr_SY"; /* An extinct language. */
2314 case SUBLANG_TAGALOG_PHILIPPINES
: return "tl_PH"; /* or "fil_PH"? */
2316 return "tl"; /* or "fil"? */
2320 case 0x1f: return "tg";
2321 case SUBLANG_TAJIK_TAJIKISTAN
: return "tg_TJ";
2324 case LANG_TAMAZIGHT
:
2325 /* Note: Microsoft uses the non-ISO language code "tmz". */
2328 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
2329 case SUBLANG_TAMAZIGHT_ARABIC
: return "ber_MA@arabic";
2330 case 0x1f: return "ber@latin";
2331 case SUBLANG_TAMAZIGHT_ALGERIA_LATIN
: return "ber_DZ@latin";
2337 case SUBLANG_TAMIL_INDIA
: return "ta_IN";
2339 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
2343 case SUBLANG_TATAR_RUSSIA
: return "tt_RU";
2349 case SUBLANG_TELUGU_INDIA
: return "te_IN";
2355 case SUBLANG_THAI_THAILAND
: return "th_TH";
2361 case SUBLANG_TIBETAN_PRC
:
2362 /* Most Tibetans would not like "bo_CN". But Tibet does not yet
2363 have a country code of its own. */
2365 case SUBLANG_TIBETAN_BHUTAN
: return "bo_BT";
2371 case SUBLANG_TIGRINYA_ETHIOPIA
: return "ti_ET";
2372 case SUBLANG_TIGRINYA_ERITREA
: return "ti_ER";
2378 case SUBLANG_DEFAULT
: return "ts_ZA";
2382 /* Spoken in South Africa, Botswana. */
2385 case SUBLANG_TSWANA_SOUTH_AFRICA
: return "tn_ZA";
2391 case SUBLANG_TURKISH_TURKEY
: return "tr_TR";
2397 case SUBLANG_TURKMEN_TURKMENISTAN
: return "tk_TM";
2403 case SUBLANG_UIGHUR_PRC
: return "ug_CN";
2406 case LANG_UKRAINIAN
:
2409 case SUBLANG_UKRAINIAN_UKRAINE
: return "uk_UA";
2415 case SUBLANG_URDU_PAKISTAN
: return "ur_PK";
2416 case SUBLANG_URDU_INDIA
: return "ur_IN";
2422 case 0x1f: return "uz";
2423 case SUBLANG_UZBEK_LATIN
: return "uz_UZ";
2424 case 0x1e: return "uz@cyrillic";
2425 case SUBLANG_UZBEK_CYRILLIC
: return "uz_UZ@cyrillic";
2431 case SUBLANG_DEFAULT
: return "ve_ZA";
2434 case LANG_VIETNAMESE
:
2437 case SUBLANG_VIETNAMESE_VIETNAM
: return "vi_VN";
2443 case SUBLANG_WELSH_UNITED_KINGDOM
: return "cy_GB";
2449 case SUBLANG_WOLOF_SENEGAL
: return "wo_SN";
2455 case SUBLANG_XHOSA_SOUTH_AFRICA
: return "xh_ZA";
2461 case SUBLANG_YAKUT_RUSSIA
: return "sah_RU";
2467 case SUBLANG_YI_PRC
: return "ii_CN";
2473 case SUBLANG_DEFAULT
: return "yi_IL";
2479 case SUBLANG_YORUBA_NIGERIA
: return "yo_NG";
2485 case SUBLANG_ZULU_SOUTH_AFRICA
: return "zu_ZA";
2488 default: return "C";
2493 # if !defined IN_LIBINTL
2497 gl_locale_name_from_win32_LCID (LCID lcid
)
2501 /* Strip off the sorting rules, keep only the language part. */
2502 langid
= LANGIDFROMLCID (lcid
);
2504 return gl_locale_name_from_win32_LANGID (langid
);
2510 #if HAVE_USELOCALE /* glibc or MacOS X */
2512 /* Simple hash set of strings. We don't want to drag in lots of hash table
2515 # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
2517 /* A hash function for NUL-terminated char* strings using
2518 the method described by Bruno Haible.
2519 See http://www.haible.de/bruno/hashfunc.html. */
2521 string_hash (const void *x
)
2523 const char *s
= (const char *) x
;
2527 h
= *s
+ ((h
<< 9) | (h
>> (SIZE_BITS
- 9)));
2532 /* A hash table of fixed size. Multiple threads can access it read-only
2533 simultaneously, but only one thread can insert into it at the same time. */
2535 /* A node in a hash bucket collision list. */
2538 struct hash_node
* volatile next
;
2539 char contents
[100]; /* has variable size */
2542 # define HASH_TABLE_SIZE 257
2543 static struct hash_node
* volatile struniq_hash_table
[HASH_TABLE_SIZE
]
2544 /* = { NULL, ..., NULL } */;
2546 /* This lock protects the struniq_hash_table against multiple simultaneous
2548 gl_lock_define_initialized(static, struniq_lock
)
2550 /* Store a copy of the given string in a string pool with indefinite extent.
2551 Return a pointer to this copy. */
2553 struniq (const char *string
)
2555 size_t hashcode
= string_hash (string
);
2556 size_t slot
= hashcode
% HASH_TABLE_SIZE
;
2558 struct hash_node
*new_node
;
2559 struct hash_node
*p
;
2560 for (p
= struniq_hash_table
[slot
]; p
!= NULL
; p
= p
->next
)
2561 if (strcmp (p
->contents
, string
) == 0)
2563 size
= strlen (string
) + 1;
2565 (struct hash_node
*)
2566 malloc (offsetof (struct hash_node
, contents
[0]) + size
);
2567 if (new_node
== NULL
)
2568 /* Out of memory. Return a statically allocated string. */
2570 memcpy (new_node
->contents
, string
, size
);
2571 /* Lock while inserting new_node. */
2572 gl_lock_lock (struniq_lock
);
2573 /* Check whether another thread already added the string while we were
2574 waiting on the lock. */
2575 for (p
= struniq_hash_table
[slot
]; p
!= NULL
; p
= p
->next
)
2576 if (strcmp (p
->contents
, string
) == 0)
2582 /* Really insert new_node into the hash table. Fill new_node entirely first,
2583 because other threads may be iterating over the linked list. */
2584 new_node
->next
= struniq_hash_table
[slot
];
2585 struniq_hash_table
[slot
] = new_node
;
2587 /* Unlock after new_node is inserted. */
2588 gl_lock_unlock (struniq_lock
);
2589 return new_node
->contents
;
2595 #if defined IN_LIBINTL || HAVE_USELOCALE
2597 /* Like gl_locale_name_thread, except that the result is not in storage of
2598 indefinite extent. */
2599 # if !defined IN_LIBINTL
2603 gl_locale_name_thread_unsafe (int category
, const char *categoryname
)
2607 locale_t thread_locale
= uselocale (NULL
);
2608 if (thread_locale
!= LC_GLOBAL_LOCALE
)
2611 /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
2613 See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>. */
2615 nl_langinfo (_NL_ITEM ((category
), _NL_ITEM_INDEX (-1)));
2616 if (name
[0] == '\0')
2617 /* Fallback code for glibc < 2.4, which did not implement
2618 nl_langinfo (_NL_LOCALE_NAME (category)). */
2619 name
= thread_locale
->__names
[category
];
2622 # if defined __APPLE__ && defined __MACH__ /* MacOS X */
2623 /* The locale name is found deep in an undocumented data structure.
2624 Since it's stored in a buffer of size 32 and newlocale() rejects
2625 locale names of length > 31, we can assume that it is NUL terminated
2626 in this buffer. But we need to make a copy of the locale name, of
2627 indefinite extent. */
2628 struct _xlocale_part1_v0
/* used in MacOS X 10.5 */
2631 void (*__free_extra
)(void *);
2632 __darwin_mbstate_t __mbs
[10];
2635 struct _xlocale_part1_v1
/* used in MacOS X >= 10.6.0 */
2638 void (*__free_extra
)(void *);
2639 __darwin_mbstate_t __mbs
[10];
2640 /*pthread_lock_t*/ int __lock
;
2643 struct _xlocale_part2
2646 unsigned char __collate_load_error
;
2647 unsigned char __collate_substitute_nontrivial
;
2648 unsigned char _messages_using_locale
;
2649 unsigned char _monetary_using_locale
;
2650 unsigned char _numeric_using_locale
;
2651 unsigned char _time_using_locale
;
2652 unsigned char __mlocale_changed
;
2653 unsigned char __nlocale_changed
;
2654 unsigned char __numeric_fp_cvt
;
2655 struct __xlocale_st_collate
*__lc_collate
;
2656 struct __xlocale_st_runelocale
*__lc_ctype
;
2657 struct __xlocale_st_messages
*__lc_messages
;
2658 struct __xlocale_st_monetary
*__lc_monetary
;
2659 struct __xlocale_st_numeric
*__lc_numeric
;
2660 struct _xlocale
*__lc_numeric_loc
;
2661 struct __xlocale_st_time
*__lc_time
;
2664 struct __xlocale_st_collate
2667 void (*__free_extra
)(void *);
2668 char __encoding
[32];
2671 struct __xlocale_st_runelocale
2674 void (*__free_extra
)(void *);
2675 char __ctype_encoding
[32];
2678 struct __xlocale_st_messages
2681 void (*__free_extra
)(void *);
2682 char *_messages_locale_buf
;
2685 struct __xlocale_st_monetary
2688 void (*__free_extra
)(void *);
2689 char *_monetary_locale_buf
;
2692 struct __xlocale_st_numeric
{
2694 void (*__free_extra
)(void *);
2695 char *_numeric_locale_buf
;
2698 struct __xlocale_st_time
{
2700 void (*__free_extra
)(void *);
2701 char *_time_locale_buf
;
2704 struct _xlocale_part2
*tlp
;
2705 if (((struct _xlocale_part1_v0
*) thread_locale
)->__magic
2706 == 0x786C6F63616C6530LL
)
2709 (struct _xlocale_part2
*)
2710 &((struct _xlocale_part1_v0
*) thread_locale
)->__magic
;
2711 else if (((struct _xlocale_part1_v1
*) thread_locale
)->__magic
2712 == 0x786C6F63616C6530LL
)
2713 /* MacOS X >= 10.6.0 */
2715 (struct _xlocale_part2
*)
2716 &((struct _xlocale_part1_v1
*) thread_locale
)->__magic
;
2718 /* Unsupported version of MacOS X: The internals of 'struct _xlocale'
2719 have changed again. */
2724 return tlp
->__lc_ctype
->__ctype_encoding
;
2726 return tlp
->_numeric_using_locale
2727 ? tlp
->__lc_numeric
->_numeric_locale_buf
2730 return tlp
->_time_using_locale
2731 ? tlp
->__lc_time
->_time_locale_buf
2734 return !tlp
->__collate_load_error
2735 ? tlp
->__lc_collate
->__encoding
2738 return tlp
->_monetary_using_locale
2739 ? tlp
->__lc_monetary
->_monetary_locale_buf
2742 return tlp
->_messages_using_locale
2743 ? tlp
->__lc_messages
->_messages_locale_buf
2745 default: /* We shouldn't get here. */
2758 gl_locale_name_thread (int category
, const char *categoryname
)
2761 const char *name
= gl_locale_name_thread_unsafe (category
, categoryname
);
2763 return struniq (name
);
2768 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
2769 "Directs 'setlocale()' to query 'category' and return the current
2770 setting of 'local'."
2771 However it does not specify the exact format. Neither do SUSV2 and
2772 ISO C 99. So we can use this feature only on selected systems (e.g.
2773 those using GNU C Library). */
2774 #if defined _LIBC || (defined __GLIBC__ && __GLIBC__ >= 2)
2775 # define HAVE_LOCALE_NULL
2779 gl_locale_name_posix (int category
, const char *categoryname
)
2781 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
2782 On some systems this can be done by the 'setlocale' function itself. */
2783 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
2784 return setlocale (category
, NULL
);
2786 /* On other systems we ignore what setlocale reports and instead look at the
2787 environment variables directly. This is necessary
2788 1. on systems which have a facility for customizing the default locale
2789 (MacOS X, native Windows, Cygwin) and where the system's setlocale()
2790 function ignores this default locale (MacOS X, Cygwin), in two cases:
2791 a. when the user missed to use the setlocale() override from libintl
2792 (for example by not including <libintl.h>),
2793 b. when setlocale supports only the "C" locale, such as on Cygwin
2794 1.5.x. In this case even the override from libintl cannot help.
2795 2. on all systems where setlocale supports only the "C" locale. */
2796 /* Strictly speaking, it is a POSIX violation to look at the environment
2797 variables regardless whether setlocale has been called or not. POSIX
2799 "For C-language programs, the POSIX locale shall be the
2800 default locale when the setlocale() function is not called."
2801 But we assume that all programs that use internationalized APIs call
2802 setlocale (LC_ALL, ""). */
2803 return gl_locale_name_environ (category
, categoryname
);
2808 gl_locale_name_environ (int category
, const char *categoryname
)
2812 /* Setting of LC_ALL overrides all other. */
2813 retval
= getenv ("LC_ALL");
2814 if (retval
!= NULL
&& retval
[0] != '\0')
2816 /* Next comes the name of the desired category. */
2817 retval
= getenv (categoryname
);
2818 if (retval
!= NULL
&& retval
[0] != '\0')
2820 /* Last possibility is the LANG environment variable. */
2821 retval
= getenv ("LANG");
2822 if (retval
!= NULL
&& retval
[0] != '\0')
2824 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2825 /* MacOS X 10.2 or newer.
2826 Ignore invalid LANG value set by the Terminal application. */
2827 if (strcmp (retval
, "UTF-8") != 0)
2829 #if defined __CYGWIN__
2831 Ignore dummy LANG value set by ~/.profile. */
2832 if (strcmp (retval
, "C.UTF-8") != 0)
2841 gl_locale_name_default (void)
2844 "All implementations shall define a locale as the default locale, to be
2845 invoked when no environment variables are set, or set to the empty
2846 string. This default locale can be the POSIX locale or any other
2847 implementation-defined locale. Some implementations may provide
2848 facilities for local installation administrators to set the default
2849 locale, customizing it for each location. POSIX:2001 does not require
2852 The systems with such a facility are MacOS X and Windows: They provide a
2853 GUI that allows the user to choose a locale.
2854 - On MacOS X, by default, none of LC_* or LANG are set. Starting with
2855 MacOS X 10.4 or 10.5, LANG is set for processes launched by the
2856 'Terminal' application (but sometimes to an incorrect value "UTF-8").
2857 When no environment variable is set, setlocale (LC_ALL, "") uses the
2859 - On native Windows, by default, none of LC_* or LANG are set.
2860 When no environment variable is set, setlocale (LC_ALL, "") uses the
2861 locale chosen by the user.
2862 - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
2863 When no environment variable is set, setlocale (LC_ALL, "") uses the
2865 - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
2866 ~/.profile is executed.
2867 When no environment variable is set, setlocale (LC_ALL, "") uses the
2868 "C.UTF-8" locale, which operates in the same way as the "C" locale.
2871 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WIN32_NATIVE || defined __CYGWIN__)
2873 /* The system does not have a way of setting the locale, other than the
2874 POSIX specified environment variables. We use C as default locale. */
2879 /* Return an XPG style locale name language[_territory][@modifier].
2880 Don't even bother determining the codeset; it's not useful in this
2881 context, because message catalogs are not specific to a single
2884 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2885 /* MacOS X 10.2 or newer */
2887 /* Cache the locale name, since CoreFoundation calls are expensive. */
2888 static const char *cached_localename
;
2890 if (cached_localename
== NULL
)
2893 # if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
2894 CFLocaleRef locale
= CFLocaleCopyCurrent ();
2895 CFStringRef name
= CFLocaleGetIdentifier (locale
);
2897 if (CFStringGetCString (name
, namebuf
, sizeof (namebuf
),
2898 kCFStringEncodingASCII
))
2900 gl_locale_name_canonicalize (namebuf
);
2901 cached_localename
= strdup (namebuf
);
2904 # elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
2906 CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
2907 kCFPreferencesCurrentApplication
);
2909 && CFGetTypeID (value
) == CFStringGetTypeID ()
2910 && CFStringGetCString ((CFStringRef
)value
,
2911 namebuf
, sizeof (namebuf
),
2912 kCFStringEncodingASCII
))
2914 gl_locale_name_canonicalize (namebuf
);
2915 cached_localename
= strdup (namebuf
);
2918 if (cached_localename
== NULL
)
2919 cached_localename
= "C";
2921 return cached_localename
;
2926 # if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
2930 /* Use native Win32 API locale ID. */
2931 lcid
= GetThreadLocale ();
2933 return gl_locale_name_from_win32_LCID (lcid
);
2939 /* Determine the current locale's name, and canonicalize it into XPG syntax
2940 language[_territory][.codeset][@modifier]
2941 The codeset part in the result is not reliable; the locale_charset()
2942 should be used for codeset information instead.
2943 The result must not be freed; it is statically allocated. */
2946 gl_locale_name (int category
, const char *categoryname
)
2950 retval
= gl_locale_name_thread (category
, categoryname
);
2954 retval
= gl_locale_name_posix (category
, categoryname
);
2958 return gl_locale_name_default ();