1 /* Determine name of the currently selected locale.
2 Copyright (C) 1995-2014 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 Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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 # include <langinfo.h>
42 # if !defined IN_LIBINTL
43 # include "glthread/lock.h"
47 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
48 # include <CoreFoundation/CFString.h>
49 # if HAVE_CFLOCALECOPYCURRENT
50 # include <CoreFoundation/CFLocale.h>
51 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
52 # include <CoreFoundation/CFPreferences.h>
56 #if defined _WIN32 || defined __WIN32__
57 # define WINDOWS_NATIVE
58 # if !defined IN_LIBINTL
59 # include "glthread/lock.h"
63 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
64 # define WIN32_LEAN_AND_MEAN
67 /* List of language codes, sorted by value:
93 0x1a LANG_CROATIAN == LANG_SERBIAN
175 0x6e LANG_LUXEMBOURGISH
176 0x6f LANG_GREENLANDIC
195 0x87 LANG_KINYARWANDA
198 0x91 LANG_SCOTTISH_GAELIC
200 /* Mingw headers don't have latest language and sublanguage codes. */
201 # ifndef LANG_AFRIKAANS
202 # define LANG_AFRIKAANS 0x36
204 # ifndef LANG_ALBANIAN
205 # define LANG_ALBANIAN 0x1c
207 # ifndef LANG_ALSATIAN
208 # define LANG_ALSATIAN 0x84
210 # ifndef LANG_AMHARIC
211 # define LANG_AMHARIC 0x5e
214 # define LANG_ARABIC 0x01
216 # ifndef LANG_ARMENIAN
217 # define LANG_ARMENIAN 0x2b
219 # ifndef LANG_ASSAMESE
220 # define LANG_ASSAMESE 0x4d
223 # define LANG_AZERI 0x2c
225 # ifndef LANG_BASHKIR
226 # define LANG_BASHKIR 0x6d
229 # define LANG_BASQUE 0x2d
231 # ifndef LANG_BELARUSIAN
232 # define LANG_BELARUSIAN 0x23
234 # ifndef LANG_BENGALI
235 # define LANG_BENGALI 0x45
238 # define LANG_BRETON 0x7e
240 # ifndef LANG_BURMESE
241 # define LANG_BURMESE 0x55
243 # ifndef LANG_CAMBODIAN
244 # define LANG_CAMBODIAN 0x53
246 # ifndef LANG_CATALAN
247 # define LANG_CATALAN 0x03
249 # ifndef LANG_CHEROKEE
250 # define LANG_CHEROKEE 0x5c
252 # ifndef LANG_CORSICAN
253 # define LANG_CORSICAN 0x83
256 # define LANG_DARI 0x8c
259 # define LANG_DIVEHI 0x65
262 # define LANG_EDO 0x66
264 # ifndef LANG_ESTONIAN
265 # define LANG_ESTONIAN 0x25
267 # ifndef LANG_FAEROESE
268 # define LANG_FAEROESE 0x38
271 # define LANG_FARSI 0x29
273 # ifndef LANG_FRISIAN
274 # define LANG_FRISIAN 0x62
276 # ifndef LANG_FULFULDE
277 # define LANG_FULFULDE 0x67
280 # define LANG_GAELIC 0x3c
282 # ifndef LANG_GALICIAN
283 # define LANG_GALICIAN 0x56
285 # ifndef LANG_GEORGIAN
286 # define LANG_GEORGIAN 0x37
288 # ifndef LANG_GREENLANDIC
289 # define LANG_GREENLANDIC 0x6f
291 # ifndef LANG_GUARANI
292 # define LANG_GUARANI 0x74
294 # ifndef LANG_GUJARATI
295 # define LANG_GUJARATI 0x47
298 # define LANG_HAUSA 0x68
300 # ifndef LANG_HAWAIIAN
301 # define LANG_HAWAIIAN 0x75
304 # define LANG_HEBREW 0x0d
307 # define LANG_HINDI 0x39
310 # define LANG_IBIBIO 0x69
313 # define LANG_IGBO 0x70
315 # ifndef LANG_INDONESIAN
316 # define LANG_INDONESIAN 0x21
318 # ifndef LANG_INUKTITUT
319 # define LANG_INUKTITUT 0x5d
321 # ifndef LANG_KANNADA
322 # define LANG_KANNADA 0x4b
325 # define LANG_KANURI 0x71
327 # ifndef LANG_KASHMIRI
328 # define LANG_KASHMIRI 0x60
331 # define LANG_KAZAK 0x3f
334 # define LANG_KICHE 0x86
336 # ifndef LANG_KINYARWANDA
337 # define LANG_KINYARWANDA 0x87
339 # ifndef LANG_KONKANI
340 # define LANG_KONKANI 0x57
343 # define LANG_KYRGYZ 0x40
346 # define LANG_LAO 0x54
349 # define LANG_LATIN 0x76
351 # ifndef LANG_LATVIAN
352 # define LANG_LATVIAN 0x26
354 # ifndef LANG_LITHUANIAN
355 # define LANG_LITHUANIAN 0x27
357 # ifndef LANG_LUXEMBOURGISH
358 # define LANG_LUXEMBOURGISH 0x6e
360 # ifndef LANG_MACEDONIAN
361 # define LANG_MACEDONIAN 0x2f
364 # define LANG_MALAY 0x3e
366 # ifndef LANG_MALAYALAM
367 # define LANG_MALAYALAM 0x4c
369 # ifndef LANG_MALTESE
370 # define LANG_MALTESE 0x3a
372 # ifndef LANG_MANIPURI
373 # define LANG_MANIPURI 0x58
376 # define LANG_MAORI 0x81
378 # ifndef LANG_MAPUDUNGUN
379 # define LANG_MAPUDUNGUN 0x7a
381 # ifndef LANG_MARATHI
382 # define LANG_MARATHI 0x4e
385 # define LANG_MOHAWK 0x7c
387 # ifndef LANG_MONGOLIAN
388 # define LANG_MONGOLIAN 0x50
391 # define LANG_NEPALI 0x61
393 # ifndef LANG_OCCITAN
394 # define LANG_OCCITAN 0x82
397 # define LANG_ORIYA 0x48
400 # define LANG_OROMO 0x72
402 # ifndef LANG_PAPIAMENTU
403 # define LANG_PAPIAMENTU 0x79
406 # define LANG_PASHTO 0x63
408 # ifndef LANG_PUNJABI
409 # define LANG_PUNJABI 0x46
411 # ifndef LANG_QUECHUA
412 # define LANG_QUECHUA 0x6b
414 # ifndef LANG_ROMANSH
415 # define LANG_ROMANSH 0x17
418 # define LANG_SAMI 0x3b
420 # ifndef LANG_SANSKRIT
421 # define LANG_SANSKRIT 0x4f
423 # ifndef LANG_SCOTTISH_GAELIC
424 # define LANG_SCOTTISH_GAELIC 0x91
426 # ifndef LANG_SERBIAN
427 # define LANG_SERBIAN 0x1a
430 # define LANG_SINDHI 0x59
432 # ifndef LANG_SINHALESE
433 # define LANG_SINHALESE 0x5b
436 # define LANG_SLOVAK 0x1b
439 # define LANG_SOMALI 0x77
441 # ifndef LANG_SORBIAN
442 # define LANG_SORBIAN 0x2e
445 # define LANG_SOTHO 0x6c
448 # define LANG_SUTU 0x30
450 # ifndef LANG_SWAHILI
451 # define LANG_SWAHILI 0x41
454 # define LANG_SYRIAC 0x5a
456 # ifndef LANG_TAGALOG
457 # define LANG_TAGALOG 0x64
460 # define LANG_TAJIK 0x28
462 # ifndef LANG_TAMAZIGHT
463 # define LANG_TAMAZIGHT 0x5f
466 # define LANG_TAMIL 0x49
469 # define LANG_TATAR 0x44
472 # define LANG_TELUGU 0x4a
475 # define LANG_THAI 0x1e
477 # ifndef LANG_TIBETAN
478 # define LANG_TIBETAN 0x51
480 # ifndef LANG_TIGRINYA
481 # define LANG_TIGRINYA 0x73
484 # define LANG_TSONGA 0x31
487 # define LANG_TSWANA 0x32
489 # ifndef LANG_TURKMEN
490 # define LANG_TURKMEN 0x42
493 # define LANG_UIGHUR 0x80
495 # ifndef LANG_UKRAINIAN
496 # define LANG_UKRAINIAN 0x22
499 # define LANG_URDU 0x20
502 # define LANG_UZBEK 0x43
505 # define LANG_VENDA 0x33
507 # ifndef LANG_VIETNAMESE
508 # define LANG_VIETNAMESE 0x2a
511 # define LANG_WELSH 0x52
514 # define LANG_WOLOF 0x88
517 # define LANG_XHOSA 0x34
520 # define LANG_YAKUT 0x85
523 # define LANG_YI 0x78
525 # ifndef LANG_YIDDISH
526 # define LANG_YIDDISH 0x3d
529 # define LANG_YORUBA 0x6a
532 # define LANG_ZULU 0x35
534 # ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
535 # define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
537 # ifndef SUBLANG_ALBANIAN_ALBANIA
538 # define SUBLANG_ALBANIAN_ALBANIA 0x01
540 # ifndef SUBLANG_ALSATIAN_FRANCE
541 # define SUBLANG_ALSATIAN_FRANCE 0x01
543 # ifndef SUBLANG_AMHARIC_ETHIOPIA
544 # define SUBLANG_AMHARIC_ETHIOPIA 0x01
546 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
547 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
549 # ifndef SUBLANG_ARABIC_IRAQ
550 # define SUBLANG_ARABIC_IRAQ 0x02
552 # ifndef SUBLANG_ARABIC_EGYPT
553 # define SUBLANG_ARABIC_EGYPT 0x03
555 # ifndef SUBLANG_ARABIC_LIBYA
556 # define SUBLANG_ARABIC_LIBYA 0x04
558 # ifndef SUBLANG_ARABIC_ALGERIA
559 # define SUBLANG_ARABIC_ALGERIA 0x05
561 # ifndef SUBLANG_ARABIC_MOROCCO
562 # define SUBLANG_ARABIC_MOROCCO 0x06
564 # ifndef SUBLANG_ARABIC_TUNISIA
565 # define SUBLANG_ARABIC_TUNISIA 0x07
567 # ifndef SUBLANG_ARABIC_OMAN
568 # define SUBLANG_ARABIC_OMAN 0x08
570 # ifndef SUBLANG_ARABIC_YEMEN
571 # define SUBLANG_ARABIC_YEMEN 0x09
573 # ifndef SUBLANG_ARABIC_SYRIA
574 # define SUBLANG_ARABIC_SYRIA 0x0a
576 # ifndef SUBLANG_ARABIC_JORDAN
577 # define SUBLANG_ARABIC_JORDAN 0x0b
579 # ifndef SUBLANG_ARABIC_LEBANON
580 # define SUBLANG_ARABIC_LEBANON 0x0c
582 # ifndef SUBLANG_ARABIC_KUWAIT
583 # define SUBLANG_ARABIC_KUWAIT 0x0d
585 # ifndef SUBLANG_ARABIC_UAE
586 # define SUBLANG_ARABIC_UAE 0x0e
588 # ifndef SUBLANG_ARABIC_BAHRAIN
589 # define SUBLANG_ARABIC_BAHRAIN 0x0f
591 # ifndef SUBLANG_ARABIC_QATAR
592 # define SUBLANG_ARABIC_QATAR 0x10
594 # ifndef SUBLANG_ARMENIAN_ARMENIA
595 # define SUBLANG_ARMENIAN_ARMENIA 0x01
597 # ifndef SUBLANG_ASSAMESE_INDIA
598 # define SUBLANG_ASSAMESE_INDIA 0x01
600 # ifndef SUBLANG_AZERI_LATIN
601 # define SUBLANG_AZERI_LATIN 0x01
603 # ifndef SUBLANG_AZERI_CYRILLIC
604 # define SUBLANG_AZERI_CYRILLIC 0x02
606 # ifndef SUBLANG_BASHKIR_RUSSIA
607 # define SUBLANG_BASHKIR_RUSSIA 0x01
609 # ifndef SUBLANG_BASQUE_BASQUE
610 # define SUBLANG_BASQUE_BASQUE 0x01
612 # ifndef SUBLANG_BELARUSIAN_BELARUS
613 # define SUBLANG_BELARUSIAN_BELARUS 0x01
615 # ifndef SUBLANG_BENGALI_INDIA
616 # define SUBLANG_BENGALI_INDIA 0x01
618 # ifndef SUBLANG_BENGALI_BANGLADESH
619 # define SUBLANG_BENGALI_BANGLADESH 0x02
621 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
622 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
624 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
625 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
627 # ifndef SUBLANG_BRETON_FRANCE
628 # define SUBLANG_BRETON_FRANCE 0x01
630 # ifndef SUBLANG_BULGARIAN_BULGARIA
631 # define SUBLANG_BULGARIAN_BULGARIA 0x01
633 # ifndef SUBLANG_CAMBODIAN_CAMBODIA
634 # define SUBLANG_CAMBODIAN_CAMBODIA 0x01
636 # ifndef SUBLANG_CATALAN_SPAIN
637 # define SUBLANG_CATALAN_SPAIN 0x01
639 # ifndef SUBLANG_CORSICAN_FRANCE
640 # define SUBLANG_CORSICAN_FRANCE 0x01
642 # ifndef SUBLANG_CROATIAN_CROATIA
643 # define SUBLANG_CROATIAN_CROATIA 0x01
645 # ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
646 # define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
648 # ifndef SUBLANG_CHINESE_MACAU
649 # define SUBLANG_CHINESE_MACAU 0x05
651 # ifndef SUBLANG_CZECH_CZECH_REPUBLIC
652 # define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
654 # ifndef SUBLANG_DANISH_DENMARK
655 # define SUBLANG_DANISH_DENMARK 0x01
657 # ifndef SUBLANG_DARI_AFGHANISTAN
658 # define SUBLANG_DARI_AFGHANISTAN 0x01
660 # ifndef SUBLANG_DIVEHI_MALDIVES
661 # define SUBLANG_DIVEHI_MALDIVES 0x01
663 # ifndef SUBLANG_DUTCH_SURINAM
664 # define SUBLANG_DUTCH_SURINAM 0x03
666 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
667 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
669 # ifndef SUBLANG_ENGLISH_JAMAICA
670 # define SUBLANG_ENGLISH_JAMAICA 0x08
672 # ifndef SUBLANG_ENGLISH_CARIBBEAN
673 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
675 # ifndef SUBLANG_ENGLISH_BELIZE
676 # define SUBLANG_ENGLISH_BELIZE 0x0a
678 # ifndef SUBLANG_ENGLISH_TRINIDAD
679 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
681 # ifndef SUBLANG_ENGLISH_ZIMBABWE
682 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
684 # ifndef SUBLANG_ENGLISH_PHILIPPINES
685 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
687 # ifndef SUBLANG_ENGLISH_INDONESIA
688 # define SUBLANG_ENGLISH_INDONESIA 0x0e
690 # ifndef SUBLANG_ENGLISH_HONGKONG
691 # define SUBLANG_ENGLISH_HONGKONG 0x0f
693 # ifndef SUBLANG_ENGLISH_INDIA
694 # define SUBLANG_ENGLISH_INDIA 0x10
696 # ifndef SUBLANG_ENGLISH_MALAYSIA
697 # define SUBLANG_ENGLISH_MALAYSIA 0x11
699 # ifndef SUBLANG_ENGLISH_SINGAPORE
700 # define SUBLANG_ENGLISH_SINGAPORE 0x12
702 # ifndef SUBLANG_ESTONIAN_ESTONIA
703 # define SUBLANG_ESTONIAN_ESTONIA 0x01
705 # ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
706 # define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
708 # ifndef SUBLANG_FARSI_IRAN
709 # define SUBLANG_FARSI_IRAN 0x01
711 # ifndef SUBLANG_FINNISH_FINLAND
712 # define SUBLANG_FINNISH_FINLAND 0x01
714 # ifndef SUBLANG_FRENCH_LUXEMBOURG
715 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
717 # ifndef SUBLANG_FRENCH_MONACO
718 # define SUBLANG_FRENCH_MONACO 0x06
720 # ifndef SUBLANG_FRENCH_WESTINDIES
721 # define SUBLANG_FRENCH_WESTINDIES 0x07
723 # ifndef SUBLANG_FRENCH_REUNION
724 # define SUBLANG_FRENCH_REUNION 0x08
726 # ifndef SUBLANG_FRENCH_CONGO
727 # define SUBLANG_FRENCH_CONGO 0x09
729 # ifndef SUBLANG_FRENCH_SENEGAL
730 # define SUBLANG_FRENCH_SENEGAL 0x0a
732 # ifndef SUBLANG_FRENCH_CAMEROON
733 # define SUBLANG_FRENCH_CAMEROON 0x0b
735 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
736 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
738 # ifndef SUBLANG_FRENCH_MALI
739 # define SUBLANG_FRENCH_MALI 0x0d
741 # ifndef SUBLANG_FRENCH_MOROCCO
742 # define SUBLANG_FRENCH_MOROCCO 0x0e
744 # ifndef SUBLANG_FRENCH_HAITI
745 # define SUBLANG_FRENCH_HAITI 0x0f
747 # ifndef SUBLANG_FRISIAN_NETHERLANDS
748 # define SUBLANG_FRISIAN_NETHERLANDS 0x01
750 # ifndef SUBLANG_GALICIAN_SPAIN
751 # define SUBLANG_GALICIAN_SPAIN 0x01
753 # ifndef SUBLANG_GEORGIAN_GEORGIA
754 # define SUBLANG_GEORGIAN_GEORGIA 0x01
756 # ifndef SUBLANG_GERMAN_LUXEMBOURG
757 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
759 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
760 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
762 # ifndef SUBLANG_GREEK_GREECE
763 # define SUBLANG_GREEK_GREECE 0x01
765 # ifndef SUBLANG_GREENLANDIC_GREENLAND
766 # define SUBLANG_GREENLANDIC_GREENLAND 0x01
768 # ifndef SUBLANG_GUJARATI_INDIA
769 # define SUBLANG_GUJARATI_INDIA 0x01
771 # ifndef SUBLANG_HAUSA_NIGERIA_LATIN
772 # define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
774 # ifndef SUBLANG_HEBREW_ISRAEL
775 # define SUBLANG_HEBREW_ISRAEL 0x01
777 # ifndef SUBLANG_HINDI_INDIA
778 # define SUBLANG_HINDI_INDIA 0x01
780 # ifndef SUBLANG_HUNGARIAN_HUNGARY
781 # define SUBLANG_HUNGARIAN_HUNGARY 0x01
783 # ifndef SUBLANG_ICELANDIC_ICELAND
784 # define SUBLANG_ICELANDIC_ICELAND 0x01
786 # ifndef SUBLANG_IGBO_NIGERIA
787 # define SUBLANG_IGBO_NIGERIA 0x01
789 # ifndef SUBLANG_INDONESIAN_INDONESIA
790 # define SUBLANG_INDONESIAN_INDONESIA 0x01
792 # ifndef SUBLANG_INUKTITUT_CANADA
793 # define SUBLANG_INUKTITUT_CANADA 0x01
795 # undef SUBLANG_INUKTITUT_CANADA_LATIN
796 # define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
797 # undef SUBLANG_IRISH_IRELAND
798 # define SUBLANG_IRISH_IRELAND 0x02
799 # ifndef SUBLANG_JAPANESE_JAPAN
800 # define SUBLANG_JAPANESE_JAPAN 0x01
802 # ifndef SUBLANG_KANNADA_INDIA
803 # define SUBLANG_KANNADA_INDIA 0x01
805 # ifndef SUBLANG_KASHMIRI_INDIA
806 # define SUBLANG_KASHMIRI_INDIA 0x02
808 # ifndef SUBLANG_KAZAK_KAZAKHSTAN
809 # define SUBLANG_KAZAK_KAZAKHSTAN 0x01
811 # ifndef SUBLANG_KICHE_GUATEMALA
812 # define SUBLANG_KICHE_GUATEMALA 0x01
814 # ifndef SUBLANG_KINYARWANDA_RWANDA
815 # define SUBLANG_KINYARWANDA_RWANDA 0x01
817 # ifndef SUBLANG_KONKANI_INDIA
818 # define SUBLANG_KONKANI_INDIA 0x01
820 # ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
821 # define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
823 # ifndef SUBLANG_LAO_LAOS
824 # define SUBLANG_LAO_LAOS 0x01
826 # ifndef SUBLANG_LATVIAN_LATVIA
827 # define SUBLANG_LATVIAN_LATVIA 0x01
829 # ifndef SUBLANG_LITHUANIAN_LITHUANIA
830 # define SUBLANG_LITHUANIAN_LITHUANIA 0x01
832 # undef SUBLANG_LOWER_SORBIAN_GERMANY
833 # define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
834 # ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
835 # define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
837 # ifndef SUBLANG_MACEDONIAN_MACEDONIA
838 # define SUBLANG_MACEDONIAN_MACEDONIA 0x01
840 # ifndef SUBLANG_MALAY_MALAYSIA
841 # define SUBLANG_MALAY_MALAYSIA 0x01
843 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
844 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
846 # ifndef SUBLANG_MALAYALAM_INDIA
847 # define SUBLANG_MALAYALAM_INDIA 0x01
849 # ifndef SUBLANG_MALTESE_MALTA
850 # define SUBLANG_MALTESE_MALTA 0x01
852 # ifndef SUBLANG_MAORI_NEW_ZEALAND
853 # define SUBLANG_MAORI_NEW_ZEALAND 0x01
855 # ifndef SUBLANG_MAPUDUNGUN_CHILE
856 # define SUBLANG_MAPUDUNGUN_CHILE 0x01
858 # ifndef SUBLANG_MARATHI_INDIA
859 # define SUBLANG_MARATHI_INDIA 0x01
861 # ifndef SUBLANG_MOHAWK_CANADA
862 # define SUBLANG_MOHAWK_CANADA 0x01
864 # ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
865 # define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
867 # ifndef SUBLANG_MONGOLIAN_PRC
868 # define SUBLANG_MONGOLIAN_PRC 0x02
870 # ifndef SUBLANG_NEPALI_NEPAL
871 # define SUBLANG_NEPALI_NEPAL 0x01
873 # ifndef SUBLANG_NEPALI_INDIA
874 # define SUBLANG_NEPALI_INDIA 0x02
876 # ifndef SUBLANG_OCCITAN_FRANCE
877 # define SUBLANG_OCCITAN_FRANCE 0x01
879 # ifndef SUBLANG_ORIYA_INDIA
880 # define SUBLANG_ORIYA_INDIA 0x01
882 # ifndef SUBLANG_PASHTO_AFGHANISTAN
883 # define SUBLANG_PASHTO_AFGHANISTAN 0x01
885 # ifndef SUBLANG_POLISH_POLAND
886 # define SUBLANG_POLISH_POLAND 0x01
888 # ifndef SUBLANG_PUNJABI_INDIA
889 # define SUBLANG_PUNJABI_INDIA 0x01
891 # ifndef SUBLANG_PUNJABI_PAKISTAN
892 # define SUBLANG_PUNJABI_PAKISTAN 0x02
894 # ifndef SUBLANG_QUECHUA_BOLIVIA
895 # define SUBLANG_QUECHUA_BOLIVIA 0x01
897 # ifndef SUBLANG_QUECHUA_ECUADOR
898 # define SUBLANG_QUECHUA_ECUADOR 0x02
900 # ifndef SUBLANG_QUECHUA_PERU
901 # define SUBLANG_QUECHUA_PERU 0x03
903 # ifndef SUBLANG_ROMANIAN_ROMANIA
904 # define SUBLANG_ROMANIAN_ROMANIA 0x01
906 # ifndef SUBLANG_ROMANIAN_MOLDOVA
907 # define SUBLANG_ROMANIAN_MOLDOVA 0x02
909 # ifndef SUBLANG_ROMANSH_SWITZERLAND
910 # define SUBLANG_ROMANSH_SWITZERLAND 0x01
912 # ifndef SUBLANG_RUSSIAN_RUSSIA
913 # define SUBLANG_RUSSIAN_RUSSIA 0x01
915 # ifndef SUBLANG_RUSSIAN_MOLDAVIA
916 # define SUBLANG_RUSSIAN_MOLDAVIA 0x02
918 # ifndef SUBLANG_SAMI_NORTHERN_NORWAY
919 # define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
921 # ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
922 # define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
924 # ifndef SUBLANG_SAMI_NORTHERN_FINLAND
925 # define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
927 # ifndef SUBLANG_SAMI_LULE_NORWAY
928 # define SUBLANG_SAMI_LULE_NORWAY 0x04
930 # ifndef SUBLANG_SAMI_LULE_SWEDEN
931 # define SUBLANG_SAMI_LULE_SWEDEN 0x05
933 # ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
934 # define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
936 # ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
937 # define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
939 # undef SUBLANG_SAMI_SKOLT_FINLAND
940 # define SUBLANG_SAMI_SKOLT_FINLAND 0x08
941 # undef SUBLANG_SAMI_INARI_FINLAND
942 # define SUBLANG_SAMI_INARI_FINLAND 0x09
943 # ifndef SUBLANG_SANSKRIT_INDIA
944 # define SUBLANG_SANSKRIT_INDIA 0x01
946 # ifndef SUBLANG_SERBIAN_LATIN
947 # define SUBLANG_SERBIAN_LATIN 0x02
949 # ifndef SUBLANG_SERBIAN_CYRILLIC
950 # define SUBLANG_SERBIAN_CYRILLIC 0x03
952 # ifndef SUBLANG_SINDHI_INDIA
953 # define SUBLANG_SINDHI_INDIA 0x01
955 # undef SUBLANG_SINDHI_PAKISTAN
956 # define SUBLANG_SINDHI_PAKISTAN 0x02
957 # ifndef SUBLANG_SINDHI_AFGHANISTAN
958 # define SUBLANG_SINDHI_AFGHANISTAN 0x02
960 # ifndef SUBLANG_SINHALESE_SRI_LANKA
961 # define SUBLANG_SINHALESE_SRI_LANKA 0x01
963 # ifndef SUBLANG_SLOVAK_SLOVAKIA
964 # define SUBLANG_SLOVAK_SLOVAKIA 0x01
966 # ifndef SUBLANG_SLOVENIAN_SLOVENIA
967 # define SUBLANG_SLOVENIAN_SLOVENIA 0x01
969 # ifndef SUBLANG_SOTHO_SOUTH_AFRICA
970 # define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
972 # ifndef SUBLANG_SPANISH_GUATEMALA
973 # define SUBLANG_SPANISH_GUATEMALA 0x04
975 # ifndef SUBLANG_SPANISH_COSTA_RICA
976 # define SUBLANG_SPANISH_COSTA_RICA 0x05
978 # ifndef SUBLANG_SPANISH_PANAMA
979 # define SUBLANG_SPANISH_PANAMA 0x06
981 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
982 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
984 # ifndef SUBLANG_SPANISH_VENEZUELA
985 # define SUBLANG_SPANISH_VENEZUELA 0x08
987 # ifndef SUBLANG_SPANISH_COLOMBIA
988 # define SUBLANG_SPANISH_COLOMBIA 0x09
990 # ifndef SUBLANG_SPANISH_PERU
991 # define SUBLANG_SPANISH_PERU 0x0a
993 # ifndef SUBLANG_SPANISH_ARGENTINA
994 # define SUBLANG_SPANISH_ARGENTINA 0x0b
996 # ifndef SUBLANG_SPANISH_ECUADOR
997 # define SUBLANG_SPANISH_ECUADOR 0x0c
999 # ifndef SUBLANG_SPANISH_CHILE
1000 # define SUBLANG_SPANISH_CHILE 0x0d
1002 # ifndef SUBLANG_SPANISH_URUGUAY
1003 # define SUBLANG_SPANISH_URUGUAY 0x0e
1005 # ifndef SUBLANG_SPANISH_PARAGUAY
1006 # define SUBLANG_SPANISH_PARAGUAY 0x0f
1008 # ifndef SUBLANG_SPANISH_BOLIVIA
1009 # define SUBLANG_SPANISH_BOLIVIA 0x10
1011 # ifndef SUBLANG_SPANISH_EL_SALVADOR
1012 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
1014 # ifndef SUBLANG_SPANISH_HONDURAS
1015 # define SUBLANG_SPANISH_HONDURAS 0x12
1017 # ifndef SUBLANG_SPANISH_NICARAGUA
1018 # define SUBLANG_SPANISH_NICARAGUA 0x13
1020 # ifndef SUBLANG_SPANISH_PUERTO_RICO
1021 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
1023 # ifndef SUBLANG_SPANISH_US
1024 # define SUBLANG_SPANISH_US 0x15
1026 # ifndef SUBLANG_SWAHILI_KENYA
1027 # define SUBLANG_SWAHILI_KENYA 0x01
1029 # ifndef SUBLANG_SWEDISH_SWEDEN
1030 # define SUBLANG_SWEDISH_SWEDEN 0x01
1032 # ifndef SUBLANG_SWEDISH_FINLAND
1033 # define SUBLANG_SWEDISH_FINLAND 0x02
1035 # ifndef SUBLANG_SYRIAC_SYRIA
1036 # define SUBLANG_SYRIAC_SYRIA 0x01
1038 # ifndef SUBLANG_TAGALOG_PHILIPPINES
1039 # define SUBLANG_TAGALOG_PHILIPPINES 0x01
1041 # ifndef SUBLANG_TAJIK_TAJIKISTAN
1042 # define SUBLANG_TAJIK_TAJIKISTAN 0x01
1044 # ifndef SUBLANG_TAMAZIGHT_ARABIC
1045 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
1047 # ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
1048 # define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
1050 # ifndef SUBLANG_TAMIL_INDIA
1051 # define SUBLANG_TAMIL_INDIA 0x01
1053 # ifndef SUBLANG_TATAR_RUSSIA
1054 # define SUBLANG_TATAR_RUSSIA 0x01
1056 # ifndef SUBLANG_TELUGU_INDIA
1057 # define SUBLANG_TELUGU_INDIA 0x01
1059 # ifndef SUBLANG_THAI_THAILAND
1060 # define SUBLANG_THAI_THAILAND 0x01
1062 # ifndef SUBLANG_TIBETAN_PRC
1063 # define SUBLANG_TIBETAN_PRC 0x01
1065 # undef SUBLANG_TIBETAN_BHUTAN
1066 # define SUBLANG_TIBETAN_BHUTAN 0x02
1067 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
1068 # define SUBLANG_TIGRINYA_ETHIOPIA 0x01
1070 # ifndef SUBLANG_TIGRINYA_ERITREA
1071 # define SUBLANG_TIGRINYA_ERITREA 0x02
1073 # ifndef SUBLANG_TSWANA_SOUTH_AFRICA
1074 # define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
1076 # ifndef SUBLANG_TURKISH_TURKEY
1077 # define SUBLANG_TURKISH_TURKEY 0x01
1079 # ifndef SUBLANG_TURKMEN_TURKMENISTAN
1080 # define SUBLANG_TURKMEN_TURKMENISTAN 0x01
1082 # ifndef SUBLANG_UIGHUR_PRC
1083 # define SUBLANG_UIGHUR_PRC 0x01
1085 # ifndef SUBLANG_UKRAINIAN_UKRAINE
1086 # define SUBLANG_UKRAINIAN_UKRAINE 0x01
1088 # ifndef SUBLANG_UPPER_SORBIAN_GERMANY
1089 # define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
1091 # ifndef SUBLANG_URDU_PAKISTAN
1092 # define SUBLANG_URDU_PAKISTAN 0x01
1094 # ifndef SUBLANG_URDU_INDIA
1095 # define SUBLANG_URDU_INDIA 0x02
1097 # ifndef SUBLANG_UZBEK_LATIN
1098 # define SUBLANG_UZBEK_LATIN 0x01
1100 # ifndef SUBLANG_UZBEK_CYRILLIC
1101 # define SUBLANG_UZBEK_CYRILLIC 0x02
1103 # ifndef SUBLANG_VIETNAMESE_VIETNAM
1104 # define SUBLANG_VIETNAMESE_VIETNAM 0x01
1106 # ifndef SUBLANG_WELSH_UNITED_KINGDOM
1107 # define SUBLANG_WELSH_UNITED_KINGDOM 0x01
1109 # ifndef SUBLANG_WOLOF_SENEGAL
1110 # define SUBLANG_WOLOF_SENEGAL 0x01
1112 # ifndef SUBLANG_XHOSA_SOUTH_AFRICA
1113 # define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
1115 # ifndef SUBLANG_YAKUT_RUSSIA
1116 # define SUBLANG_YAKUT_RUSSIA 0x01
1118 # ifndef SUBLANG_YI_PRC
1119 # define SUBLANG_YI_PRC 0x01
1121 # ifndef SUBLANG_YORUBA_NIGERIA
1122 # define SUBLANG_YORUBA_NIGERIA 0x01
1124 # ifndef SUBLANG_ZULU_SOUTH_AFRICA
1125 # define SUBLANG_ZULU_SOUTH_AFRICA 0x01
1127 /* GetLocaleInfoA operations. */
1128 # ifndef LOCALE_SNAME
1129 # define LOCALE_SNAME 0x5c
1131 # ifndef LOCALE_NAME_MAX_LENGTH
1132 # define LOCALE_NAME_MAX_LENGTH 85
1137 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1138 /* Mac OS X 10.2 or newer */
1140 /* Canonicalize a Mac OS X locale name to a Unix locale name.
1141 NAME is a sufficiently large buffer.
1142 On input, it contains the Mac OS X locale name.
1143 On output, it contains the Unix locale name. */
1144 # if !defined IN_LIBINTL
1148 gl_locale_name_canonicalize (char *name)
1150 /* This conversion is based on a posting by
1151 Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
1152 http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
1154 /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
1155 ISO 3166) names. Prior to Mac OS X 10.3, there is no API for doing this.
1156 Therefore we do it ourselves, using a table based on the results of the
1157 Mac OS X 10.3.8 function
1158 CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
1159 typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
1161 static const legacy_entry legacy_table[] = {
1162 { "Afrikaans", "af" },
1163 { "Albanian", "sq" },
1164 { "Amharic", "am" },
1166 { "Armenian", "hy" },
1167 { "Assamese", "as" },
1169 { "Azerbaijani", "az" },
1171 { "Belarusian", "be" },
1172 { "Belorussian", "be" },
1173 { "Bengali", "bn" },
1174 { "Brazilian Portugese", "pt_BR" },
1175 { "Brazilian Portuguese", "pt_BR" },
1177 { "Bulgarian", "bg" },
1178 { "Burmese", "my" },
1179 { "Byelorussian", "be" },
1180 { "Catalan", "ca" },
1182 { "Chichewa", "ny" },
1183 { "Chinese", "zh" },
1184 { "Chinese, Simplified", "zh_CN" },
1185 { "Chinese, Traditional", "zh_TW" },
1186 { "Chinese, Tradtional", "zh_TW" },
1187 { "Croatian", "hr" },
1191 { "Dzongkha", "dz" },
1192 { "English", "en" },
1193 { "Esperanto", "eo" },
1194 { "Estonian", "et" },
1195 { "Faroese", "fo" },
1197 { "Finnish", "fi" },
1198 { "Flemish", "nl_BE" },
1200 { "Galician", "gl" },
1201 { "Gallegan", "gl" },
1202 { "Georgian", "ka" },
1205 { "Greenlandic", "kl" },
1206 { "Guarani", "gn" },
1207 { "Gujarati", "gu" },
1208 { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
1211 { "Hungarian", "hu" },
1212 { "Icelandic", "is" },
1213 { "Indonesian", "id" },
1214 { "Inuktitut", "iu" },
1216 { "Italian", "it" },
1217 { "Japanese", "ja" },
1218 { "Javanese", "jv" },
1219 { "Kalaallisut", "kl" },
1220 { "Kannada", "kn" },
1221 { "Kashmiri", "ks" },
1224 { "Kinyarwanda", "rw" },
1225 { "Kirghiz", "ky" },
1227 { "Kurdish", "ku" },
1229 { "Latvian", "lv" },
1230 { "Lithuanian", "lt" },
1231 { "Macedonian", "mk" },
1232 { "Malagasy", "mg" },
1234 { "Malayalam", "ml" },
1235 { "Maltese", "mt" },
1237 { "Marathi", "mr" },
1238 { "Moldavian", "mo" },
1239 { "Mongolian", "mn" },
1241 { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
1243 { "Nynorsk", "nn" },
1246 { "Panjabi", "pa" },
1248 { "Persian", "fa" },
1250 { "Portuguese", "pt" },
1251 { "Portuguese, Brazilian", "pt_BR" },
1252 { "Punjabi", "pa" },
1254 { "Quechua", "qu" },
1255 { "Romanian", "ro" },
1258 { "Russian", "ru" },
1259 { "Sami", "se_NO" }, /* Not just "se". */
1260 { "Sanskrit", "sa" },
1261 { "Scottish", "gd" },
1262 { "Serbian", "sr" },
1263 { "Simplified Chinese", "zh_CN" },
1265 { "Sinhalese", "si" },
1267 { "Slovenian", "sl" },
1269 { "Spanish", "es" },
1270 { "Sundanese", "su" },
1271 { "Swahili", "sw" },
1272 { "Swedish", "sv" },
1273 { "Tagalog", "tl" },
1280 { "Tibetan", "bo" },
1281 { "Tigrinya", "ti" },
1283 { "Traditional Chinese", "zh_TW" },
1284 { "Turkish", "tr" },
1285 { "Turkmen", "tk" },
1287 { "Ukrainian", "uk" },
1290 { "Vietnamese", "vi" },
1295 /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
1296 to Unix (ISO 639 and ISO 3166) names. */
1297 typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
1299 static const langtag_entry langtag_table[] = {
1300 /* Mac OS X has "az-Arab", "az-Cyrl", "az-Latn".
1301 The default script for az on Unix is Latin. */
1302 { "az-Latn", "az" },
1303 /* Mac OS X has "ga-dots". Does not yet exist on Unix. */
1304 { "ga-dots", "ga" },
1305 /* Mac OS X has "kk-Cyrl". Does not yet exist on Unix. */
1306 /* Mac OS X has "mn-Cyrl", "mn-Mong".
1307 The default script for mn on Unix is Cyrillic. */
1308 { "mn-Cyrl", "mn" },
1309 /* Mac OS X has "ms-Arab", "ms-Latn".
1310 The default script for ms on Unix is Latin. */
1311 { "ms-Latn", "ms" },
1312 /* Mac OS X has "tg-Cyrl".
1313 The default script for tg on Unix is Cyrillic. */
1314 { "tg-Cyrl", "tg" },
1315 /* Mac OS X has "tk-Cyrl". Does not yet exist on Unix. */
1316 /* Mac OS X has "tt-Cyrl".
1317 The default script for tt on Unix is Cyrillic. */
1318 { "tt-Cyrl", "tt" },
1319 /* Mac OS X has "zh-Hans", "zh-Hant".
1320 Country codes are used to distinguish these on Unix. */
1321 { "zh-Hans", "zh_CN" },
1322 { "zh-Hant", "zh_TW" }
1325 /* Convert script names (ISO 15924) to Unix conventions.
1326 See http://www.unicode.org/iso15924/iso15924-codes.html */
1327 typedef struct { const char script[4+1]; const char unixy[9+1]; }
1329 static const script_entry script_table[] = {
1330 { "Arab", "arabic" },
1331 { "Cyrl", "cyrillic" },
1332 { "Mong", "mongolian" }
1335 /* Step 1: Convert using legacy_table. */
1336 if (name[0] >= 'A' && name[0] <= 'Z')
1338 unsigned int i1, i2;
1340 i2 = sizeof (legacy_table) / sizeof (legacy_entry);
1343 /* At this point we know that if name occurs in legacy_table,
1344 its index must be >= i1 and < i2. */
1345 unsigned int i = (i1 + i2) >> 1;
1346 const legacy_entry *p = &legacy_table[i];
1347 if (strcmp (name, p->legacy) < 0)
1352 if (strcmp (name, legacy_table[i1].legacy) == 0)
1354 strcpy (name, legacy_table[i1].unixy);
1359 /* Step 2: Convert using langtag_table and script_table. */
1360 if (strlen (name) == 7 && name[2] == '-')
1362 unsigned int i1, i2;
1364 i2 = sizeof (langtag_table) / sizeof (langtag_entry);
1367 /* At this point we know that if name occurs in langtag_table,
1368 its index must be >= i1 and < i2. */
1369 unsigned int i = (i1 + i2) >> 1;
1370 const langtag_entry *p = &langtag_table[i];
1371 if (strcmp (name, p->langtag) < 0)
1376 if (strcmp (name, langtag_table[i1].langtag) == 0)
1378 strcpy (name, langtag_table[i1].unixy);
1383 i2 = sizeof (script_table) / sizeof (script_entry);
1386 /* At this point we know that if (name + 3) occurs in script_table,
1387 its index must be >= i1 and < i2. */
1388 unsigned int i = (i1 + i2) >> 1;
1389 const script_entry *p = &script_table[i];
1390 if (strcmp (name + 3, p->script) < 0)
1395 if (strcmp (name + 3, script_table[i1].script) == 0)
1398 strcpy (name + 3, script_table[i1].unixy);
1403 /* Step 3: Convert new-style dash to Unix underscore. */
1406 for (p = name; *p != '\0'; p++)
1415 #if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
1417 /* Canonicalize a Windows native locale name to a Unix locale name.
1418 NAME is a sufficiently large buffer.
1419 On input, it contains the Windows locale name.
1420 On output, it contains the Unix locale name. */
1421 # if !defined IN_LIBINTL
1425 gl_locale_name_canonicalize (char *name)
1427 /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
1431 for (p = name; *p != '\0'; p++)
1436 for (; *p != '\0'; p++)
1438 if (*p >= 'a' && *p <= 'z')
1450 # if !defined IN_LIBINTL
1454 gl_locale_name_from_win32_LANGID (LANGID langid)
1456 /* Activate the new code only when the GETTEXT_MUI environment variable is
1457 set, for the time being, since the new code is not well tested. */
1458 if (getenv ("GETTEXT_MUI") != NULL)
1460 static char namebuf[256];
1462 /* Query the system's notion of locale name.
1463 On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
1464 But we don't need to support systems that are so old. */
1465 if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
1466 namebuf, sizeof (namebuf) - 1))
1468 /* Convert it to a Unix locale name. */
1469 gl_locale_name_canonicalize (namebuf);
1473 /* Internet Explorer has an LCID to RFC3066 name mapping stored in
1474 HKEY_CLASSES_ROOT\Mime\Database\Rfc1766. But we better don't use that
1475 since IE's i18n subsystem is known to be inconsistent with the native
1476 Windows base (e.g. they have different character conversion facilities
1477 that produce different results). */
1478 /* Use our own table. */
1482 /* Split into language and territory part. */
1483 primary = PRIMARYLANGID (langid);
1484 sub = SUBLANGID (langid);
1486 /* Dispatch on language.
1487 See also http://www.unicode.org/unicode/onlinedat/languages.html .
1488 For details about languages, see http://www.ethnologue.com/ . */
1491 case LANG_AFRIKAANS:
1494 case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
1500 case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
1506 case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
1512 case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
1518 case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
1519 case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
1520 case SUBLANG_ARABIC_EGYPT: return "ar_EG";
1521 case SUBLANG_ARABIC_LIBYA: return "ar_LY";
1522 case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
1523 case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
1524 case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
1525 case SUBLANG_ARABIC_OMAN: return "ar_OM";
1526 case SUBLANG_ARABIC_YEMEN: return "ar_YE";
1527 case SUBLANG_ARABIC_SYRIA: return "ar_SY";
1528 case SUBLANG_ARABIC_JORDAN: return "ar_JO";
1529 case SUBLANG_ARABIC_LEBANON: return "ar_LB";
1530 case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
1531 case SUBLANG_ARABIC_UAE: return "ar_AE";
1532 case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
1533 case SUBLANG_ARABIC_QATAR: return "ar_QA";
1539 case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
1545 case SUBLANG_ASSAMESE_INDIA: return "as_IN";
1551 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
1552 case 0x1e: return "az@latin";
1553 case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
1554 case 0x1d: return "az@cyrillic";
1555 case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
1561 case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
1567 case SUBLANG_BASQUE_BASQUE: return "eu_ES";
1569 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
1570 case LANG_BELARUSIAN:
1573 case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
1579 case SUBLANG_BENGALI_INDIA: return "bn_IN";
1580 case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
1586 case SUBLANG_BRETON_FRANCE: return "br_FR";
1589 case LANG_BULGARIAN:
1592 case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
1598 case SUBLANG_DEFAULT: return "my_MM";
1601 case LANG_CAMBODIAN:
1604 case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
1610 case SUBLANG_CATALAN_SPAIN: return "ca_ES";
1616 case SUBLANG_DEFAULT: return "chr_US";
1622 case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
1623 case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
1624 case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
1625 case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
1626 case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
1632 case SUBLANG_CORSICAN_FRANCE: return "co_FR";
1635 case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
1636 * What used to be called Serbo-Croatian
1637 * should really now be two separate
1638 * languages because of political reasons.
1639 * (Says tml, who knows nothing about Serbian
1641 * (I can feel those flames coming already.)
1646 case 0x00: return "hr";
1647 case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
1648 case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
1650 case 0x1f: return "sr";
1651 case 0x1c: return "sr"; /* latin */
1652 case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
1653 case 0x09: return "sr_RS"; /* latin */
1654 case 0x0b: return "sr_ME"; /* latin */
1655 case 0x06: return "sr_BA"; /* latin */
1656 case 0x1b: return "sr@cyrillic";
1657 case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
1658 case 0x0a: return "sr_RS@cyrillic";
1659 case 0x0c: return "sr_ME@cyrillic";
1660 case 0x07: return "sr_BA@cyrillic";
1662 case 0x1e: return "bs";
1663 case 0x1a: return "bs"; /* latin */
1664 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
1665 case 0x19: return "bs@cyrillic";
1666 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
1672 case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
1678 case SUBLANG_DANISH_DENMARK: return "da_DK";
1682 /* FIXME: Adjust this when such locales appear on Unix. */
1685 case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
1691 case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
1697 case SUBLANG_DUTCH: return "nl_NL";
1698 case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
1699 case SUBLANG_DUTCH_SURINAM: return "nl_SR";
1705 case SUBLANG_DEFAULT: return "bin_NG";
1711 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1712 * English was the language spoken in England.
1715 case SUBLANG_ENGLISH_US: return "en_US";
1716 case SUBLANG_ENGLISH_UK: return "en_GB";
1717 case SUBLANG_ENGLISH_AUS: return "en_AU";
1718 case SUBLANG_ENGLISH_CAN: return "en_CA";
1719 case SUBLANG_ENGLISH_NZ: return "en_NZ";
1720 case SUBLANG_ENGLISH_EIRE: return "en_IE";
1721 case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
1722 case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
1723 case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
1724 case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
1725 case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
1726 case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
1727 case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
1728 case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
1729 case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
1730 case SUBLANG_ENGLISH_INDIA: return "en_IN";
1731 case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
1732 case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
1738 case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
1744 case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
1750 case SUBLANG_FARSI_IRAN: return "fa_IR";
1756 case SUBLANG_FINNISH_FINLAND: return "fi_FI";
1762 case SUBLANG_FRENCH: return "fr_FR";
1763 case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
1764 case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
1765 case SUBLANG_FRENCH_SWISS: return "fr_CH";
1766 case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
1767 case SUBLANG_FRENCH_MONACO: return "fr_MC";
1768 case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
1769 case SUBLANG_FRENCH_REUNION: return "fr_RE";
1770 case SUBLANG_FRENCH_CONGO: return "fr_CG";
1771 case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
1772 case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
1773 case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
1774 case SUBLANG_FRENCH_MALI: return "fr_ML";
1775 case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
1776 case SUBLANG_FRENCH_HAITI: return "fr_HT";
1782 case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
1786 /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
1789 case SUBLANG_DEFAULT: return "ff_NG";
1795 case 0x01: /* SCOTTISH */
1796 /* old, superseded by LANG_SCOTTISH_GAELIC */
1798 case SUBLANG_IRISH_IRELAND: return "ga_IE";
1804 case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
1810 case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
1816 case SUBLANG_GERMAN: return "de_DE";
1817 case SUBLANG_GERMAN_SWISS: return "de_CH";
1818 case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
1819 case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
1820 case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
1826 case SUBLANG_GREEK_GREECE: return "el_GR";
1829 case LANG_GREENLANDIC:
1832 case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
1838 case SUBLANG_DEFAULT: return "gn_PY";
1844 case SUBLANG_GUJARATI_INDIA: return "gu_IN";
1850 case 0x1f: return "ha";
1851 case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
1855 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1856 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
1859 case SUBLANG_DEFAULT: return "cpe_US";
1865 case SUBLANG_HEBREW_ISRAEL: return "he_IL";
1871 case SUBLANG_HINDI_INDIA: return "hi_IN";
1874 case LANG_HUNGARIAN:
1877 case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
1883 case SUBLANG_DEFAULT: return "nic_NG";
1886 case LANG_ICELANDIC:
1889 case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
1895 case SUBLANG_IGBO_NIGERIA: return "ig_NG";
1898 case LANG_INDONESIAN:
1901 case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
1904 case LANG_INUKTITUT:
1907 case 0x1e: return "iu"; /* syllabic */
1908 case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
1909 case 0x1f: return "iu@latin";
1910 case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
1916 case SUBLANG_ITALIAN: return "it_IT";
1917 case SUBLANG_ITALIAN_SWISS: return "it_CH";
1923 case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
1929 case SUBLANG_KANNADA_INDIA: return "kn_IN";
1935 case SUBLANG_DEFAULT: return "kr_NG";
1941 case SUBLANG_DEFAULT: return "ks_PK";
1942 case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
1948 case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
1952 /* FIXME: Adjust this when such locales appear on Unix. */
1955 case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
1958 case LANG_KINYARWANDA:
1961 case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
1965 /* FIXME: Adjust this when such locales appear on Unix. */
1968 case SUBLANG_KONKANI_INDIA: return "kok_IN";
1974 case SUBLANG_DEFAULT: return "ko_KR";
1980 case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
1986 case SUBLANG_LAO_LAOS: return "lo_LA";
1992 case SUBLANG_DEFAULT: return "la_VA";
1998 case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
2001 case LANG_LITHUANIAN:
2004 case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
2007 case LANG_LUXEMBOURGISH:
2010 case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
2013 case LANG_MACEDONIAN:
2016 case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
2022 case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
2023 case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
2026 case LANG_MALAYALAM:
2029 case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
2035 case SUBLANG_MALTESE_MALTA: return "mt_MT";
2039 /* FIXME: Adjust this when such locales appear on Unix. */
2042 case SUBLANG_DEFAULT: return "mni_IN";
2048 case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
2051 case LANG_MAPUDUNGUN:
2054 case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
2060 case SUBLANG_MARATHI_INDIA: return "mr_IN";
2066 case SUBLANG_MOHAWK_CANADA: return "moh_CA";
2069 case LANG_MONGOLIAN:
2072 case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
2073 case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
2075 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
2079 case SUBLANG_NEPALI_NEPAL: return "ne_NP";
2080 case SUBLANG_NEPALI_INDIA: return "ne_IN";
2083 case LANG_NORWEGIAN:
2086 case 0x1f: return "nb";
2087 case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
2088 case 0x1e: return "nn";
2089 case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
2095 case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
2101 case SUBLANG_ORIYA_INDIA: return "or_IN";
2107 case SUBLANG_DEFAULT: return "om_ET";
2110 case LANG_PAPIAMENTU:
2113 case SUBLANG_DEFAULT: return "pap_AN";
2119 case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
2121 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
2125 case SUBLANG_POLISH_POLAND: return "pl_PL";
2128 case LANG_PORTUGUESE:
2131 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
2132 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
2133 case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
2134 case SUBLANG_PORTUGUESE: return "pt_PT";
2140 case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
2141 case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
2145 /* Note: Microsoft uses the non-ISO language code "quz". */
2148 case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
2149 case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
2150 case SUBLANG_QUECHUA_PERU: return "qu_PE";
2156 case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
2157 case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
2163 case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
2169 case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
2170 case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
2172 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
2177 case 0x00: return "se";
2178 case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
2179 case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
2180 case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
2182 case 0x1f: return "smj";
2183 case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
2184 case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
2186 case 0x1e: return "sma";
2187 case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
2188 case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
2190 case 0x1d: return "sms";
2191 case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
2193 case 0x1c: return "smn";
2194 case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
2196 return "se"; /* or "smi"? */
2200 case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
2203 case LANG_SCOTTISH_GAELIC:
2206 case SUBLANG_DEFAULT: return "gd_GB";
2212 case SUBLANG_SINDHI_INDIA: return "sd_IN";
2213 case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
2214 /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
2217 case LANG_SINHALESE:
2220 case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
2226 case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
2229 case LANG_SLOVENIAN:
2232 case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
2238 case SUBLANG_DEFAULT: return "so_SO";
2242 /* FIXME: Adjust this when such locales appear on Unix. */
2246 case 0x00: return "hsb";
2247 case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
2249 case 0x1f: return "dsb";
2250 case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
2254 /* <http://www.microsoft.com/globaldev/reference/lcid-all.mspx> calls
2255 it "Sepedi"; according to
2256 <http://www.ethnologue.com/show_language.asp?code=nso>
2257 <http://www.ethnologue.com/show_language.asp?code=sot>
2258 it's the same as Northern Sotho. */
2261 case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
2267 case SUBLANG_SPANISH: return "es_ES";
2268 case SUBLANG_SPANISH_MEXICAN: return "es_MX";
2269 case SUBLANG_SPANISH_MODERN:
2270 return "es_ES@modern"; /* not seen on Unix */
2271 case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
2272 case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
2273 case SUBLANG_SPANISH_PANAMA: return "es_PA";
2274 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
2275 case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
2276 case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
2277 case SUBLANG_SPANISH_PERU: return "es_PE";
2278 case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
2279 case SUBLANG_SPANISH_ECUADOR: return "es_EC";
2280 case SUBLANG_SPANISH_CHILE: return "es_CL";
2281 case SUBLANG_SPANISH_URUGUAY: return "es_UY";
2282 case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
2283 case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
2284 case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
2285 case SUBLANG_SPANISH_HONDURAS: return "es_HN";
2286 case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
2287 case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
2288 case SUBLANG_SPANISH_US: return "es_US";
2294 case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
2300 case SUBLANG_SWAHILI_KENYA: return "sw_KE";
2306 case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
2307 case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
2313 case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language. */
2319 case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
2321 return "tl"; /* or "fil"? */
2325 case 0x1f: return "tg";
2326 case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
2329 case LANG_TAMAZIGHT:
2330 /* Note: Microsoft uses the non-ISO language code "tmz". */
2333 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
2334 case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
2335 case 0x1f: return "ber@latin";
2336 case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
2342 case SUBLANG_TAMIL_INDIA: return "ta_IN";
2344 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
2348 case SUBLANG_TATAR_RUSSIA: return "tt_RU";
2354 case SUBLANG_TELUGU_INDIA: return "te_IN";
2360 case SUBLANG_THAI_THAILAND: return "th_TH";
2366 case SUBLANG_TIBETAN_PRC:
2367 /* Most Tibetans would not like "bo_CN". But Tibet does not yet
2368 have a country code of its own. */
2370 case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
2376 case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
2377 case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
2383 case SUBLANG_DEFAULT: return "ts_ZA";
2387 /* Spoken in South Africa, Botswana. */
2390 case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
2396 case SUBLANG_TURKISH_TURKEY: return "tr_TR";
2402 case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
2408 case SUBLANG_UIGHUR_PRC: return "ug_CN";
2411 case LANG_UKRAINIAN:
2414 case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
2420 case SUBLANG_URDU_PAKISTAN: return "ur_PK";
2421 case SUBLANG_URDU_INDIA: return "ur_IN";
2427 case 0x1f: return "uz";
2428 case SUBLANG_UZBEK_LATIN: return "uz_UZ";
2429 case 0x1e: return "uz@cyrillic";
2430 case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
2436 case SUBLANG_DEFAULT: return "ve_ZA";
2439 case LANG_VIETNAMESE:
2442 case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
2448 case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
2454 case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
2460 case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
2466 case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
2472 case SUBLANG_YI_PRC: return "ii_CN";
2478 case SUBLANG_DEFAULT: return "yi_IL";
2484 case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
2490 case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
2493 default: return "C";
2498 # if !defined IN_LIBINTL
2502 gl_locale_name_from_win32_LCID (LCID lcid)
2506 /* Strip off the sorting rules, keep only the language part. */
2507 langid = LANGIDFROMLCID (lcid);
2509 return gl_locale_name_from_win32_LANGID (langid);
2512 # ifdef WINDOWS_NATIVE
2514 /* Two variables to interface between get_lcid and the EnumLocales
2515 callback function below. */
2516 static LCID found_lcid;
2517 static char lname[LC_MAX * (LOCALE_NAME_MAX_LENGTH + 1) + 1];
2519 /* Callback function for EnumLocales. */
2520 static BOOL CALLBACK
2521 enum_locales_fn (LPTSTR locale_num_str)
2524 char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
2525 LCID try_lcid = strtoul (locale_num_str, &endp, 16);
2527 if (GetLocaleInfo (try_lcid, LOCALE_SENGLANGUAGE,
2528 locval, LOCALE_NAME_MAX_LENGTH))
2530 strcat (locval, "_");
2531 if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
2532 locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
2534 size_t locval_len = strlen (locval);
2536 if (strncmp (locval, lname, locval_len) == 0
2537 && (lname[locval_len] == '.'
2538 || lname[locval_len] == '\0'))
2540 found_lcid = try_lcid;
2548 /* This lock protects the get_lcid against multiple simultaneous calls. */
2549 gl_lock_define_initialized(static, get_lcid_lock)
2551 /* Return the Locale ID (LCID) number given the locale's name, a
2552 string, in LOCALE_NAME. This works by enumerating all the locales
2553 supported by the system, until we find one whose name matches
2556 get_lcid (const char *locale_name)
2558 /* A simple cache. */
2559 static LCID last_lcid;
2560 static char last_locale[1000];
2562 /* Lock while looking for an LCID, to protect access to static
2563 variables: last_lcid, last_locale, found_lcid, and lname. */
2564 gl_lock_lock (get_lcid_lock);
2565 if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
2567 gl_lock_unlock (get_lcid_lock);
2570 strncpy (lname, locale_name, sizeof (lname) - 1);
2571 lname[sizeof (lname) - 1] = '\0';
2573 EnumSystemLocales (enum_locales_fn, LCID_SUPPORTED);
2576 last_lcid = found_lcid;
2577 strcpy (last_locale, locale_name);
2579 gl_lock_unlock (get_lcid_lock);
2587 #if HAVE_USELOCALE /* glibc or Mac OS X */
2589 /* Simple hash set of strings. We don't want to drag in lots of hash table
2592 # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
2594 /* A hash function for NUL-terminated char* strings using
2595 the method described by Bruno Haible.
2596 See http://www.haible.de/bruno/hashfunc.html. */
2597 static size_t _GL_ATTRIBUTE_PURE
2598 string_hash (const void *x)
2600 const char *s = (const char *) x;
2604 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
2609 /* A hash table of fixed size. Multiple threads can access it read-only
2610 simultaneously, but only one thread can insert into it at the same time. */
2612 /* A node in a hash bucket collision list. */
2615 struct hash_node * volatile next;
2616 char contents[100]; /* has variable size */
2619 # define HASH_TABLE_SIZE 257
2620 static struct hash_node * volatile struniq_hash_table[HASH_TABLE_SIZE]
2621 /* = { NULL, ..., NULL } */;
2623 /* This lock protects the struniq_hash_table against multiple simultaneous
2625 gl_lock_define_initialized(static, struniq_lock)
2627 /* Store a copy of the given string in a string pool with indefinite extent.
2628 Return a pointer to this copy. */
2630 struniq (const char *string)
2632 size_t hashcode = string_hash (string);
2633 size_t slot = hashcode % HASH_TABLE_SIZE;
2635 struct hash_node *new_node;
2636 struct hash_node *p;
2637 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2638 if (strcmp (p->contents, string) == 0)
2640 size = strlen (string) + 1;
2642 (struct hash_node *)
2643 malloc (offsetof (struct hash_node, contents[0]) + size);
2644 if (new_node == NULL)
2645 /* Out of memory. Return a statically allocated string. */
2647 memcpy (new_node->contents, string, size);
2648 /* Lock while inserting new_node. */
2649 gl_lock_lock (struniq_lock);
2650 /* Check whether another thread already added the string while we were
2651 waiting on the lock. */
2652 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2653 if (strcmp (p->contents, string) == 0)
2659 /* Really insert new_node into the hash table. Fill new_node entirely first,
2660 because other threads may be iterating over the linked list. */
2661 new_node->next = struniq_hash_table[slot];
2662 struniq_hash_table[slot] = new_node;
2664 /* Unlock after new_node is inserted. */
2665 gl_lock_unlock (struniq_lock);
2666 return new_node->contents;
2672 #if defined IN_LIBINTL || HAVE_USELOCALE
2674 /* Like gl_locale_name_thread, except that the result is not in storage of
2675 indefinite extent. */
2676 # if !defined IN_LIBINTL
2680 gl_locale_name_thread_unsafe (int category, const char *categoryname)
2684 locale_t thread_locale = uselocale (NULL);
2685 if (thread_locale != LC_GLOBAL_LOCALE)
2687 # if __GLIBC__ >= 2 && !defined __UCLIBC__
2688 /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
2690 See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>. */
2692 nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
2693 if (name[0] == '\0')
2694 /* Fallback code for glibc < 2.4, which did not implement
2695 nl_langinfo (_NL_LOCALE_NAME (category)). */
2696 name = thread_locale->__names[category];
2698 # elif defined __FreeBSD__ || (defined __APPLE__ && defined __MACH__)
2699 /* FreeBSD, Mac OS X */
2705 mask = LC_CTYPE_MASK;
2708 mask = LC_NUMERIC_MASK;
2711 mask = LC_TIME_MASK;
2714 mask = LC_COLLATE_MASK;
2717 mask = LC_MONETARY_MASK;
2720 mask = LC_MESSAGES_MASK;
2722 default: /* We shouldn't get here. */
2725 return querylocale (mask, thread_locale);
2736 gl_locale_name_thread (int category, const char *categoryname)
2739 const char *name = gl_locale_name_thread_unsafe (category, categoryname);
2741 return struniq (name);
2742 #elif defined WINDOWS_NATIVE
2743 if (LC_MIN <= category && category <= LC_MAX)
2745 char *locname = setlocale (category, NULL);
2748 /* If CATEGORY is LC_ALL, the result might be a semi-colon
2749 separated list of locales. We need only one, so we take the
2750 one corresponding to LC_CTYPE, as the most important for
2751 character translations. */
2752 if (strchr (locname, ';'))
2753 locname = setlocale (LC_CTYPE, NULL);
2755 /* Convert locale name to LCID. We don't want to use
2756 LocaleNameToLCID because (a) it is only available since Vista,
2757 and (b) it doesn't accept locale names returned by 'setlocale'. */
2758 lcid = get_lcid (locname);
2761 return gl_locale_name_from_win32_LCID (lcid);
2767 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
2768 "Directs 'setlocale()' to query 'category' and return the current
2769 setting of 'local'."
2770 However it does not specify the exact format. Neither do SUSV2 and
2771 ISO C 99. So we can use this feature only on selected systems (e.g.
2772 those using GNU C Library). */
2773 #if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
2774 # define HAVE_LOCALE_NULL
2778 gl_locale_name_posix (int category, const char *categoryname)
2780 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
2781 On some systems this can be done by the 'setlocale' function itself. */
2782 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
2783 return setlocale (category, NULL);
2785 /* On other systems we ignore what setlocale reports and instead look at the
2786 environment variables directly. This is necessary
2787 1. on systems which have a facility for customizing the default locale
2788 (Mac OS X, native Windows, Cygwin) and where the system's setlocale()
2789 function ignores this default locale (Mac OS X, Cygwin), in two cases:
2790 a. when the user missed to use the setlocale() override from libintl
2791 (for example by not including <libintl.h>),
2792 b. when setlocale supports only the "C" locale, such as on Cygwin
2793 1.5.x. In this case even the override from libintl cannot help.
2794 2. on all systems where setlocale supports only the "C" locale. */
2795 /* Strictly speaking, it is a POSIX violation to look at the environment
2796 variables regardless whether setlocale has been called or not. POSIX
2798 "For C-language programs, the POSIX locale shall be the
2799 default locale when the setlocale() function is not called."
2800 But we assume that all programs that use internationalized APIs call
2801 setlocale (LC_ALL, ""). */
2802 return gl_locale_name_environ (category, categoryname);
2807 gl_locale_name_environ (int category, const char *categoryname)
2811 /* Setting of LC_ALL overrides all other. */
2812 retval = getenv ("LC_ALL");
2813 if (retval != NULL && retval[0] != '\0')
2815 /* Next comes the name of the desired category. */
2816 retval = getenv (categoryname);
2817 if (retval != NULL && retval[0] != '\0')
2819 /* Last possibility is the LANG environment variable. */
2820 retval = getenv ("LANG");
2821 if (retval != NULL && retval[0] != '\0')
2823 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2824 /* Mac OS X 10.2 or newer.
2825 Ignore invalid LANG value set by the Terminal application. */
2826 if (strcmp (retval, "UTF-8") != 0)
2828 #if defined __CYGWIN__
2830 Ignore dummy LANG value set by ~/.profile. */
2831 if (strcmp (retval, "C.UTF-8") != 0)
2840 gl_locale_name_default (void)
2843 "All implementations shall define a locale as the default locale, to be
2844 invoked when no environment variables are set, or set to the empty
2845 string. This default locale can be the POSIX locale or any other
2846 implementation-defined locale. Some implementations may provide
2847 facilities for local installation administrators to set the default
2848 locale, customizing it for each location. POSIX:2001 does not require
2851 The systems with such a facility are Mac OS X and Windows: They provide a
2852 GUI that allows the user to choose a locale.
2853 - On Mac OS X, by default, none of LC_* or LANG are set. Starting with
2854 Mac OS X 10.4 or 10.5, LANG is set for processes launched by the
2855 'Terminal' application (but sometimes to an incorrect value "UTF-8").
2856 When no environment variable is set, setlocale (LC_ALL, "") uses the
2858 - On native Windows, by default, none of LC_* or LANG are set.
2859 When no environment variable is set, setlocale (LC_ALL, "") uses the
2860 locale chosen by the user.
2861 - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
2862 When no environment variable is set, setlocale (LC_ALL, "") uses the
2864 - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
2865 ~/.profile is executed.
2866 When no environment variable is set, setlocale (LC_ALL, "") uses the
2867 "C.UTF-8" locale, which operates in the same way as the "C" locale.
2870 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WINDOWS_NATIVE || defined __CYGWIN__)
2872 /* The system does not have a way of setting the locale, other than the
2873 POSIX specified environment variables. We use C as default locale. */
2878 /* Return an XPG style locale name language[_territory][@modifier].
2879 Don't even bother determining the codeset; it's not useful in this
2880 context, because message catalogs are not specific to a single
2883 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2884 /* Mac OS X 10.2 or newer */
2886 /* Cache the locale name, since CoreFoundation calls are expensive. */
2887 static const char *cached_localename;
2889 if (cached_localename == NULL)
2892 # if HAVE_CFLOCALECOPYCURRENT /* Mac OS X 10.3 or newer */
2893 CFLocaleRef locale = CFLocaleCopyCurrent ();
2894 CFStringRef name = CFLocaleGetIdentifier (locale);
2896 if (CFStringGetCString (name, namebuf, sizeof (namebuf),
2897 kCFStringEncodingASCII))
2899 gl_locale_name_canonicalize (namebuf);
2900 cached_localename = strdup (namebuf);
2903 # elif HAVE_CFPREFERENCESCOPYAPPVALUE /* Mac OS X 10.2 or newer */
2905 CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
2906 kCFPreferencesCurrentApplication);
2908 && CFGetTypeID (value) == CFStringGetTypeID ()
2909 && CFStringGetCString ((CFStringRef)value,
2910 namebuf, sizeof (namebuf),
2911 kCFStringEncodingASCII))
2913 gl_locale_name_canonicalize (namebuf);
2914 cached_localename = strdup (namebuf);
2917 if (cached_localename == NULL)
2918 cached_localename = "C";
2920 return cached_localename;
2925 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
2929 /* Use native Windows API locale ID. */
2930 lcid = GetThreadLocale ();
2932 return gl_locale_name_from_win32_LCID (lcid);
2938 /* Determine the current locale's name, and canonicalize it into XPG syntax
2939 language[_territory][.codeset][@modifier]
2940 The codeset part in the result is not reliable; the locale_charset()
2941 should be used for codeset information instead.
2942 The result must not be freed; it is statically allocated. */
2945 gl_locale_name (int category, const char *categoryname)
2949 retval = gl_locale_name_thread (category, categoryname);
2953 retval = gl_locale_name_posix (category, categoryname);
2957 return gl_locale_name_default ();