1 /* Determine name of the currently selected locale.
2 Copyright (C) 1995-2015 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */
18 /* Native Windows code written by Tor Lillqvist <tml@iki.fi>. */
19 /* Mac OS X code written by Bruno Haible <bruno@clisp.org>. */
25 # include "gettextP.h"
27 # include "localename.h"
37 /* Mac OS X 10.5 defines the locale_t type in <xlocale.h>. */
38 # if defined __APPLE__ && defined __MACH__
41 # if __GLIBC__ >= 2 && !defined __UCLIBC__
42 # include <langinfo.h>
44 # if !defined IN_LIBINTL
45 # include "glthread/lock.h"
47 # if defined __sun && HAVE_GETLOCALENAME_L
49 extern char * getlocalename_l(int, locale_t);
53 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
54 # include <CoreFoundation/CFString.h>
55 # if HAVE_CFLOCALECOPYCURRENT
56 # include <CoreFoundation/CFLocale.h>
57 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
58 # include <CoreFoundation/CFPreferences.h>
62 #if defined _WIN32 || defined __WIN32__
63 # define WINDOWS_NATIVE
64 # if !defined IN_LIBINTL
65 # include "glthread/lock.h"
69 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
70 # define WIN32_LEAN_AND_MEAN
73 /* List of language codes, sorted by value:
99 0x1a LANG_CROATIAN == LANG_SERBIAN
181 0x6e LANG_LUXEMBOURGISH
182 0x6f LANG_GREENLANDIC
201 0x87 LANG_KINYARWANDA
204 0x91 LANG_SCOTTISH_GAELIC
206 /* Mingw headers don't have latest language and sublanguage codes. */
207 # ifndef LANG_AFRIKAANS
208 # define LANG_AFRIKAANS 0x36
210 # ifndef LANG_ALBANIAN
211 # define LANG_ALBANIAN 0x1c
213 # ifndef LANG_ALSATIAN
214 # define LANG_ALSATIAN 0x84
216 # ifndef LANG_AMHARIC
217 # define LANG_AMHARIC 0x5e
220 # define LANG_ARABIC 0x01
222 # ifndef LANG_ARMENIAN
223 # define LANG_ARMENIAN 0x2b
225 # ifndef LANG_ASSAMESE
226 # define LANG_ASSAMESE 0x4d
229 # define LANG_AZERI 0x2c
231 # ifndef LANG_BASHKIR
232 # define LANG_BASHKIR 0x6d
235 # define LANG_BASQUE 0x2d
237 # ifndef LANG_BELARUSIAN
238 # define LANG_BELARUSIAN 0x23
240 # ifndef LANG_BENGALI
241 # define LANG_BENGALI 0x45
244 # define LANG_BRETON 0x7e
246 # ifndef LANG_BURMESE
247 # define LANG_BURMESE 0x55
249 # ifndef LANG_CAMBODIAN
250 # define LANG_CAMBODIAN 0x53
252 # ifndef LANG_CATALAN
253 # define LANG_CATALAN 0x03
255 # ifndef LANG_CHEROKEE
256 # define LANG_CHEROKEE 0x5c
258 # ifndef LANG_CORSICAN
259 # define LANG_CORSICAN 0x83
262 # define LANG_DARI 0x8c
265 # define LANG_DIVEHI 0x65
268 # define LANG_EDO 0x66
270 # ifndef LANG_ESTONIAN
271 # define LANG_ESTONIAN 0x25
273 # ifndef LANG_FAEROESE
274 # define LANG_FAEROESE 0x38
277 # define LANG_FARSI 0x29
279 # ifndef LANG_FRISIAN
280 # define LANG_FRISIAN 0x62
282 # ifndef LANG_FULFULDE
283 # define LANG_FULFULDE 0x67
286 # define LANG_GAELIC 0x3c
288 # ifndef LANG_GALICIAN
289 # define LANG_GALICIAN 0x56
291 # ifndef LANG_GEORGIAN
292 # define LANG_GEORGIAN 0x37
294 # ifndef LANG_GREENLANDIC
295 # define LANG_GREENLANDIC 0x6f
297 # ifndef LANG_GUARANI
298 # define LANG_GUARANI 0x74
300 # ifndef LANG_GUJARATI
301 # define LANG_GUJARATI 0x47
304 # define LANG_HAUSA 0x68
306 # ifndef LANG_HAWAIIAN
307 # define LANG_HAWAIIAN 0x75
310 # define LANG_HEBREW 0x0d
313 # define LANG_HINDI 0x39
316 # define LANG_IBIBIO 0x69
319 # define LANG_IGBO 0x70
321 # ifndef LANG_INDONESIAN
322 # define LANG_INDONESIAN 0x21
324 # ifndef LANG_INUKTITUT
325 # define LANG_INUKTITUT 0x5d
327 # ifndef LANG_KANNADA
328 # define LANG_KANNADA 0x4b
331 # define LANG_KANURI 0x71
333 # ifndef LANG_KASHMIRI
334 # define LANG_KASHMIRI 0x60
337 # define LANG_KAZAK 0x3f
340 # define LANG_KICHE 0x86
342 # ifndef LANG_KINYARWANDA
343 # define LANG_KINYARWANDA 0x87
345 # ifndef LANG_KONKANI
346 # define LANG_KONKANI 0x57
349 # define LANG_KYRGYZ 0x40
352 # define LANG_LAO 0x54
355 # define LANG_LATIN 0x76
357 # ifndef LANG_LATVIAN
358 # define LANG_LATVIAN 0x26
360 # ifndef LANG_LITHUANIAN
361 # define LANG_LITHUANIAN 0x27
363 # ifndef LANG_LUXEMBOURGISH
364 # define LANG_LUXEMBOURGISH 0x6e
366 # ifndef LANG_MACEDONIAN
367 # define LANG_MACEDONIAN 0x2f
370 # define LANG_MALAY 0x3e
372 # ifndef LANG_MALAYALAM
373 # define LANG_MALAYALAM 0x4c
375 # ifndef LANG_MALTESE
376 # define LANG_MALTESE 0x3a
378 # ifndef LANG_MANIPURI
379 # define LANG_MANIPURI 0x58
382 # define LANG_MAORI 0x81
384 # ifndef LANG_MAPUDUNGUN
385 # define LANG_MAPUDUNGUN 0x7a
387 # ifndef LANG_MARATHI
388 # define LANG_MARATHI 0x4e
391 # define LANG_MOHAWK 0x7c
393 # ifndef LANG_MONGOLIAN
394 # define LANG_MONGOLIAN 0x50
397 # define LANG_NEPALI 0x61
399 # ifndef LANG_OCCITAN
400 # define LANG_OCCITAN 0x82
403 # define LANG_ORIYA 0x48
406 # define LANG_OROMO 0x72
408 # ifndef LANG_PAPIAMENTU
409 # define LANG_PAPIAMENTU 0x79
412 # define LANG_PASHTO 0x63
414 # ifndef LANG_PUNJABI
415 # define LANG_PUNJABI 0x46
417 # ifndef LANG_QUECHUA
418 # define LANG_QUECHUA 0x6b
420 # ifndef LANG_ROMANSH
421 # define LANG_ROMANSH 0x17
424 # define LANG_SAMI 0x3b
426 # ifndef LANG_SANSKRIT
427 # define LANG_SANSKRIT 0x4f
429 # ifndef LANG_SCOTTISH_GAELIC
430 # define LANG_SCOTTISH_GAELIC 0x91
432 # ifndef LANG_SERBIAN
433 # define LANG_SERBIAN 0x1a
436 # define LANG_SINDHI 0x59
438 # ifndef LANG_SINHALESE
439 # define LANG_SINHALESE 0x5b
442 # define LANG_SLOVAK 0x1b
445 # define LANG_SOMALI 0x77
447 # ifndef LANG_SORBIAN
448 # define LANG_SORBIAN 0x2e
451 # define LANG_SOTHO 0x6c
454 # define LANG_SUTU 0x30
456 # ifndef LANG_SWAHILI
457 # define LANG_SWAHILI 0x41
460 # define LANG_SYRIAC 0x5a
462 # ifndef LANG_TAGALOG
463 # define LANG_TAGALOG 0x64
466 # define LANG_TAJIK 0x28
468 # ifndef LANG_TAMAZIGHT
469 # define LANG_TAMAZIGHT 0x5f
472 # define LANG_TAMIL 0x49
475 # define LANG_TATAR 0x44
478 # define LANG_TELUGU 0x4a
481 # define LANG_THAI 0x1e
483 # ifndef LANG_TIBETAN
484 # define LANG_TIBETAN 0x51
486 # ifndef LANG_TIGRINYA
487 # define LANG_TIGRINYA 0x73
490 # define LANG_TSONGA 0x31
493 # define LANG_TSWANA 0x32
495 # ifndef LANG_TURKMEN
496 # define LANG_TURKMEN 0x42
499 # define LANG_UIGHUR 0x80
501 # ifndef LANG_UKRAINIAN
502 # define LANG_UKRAINIAN 0x22
505 # define LANG_URDU 0x20
508 # define LANG_UZBEK 0x43
511 # define LANG_VENDA 0x33
513 # ifndef LANG_VIETNAMESE
514 # define LANG_VIETNAMESE 0x2a
517 # define LANG_WELSH 0x52
520 # define LANG_WOLOF 0x88
523 # define LANG_XHOSA 0x34
526 # define LANG_YAKUT 0x85
529 # define LANG_YI 0x78
531 # ifndef LANG_YIDDISH
532 # define LANG_YIDDISH 0x3d
535 # define LANG_YORUBA 0x6a
538 # define LANG_ZULU 0x35
540 # ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
541 # define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
543 # ifndef SUBLANG_ALBANIAN_ALBANIA
544 # define SUBLANG_ALBANIAN_ALBANIA 0x01
546 # ifndef SUBLANG_ALSATIAN_FRANCE
547 # define SUBLANG_ALSATIAN_FRANCE 0x01
549 # ifndef SUBLANG_AMHARIC_ETHIOPIA
550 # define SUBLANG_AMHARIC_ETHIOPIA 0x01
552 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
553 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
555 # ifndef SUBLANG_ARABIC_IRAQ
556 # define SUBLANG_ARABIC_IRAQ 0x02
558 # ifndef SUBLANG_ARABIC_EGYPT
559 # define SUBLANG_ARABIC_EGYPT 0x03
561 # ifndef SUBLANG_ARABIC_LIBYA
562 # define SUBLANG_ARABIC_LIBYA 0x04
564 # ifndef SUBLANG_ARABIC_ALGERIA
565 # define SUBLANG_ARABIC_ALGERIA 0x05
567 # ifndef SUBLANG_ARABIC_MOROCCO
568 # define SUBLANG_ARABIC_MOROCCO 0x06
570 # ifndef SUBLANG_ARABIC_TUNISIA
571 # define SUBLANG_ARABIC_TUNISIA 0x07
573 # ifndef SUBLANG_ARABIC_OMAN
574 # define SUBLANG_ARABIC_OMAN 0x08
576 # ifndef SUBLANG_ARABIC_YEMEN
577 # define SUBLANG_ARABIC_YEMEN 0x09
579 # ifndef SUBLANG_ARABIC_SYRIA
580 # define SUBLANG_ARABIC_SYRIA 0x0a
582 # ifndef SUBLANG_ARABIC_JORDAN
583 # define SUBLANG_ARABIC_JORDAN 0x0b
585 # ifndef SUBLANG_ARABIC_LEBANON
586 # define SUBLANG_ARABIC_LEBANON 0x0c
588 # ifndef SUBLANG_ARABIC_KUWAIT
589 # define SUBLANG_ARABIC_KUWAIT 0x0d
591 # ifndef SUBLANG_ARABIC_UAE
592 # define SUBLANG_ARABIC_UAE 0x0e
594 # ifndef SUBLANG_ARABIC_BAHRAIN
595 # define SUBLANG_ARABIC_BAHRAIN 0x0f
597 # ifndef SUBLANG_ARABIC_QATAR
598 # define SUBLANG_ARABIC_QATAR 0x10
600 # ifndef SUBLANG_ARMENIAN_ARMENIA
601 # define SUBLANG_ARMENIAN_ARMENIA 0x01
603 # ifndef SUBLANG_ASSAMESE_INDIA
604 # define SUBLANG_ASSAMESE_INDIA 0x01
606 # ifndef SUBLANG_AZERI_LATIN
607 # define SUBLANG_AZERI_LATIN 0x01
609 # ifndef SUBLANG_AZERI_CYRILLIC
610 # define SUBLANG_AZERI_CYRILLIC 0x02
612 # ifndef SUBLANG_BASHKIR_RUSSIA
613 # define SUBLANG_BASHKIR_RUSSIA 0x01
615 # ifndef SUBLANG_BASQUE_BASQUE
616 # define SUBLANG_BASQUE_BASQUE 0x01
618 # ifndef SUBLANG_BELARUSIAN_BELARUS
619 # define SUBLANG_BELARUSIAN_BELARUS 0x01
621 # ifndef SUBLANG_BENGALI_INDIA
622 # define SUBLANG_BENGALI_INDIA 0x01
624 # ifndef SUBLANG_BENGALI_BANGLADESH
625 # define SUBLANG_BENGALI_BANGLADESH 0x02
627 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
628 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
630 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
631 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
633 # ifndef SUBLANG_BRETON_FRANCE
634 # define SUBLANG_BRETON_FRANCE 0x01
636 # ifndef SUBLANG_BULGARIAN_BULGARIA
637 # define SUBLANG_BULGARIAN_BULGARIA 0x01
639 # ifndef SUBLANG_CAMBODIAN_CAMBODIA
640 # define SUBLANG_CAMBODIAN_CAMBODIA 0x01
642 # ifndef SUBLANG_CATALAN_SPAIN
643 # define SUBLANG_CATALAN_SPAIN 0x01
645 # ifndef SUBLANG_CORSICAN_FRANCE
646 # define SUBLANG_CORSICAN_FRANCE 0x01
648 # ifndef SUBLANG_CROATIAN_CROATIA
649 # define SUBLANG_CROATIAN_CROATIA 0x01
651 # ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
652 # define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
654 # ifndef SUBLANG_CHINESE_MACAU
655 # define SUBLANG_CHINESE_MACAU 0x05
657 # ifndef SUBLANG_CZECH_CZECH_REPUBLIC
658 # define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
660 # ifndef SUBLANG_DANISH_DENMARK
661 # define SUBLANG_DANISH_DENMARK 0x01
663 # ifndef SUBLANG_DARI_AFGHANISTAN
664 # define SUBLANG_DARI_AFGHANISTAN 0x01
666 # ifndef SUBLANG_DIVEHI_MALDIVES
667 # define SUBLANG_DIVEHI_MALDIVES 0x01
669 # ifndef SUBLANG_DUTCH_SURINAM
670 # define SUBLANG_DUTCH_SURINAM 0x03
672 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
673 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
675 # ifndef SUBLANG_ENGLISH_JAMAICA
676 # define SUBLANG_ENGLISH_JAMAICA 0x08
678 # ifndef SUBLANG_ENGLISH_CARIBBEAN
679 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
681 # ifndef SUBLANG_ENGLISH_BELIZE
682 # define SUBLANG_ENGLISH_BELIZE 0x0a
684 # ifndef SUBLANG_ENGLISH_TRINIDAD
685 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
687 # ifndef SUBLANG_ENGLISH_ZIMBABWE
688 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
690 # ifndef SUBLANG_ENGLISH_PHILIPPINES
691 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
693 # ifndef SUBLANG_ENGLISH_INDONESIA
694 # define SUBLANG_ENGLISH_INDONESIA 0x0e
696 # ifndef SUBLANG_ENGLISH_HONGKONG
697 # define SUBLANG_ENGLISH_HONGKONG 0x0f
699 # ifndef SUBLANG_ENGLISH_INDIA
700 # define SUBLANG_ENGLISH_INDIA 0x10
702 # ifndef SUBLANG_ENGLISH_MALAYSIA
703 # define SUBLANG_ENGLISH_MALAYSIA 0x11
705 # ifndef SUBLANG_ENGLISH_SINGAPORE
706 # define SUBLANG_ENGLISH_SINGAPORE 0x12
708 # ifndef SUBLANG_ESTONIAN_ESTONIA
709 # define SUBLANG_ESTONIAN_ESTONIA 0x01
711 # ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
712 # define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
714 # ifndef SUBLANG_FARSI_IRAN
715 # define SUBLANG_FARSI_IRAN 0x01
717 # ifndef SUBLANG_FINNISH_FINLAND
718 # define SUBLANG_FINNISH_FINLAND 0x01
720 # ifndef SUBLANG_FRENCH_LUXEMBOURG
721 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
723 # ifndef SUBLANG_FRENCH_MONACO
724 # define SUBLANG_FRENCH_MONACO 0x06
726 # ifndef SUBLANG_FRENCH_WESTINDIES
727 # define SUBLANG_FRENCH_WESTINDIES 0x07
729 # ifndef SUBLANG_FRENCH_REUNION
730 # define SUBLANG_FRENCH_REUNION 0x08
732 # ifndef SUBLANG_FRENCH_CONGO
733 # define SUBLANG_FRENCH_CONGO 0x09
735 # ifndef SUBLANG_FRENCH_SENEGAL
736 # define SUBLANG_FRENCH_SENEGAL 0x0a
738 # ifndef SUBLANG_FRENCH_CAMEROON
739 # define SUBLANG_FRENCH_CAMEROON 0x0b
741 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
742 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
744 # ifndef SUBLANG_FRENCH_MALI
745 # define SUBLANG_FRENCH_MALI 0x0d
747 # ifndef SUBLANG_FRENCH_MOROCCO
748 # define SUBLANG_FRENCH_MOROCCO 0x0e
750 # ifndef SUBLANG_FRENCH_HAITI
751 # define SUBLANG_FRENCH_HAITI 0x0f
753 # ifndef SUBLANG_FRISIAN_NETHERLANDS
754 # define SUBLANG_FRISIAN_NETHERLANDS 0x01
756 # ifndef SUBLANG_GALICIAN_SPAIN
757 # define SUBLANG_GALICIAN_SPAIN 0x01
759 # ifndef SUBLANG_GEORGIAN_GEORGIA
760 # define SUBLANG_GEORGIAN_GEORGIA 0x01
762 # ifndef SUBLANG_GERMAN_LUXEMBOURG
763 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
765 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
766 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
768 # ifndef SUBLANG_GREEK_GREECE
769 # define SUBLANG_GREEK_GREECE 0x01
771 # ifndef SUBLANG_GREENLANDIC_GREENLAND
772 # define SUBLANG_GREENLANDIC_GREENLAND 0x01
774 # ifndef SUBLANG_GUJARATI_INDIA
775 # define SUBLANG_GUJARATI_INDIA 0x01
777 # ifndef SUBLANG_HAUSA_NIGERIA_LATIN
778 # define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
780 # ifndef SUBLANG_HEBREW_ISRAEL
781 # define SUBLANG_HEBREW_ISRAEL 0x01
783 # ifndef SUBLANG_HINDI_INDIA
784 # define SUBLANG_HINDI_INDIA 0x01
786 # ifndef SUBLANG_HUNGARIAN_HUNGARY
787 # define SUBLANG_HUNGARIAN_HUNGARY 0x01
789 # ifndef SUBLANG_ICELANDIC_ICELAND
790 # define SUBLANG_ICELANDIC_ICELAND 0x01
792 # ifndef SUBLANG_IGBO_NIGERIA
793 # define SUBLANG_IGBO_NIGERIA 0x01
795 # ifndef SUBLANG_INDONESIAN_INDONESIA
796 # define SUBLANG_INDONESIAN_INDONESIA 0x01
798 # ifndef SUBLANG_INUKTITUT_CANADA
799 # define SUBLANG_INUKTITUT_CANADA 0x01
801 # undef SUBLANG_INUKTITUT_CANADA_LATIN
802 # define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
803 # undef SUBLANG_IRISH_IRELAND
804 # define SUBLANG_IRISH_IRELAND 0x02
805 # ifndef SUBLANG_JAPANESE_JAPAN
806 # define SUBLANG_JAPANESE_JAPAN 0x01
808 # ifndef SUBLANG_KANNADA_INDIA
809 # define SUBLANG_KANNADA_INDIA 0x01
811 # ifndef SUBLANG_KASHMIRI_INDIA
812 # define SUBLANG_KASHMIRI_INDIA 0x02
814 # ifndef SUBLANG_KAZAK_KAZAKHSTAN
815 # define SUBLANG_KAZAK_KAZAKHSTAN 0x01
817 # ifndef SUBLANG_KICHE_GUATEMALA
818 # define SUBLANG_KICHE_GUATEMALA 0x01
820 # ifndef SUBLANG_KINYARWANDA_RWANDA
821 # define SUBLANG_KINYARWANDA_RWANDA 0x01
823 # ifndef SUBLANG_KONKANI_INDIA
824 # define SUBLANG_KONKANI_INDIA 0x01
826 # ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
827 # define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
829 # ifndef SUBLANG_LAO_LAOS
830 # define SUBLANG_LAO_LAOS 0x01
832 # ifndef SUBLANG_LATVIAN_LATVIA
833 # define SUBLANG_LATVIAN_LATVIA 0x01
835 # ifndef SUBLANG_LITHUANIAN_LITHUANIA
836 # define SUBLANG_LITHUANIAN_LITHUANIA 0x01
838 # undef SUBLANG_LOWER_SORBIAN_GERMANY
839 # define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
840 # ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
841 # define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
843 # ifndef SUBLANG_MACEDONIAN_MACEDONIA
844 # define SUBLANG_MACEDONIAN_MACEDONIA 0x01
846 # ifndef SUBLANG_MALAY_MALAYSIA
847 # define SUBLANG_MALAY_MALAYSIA 0x01
849 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
850 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
852 # ifndef SUBLANG_MALAYALAM_INDIA
853 # define SUBLANG_MALAYALAM_INDIA 0x01
855 # ifndef SUBLANG_MALTESE_MALTA
856 # define SUBLANG_MALTESE_MALTA 0x01
858 # ifndef SUBLANG_MAORI_NEW_ZEALAND
859 # define SUBLANG_MAORI_NEW_ZEALAND 0x01
861 # ifndef SUBLANG_MAPUDUNGUN_CHILE
862 # define SUBLANG_MAPUDUNGUN_CHILE 0x01
864 # ifndef SUBLANG_MARATHI_INDIA
865 # define SUBLANG_MARATHI_INDIA 0x01
867 # ifndef SUBLANG_MOHAWK_CANADA
868 # define SUBLANG_MOHAWK_CANADA 0x01
870 # ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
871 # define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
873 # ifndef SUBLANG_MONGOLIAN_PRC
874 # define SUBLANG_MONGOLIAN_PRC 0x02
876 # ifndef SUBLANG_NEPALI_NEPAL
877 # define SUBLANG_NEPALI_NEPAL 0x01
879 # ifndef SUBLANG_NEPALI_INDIA
880 # define SUBLANG_NEPALI_INDIA 0x02
882 # ifndef SUBLANG_OCCITAN_FRANCE
883 # define SUBLANG_OCCITAN_FRANCE 0x01
885 # ifndef SUBLANG_ORIYA_INDIA
886 # define SUBLANG_ORIYA_INDIA 0x01
888 # ifndef SUBLANG_PASHTO_AFGHANISTAN
889 # define SUBLANG_PASHTO_AFGHANISTAN 0x01
891 # ifndef SUBLANG_POLISH_POLAND
892 # define SUBLANG_POLISH_POLAND 0x01
894 # ifndef SUBLANG_PUNJABI_INDIA
895 # define SUBLANG_PUNJABI_INDIA 0x01
897 # ifndef SUBLANG_PUNJABI_PAKISTAN
898 # define SUBLANG_PUNJABI_PAKISTAN 0x02
900 # ifndef SUBLANG_QUECHUA_BOLIVIA
901 # define SUBLANG_QUECHUA_BOLIVIA 0x01
903 # ifndef SUBLANG_QUECHUA_ECUADOR
904 # define SUBLANG_QUECHUA_ECUADOR 0x02
906 # ifndef SUBLANG_QUECHUA_PERU
907 # define SUBLANG_QUECHUA_PERU 0x03
909 # ifndef SUBLANG_ROMANIAN_ROMANIA
910 # define SUBLANG_ROMANIAN_ROMANIA 0x01
912 # ifndef SUBLANG_ROMANIAN_MOLDOVA
913 # define SUBLANG_ROMANIAN_MOLDOVA 0x02
915 # ifndef SUBLANG_ROMANSH_SWITZERLAND
916 # define SUBLANG_ROMANSH_SWITZERLAND 0x01
918 # ifndef SUBLANG_RUSSIAN_RUSSIA
919 # define SUBLANG_RUSSIAN_RUSSIA 0x01
921 # ifndef SUBLANG_RUSSIAN_MOLDAVIA
922 # define SUBLANG_RUSSIAN_MOLDAVIA 0x02
924 # ifndef SUBLANG_SAMI_NORTHERN_NORWAY
925 # define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
927 # ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
928 # define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
930 # ifndef SUBLANG_SAMI_NORTHERN_FINLAND
931 # define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
933 # ifndef SUBLANG_SAMI_LULE_NORWAY
934 # define SUBLANG_SAMI_LULE_NORWAY 0x04
936 # ifndef SUBLANG_SAMI_LULE_SWEDEN
937 # define SUBLANG_SAMI_LULE_SWEDEN 0x05
939 # ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
940 # define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
942 # ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
943 # define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
945 # undef SUBLANG_SAMI_SKOLT_FINLAND
946 # define SUBLANG_SAMI_SKOLT_FINLAND 0x08
947 # undef SUBLANG_SAMI_INARI_FINLAND
948 # define SUBLANG_SAMI_INARI_FINLAND 0x09
949 # ifndef SUBLANG_SANSKRIT_INDIA
950 # define SUBLANG_SANSKRIT_INDIA 0x01
952 # ifndef SUBLANG_SERBIAN_LATIN
953 # define SUBLANG_SERBIAN_LATIN 0x02
955 # ifndef SUBLANG_SERBIAN_CYRILLIC
956 # define SUBLANG_SERBIAN_CYRILLIC 0x03
958 # ifndef SUBLANG_SINDHI_INDIA
959 # define SUBLANG_SINDHI_INDIA 0x01
961 # undef SUBLANG_SINDHI_PAKISTAN
962 # define SUBLANG_SINDHI_PAKISTAN 0x02
963 # ifndef SUBLANG_SINDHI_AFGHANISTAN
964 # define SUBLANG_SINDHI_AFGHANISTAN 0x02
966 # ifndef SUBLANG_SINHALESE_SRI_LANKA
967 # define SUBLANG_SINHALESE_SRI_LANKA 0x01
969 # ifndef SUBLANG_SLOVAK_SLOVAKIA
970 # define SUBLANG_SLOVAK_SLOVAKIA 0x01
972 # ifndef SUBLANG_SLOVENIAN_SLOVENIA
973 # define SUBLANG_SLOVENIAN_SLOVENIA 0x01
975 # ifndef SUBLANG_SOTHO_SOUTH_AFRICA
976 # define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
978 # ifndef SUBLANG_SPANISH_GUATEMALA
979 # define SUBLANG_SPANISH_GUATEMALA 0x04
981 # ifndef SUBLANG_SPANISH_COSTA_RICA
982 # define SUBLANG_SPANISH_COSTA_RICA 0x05
984 # ifndef SUBLANG_SPANISH_PANAMA
985 # define SUBLANG_SPANISH_PANAMA 0x06
987 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
988 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
990 # ifndef SUBLANG_SPANISH_VENEZUELA
991 # define SUBLANG_SPANISH_VENEZUELA 0x08
993 # ifndef SUBLANG_SPANISH_COLOMBIA
994 # define SUBLANG_SPANISH_COLOMBIA 0x09
996 # ifndef SUBLANG_SPANISH_PERU
997 # define SUBLANG_SPANISH_PERU 0x0a
999 # ifndef SUBLANG_SPANISH_ARGENTINA
1000 # define SUBLANG_SPANISH_ARGENTINA 0x0b
1002 # ifndef SUBLANG_SPANISH_ECUADOR
1003 # define SUBLANG_SPANISH_ECUADOR 0x0c
1005 # ifndef SUBLANG_SPANISH_CHILE
1006 # define SUBLANG_SPANISH_CHILE 0x0d
1008 # ifndef SUBLANG_SPANISH_URUGUAY
1009 # define SUBLANG_SPANISH_URUGUAY 0x0e
1011 # ifndef SUBLANG_SPANISH_PARAGUAY
1012 # define SUBLANG_SPANISH_PARAGUAY 0x0f
1014 # ifndef SUBLANG_SPANISH_BOLIVIA
1015 # define SUBLANG_SPANISH_BOLIVIA 0x10
1017 # ifndef SUBLANG_SPANISH_EL_SALVADOR
1018 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
1020 # ifndef SUBLANG_SPANISH_HONDURAS
1021 # define SUBLANG_SPANISH_HONDURAS 0x12
1023 # ifndef SUBLANG_SPANISH_NICARAGUA
1024 # define SUBLANG_SPANISH_NICARAGUA 0x13
1026 # ifndef SUBLANG_SPANISH_PUERTO_RICO
1027 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
1029 # ifndef SUBLANG_SPANISH_US
1030 # define SUBLANG_SPANISH_US 0x15
1032 # ifndef SUBLANG_SWAHILI_KENYA
1033 # define SUBLANG_SWAHILI_KENYA 0x01
1035 # ifndef SUBLANG_SWEDISH_SWEDEN
1036 # define SUBLANG_SWEDISH_SWEDEN 0x01
1038 # ifndef SUBLANG_SWEDISH_FINLAND
1039 # define SUBLANG_SWEDISH_FINLAND 0x02
1041 # ifndef SUBLANG_SYRIAC_SYRIA
1042 # define SUBLANG_SYRIAC_SYRIA 0x01
1044 # ifndef SUBLANG_TAGALOG_PHILIPPINES
1045 # define SUBLANG_TAGALOG_PHILIPPINES 0x01
1047 # ifndef SUBLANG_TAJIK_TAJIKISTAN
1048 # define SUBLANG_TAJIK_TAJIKISTAN 0x01
1050 # ifndef SUBLANG_TAMAZIGHT_ARABIC
1051 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
1053 # ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
1054 # define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
1056 # ifndef SUBLANG_TAMIL_INDIA
1057 # define SUBLANG_TAMIL_INDIA 0x01
1059 # ifndef SUBLANG_TATAR_RUSSIA
1060 # define SUBLANG_TATAR_RUSSIA 0x01
1062 # ifndef SUBLANG_TELUGU_INDIA
1063 # define SUBLANG_TELUGU_INDIA 0x01
1065 # ifndef SUBLANG_THAI_THAILAND
1066 # define SUBLANG_THAI_THAILAND 0x01
1068 # ifndef SUBLANG_TIBETAN_PRC
1069 # define SUBLANG_TIBETAN_PRC 0x01
1071 # undef SUBLANG_TIBETAN_BHUTAN
1072 # define SUBLANG_TIBETAN_BHUTAN 0x02
1073 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
1074 # define SUBLANG_TIGRINYA_ETHIOPIA 0x01
1076 # ifndef SUBLANG_TIGRINYA_ERITREA
1077 # define SUBLANG_TIGRINYA_ERITREA 0x02
1079 # ifndef SUBLANG_TSWANA_SOUTH_AFRICA
1080 # define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
1082 # ifndef SUBLANG_TURKISH_TURKEY
1083 # define SUBLANG_TURKISH_TURKEY 0x01
1085 # ifndef SUBLANG_TURKMEN_TURKMENISTAN
1086 # define SUBLANG_TURKMEN_TURKMENISTAN 0x01
1088 # ifndef SUBLANG_UIGHUR_PRC
1089 # define SUBLANG_UIGHUR_PRC 0x01
1091 # ifndef SUBLANG_UKRAINIAN_UKRAINE
1092 # define SUBLANG_UKRAINIAN_UKRAINE 0x01
1094 # ifndef SUBLANG_UPPER_SORBIAN_GERMANY
1095 # define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
1097 # ifndef SUBLANG_URDU_PAKISTAN
1098 # define SUBLANG_URDU_PAKISTAN 0x01
1100 # ifndef SUBLANG_URDU_INDIA
1101 # define SUBLANG_URDU_INDIA 0x02
1103 # ifndef SUBLANG_UZBEK_LATIN
1104 # define SUBLANG_UZBEK_LATIN 0x01
1106 # ifndef SUBLANG_UZBEK_CYRILLIC
1107 # define SUBLANG_UZBEK_CYRILLIC 0x02
1109 # ifndef SUBLANG_VIETNAMESE_VIETNAM
1110 # define SUBLANG_VIETNAMESE_VIETNAM 0x01
1112 # ifndef SUBLANG_WELSH_UNITED_KINGDOM
1113 # define SUBLANG_WELSH_UNITED_KINGDOM 0x01
1115 # ifndef SUBLANG_WOLOF_SENEGAL
1116 # define SUBLANG_WOLOF_SENEGAL 0x01
1118 # ifndef SUBLANG_XHOSA_SOUTH_AFRICA
1119 # define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
1121 # ifndef SUBLANG_YAKUT_RUSSIA
1122 # define SUBLANG_YAKUT_RUSSIA 0x01
1124 # ifndef SUBLANG_YI_PRC
1125 # define SUBLANG_YI_PRC 0x01
1127 # ifndef SUBLANG_YORUBA_NIGERIA
1128 # define SUBLANG_YORUBA_NIGERIA 0x01
1130 # ifndef SUBLANG_ZULU_SOUTH_AFRICA
1131 # define SUBLANG_ZULU_SOUTH_AFRICA 0x01
1133 /* GetLocaleInfoA operations. */
1134 # ifndef LOCALE_SNAME
1135 # define LOCALE_SNAME 0x5c
1137 # ifndef LOCALE_NAME_MAX_LENGTH
1138 # define LOCALE_NAME_MAX_LENGTH 85
1143 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1144 /* Mac OS X 10.2 or newer */
1146 /* Canonicalize a Mac OS X locale name to a Unix locale name.
1147 NAME is a sufficiently large buffer.
1148 On input, it contains the Mac OS X locale name.
1149 On output, it contains the Unix locale name. */
1150 # if !defined IN_LIBINTL
1154 gl_locale_name_canonicalize (char *name)
1156 /* This conversion is based on a posting by
1157 Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
1158 http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
1160 /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
1161 ISO 3166) names. Prior to Mac OS X 10.3, there is no API for doing this.
1162 Therefore we do it ourselves, using a table based on the results of the
1163 Mac OS X 10.3.8 function
1164 CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
1165 typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
1167 static const legacy_entry legacy_table[] = {
1168 { "Afrikaans", "af" },
1169 { "Albanian", "sq" },
1170 { "Amharic", "am" },
1172 { "Armenian", "hy" },
1173 { "Assamese", "as" },
1175 { "Azerbaijani", "az" },
1177 { "Belarusian", "be" },
1178 { "Belorussian", "be" },
1179 { "Bengali", "bn" },
1180 { "Brazilian Portugese", "pt_BR" },
1181 { "Brazilian Portuguese", "pt_BR" },
1183 { "Bulgarian", "bg" },
1184 { "Burmese", "my" },
1185 { "Byelorussian", "be" },
1186 { "Catalan", "ca" },
1188 { "Chichewa", "ny" },
1189 { "Chinese", "zh" },
1190 { "Chinese, Simplified", "zh_CN" },
1191 { "Chinese, Traditional", "zh_TW" },
1192 { "Chinese, Tradtional", "zh_TW" },
1193 { "Croatian", "hr" },
1197 { "Dzongkha", "dz" },
1198 { "English", "en" },
1199 { "Esperanto", "eo" },
1200 { "Estonian", "et" },
1201 { "Faroese", "fo" },
1203 { "Finnish", "fi" },
1204 { "Flemish", "nl_BE" },
1206 { "Galician", "gl" },
1207 { "Gallegan", "gl" },
1208 { "Georgian", "ka" },
1211 { "Greenlandic", "kl" },
1212 { "Guarani", "gn" },
1213 { "Gujarati", "gu" },
1214 { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
1217 { "Hungarian", "hu" },
1218 { "Icelandic", "is" },
1219 { "Indonesian", "id" },
1220 { "Inuktitut", "iu" },
1222 { "Italian", "it" },
1223 { "Japanese", "ja" },
1224 { "Javanese", "jv" },
1225 { "Kalaallisut", "kl" },
1226 { "Kannada", "kn" },
1227 { "Kashmiri", "ks" },
1230 { "Kinyarwanda", "rw" },
1231 { "Kirghiz", "ky" },
1233 { "Kurdish", "ku" },
1235 { "Latvian", "lv" },
1236 { "Lithuanian", "lt" },
1237 { "Macedonian", "mk" },
1238 { "Malagasy", "mg" },
1240 { "Malayalam", "ml" },
1241 { "Maltese", "mt" },
1243 { "Marathi", "mr" },
1244 { "Moldavian", "mo" },
1245 { "Mongolian", "mn" },
1247 { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
1249 { "Nynorsk", "nn" },
1252 { "Panjabi", "pa" },
1254 { "Persian", "fa" },
1256 { "Portuguese", "pt" },
1257 { "Portuguese, Brazilian", "pt_BR" },
1258 { "Punjabi", "pa" },
1260 { "Quechua", "qu" },
1261 { "Romanian", "ro" },
1264 { "Russian", "ru" },
1265 { "Sami", "se_NO" }, /* Not just "se". */
1266 { "Sanskrit", "sa" },
1267 { "Scottish", "gd" },
1268 { "Serbian", "sr" },
1269 { "Simplified Chinese", "zh_CN" },
1271 { "Sinhalese", "si" },
1273 { "Slovenian", "sl" },
1275 { "Spanish", "es" },
1276 { "Sundanese", "su" },
1277 { "Swahili", "sw" },
1278 { "Swedish", "sv" },
1279 { "Tagalog", "tl" },
1286 { "Tibetan", "bo" },
1287 { "Tigrinya", "ti" },
1289 { "Traditional Chinese", "zh_TW" },
1290 { "Turkish", "tr" },
1291 { "Turkmen", "tk" },
1293 { "Ukrainian", "uk" },
1296 { "Vietnamese", "vi" },
1301 /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
1302 to Unix (ISO 639 and ISO 3166) names. */
1303 typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
1305 static const langtag_entry langtag_table[] = {
1306 /* Mac OS X has "az-Arab", "az-Cyrl", "az-Latn".
1307 The default script for az on Unix is Latin. */
1308 { "az-Latn", "az" },
1309 /* Mac OS X has "ga-dots". Does not yet exist on Unix. */
1310 { "ga-dots", "ga" },
1311 /* Mac OS X has "kk-Cyrl". Does not yet exist on Unix. */
1312 /* Mac OS X has "mn-Cyrl", "mn-Mong".
1313 The default script for mn on Unix is Cyrillic. */
1314 { "mn-Cyrl", "mn" },
1315 /* Mac OS X has "ms-Arab", "ms-Latn".
1316 The default script for ms on Unix is Latin. */
1317 { "ms-Latn", "ms" },
1318 /* Mac OS X has "tg-Cyrl".
1319 The default script for tg on Unix is Cyrillic. */
1320 { "tg-Cyrl", "tg" },
1321 /* Mac OS X has "tk-Cyrl". Does not yet exist on Unix. */
1322 /* Mac OS X has "tt-Cyrl".
1323 The default script for tt on Unix is Cyrillic. */
1324 { "tt-Cyrl", "tt" },
1325 /* Mac OS X has "zh-Hans", "zh-Hant".
1326 Country codes are used to distinguish these on Unix. */
1327 { "zh-Hans", "zh_CN" },
1328 { "zh-Hant", "zh_TW" }
1331 /* Convert script names (ISO 15924) to Unix conventions.
1332 See http://www.unicode.org/iso15924/iso15924-codes.html */
1333 typedef struct { const char script[4+1]; const char unixy[9+1]; }
1335 static const script_entry script_table[] = {
1336 { "Arab", "arabic" },
1337 { "Cyrl", "cyrillic" },
1338 { "Mong", "mongolian" }
1341 /* Step 1: Convert using legacy_table. */
1342 if (name[0] >= 'A' && name[0] <= 'Z')
1344 unsigned int i1, i2;
1346 i2 = sizeof (legacy_table) / sizeof (legacy_entry);
1349 /* At this point we know that if name occurs in legacy_table,
1350 its index must be >= i1 and < i2. */
1351 unsigned int i = (i1 + i2) >> 1;
1352 const legacy_entry *p = &legacy_table[i];
1353 if (strcmp (name, p->legacy) < 0)
1358 if (strcmp (name, legacy_table[i1].legacy) == 0)
1360 strcpy (name, legacy_table[i1].unixy);
1365 /* Step 2: Convert using langtag_table and script_table. */
1366 if (strlen (name) == 7 && name[2] == '-')
1368 unsigned int i1, i2;
1370 i2 = sizeof (langtag_table) / sizeof (langtag_entry);
1373 /* At this point we know that if name occurs in langtag_table,
1374 its index must be >= i1 and < i2. */
1375 unsigned int i = (i1 + i2) >> 1;
1376 const langtag_entry *p = &langtag_table[i];
1377 if (strcmp (name, p->langtag) < 0)
1382 if (strcmp (name, langtag_table[i1].langtag) == 0)
1384 strcpy (name, langtag_table[i1].unixy);
1389 i2 = sizeof (script_table) / sizeof (script_entry);
1392 /* At this point we know that if (name + 3) occurs in script_table,
1393 its index must be >= i1 and < i2. */
1394 unsigned int i = (i1 + i2) >> 1;
1395 const script_entry *p = &script_table[i];
1396 if (strcmp (name + 3, p->script) < 0)
1401 if (strcmp (name + 3, script_table[i1].script) == 0)
1404 strcpy (name + 3, script_table[i1].unixy);
1409 /* Step 3: Convert new-style dash to Unix underscore. */
1412 for (p = name; *p != '\0'; p++)
1421 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
1423 /* Canonicalize a Windows native locale name to a Unix locale name.
1424 NAME is a sufficiently large buffer.
1425 On input, it contains the Windows locale name.
1426 On output, it contains the Unix locale name. */
1427 # if !defined IN_LIBINTL
1431 gl_locale_name_canonicalize (char *name)
1433 /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
1437 for (p = name; *p != '\0'; p++)
1442 for (; *p != '\0'; p++)
1444 if (*p >= 'a' && *p <= 'z')
1456 # if !defined IN_LIBINTL
1460 gl_locale_name_from_win32_LANGID (LANGID langid)
1462 /* Activate the new code only when the GETTEXT_MUI environment variable is
1463 set, for the time being, since the new code is not well tested. */
1464 if (getenv ("GETTEXT_MUI") != NULL)
1466 static char namebuf[256];
1468 /* Query the system's notion of locale name.
1469 On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
1470 But we don't need to support systems that are so old. */
1471 if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
1472 namebuf, sizeof (namebuf) - 1))
1474 /* Convert it to a Unix locale name. */
1475 gl_locale_name_canonicalize (namebuf);
1479 /* Internet Explorer has an LCID to RFC3066 name mapping stored in
1480 HKEY_CLASSES_ROOT\Mime\Database\Rfc1766. But we better don't use that
1481 since IE's i18n subsystem is known to be inconsistent with the native
1482 Windows base (e.g. they have different character conversion facilities
1483 that produce different results). */
1484 /* Use our own table. */
1488 /* Split into language and territory part. */
1489 primary = PRIMARYLANGID (langid);
1490 sub = SUBLANGID (langid);
1492 /* Dispatch on language.
1493 See also http://www.unicode.org/unicode/onlinedat/languages.html .
1494 For details about languages, see http://www.ethnologue.com/ . */
1497 case LANG_AFRIKAANS:
1500 case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
1506 case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
1512 case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
1518 case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
1524 case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
1525 case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
1526 case SUBLANG_ARABIC_EGYPT: return "ar_EG";
1527 case SUBLANG_ARABIC_LIBYA: return "ar_LY";
1528 case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
1529 case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
1530 case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
1531 case SUBLANG_ARABIC_OMAN: return "ar_OM";
1532 case SUBLANG_ARABIC_YEMEN: return "ar_YE";
1533 case SUBLANG_ARABIC_SYRIA: return "ar_SY";
1534 case SUBLANG_ARABIC_JORDAN: return "ar_JO";
1535 case SUBLANG_ARABIC_LEBANON: return "ar_LB";
1536 case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
1537 case SUBLANG_ARABIC_UAE: return "ar_AE";
1538 case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
1539 case SUBLANG_ARABIC_QATAR: return "ar_QA";
1545 case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
1551 case SUBLANG_ASSAMESE_INDIA: return "as_IN";
1557 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
1558 case 0x1e: return "az@latin";
1559 case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
1560 case 0x1d: return "az@cyrillic";
1561 case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
1567 case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
1573 case SUBLANG_BASQUE_BASQUE: return "eu_ES";
1575 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
1576 case LANG_BELARUSIAN:
1579 case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
1585 case SUBLANG_BENGALI_INDIA: return "bn_IN";
1586 case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
1592 case SUBLANG_BRETON_FRANCE: return "br_FR";
1595 case LANG_BULGARIAN:
1598 case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
1604 case SUBLANG_DEFAULT: return "my_MM";
1607 case LANG_CAMBODIAN:
1610 case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
1616 case SUBLANG_CATALAN_SPAIN: return "ca_ES";
1622 case SUBLANG_DEFAULT: return "chr_US";
1628 case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
1629 case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
1630 case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
1631 case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
1632 case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
1638 case SUBLANG_CORSICAN_FRANCE: return "co_FR";
1641 case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
1642 * What used to be called Serbo-Croatian
1643 * should really now be two separate
1644 * languages because of political reasons.
1645 * (Says tml, who knows nothing about Serbian
1647 * (I can feel those flames coming already.)
1652 case 0x00: return "hr";
1653 case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
1654 case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
1656 case 0x1f: return "sr";
1657 case 0x1c: return "sr"; /* latin */
1658 case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
1659 case 0x09: return "sr_RS"; /* latin */
1660 case 0x0b: return "sr_ME"; /* latin */
1661 case 0x06: return "sr_BA"; /* latin */
1662 case 0x1b: return "sr@cyrillic";
1663 case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
1664 case 0x0a: return "sr_RS@cyrillic";
1665 case 0x0c: return "sr_ME@cyrillic";
1666 case 0x07: return "sr_BA@cyrillic";
1668 case 0x1e: return "bs";
1669 case 0x1a: return "bs"; /* latin */
1670 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
1671 case 0x19: return "bs@cyrillic";
1672 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
1678 case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
1684 case SUBLANG_DANISH_DENMARK: return "da_DK";
1688 /* FIXME: Adjust this when such locales appear on Unix. */
1691 case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
1697 case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
1703 case SUBLANG_DUTCH: return "nl_NL";
1704 case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
1705 case SUBLANG_DUTCH_SURINAM: return "nl_SR";
1711 case SUBLANG_DEFAULT: return "bin_NG";
1717 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1718 * English was the language spoken in England.
1721 case SUBLANG_ENGLISH_US: return "en_US";
1722 case SUBLANG_ENGLISH_UK: return "en_GB";
1723 case SUBLANG_ENGLISH_AUS: return "en_AU";
1724 case SUBLANG_ENGLISH_CAN: return "en_CA";
1725 case SUBLANG_ENGLISH_NZ: return "en_NZ";
1726 case SUBLANG_ENGLISH_EIRE: return "en_IE";
1727 case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
1728 case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
1729 case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
1730 case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
1731 case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
1732 case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
1733 case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
1734 case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
1735 case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
1736 case SUBLANG_ENGLISH_INDIA: return "en_IN";
1737 case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
1738 case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
1744 case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
1750 case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
1756 case SUBLANG_FARSI_IRAN: return "fa_IR";
1762 case SUBLANG_FINNISH_FINLAND: return "fi_FI";
1768 case SUBLANG_FRENCH: return "fr_FR";
1769 case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
1770 case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
1771 case SUBLANG_FRENCH_SWISS: return "fr_CH";
1772 case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
1773 case SUBLANG_FRENCH_MONACO: return "fr_MC";
1774 case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
1775 case SUBLANG_FRENCH_REUNION: return "fr_RE";
1776 case SUBLANG_FRENCH_CONGO: return "fr_CG";
1777 case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
1778 case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
1779 case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
1780 case SUBLANG_FRENCH_MALI: return "fr_ML";
1781 case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
1782 case SUBLANG_FRENCH_HAITI: return "fr_HT";
1788 case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
1792 /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
1795 case SUBLANG_DEFAULT: return "ff_NG";
1801 case 0x01: /* SCOTTISH */
1802 /* old, superseded by LANG_SCOTTISH_GAELIC */
1804 case SUBLANG_IRISH_IRELAND: return "ga_IE";
1810 case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
1816 case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
1822 case SUBLANG_GERMAN: return "de_DE";
1823 case SUBLANG_GERMAN_SWISS: return "de_CH";
1824 case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
1825 case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
1826 case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
1832 case SUBLANG_GREEK_GREECE: return "el_GR";
1835 case LANG_GREENLANDIC:
1838 case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
1844 case SUBLANG_DEFAULT: return "gn_PY";
1850 case SUBLANG_GUJARATI_INDIA: return "gu_IN";
1856 case 0x1f: return "ha";
1857 case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
1861 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1862 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
1865 case SUBLANG_DEFAULT: return "cpe_US";
1871 case SUBLANG_HEBREW_ISRAEL: return "he_IL";
1877 case SUBLANG_HINDI_INDIA: return "hi_IN";
1880 case LANG_HUNGARIAN:
1883 case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
1889 case SUBLANG_DEFAULT: return "nic_NG";
1892 case LANG_ICELANDIC:
1895 case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
1901 case SUBLANG_IGBO_NIGERIA: return "ig_NG";
1904 case LANG_INDONESIAN:
1907 case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
1910 case LANG_INUKTITUT:
1913 case 0x1e: return "iu"; /* syllabic */
1914 case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
1915 case 0x1f: return "iu@latin";
1916 case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
1922 case SUBLANG_ITALIAN: return "it_IT";
1923 case SUBLANG_ITALIAN_SWISS: return "it_CH";
1929 case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
1935 case SUBLANG_KANNADA_INDIA: return "kn_IN";
1941 case SUBLANG_DEFAULT: return "kr_NG";
1947 case SUBLANG_DEFAULT: return "ks_PK";
1948 case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
1954 case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
1958 /* FIXME: Adjust this when such locales appear on Unix. */
1961 case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
1964 case LANG_KINYARWANDA:
1967 case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
1971 /* FIXME: Adjust this when such locales appear on Unix. */
1974 case SUBLANG_KONKANI_INDIA: return "kok_IN";
1980 case SUBLANG_DEFAULT: return "ko_KR";
1986 case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
1992 case SUBLANG_LAO_LAOS: return "lo_LA";
1998 case SUBLANG_DEFAULT: return "la_VA";
2004 case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
2007 case LANG_LITHUANIAN:
2010 case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
2013 case LANG_LUXEMBOURGISH:
2016 case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
2019 case LANG_MACEDONIAN:
2022 case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
2028 case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
2029 case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
2032 case LANG_MALAYALAM:
2035 case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
2041 case SUBLANG_MALTESE_MALTA: return "mt_MT";
2045 /* FIXME: Adjust this when such locales appear on Unix. */
2048 case SUBLANG_DEFAULT: return "mni_IN";
2054 case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
2057 case LANG_MAPUDUNGUN:
2060 case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
2066 case SUBLANG_MARATHI_INDIA: return "mr_IN";
2072 case SUBLANG_MOHAWK_CANADA: return "moh_CA";
2075 case LANG_MONGOLIAN:
2078 case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
2079 case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
2081 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
2085 case SUBLANG_NEPALI_NEPAL: return "ne_NP";
2086 case SUBLANG_NEPALI_INDIA: return "ne_IN";
2089 case LANG_NORWEGIAN:
2092 case 0x1f: return "nb";
2093 case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
2094 case 0x1e: return "nn";
2095 case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
2101 case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
2107 case SUBLANG_ORIYA_INDIA: return "or_IN";
2113 case SUBLANG_DEFAULT: return "om_ET";
2116 case LANG_PAPIAMENTU:
2119 case SUBLANG_DEFAULT: return "pap_AN";
2125 case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
2127 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
2131 case SUBLANG_POLISH_POLAND: return "pl_PL";
2134 case LANG_PORTUGUESE:
2137 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
2138 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
2139 case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
2140 case SUBLANG_PORTUGUESE: return "pt_PT";
2146 case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
2147 case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
2151 /* Note: Microsoft uses the non-ISO language code "quz". */
2154 case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
2155 case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
2156 case SUBLANG_QUECHUA_PERU: return "qu_PE";
2162 case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
2163 case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
2169 case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
2175 case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
2176 case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
2178 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
2183 case 0x00: return "se";
2184 case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
2185 case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
2186 case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
2188 case 0x1f: return "smj";
2189 case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
2190 case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
2192 case 0x1e: return "sma";
2193 case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
2194 case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
2196 case 0x1d: return "sms";
2197 case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
2199 case 0x1c: return "smn";
2200 case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
2202 return "se"; /* or "smi"? */
2206 case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
2209 case LANG_SCOTTISH_GAELIC:
2212 case SUBLANG_DEFAULT: return "gd_GB";
2218 case SUBLANG_SINDHI_INDIA: return "sd_IN";
2219 case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
2220 /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
2223 case LANG_SINHALESE:
2226 case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
2232 case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
2235 case LANG_SLOVENIAN:
2238 case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
2244 case SUBLANG_DEFAULT: return "so_SO";
2248 /* FIXME: Adjust this when such locales appear on Unix. */
2252 case 0x00: return "hsb";
2253 case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
2255 case 0x1f: return "dsb";
2256 case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
2260 /* <http://www.microsoft.com/globaldev/reference/lcid-all.mspx> calls
2261 it "Sepedi"; according to
2262 <http://www.ethnologue.com/show_language.asp?code=nso>
2263 <http://www.ethnologue.com/show_language.asp?code=sot>
2264 it's the same as Northern Sotho. */
2267 case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
2273 case SUBLANG_SPANISH: return "es_ES";
2274 case SUBLANG_SPANISH_MEXICAN: return "es_MX";
2275 case SUBLANG_SPANISH_MODERN:
2276 return "es_ES@modern"; /* not seen on Unix */
2277 case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
2278 case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
2279 case SUBLANG_SPANISH_PANAMA: return "es_PA";
2280 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
2281 case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
2282 case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
2283 case SUBLANG_SPANISH_PERU: return "es_PE";
2284 case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
2285 case SUBLANG_SPANISH_ECUADOR: return "es_EC";
2286 case SUBLANG_SPANISH_CHILE: return "es_CL";
2287 case SUBLANG_SPANISH_URUGUAY: return "es_UY";
2288 case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
2289 case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
2290 case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
2291 case SUBLANG_SPANISH_HONDURAS: return "es_HN";
2292 case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
2293 case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
2294 case SUBLANG_SPANISH_US: return "es_US";
2300 case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
2306 case SUBLANG_SWAHILI_KENYA: return "sw_KE";
2312 case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
2313 case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
2319 case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language. */
2325 case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
2327 return "tl"; /* or "fil"? */
2331 case 0x1f: return "tg";
2332 case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
2335 case LANG_TAMAZIGHT:
2336 /* Note: Microsoft uses the non-ISO language code "tmz". */
2339 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
2340 case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
2341 case 0x1f: return "ber@latin";
2342 case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
2348 case SUBLANG_TAMIL_INDIA: return "ta_IN";
2350 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
2354 case SUBLANG_TATAR_RUSSIA: return "tt_RU";
2360 case SUBLANG_TELUGU_INDIA: return "te_IN";
2366 case SUBLANG_THAI_THAILAND: return "th_TH";
2372 case SUBLANG_TIBETAN_PRC:
2373 /* Most Tibetans would not like "bo_CN". But Tibet does not yet
2374 have a country code of its own. */
2376 case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
2382 case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
2383 case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
2389 case SUBLANG_DEFAULT: return "ts_ZA";
2393 /* Spoken in South Africa, Botswana. */
2396 case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
2402 case SUBLANG_TURKISH_TURKEY: return "tr_TR";
2408 case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
2414 case SUBLANG_UIGHUR_PRC: return "ug_CN";
2417 case LANG_UKRAINIAN:
2420 case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
2426 case SUBLANG_URDU_PAKISTAN: return "ur_PK";
2427 case SUBLANG_URDU_INDIA: return "ur_IN";
2433 case 0x1f: return "uz";
2434 case SUBLANG_UZBEK_LATIN: return "uz_UZ";
2435 case 0x1e: return "uz@cyrillic";
2436 case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
2442 case SUBLANG_DEFAULT: return "ve_ZA";
2445 case LANG_VIETNAMESE:
2448 case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
2454 case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
2460 case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
2466 case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
2472 case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
2478 case SUBLANG_YI_PRC: return "ii_CN";
2484 case SUBLANG_DEFAULT: return "yi_IL";
2490 case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
2496 case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
2499 default: return "C";
2504 # if !defined IN_LIBINTL
2508 gl_locale_name_from_win32_LCID (LCID lcid)
2512 /* Strip off the sorting rules, keep only the language part. */
2513 langid = LANGIDFROMLCID (lcid);
2515 return gl_locale_name_from_win32_LANGID (langid);
2518 # ifdef WINDOWS_NATIVE
2520 /* Two variables to interface between get_lcid and the EnumLocales
2521 callback function below. */
2522 static LCID found_lcid;
2523 static char lname[LC_MAX * (LOCALE_NAME_MAX_LENGTH + 1) + 1];
2525 /* Callback function for EnumLocales. */
2526 static BOOL CALLBACK
2527 enum_locales_fn (LPTSTR locale_num_str)
2530 char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
2531 LCID try_lcid = strtoul (locale_num_str, &endp, 16);
2533 if (GetLocaleInfo (try_lcid, LOCALE_SENGLANGUAGE,
2534 locval, LOCALE_NAME_MAX_LENGTH))
2536 strcat (locval, "_");
2537 if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
2538 locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
2540 size_t locval_len = strlen (locval);
2542 if (strncmp (locval, lname, locval_len) == 0
2543 && (lname[locval_len] == '.'
2544 || lname[locval_len] == '\0'))
2546 found_lcid = try_lcid;
2554 /* This lock protects the get_lcid against multiple simultaneous calls. */
2555 gl_lock_define_initialized(static, get_lcid_lock)
2557 /* Return the Locale ID (LCID) number given the locale's name, a
2558 string, in LOCALE_NAME. This works by enumerating all the locales
2559 supported by the system, until we find one whose name matches
2562 get_lcid (const char *locale_name)
2564 /* A simple cache. */
2565 static LCID last_lcid;
2566 static char last_locale[1000];
2568 /* Lock while looking for an LCID, to protect access to static
2569 variables: last_lcid, last_locale, found_lcid, and lname. */
2570 gl_lock_lock (get_lcid_lock);
2571 if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
2573 gl_lock_unlock (get_lcid_lock);
2576 strncpy (lname, locale_name, sizeof (lname) - 1);
2577 lname[sizeof (lname) - 1] = '\0';
2579 EnumSystemLocales (enum_locales_fn, LCID_SUPPORTED);
2582 last_lcid = found_lcid;
2583 strcpy (last_locale, locale_name);
2585 gl_lock_unlock (get_lcid_lock);
2593 #if HAVE_USELOCALE /* glibc, Solaris >= 12 or Mac OS X */
2595 /* Simple hash set of strings. We don't want to drag in lots of hash table
2598 # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
2600 /* A hash function for NUL-terminated char* strings using
2601 the method described by Bruno Haible.
2602 See http://www.haible.de/bruno/hashfunc.html. */
2603 static size_t _GL_ATTRIBUTE_PURE
2604 string_hash (const void *x)
2606 const char *s = (const char *) x;
2610 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
2615 /* A hash table of fixed size. Multiple threads can access it read-only
2616 simultaneously, but only one thread can insert into it at the same time. */
2618 /* A node in a hash bucket collision list. */
2621 struct hash_node * volatile next;
2622 char contents[100]; /* has variable size */
2625 # define HASH_TABLE_SIZE 257
2626 static struct hash_node * volatile struniq_hash_table[HASH_TABLE_SIZE]
2627 /* = { NULL, ..., NULL } */;
2629 /* This lock protects the struniq_hash_table against multiple simultaneous
2631 gl_lock_define_initialized(static, struniq_lock)
2633 /* Store a copy of the given string in a string pool with indefinite extent.
2634 Return a pointer to this copy. */
2636 struniq (const char *string)
2638 size_t hashcode = string_hash (string);
2639 size_t slot = hashcode % HASH_TABLE_SIZE;
2641 struct hash_node *new_node;
2642 struct hash_node *p;
2643 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2644 if (strcmp (p->contents, string) == 0)
2646 size = strlen (string) + 1;
2648 (struct hash_node *)
2649 malloc (offsetof (struct hash_node, contents[0]) + size);
2650 if (new_node == NULL)
2651 /* Out of memory. Return a statically allocated string. */
2653 memcpy (new_node->contents, string, size);
2654 /* Lock while inserting new_node. */
2655 gl_lock_lock (struniq_lock);
2656 /* Check whether another thread already added the string while we were
2657 waiting on the lock. */
2658 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2659 if (strcmp (p->contents, string) == 0)
2665 /* Really insert new_node into the hash table. Fill new_node entirely first,
2666 because other threads may be iterating over the linked list. */
2667 new_node->next = struniq_hash_table[slot];
2668 struniq_hash_table[slot] = new_node;
2670 /* Unlock after new_node is inserted. */
2671 gl_lock_unlock (struniq_lock);
2672 return new_node->contents;
2678 #if defined IN_LIBINTL || HAVE_USELOCALE
2680 /* Like gl_locale_name_thread, except that the result is not in storage of
2681 indefinite extent. */
2682 # if !defined IN_LIBINTL
2686 gl_locale_name_thread_unsafe (int category, const char *categoryname)
2690 locale_t thread_locale = uselocale (NULL);
2691 if (thread_locale != LC_GLOBAL_LOCALE)
2693 # if __GLIBC__ >= 2 && !defined __UCLIBC__
2694 /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
2696 See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>. */
2698 nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
2699 if (name[0] == '\0')
2700 /* Fallback code for glibc < 2.4, which did not implement
2701 nl_langinfo (_NL_LOCALE_NAME (category)). */
2702 name = thread_locale->__names[category];
2704 # elif defined __FreeBSD__ || (defined __APPLE__ && defined __MACH__)
2705 /* FreeBSD, Mac OS X */
2711 mask = LC_CTYPE_MASK;
2714 mask = LC_NUMERIC_MASK;
2717 mask = LC_TIME_MASK;
2720 mask = LC_COLLATE_MASK;
2723 mask = LC_MONETARY_MASK;
2726 mask = LC_MESSAGES_MASK;
2728 default: /* We shouldn't get here. */
2731 return querylocale (mask, thread_locale);
2732 # elif defined __sun && HAVE_GETLOCALENAME_L
2733 /* Solaris >= 12. */
2734 return getlocalename_l (category, thread_locale);
2735 # elif defined __ANDROID__
2736 return MB_CUR_MAX == 4 ? "C.UTF-8" : "C";
2747 gl_locale_name_thread (int category, const char *categoryname)
2750 const char *name = gl_locale_name_thread_unsafe (category, categoryname);
2752 return struniq (name);
2753 #elif defined WINDOWS_NATIVE
2754 if (LC_MIN <= category && category <= LC_MAX)
2756 char *locname = setlocale (category, NULL);
2759 /* If CATEGORY is LC_ALL, the result might be a semi-colon
2760 separated list of locales. We need only one, so we take the
2761 one corresponding to LC_CTYPE, as the most important for
2762 character translations. */
2763 if (strchr (locname, ';'))
2764 locname = setlocale (LC_CTYPE, NULL);
2766 /* Convert locale name to LCID. We don't want to use
2767 LocaleNameToLCID because (a) it is only available since Vista,
2768 and (b) it doesn't accept locale names returned by 'setlocale'. */
2769 lcid = get_lcid (locname);
2772 return gl_locale_name_from_win32_LCID (lcid);
2778 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
2779 "Directs 'setlocale()' to query 'category' and return the current
2780 setting of 'local'."
2781 However it does not specify the exact format. Neither do SUSV2 and
2782 ISO C 99. So we can use this feature only on selected systems (e.g.
2783 those using GNU C Library). */
2784 #if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
2785 # define HAVE_LOCALE_NULL
2789 gl_locale_name_posix (int category, const char *categoryname)
2791 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
2792 On some systems this can be done by the 'setlocale' function itself. */
2793 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
2794 return setlocale (category, NULL);
2796 /* On other systems we ignore what setlocale reports and instead look at the
2797 environment variables directly. This is necessary
2798 1. on systems which have a facility for customizing the default locale
2799 (Mac OS X, native Windows, Cygwin) and where the system's setlocale()
2800 function ignores this default locale (Mac OS X, Cygwin), in two cases:
2801 a. when the user missed to use the setlocale() override from libintl
2802 (for example by not including <libintl.h>),
2803 b. when setlocale supports only the "C" locale, such as on Cygwin
2804 1.5.x. In this case even the override from libintl cannot help.
2805 2. on all systems where setlocale supports only the "C" locale. */
2806 /* Strictly speaking, it is a POSIX violation to look at the environment
2807 variables regardless whether setlocale has been called or not. POSIX
2809 "For C-language programs, the POSIX locale shall be the
2810 default locale when the setlocale() function is not called."
2811 But we assume that all programs that use internationalized APIs call
2812 setlocale (LC_ALL, ""). */
2813 return gl_locale_name_environ (category, categoryname);
2818 gl_locale_name_environ (int category, const char *categoryname)
2822 /* Setting of LC_ALL overrides all other. */
2823 retval = getenv ("LC_ALL");
2824 if (retval != NULL && retval[0] != '\0')
2826 /* Next comes the name of the desired category. */
2827 retval = getenv (categoryname);
2828 if (retval != NULL && retval[0] != '\0')
2830 /* Last possibility is the LANG environment variable. */
2831 retval = getenv ("LANG");
2832 if (retval != NULL && retval[0] != '\0')
2834 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2835 /* Mac OS X 10.2 or newer.
2836 Ignore invalid LANG value set by the Terminal application. */
2837 if (strcmp (retval, "UTF-8") != 0)
2839 #if defined __CYGWIN__
2841 Ignore dummy LANG value set by ~/.profile. */
2842 if (strcmp (retval, "C.UTF-8") != 0)
2851 gl_locale_name_default (void)
2854 "All implementations shall define a locale as the default locale, to be
2855 invoked when no environment variables are set, or set to the empty
2856 string. This default locale can be the POSIX locale or any other
2857 implementation-defined locale. Some implementations may provide
2858 facilities for local installation administrators to set the default
2859 locale, customizing it for each location. POSIX:2001 does not require
2862 The systems with such a facility are Mac OS X and Windows: They provide a
2863 GUI that allows the user to choose a locale.
2864 - On Mac OS X, by default, none of LC_* or LANG are set. Starting with
2865 Mac OS X 10.4 or 10.5, LANG is set for processes launched by the
2866 'Terminal' application (but sometimes to an incorrect value "UTF-8").
2867 When no environment variable is set, setlocale (LC_ALL, "") uses the
2869 - On native Windows, by default, none of LC_* or LANG are set.
2870 When no environment variable is set, setlocale (LC_ALL, "") uses the
2871 locale chosen by the user.
2872 - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
2873 When no environment variable is set, setlocale (LC_ALL, "") uses the
2875 - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
2876 ~/.profile is executed.
2877 When no environment variable is set, setlocale (LC_ALL, "") uses the
2878 "C.UTF-8" locale, which operates in the same way as the "C" locale.
2881 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WINDOWS_NATIVE || defined __CYGWIN__)
2883 /* The system does not have a way of setting the locale, other than the
2884 POSIX specified environment variables. We use C as default locale. */
2889 /* Return an XPG style locale name language[_territory][@modifier].
2890 Don't even bother determining the codeset; it's not useful in this
2891 context, because message catalogs are not specific to a single
2894 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2895 /* Mac OS X 10.2 or newer */
2897 /* Cache the locale name, since CoreFoundation calls are expensive. */
2898 static const char *cached_localename;
2900 if (cached_localename == NULL)
2903 # if HAVE_CFLOCALECOPYCURRENT /* Mac OS X 10.3 or newer */
2904 CFLocaleRef locale = CFLocaleCopyCurrent ();
2905 CFStringRef name = CFLocaleGetIdentifier (locale);
2907 if (CFStringGetCString (name, namebuf, sizeof (namebuf),
2908 kCFStringEncodingASCII))
2910 gl_locale_name_canonicalize (namebuf);
2911 cached_localename = strdup (namebuf);
2914 # elif HAVE_CFPREFERENCESCOPYAPPVALUE /* Mac OS X 10.2 or newer */
2916 CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
2917 kCFPreferencesCurrentApplication);
2919 && CFGetTypeID (value) == CFStringGetTypeID ()
2920 && CFStringGetCString ((CFStringRef)value,
2921 namebuf, sizeof (namebuf),
2922 kCFStringEncodingASCII))
2924 gl_locale_name_canonicalize (namebuf);
2925 cached_localename = strdup (namebuf);
2928 if (cached_localename == NULL)
2929 cached_localename = "C";
2931 return cached_localename;
2936 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
2940 /* Use native Windows API locale ID. */
2941 lcid = GetThreadLocale ();
2943 return gl_locale_name_from_win32_LCID (lcid);
2949 /* Determine the current locale's name, and canonicalize it into XPG syntax
2950 language[_territory][.codeset][@modifier]
2951 The codeset part in the result is not reliable; the locale_charset()
2952 should be used for codeset information instead.
2953 The result must not be freed; it is statically allocated. */
2956 gl_locale_name (int category, const char *categoryname)
2960 retval = gl_locale_name_thread (category, categoryname);
2964 retval = gl_locale_name_posix (category, categoryname);
2968 return gl_locale_name_default ();