1 /* Determine name of the currently selected locale.
2 Copyright (C) 1995-2011 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 /* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
19 /* MacOS X code written by Bruno Haible <bruno@clisp.org>. */
25 # include "gettextP.h"
27 # include "localename.h"
37 /* MacOS 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__
60 #if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
61 # define WIN32_LEAN_AND_MEAN
63 /* List of language codes, sorted by value:
89 0x1a LANG_CROATIAN == LANG_SERBIAN
171 0x6e LANG_LUXEMBOURGISH
172 0x6f LANG_GREENLANDIC
191 0x87 LANG_KINYARWANDA
194 0x91 LANG_SCOTTISH_GAELIC
196 /* Mingw headers don't have latest language and sublanguage codes. */
197 # ifndef LANG_AFRIKAANS
198 # define LANG_AFRIKAANS 0x36
200 # ifndef LANG_ALBANIAN
201 # define LANG_ALBANIAN 0x1c
203 # ifndef LANG_ALSATIAN
204 # define LANG_ALSATIAN 0x84
206 # ifndef LANG_AMHARIC
207 # define LANG_AMHARIC 0x5e
210 # define LANG_ARABIC 0x01
212 # ifndef LANG_ARMENIAN
213 # define LANG_ARMENIAN 0x2b
215 # ifndef LANG_ASSAMESE
216 # define LANG_ASSAMESE 0x4d
219 # define LANG_AZERI 0x2c
221 # ifndef LANG_BASHKIR
222 # define LANG_BASHKIR 0x6d
225 # define LANG_BASQUE 0x2d
227 # ifndef LANG_BELARUSIAN
228 # define LANG_BELARUSIAN 0x23
230 # ifndef LANG_BENGALI
231 # define LANG_BENGALI 0x45
234 # define LANG_BRETON 0x7e
236 # ifndef LANG_BURMESE
237 # define LANG_BURMESE 0x55
239 # ifndef LANG_CAMBODIAN
240 # define LANG_CAMBODIAN 0x53
242 # ifndef LANG_CATALAN
243 # define LANG_CATALAN 0x03
245 # ifndef LANG_CHEROKEE
246 # define LANG_CHEROKEE 0x5c
248 # ifndef LANG_CORSICAN
249 # define LANG_CORSICAN 0x83
252 # define LANG_DARI 0x8c
255 # define LANG_DIVEHI 0x65
258 # define LANG_EDO 0x66
260 # ifndef LANG_ESTONIAN
261 # define LANG_ESTONIAN 0x25
263 # ifndef LANG_FAEROESE
264 # define LANG_FAEROESE 0x38
267 # define LANG_FARSI 0x29
269 # ifndef LANG_FRISIAN
270 # define LANG_FRISIAN 0x62
272 # ifndef LANG_FULFULDE
273 # define LANG_FULFULDE 0x67
276 # define LANG_GAELIC 0x3c
278 # ifndef LANG_GALICIAN
279 # define LANG_GALICIAN 0x56
281 # ifndef LANG_GEORGIAN
282 # define LANG_GEORGIAN 0x37
284 # ifndef LANG_GREENLANDIC
285 # define LANG_GREENLANDIC 0x6f
287 # ifndef LANG_GUARANI
288 # define LANG_GUARANI 0x74
290 # ifndef LANG_GUJARATI
291 # define LANG_GUJARATI 0x47
294 # define LANG_HAUSA 0x68
296 # ifndef LANG_HAWAIIAN
297 # define LANG_HAWAIIAN 0x75
300 # define LANG_HEBREW 0x0d
303 # define LANG_HINDI 0x39
306 # define LANG_IBIBIO 0x69
309 # define LANG_IGBO 0x70
311 # ifndef LANG_INDONESIAN
312 # define LANG_INDONESIAN 0x21
314 # ifndef LANG_INUKTITUT
315 # define LANG_INUKTITUT 0x5d
317 # ifndef LANG_KANNADA
318 # define LANG_KANNADA 0x4b
321 # define LANG_KANURI 0x71
323 # ifndef LANG_KASHMIRI
324 # define LANG_KASHMIRI 0x60
327 # define LANG_KAZAK 0x3f
330 # define LANG_KICHE 0x86
332 # ifndef LANG_KINYARWANDA
333 # define LANG_KINYARWANDA 0x87
335 # ifndef LANG_KONKANI
336 # define LANG_KONKANI 0x57
339 # define LANG_KYRGYZ 0x40
342 # define LANG_LAO 0x54
345 # define LANG_LATIN 0x76
347 # ifndef LANG_LATVIAN
348 # define LANG_LATVIAN 0x26
350 # ifndef LANG_LITHUANIAN
351 # define LANG_LITHUANIAN 0x27
353 # ifndef LANG_LUXEMBOURGISH
354 # define LANG_LUXEMBOURGISH 0x6e
356 # ifndef LANG_MACEDONIAN
357 # define LANG_MACEDONIAN 0x2f
360 # define LANG_MALAY 0x3e
362 # ifndef LANG_MALAYALAM
363 # define LANG_MALAYALAM 0x4c
365 # ifndef LANG_MALTESE
366 # define LANG_MALTESE 0x3a
368 # ifndef LANG_MANIPURI
369 # define LANG_MANIPURI 0x58
372 # define LANG_MAORI 0x81
374 # ifndef LANG_MAPUDUNGUN
375 # define LANG_MAPUDUNGUN 0x7a
377 # ifndef LANG_MARATHI
378 # define LANG_MARATHI 0x4e
381 # define LANG_MOHAWK 0x7c
383 # ifndef LANG_MONGOLIAN
384 # define LANG_MONGOLIAN 0x50
387 # define LANG_NEPALI 0x61
389 # ifndef LANG_OCCITAN
390 # define LANG_OCCITAN 0x82
393 # define LANG_ORIYA 0x48
396 # define LANG_OROMO 0x72
398 # ifndef LANG_PAPIAMENTU
399 # define LANG_PAPIAMENTU 0x79
402 # define LANG_PASHTO 0x63
404 # ifndef LANG_PUNJABI
405 # define LANG_PUNJABI 0x46
407 # ifndef LANG_QUECHUA
408 # define LANG_QUECHUA 0x6b
410 # ifndef LANG_ROMANSH
411 # define LANG_ROMANSH 0x17
414 # define LANG_SAMI 0x3b
416 # ifndef LANG_SANSKRIT
417 # define LANG_SANSKRIT 0x4f
419 # ifndef LANG_SCOTTISH_GAELIC
420 # define LANG_SCOTTISH_GAELIC 0x91
422 # ifndef LANG_SERBIAN
423 # define LANG_SERBIAN 0x1a
426 # define LANG_SINDHI 0x59
428 # ifndef LANG_SINHALESE
429 # define LANG_SINHALESE 0x5b
432 # define LANG_SLOVAK 0x1b
435 # define LANG_SOMALI 0x77
437 # ifndef LANG_SORBIAN
438 # define LANG_SORBIAN 0x2e
441 # define LANG_SOTHO 0x6c
444 # define LANG_SUTU 0x30
446 # ifndef LANG_SWAHILI
447 # define LANG_SWAHILI 0x41
450 # define LANG_SYRIAC 0x5a
452 # ifndef LANG_TAGALOG
453 # define LANG_TAGALOG 0x64
456 # define LANG_TAJIK 0x28
458 # ifndef LANG_TAMAZIGHT
459 # define LANG_TAMAZIGHT 0x5f
462 # define LANG_TAMIL 0x49
465 # define LANG_TATAR 0x44
468 # define LANG_TELUGU 0x4a
471 # define LANG_THAI 0x1e
473 # ifndef LANG_TIBETAN
474 # define LANG_TIBETAN 0x51
476 # ifndef LANG_TIGRINYA
477 # define LANG_TIGRINYA 0x73
480 # define LANG_TSONGA 0x31
483 # define LANG_TSWANA 0x32
485 # ifndef LANG_TURKMEN
486 # define LANG_TURKMEN 0x42
489 # define LANG_UIGHUR 0x80
491 # ifndef LANG_UKRAINIAN
492 # define LANG_UKRAINIAN 0x22
495 # define LANG_URDU 0x20
498 # define LANG_UZBEK 0x43
501 # define LANG_VENDA 0x33
503 # ifndef LANG_VIETNAMESE
504 # define LANG_VIETNAMESE 0x2a
507 # define LANG_WELSH 0x52
510 # define LANG_WOLOF 0x88
513 # define LANG_XHOSA 0x34
516 # define LANG_YAKUT 0x85
519 # define LANG_YI 0x78
521 # ifndef LANG_YIDDISH
522 # define LANG_YIDDISH 0x3d
525 # define LANG_YORUBA 0x6a
528 # define LANG_ZULU 0x35
530 # ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
531 # define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
533 # ifndef SUBLANG_ALBANIAN_ALBANIA
534 # define SUBLANG_ALBANIAN_ALBANIA 0x01
536 # ifndef SUBLANG_ALSATIAN_FRANCE
537 # define SUBLANG_ALSATIAN_FRANCE 0x01
539 # ifndef SUBLANG_AMHARIC_ETHIOPIA
540 # define SUBLANG_AMHARIC_ETHIOPIA 0x01
542 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
543 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
545 # ifndef SUBLANG_ARABIC_IRAQ
546 # define SUBLANG_ARABIC_IRAQ 0x02
548 # ifndef SUBLANG_ARABIC_EGYPT
549 # define SUBLANG_ARABIC_EGYPT 0x03
551 # ifndef SUBLANG_ARABIC_LIBYA
552 # define SUBLANG_ARABIC_LIBYA 0x04
554 # ifndef SUBLANG_ARABIC_ALGERIA
555 # define SUBLANG_ARABIC_ALGERIA 0x05
557 # ifndef SUBLANG_ARABIC_MOROCCO
558 # define SUBLANG_ARABIC_MOROCCO 0x06
560 # ifndef SUBLANG_ARABIC_TUNISIA
561 # define SUBLANG_ARABIC_TUNISIA 0x07
563 # ifndef SUBLANG_ARABIC_OMAN
564 # define SUBLANG_ARABIC_OMAN 0x08
566 # ifndef SUBLANG_ARABIC_YEMEN
567 # define SUBLANG_ARABIC_YEMEN 0x09
569 # ifndef SUBLANG_ARABIC_SYRIA
570 # define SUBLANG_ARABIC_SYRIA 0x0a
572 # ifndef SUBLANG_ARABIC_JORDAN
573 # define SUBLANG_ARABIC_JORDAN 0x0b
575 # ifndef SUBLANG_ARABIC_LEBANON
576 # define SUBLANG_ARABIC_LEBANON 0x0c
578 # ifndef SUBLANG_ARABIC_KUWAIT
579 # define SUBLANG_ARABIC_KUWAIT 0x0d
581 # ifndef SUBLANG_ARABIC_UAE
582 # define SUBLANG_ARABIC_UAE 0x0e
584 # ifndef SUBLANG_ARABIC_BAHRAIN
585 # define SUBLANG_ARABIC_BAHRAIN 0x0f
587 # ifndef SUBLANG_ARABIC_QATAR
588 # define SUBLANG_ARABIC_QATAR 0x10
590 # ifndef SUBLANG_ARMENIAN_ARMENIA
591 # define SUBLANG_ARMENIAN_ARMENIA 0x01
593 # ifndef SUBLANG_ASSAMESE_INDIA
594 # define SUBLANG_ASSAMESE_INDIA 0x01
596 # ifndef SUBLANG_AZERI_LATIN
597 # define SUBLANG_AZERI_LATIN 0x01
599 # ifndef SUBLANG_AZERI_CYRILLIC
600 # define SUBLANG_AZERI_CYRILLIC 0x02
602 # ifndef SUBLANG_BASHKIR_RUSSIA
603 # define SUBLANG_BASHKIR_RUSSIA 0x01
605 # ifndef SUBLANG_BASQUE_BASQUE
606 # define SUBLANG_BASQUE_BASQUE 0x01
608 # ifndef SUBLANG_BELARUSIAN_BELARUS
609 # define SUBLANG_BELARUSIAN_BELARUS 0x01
611 # ifndef SUBLANG_BENGALI_INDIA
612 # define SUBLANG_BENGALI_INDIA 0x01
614 # ifndef SUBLANG_BENGALI_BANGLADESH
615 # define SUBLANG_BENGALI_BANGLADESH 0x02
617 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
618 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
620 # ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
621 # define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
623 # ifndef SUBLANG_BRETON_FRANCE
624 # define SUBLANG_BRETON_FRANCE 0x01
626 # ifndef SUBLANG_BULGARIAN_BULGARIA
627 # define SUBLANG_BULGARIAN_BULGARIA 0x01
629 # ifndef SUBLANG_CAMBODIAN_CAMBODIA
630 # define SUBLANG_CAMBODIAN_CAMBODIA 0x01
632 # ifndef SUBLANG_CATALAN_SPAIN
633 # define SUBLANG_CATALAN_SPAIN 0x01
635 # ifndef SUBLANG_CORSICAN_FRANCE
636 # define SUBLANG_CORSICAN_FRANCE 0x01
638 # ifndef SUBLANG_CROATIAN_CROATIA
639 # define SUBLANG_CROATIAN_CROATIA 0x01
641 # ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
642 # define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
644 # ifndef SUBLANG_CHINESE_MACAU
645 # define SUBLANG_CHINESE_MACAU 0x05
647 # ifndef SUBLANG_CZECH_CZECH_REPUBLIC
648 # define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
650 # ifndef SUBLANG_DANISH_DENMARK
651 # define SUBLANG_DANISH_DENMARK 0x01
653 # ifndef SUBLANG_DARI_AFGHANISTAN
654 # define SUBLANG_DARI_AFGHANISTAN 0x01
656 # ifndef SUBLANG_DIVEHI_MALDIVES
657 # define SUBLANG_DIVEHI_MALDIVES 0x01
659 # ifndef SUBLANG_DUTCH_SURINAM
660 # define SUBLANG_DUTCH_SURINAM 0x03
662 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
663 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
665 # ifndef SUBLANG_ENGLISH_JAMAICA
666 # define SUBLANG_ENGLISH_JAMAICA 0x08
668 # ifndef SUBLANG_ENGLISH_CARIBBEAN
669 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
671 # ifndef SUBLANG_ENGLISH_BELIZE
672 # define SUBLANG_ENGLISH_BELIZE 0x0a
674 # ifndef SUBLANG_ENGLISH_TRINIDAD
675 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
677 # ifndef SUBLANG_ENGLISH_ZIMBABWE
678 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
680 # ifndef SUBLANG_ENGLISH_PHILIPPINES
681 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
683 # ifndef SUBLANG_ENGLISH_INDONESIA
684 # define SUBLANG_ENGLISH_INDONESIA 0x0e
686 # ifndef SUBLANG_ENGLISH_HONGKONG
687 # define SUBLANG_ENGLISH_HONGKONG 0x0f
689 # ifndef SUBLANG_ENGLISH_INDIA
690 # define SUBLANG_ENGLISH_INDIA 0x10
692 # ifndef SUBLANG_ENGLISH_MALAYSIA
693 # define SUBLANG_ENGLISH_MALAYSIA 0x11
695 # ifndef SUBLANG_ENGLISH_SINGAPORE
696 # define SUBLANG_ENGLISH_SINGAPORE 0x12
698 # ifndef SUBLANG_ESTONIAN_ESTONIA
699 # define SUBLANG_ESTONIAN_ESTONIA 0x01
701 # ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
702 # define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
704 # ifndef SUBLANG_FARSI_IRAN
705 # define SUBLANG_FARSI_IRAN 0x01
707 # ifndef SUBLANG_FINNISH_FINLAND
708 # define SUBLANG_FINNISH_FINLAND 0x01
710 # ifndef SUBLANG_FRENCH_LUXEMBOURG
711 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
713 # ifndef SUBLANG_FRENCH_MONACO
714 # define SUBLANG_FRENCH_MONACO 0x06
716 # ifndef SUBLANG_FRENCH_WESTINDIES
717 # define SUBLANG_FRENCH_WESTINDIES 0x07
719 # ifndef SUBLANG_FRENCH_REUNION
720 # define SUBLANG_FRENCH_REUNION 0x08
722 # ifndef SUBLANG_FRENCH_CONGO
723 # define SUBLANG_FRENCH_CONGO 0x09
725 # ifndef SUBLANG_FRENCH_SENEGAL
726 # define SUBLANG_FRENCH_SENEGAL 0x0a
728 # ifndef SUBLANG_FRENCH_CAMEROON
729 # define SUBLANG_FRENCH_CAMEROON 0x0b
731 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
732 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
734 # ifndef SUBLANG_FRENCH_MALI
735 # define SUBLANG_FRENCH_MALI 0x0d
737 # ifndef SUBLANG_FRENCH_MOROCCO
738 # define SUBLANG_FRENCH_MOROCCO 0x0e
740 # ifndef SUBLANG_FRENCH_HAITI
741 # define SUBLANG_FRENCH_HAITI 0x0f
743 # ifndef SUBLANG_FRISIAN_NETHERLANDS
744 # define SUBLANG_FRISIAN_NETHERLANDS 0x01
746 # ifndef SUBLANG_GALICIAN_SPAIN
747 # define SUBLANG_GALICIAN_SPAIN 0x01
749 # ifndef SUBLANG_GEORGIAN_GEORGIA
750 # define SUBLANG_GEORGIAN_GEORGIA 0x01
752 # ifndef SUBLANG_GERMAN_LUXEMBOURG
753 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
755 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
756 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
758 # ifndef SUBLANG_GREEK_GREECE
759 # define SUBLANG_GREEK_GREECE 0x01
761 # ifndef SUBLANG_GREENLANDIC_GREENLAND
762 # define SUBLANG_GREENLANDIC_GREENLAND 0x01
764 # ifndef SUBLANG_GUJARATI_INDIA
765 # define SUBLANG_GUJARATI_INDIA 0x01
767 # ifndef SUBLANG_HAUSA_NIGERIA_LATIN
768 # define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
770 # ifndef SUBLANG_HEBREW_ISRAEL
771 # define SUBLANG_HEBREW_ISRAEL 0x01
773 # ifndef SUBLANG_HINDI_INDIA
774 # define SUBLANG_HINDI_INDIA 0x01
776 # ifndef SUBLANG_HUNGARIAN_HUNGARY
777 # define SUBLANG_HUNGARIAN_HUNGARY 0x01
779 # ifndef SUBLANG_ICELANDIC_ICELAND
780 # define SUBLANG_ICELANDIC_ICELAND 0x01
782 # ifndef SUBLANG_IGBO_NIGERIA
783 # define SUBLANG_IGBO_NIGERIA 0x01
785 # ifndef SUBLANG_INDONESIAN_INDONESIA
786 # define SUBLANG_INDONESIAN_INDONESIA 0x01
788 # ifndef SUBLANG_INUKTITUT_CANADA
789 # define SUBLANG_INUKTITUT_CANADA 0x01
791 # undef SUBLANG_INUKTITUT_CANADA_LATIN
792 # define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
793 # undef SUBLANG_IRISH_IRELAND
794 # define SUBLANG_IRISH_IRELAND 0x02
795 # ifndef SUBLANG_JAPANESE_JAPAN
796 # define SUBLANG_JAPANESE_JAPAN 0x01
798 # ifndef SUBLANG_KANNADA_INDIA
799 # define SUBLANG_KANNADA_INDIA 0x01
801 # ifndef SUBLANG_KASHMIRI_INDIA
802 # define SUBLANG_KASHMIRI_INDIA 0x02
804 # ifndef SUBLANG_KAZAK_KAZAKHSTAN
805 # define SUBLANG_KAZAK_KAZAKHSTAN 0x01
807 # ifndef SUBLANG_KICHE_GUATEMALA
808 # define SUBLANG_KICHE_GUATEMALA 0x01
810 # ifndef SUBLANG_KINYARWANDA_RWANDA
811 # define SUBLANG_KINYARWANDA_RWANDA 0x01
813 # ifndef SUBLANG_KONKANI_INDIA
814 # define SUBLANG_KONKANI_INDIA 0x01
816 # ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
817 # define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
819 # ifndef SUBLANG_LAO_LAOS
820 # define SUBLANG_LAO_LAOS 0x01
822 # ifndef SUBLANG_LATVIAN_LATVIA
823 # define SUBLANG_LATVIAN_LATVIA 0x01
825 # ifndef SUBLANG_LITHUANIAN_LITHUANIA
826 # define SUBLANG_LITHUANIAN_LITHUANIA 0x01
828 # undef SUBLANG_LOWER_SORBIAN_GERMANY
829 # define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
830 # ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
831 # define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
833 # ifndef SUBLANG_MACEDONIAN_MACEDONIA
834 # define SUBLANG_MACEDONIAN_MACEDONIA 0x01
836 # ifndef SUBLANG_MALAY_MALAYSIA
837 # define SUBLANG_MALAY_MALAYSIA 0x01
839 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
840 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
842 # ifndef SUBLANG_MALAYALAM_INDIA
843 # define SUBLANG_MALAYALAM_INDIA 0x01
845 # ifndef SUBLANG_MALTESE_MALTA
846 # define SUBLANG_MALTESE_MALTA 0x01
848 # ifndef SUBLANG_MAORI_NEW_ZEALAND
849 # define SUBLANG_MAORI_NEW_ZEALAND 0x01
851 # ifndef SUBLANG_MAPUDUNGUN_CHILE
852 # define SUBLANG_MAPUDUNGUN_CHILE 0x01
854 # ifndef SUBLANG_MARATHI_INDIA
855 # define SUBLANG_MARATHI_INDIA 0x01
857 # ifndef SUBLANG_MOHAWK_CANADA
858 # define SUBLANG_MOHAWK_CANADA 0x01
860 # ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
861 # define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
863 # ifndef SUBLANG_MONGOLIAN_PRC
864 # define SUBLANG_MONGOLIAN_PRC 0x02
866 # ifndef SUBLANG_NEPALI_NEPAL
867 # define SUBLANG_NEPALI_NEPAL 0x01
869 # ifndef SUBLANG_NEPALI_INDIA
870 # define SUBLANG_NEPALI_INDIA 0x02
872 # ifndef SUBLANG_OCCITAN_FRANCE
873 # define SUBLANG_OCCITAN_FRANCE 0x01
875 # ifndef SUBLANG_ORIYA_INDIA
876 # define SUBLANG_ORIYA_INDIA 0x01
878 # ifndef SUBLANG_PASHTO_AFGHANISTAN
879 # define SUBLANG_PASHTO_AFGHANISTAN 0x01
881 # ifndef SUBLANG_POLISH_POLAND
882 # define SUBLANG_POLISH_POLAND 0x01
884 # ifndef SUBLANG_PUNJABI_INDIA
885 # define SUBLANG_PUNJABI_INDIA 0x01
887 # ifndef SUBLANG_PUNJABI_PAKISTAN
888 # define SUBLANG_PUNJABI_PAKISTAN 0x02
890 # ifndef SUBLANG_QUECHUA_BOLIVIA
891 # define SUBLANG_QUECHUA_BOLIVIA 0x01
893 # ifndef SUBLANG_QUECHUA_ECUADOR
894 # define SUBLANG_QUECHUA_ECUADOR 0x02
896 # ifndef SUBLANG_QUECHUA_PERU
897 # define SUBLANG_QUECHUA_PERU 0x03
899 # ifndef SUBLANG_ROMANIAN_ROMANIA
900 # define SUBLANG_ROMANIAN_ROMANIA 0x01
902 # ifndef SUBLANG_ROMANIAN_MOLDOVA
903 # define SUBLANG_ROMANIAN_MOLDOVA 0x02
905 # ifndef SUBLANG_ROMANSH_SWITZERLAND
906 # define SUBLANG_ROMANSH_SWITZERLAND 0x01
908 # ifndef SUBLANG_RUSSIAN_RUSSIA
909 # define SUBLANG_RUSSIAN_RUSSIA 0x01
911 # ifndef SUBLANG_RUSSIAN_MOLDAVIA
912 # define SUBLANG_RUSSIAN_MOLDAVIA 0x02
914 # ifndef SUBLANG_SAMI_NORTHERN_NORWAY
915 # define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
917 # ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
918 # define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
920 # ifndef SUBLANG_SAMI_NORTHERN_FINLAND
921 # define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
923 # ifndef SUBLANG_SAMI_LULE_NORWAY
924 # define SUBLANG_SAMI_LULE_NORWAY 0x04
926 # ifndef SUBLANG_SAMI_LULE_SWEDEN
927 # define SUBLANG_SAMI_LULE_SWEDEN 0x05
929 # ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
930 # define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
932 # ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
933 # define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
935 # undef SUBLANG_SAMI_SKOLT_FINLAND
936 # define SUBLANG_SAMI_SKOLT_FINLAND 0x08
937 # undef SUBLANG_SAMI_INARI_FINLAND
938 # define SUBLANG_SAMI_INARI_FINLAND 0x09
939 # ifndef SUBLANG_SANSKRIT_INDIA
940 # define SUBLANG_SANSKRIT_INDIA 0x01
942 # ifndef SUBLANG_SERBIAN_LATIN
943 # define SUBLANG_SERBIAN_LATIN 0x02
945 # ifndef SUBLANG_SERBIAN_CYRILLIC
946 # define SUBLANG_SERBIAN_CYRILLIC 0x03
948 # ifndef SUBLANG_SINDHI_INDIA
949 # define SUBLANG_SINDHI_INDIA 0x01
951 # undef SUBLANG_SINDHI_PAKISTAN
952 # define SUBLANG_SINDHI_PAKISTAN 0x02
953 # ifndef SUBLANG_SINDHI_AFGHANISTAN
954 # define SUBLANG_SINDHI_AFGHANISTAN 0x02
956 # ifndef SUBLANG_SINHALESE_SRI_LANKA
957 # define SUBLANG_SINHALESE_SRI_LANKA 0x01
959 # ifndef SUBLANG_SLOVAK_SLOVAKIA
960 # define SUBLANG_SLOVAK_SLOVAKIA 0x01
962 # ifndef SUBLANG_SLOVENIAN_SLOVENIA
963 # define SUBLANG_SLOVENIAN_SLOVENIA 0x01
965 # ifndef SUBLANG_SOTHO_SOUTH_AFRICA
966 # define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
968 # ifndef SUBLANG_SPANISH_GUATEMALA
969 # define SUBLANG_SPANISH_GUATEMALA 0x04
971 # ifndef SUBLANG_SPANISH_COSTA_RICA
972 # define SUBLANG_SPANISH_COSTA_RICA 0x05
974 # ifndef SUBLANG_SPANISH_PANAMA
975 # define SUBLANG_SPANISH_PANAMA 0x06
977 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
978 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
980 # ifndef SUBLANG_SPANISH_VENEZUELA
981 # define SUBLANG_SPANISH_VENEZUELA 0x08
983 # ifndef SUBLANG_SPANISH_COLOMBIA
984 # define SUBLANG_SPANISH_COLOMBIA 0x09
986 # ifndef SUBLANG_SPANISH_PERU
987 # define SUBLANG_SPANISH_PERU 0x0a
989 # ifndef SUBLANG_SPANISH_ARGENTINA
990 # define SUBLANG_SPANISH_ARGENTINA 0x0b
992 # ifndef SUBLANG_SPANISH_ECUADOR
993 # define SUBLANG_SPANISH_ECUADOR 0x0c
995 # ifndef SUBLANG_SPANISH_CHILE
996 # define SUBLANG_SPANISH_CHILE 0x0d
998 # ifndef SUBLANG_SPANISH_URUGUAY
999 # define SUBLANG_SPANISH_URUGUAY 0x0e
1001 # ifndef SUBLANG_SPANISH_PARAGUAY
1002 # define SUBLANG_SPANISH_PARAGUAY 0x0f
1004 # ifndef SUBLANG_SPANISH_BOLIVIA
1005 # define SUBLANG_SPANISH_BOLIVIA 0x10
1007 # ifndef SUBLANG_SPANISH_EL_SALVADOR
1008 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
1010 # ifndef SUBLANG_SPANISH_HONDURAS
1011 # define SUBLANG_SPANISH_HONDURAS 0x12
1013 # ifndef SUBLANG_SPANISH_NICARAGUA
1014 # define SUBLANG_SPANISH_NICARAGUA 0x13
1016 # ifndef SUBLANG_SPANISH_PUERTO_RICO
1017 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
1019 # ifndef SUBLANG_SPANISH_US
1020 # define SUBLANG_SPANISH_US 0x15
1022 # ifndef SUBLANG_SWAHILI_KENYA
1023 # define SUBLANG_SWAHILI_KENYA 0x01
1025 # ifndef SUBLANG_SWEDISH_SWEDEN
1026 # define SUBLANG_SWEDISH_SWEDEN 0x01
1028 # ifndef SUBLANG_SWEDISH_FINLAND
1029 # define SUBLANG_SWEDISH_FINLAND 0x02
1031 # ifndef SUBLANG_SYRIAC_SYRIA
1032 # define SUBLANG_SYRIAC_SYRIA 0x01
1034 # ifndef SUBLANG_TAGALOG_PHILIPPINES
1035 # define SUBLANG_TAGALOG_PHILIPPINES 0x01
1037 # ifndef SUBLANG_TAJIK_TAJIKISTAN
1038 # define SUBLANG_TAJIK_TAJIKISTAN 0x01
1040 # ifndef SUBLANG_TAMAZIGHT_ARABIC
1041 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
1043 # ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
1044 # define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
1046 # ifndef SUBLANG_TAMIL_INDIA
1047 # define SUBLANG_TAMIL_INDIA 0x01
1049 # ifndef SUBLANG_TATAR_RUSSIA
1050 # define SUBLANG_TATAR_RUSSIA 0x01
1052 # ifndef SUBLANG_TELUGU_INDIA
1053 # define SUBLANG_TELUGU_INDIA 0x01
1055 # ifndef SUBLANG_THAI_THAILAND
1056 # define SUBLANG_THAI_THAILAND 0x01
1058 # ifndef SUBLANG_TIBETAN_PRC
1059 # define SUBLANG_TIBETAN_PRC 0x01
1061 # undef SUBLANG_TIBETAN_BHUTAN
1062 # define SUBLANG_TIBETAN_BHUTAN 0x02
1063 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
1064 # define SUBLANG_TIGRINYA_ETHIOPIA 0x01
1066 # ifndef SUBLANG_TIGRINYA_ERITREA
1067 # define SUBLANG_TIGRINYA_ERITREA 0x02
1069 # ifndef SUBLANG_TSWANA_SOUTH_AFRICA
1070 # define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
1072 # ifndef SUBLANG_TURKISH_TURKEY
1073 # define SUBLANG_TURKISH_TURKEY 0x01
1075 # ifndef SUBLANG_TURKMEN_TURKMENISTAN
1076 # define SUBLANG_TURKMEN_TURKMENISTAN 0x01
1078 # ifndef SUBLANG_UIGHUR_PRC
1079 # define SUBLANG_UIGHUR_PRC 0x01
1081 # ifndef SUBLANG_UKRAINIAN_UKRAINE
1082 # define SUBLANG_UKRAINIAN_UKRAINE 0x01
1084 # ifndef SUBLANG_UPPER_SORBIAN_GERMANY
1085 # define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
1087 # ifndef SUBLANG_URDU_PAKISTAN
1088 # define SUBLANG_URDU_PAKISTAN 0x01
1090 # ifndef SUBLANG_URDU_INDIA
1091 # define SUBLANG_URDU_INDIA 0x02
1093 # ifndef SUBLANG_UZBEK_LATIN
1094 # define SUBLANG_UZBEK_LATIN 0x01
1096 # ifndef SUBLANG_UZBEK_CYRILLIC
1097 # define SUBLANG_UZBEK_CYRILLIC 0x02
1099 # ifndef SUBLANG_VIETNAMESE_VIETNAM
1100 # define SUBLANG_VIETNAMESE_VIETNAM 0x01
1102 # ifndef SUBLANG_WELSH_UNITED_KINGDOM
1103 # define SUBLANG_WELSH_UNITED_KINGDOM 0x01
1105 # ifndef SUBLANG_WOLOF_SENEGAL
1106 # define SUBLANG_WOLOF_SENEGAL 0x01
1108 # ifndef SUBLANG_XHOSA_SOUTH_AFRICA
1109 # define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
1111 # ifndef SUBLANG_YAKUT_RUSSIA
1112 # define SUBLANG_YAKUT_RUSSIA 0x01
1114 # ifndef SUBLANG_YI_PRC
1115 # define SUBLANG_YI_PRC 0x01
1117 # ifndef SUBLANG_YORUBA_NIGERIA
1118 # define SUBLANG_YORUBA_NIGERIA 0x01
1120 # ifndef SUBLANG_ZULU_SOUTH_AFRICA
1121 # define SUBLANG_ZULU_SOUTH_AFRICA 0x01
1123 /* GetLocaleInfoA operations. */
1124 # ifndef LOCALE_SNAME
1125 # define LOCALE_SNAME 0x5c
1130 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1131 /* MacOS X 10.2 or newer */
1133 /* Canonicalize a MacOS X locale name to a Unix locale name.
1134 NAME is a sufficiently large buffer.
1135 On input, it contains the MacOS X locale name.
1136 On output, it contains the Unix locale name. */
1137 # if !defined IN_LIBINTL
1141 gl_locale_name_canonicalize (char *name)
1143 /* This conversion is based on a posting by
1144 Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
1145 http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
1147 /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
1148 ISO 3166) names. Prior to MacOS X 10.3, there is no API for doing this.
1149 Therefore we do it ourselves, using a table based on the results of the
1150 MacOS X 10.3.8 function
1151 CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
1152 typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
1154 static const legacy_entry legacy_table[] = {
1155 { "Afrikaans", "af" },
1156 { "Albanian", "sq" },
1157 { "Amharic", "am" },
1159 { "Armenian", "hy" },
1160 { "Assamese", "as" },
1162 { "Azerbaijani", "az" },
1164 { "Belarusian", "be" },
1165 { "Belorussian", "be" },
1166 { "Bengali", "bn" },
1167 { "Brazilian Portugese", "pt_BR" },
1168 { "Brazilian Portuguese", "pt_BR" },
1170 { "Bulgarian", "bg" },
1171 { "Burmese", "my" },
1172 { "Byelorussian", "be" },
1173 { "Catalan", "ca" },
1175 { "Chichewa", "ny" },
1176 { "Chinese", "zh" },
1177 { "Chinese, Simplified", "zh_CN" },
1178 { "Chinese, Traditional", "zh_TW" },
1179 { "Chinese, Tradtional", "zh_TW" },
1180 { "Croatian", "hr" },
1184 { "Dzongkha", "dz" },
1185 { "English", "en" },
1186 { "Esperanto", "eo" },
1187 { "Estonian", "et" },
1188 { "Faroese", "fo" },
1190 { "Finnish", "fi" },
1191 { "Flemish", "nl_BE" },
1193 { "Galician", "gl" },
1194 { "Gallegan", "gl" },
1195 { "Georgian", "ka" },
1198 { "Greenlandic", "kl" },
1199 { "Guarani", "gn" },
1200 { "Gujarati", "gu" },
1201 { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
1204 { "Hungarian", "hu" },
1205 { "Icelandic", "is" },
1206 { "Indonesian", "id" },
1207 { "Inuktitut", "iu" },
1209 { "Italian", "it" },
1210 { "Japanese", "ja" },
1211 { "Javanese", "jv" },
1212 { "Kalaallisut", "kl" },
1213 { "Kannada", "kn" },
1214 { "Kashmiri", "ks" },
1217 { "Kinyarwanda", "rw" },
1218 { "Kirghiz", "ky" },
1220 { "Kurdish", "ku" },
1222 { "Latvian", "lv" },
1223 { "Lithuanian", "lt" },
1224 { "Macedonian", "mk" },
1225 { "Malagasy", "mg" },
1227 { "Malayalam", "ml" },
1228 { "Maltese", "mt" },
1230 { "Marathi", "mr" },
1231 { "Moldavian", "mo" },
1232 { "Mongolian", "mn" },
1234 { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
1236 { "Nynorsk", "nn" },
1239 { "Panjabi", "pa" },
1241 { "Persian", "fa" },
1243 { "Portuguese", "pt" },
1244 { "Portuguese, Brazilian", "pt_BR" },
1245 { "Punjabi", "pa" },
1247 { "Quechua", "qu" },
1248 { "Romanian", "ro" },
1251 { "Russian", "ru" },
1252 { "Sami", "se_NO" }, /* Not just "se". */
1253 { "Sanskrit", "sa" },
1254 { "Scottish", "gd" },
1255 { "Serbian", "sr" },
1256 { "Simplified Chinese", "zh_CN" },
1258 { "Sinhalese", "si" },
1260 { "Slovenian", "sl" },
1262 { "Spanish", "es" },
1263 { "Sundanese", "su" },
1264 { "Swahili", "sw" },
1265 { "Swedish", "sv" },
1266 { "Tagalog", "tl" },
1273 { "Tibetan", "bo" },
1274 { "Tigrinya", "ti" },
1276 { "Traditional Chinese", "zh_TW" },
1277 { "Turkish", "tr" },
1278 { "Turkmen", "tk" },
1280 { "Ukrainian", "uk" },
1283 { "Vietnamese", "vi" },
1288 /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
1289 to Unix (ISO 639 and ISO 3166) names. */
1290 typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
1292 static const langtag_entry langtag_table[] = {
1293 /* MacOS X has "az-Arab", "az-Cyrl", "az-Latn".
1294 The default script for az on Unix is Latin. */
1295 { "az-Latn", "az" },
1296 /* MacOS X has "ga-dots". Does not yet exist on Unix. */
1297 { "ga-dots", "ga" },
1298 /* MacOS X has "kk-Cyrl". Does not yet exist on Unix. */
1299 /* MacOS X has "mn-Cyrl", "mn-Mong".
1300 The default script for mn on Unix is Cyrillic. */
1301 { "mn-Cyrl", "mn" },
1302 /* MacOS X has "ms-Arab", "ms-Latn".
1303 The default script for ms on Unix is Latin. */
1304 { "ms-Latn", "ms" },
1305 /* MacOS X has "tg-Cyrl".
1306 The default script for tg on Unix is Cyrillic. */
1307 { "tg-Cyrl", "tg" },
1308 /* MacOS X has "tk-Cyrl". Does not yet exist on Unix. */
1309 /* MacOS X has "tt-Cyrl".
1310 The default script for tt on Unix is Cyrillic. */
1311 { "tt-Cyrl", "tt" },
1312 /* MacOS X has "zh-Hans", "zh-Hant".
1313 Country codes are used to distinguish these on Unix. */
1314 { "zh-Hans", "zh_CN" },
1315 { "zh-Hant", "zh_TW" }
1318 /* Convert script names (ISO 15924) to Unix conventions.
1319 See http://www.unicode.org/iso15924/iso15924-codes.html */
1320 typedef struct { const char script[4+1]; const char unixy[9+1]; }
1322 static const script_entry script_table[] = {
1323 { "Arab", "arabic" },
1324 { "Cyrl", "cyrillic" },
1325 { "Mong", "mongolian" }
1328 /* Step 1: Convert using legacy_table. */
1329 if (name[0] >= 'A' && name[0] <= 'Z')
1331 unsigned int i1, i2;
1333 i2 = sizeof (legacy_table) / sizeof (legacy_entry);
1336 /* At this point we know that if name occurs in legacy_table,
1337 its index must be >= i1 and < i2. */
1338 unsigned int i = (i1 + i2) >> 1;
1339 const legacy_entry *p = &legacy_table[i];
1340 if (strcmp (name, p->legacy) < 0)
1345 if (strcmp (name, legacy_table[i1].legacy) == 0)
1347 strcpy (name, legacy_table[i1].unixy);
1352 /* Step 2: Convert using langtag_table and script_table. */
1353 if (strlen (name) == 7 && name[2] == '-')
1355 unsigned int i1, i2;
1357 i2 = sizeof (langtag_table) / sizeof (langtag_entry);
1360 /* At this point we know that if name occurs in langtag_table,
1361 its index must be >= i1 and < i2. */
1362 unsigned int i = (i1 + i2) >> 1;
1363 const langtag_entry *p = &langtag_table[i];
1364 if (strcmp (name, p->langtag) < 0)
1369 if (strcmp (name, langtag_table[i1].langtag) == 0)
1371 strcpy (name, langtag_table[i1].unixy);
1376 i2 = sizeof (script_table) / sizeof (script_entry);
1379 /* At this point we know that if (name + 3) occurs in script_table,
1380 its index must be >= i1 and < i2. */
1381 unsigned int i = (i1 + i2) >> 1;
1382 const script_entry *p = &script_table[i];
1383 if (strcmp (name + 3, p->script) < 0)
1388 if (strcmp (name + 3, script_table[i1].script) == 0)
1391 strcpy (name + 3, script_table[i1].unixy);
1396 /* Step 3: Convert new-style dash to Unix underscore. */
1399 for (p = name; *p != '\0'; p++)
1408 #if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
1410 /* Canonicalize a Win32 native locale name to a Unix locale name.
1411 NAME is a sufficiently large buffer.
1412 On input, it contains the Win32 locale name.
1413 On output, it contains the Unix locale name. */
1414 # if !defined IN_LIBINTL
1418 gl_locale_name_canonicalize (char *name)
1420 /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
1424 for (p = name; *p != '\0'; p++)
1429 for (; *p != '\0'; p++)
1431 if (*p >= 'a' && *p <= 'z')
1443 # if !defined IN_LIBINTL
1447 gl_locale_name_from_win32_LANGID (LANGID langid)
1449 /* Activate the new code only when the GETTEXT_MUI environment variable is
1450 set, for the time being, since the new code is not well tested. */
1451 if (getenv ("GETTEXT_MUI") != NULL)
1453 static char namebuf[256];
1455 /* Query the system's notion of locale name.
1456 On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
1457 But we don't need to support systems that are so old. */
1458 if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
1459 namebuf, sizeof (namebuf) - 1))
1461 /* Convert it to a Unix locale name. */
1462 gl_locale_name_canonicalize (namebuf);
1466 /* Internet Explorer has an LCID to RFC3066 name mapping stored in
1467 HKEY_CLASSES_ROOT\Mime\Database\Rfc1766. But we better don't use that
1468 since IE's i18n subsystem is known to be inconsistent with the Win32 base
1469 (e.g. they have different character conversion facilities that produce
1470 different results). */
1471 /* Use our own table. */
1475 /* Split into language and territory part. */
1476 primary = PRIMARYLANGID (langid);
1477 sub = SUBLANGID (langid);
1479 /* Dispatch on language.
1480 See also http://www.unicode.org/unicode/onlinedat/languages.html .
1481 For details about languages, see http://www.ethnologue.com/ . */
1484 case LANG_AFRIKAANS:
1487 case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
1493 case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
1499 case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
1505 case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
1511 case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
1512 case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
1513 case SUBLANG_ARABIC_EGYPT: return "ar_EG";
1514 case SUBLANG_ARABIC_LIBYA: return "ar_LY";
1515 case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
1516 case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
1517 case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
1518 case SUBLANG_ARABIC_OMAN: return "ar_OM";
1519 case SUBLANG_ARABIC_YEMEN: return "ar_YE";
1520 case SUBLANG_ARABIC_SYRIA: return "ar_SY";
1521 case SUBLANG_ARABIC_JORDAN: return "ar_JO";
1522 case SUBLANG_ARABIC_LEBANON: return "ar_LB";
1523 case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
1524 case SUBLANG_ARABIC_UAE: return "ar_AE";
1525 case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
1526 case SUBLANG_ARABIC_QATAR: return "ar_QA";
1532 case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
1538 case SUBLANG_ASSAMESE_INDIA: return "as_IN";
1544 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
1545 case 0x1e: return "az@latin";
1546 case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
1547 case 0x1d: return "az@cyrillic";
1548 case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
1554 case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
1560 case SUBLANG_BASQUE_BASQUE: return "eu_ES";
1562 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
1563 case LANG_BELARUSIAN:
1566 case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
1572 case SUBLANG_BENGALI_INDIA: return "bn_IN";
1573 case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
1579 case SUBLANG_BRETON_FRANCE: return "br_FR";
1582 case LANG_BULGARIAN:
1585 case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
1591 case SUBLANG_DEFAULT: return "my_MM";
1594 case LANG_CAMBODIAN:
1597 case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
1603 case SUBLANG_CATALAN_SPAIN: return "ca_ES";
1609 case SUBLANG_DEFAULT: return "chr_US";
1615 case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
1616 case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
1617 case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
1618 case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
1619 case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
1625 case SUBLANG_CORSICAN_FRANCE: return "co_FR";
1628 case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
1629 * What used to be called Serbo-Croatian
1630 * should really now be two separate
1631 * languages because of political reasons.
1632 * (Says tml, who knows nothing about Serbian
1634 * (I can feel those flames coming already.)
1639 case 0x00: return "hr";
1640 case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
1641 case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
1643 case 0x1f: return "sr";
1644 case 0x1c: return "sr"; /* latin */
1645 case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
1646 case 0x09: return "sr_RS"; /* latin */
1647 case 0x0b: return "sr_ME"; /* latin */
1648 case 0x06: return "sr_BA"; /* latin */
1649 case 0x1b: return "sr@cyrillic";
1650 case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
1651 case 0x0a: return "sr_RS@cyrillic";
1652 case 0x0c: return "sr_ME@cyrillic";
1653 case 0x07: return "sr_BA@cyrillic";
1655 case 0x1e: return "bs";
1656 case 0x1a: return "bs"; /* latin */
1657 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
1658 case 0x19: return "bs@cyrillic";
1659 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
1665 case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
1671 case SUBLANG_DANISH_DENMARK: return "da_DK";
1675 /* FIXME: Adjust this when such locales appear on Unix. */
1678 case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
1684 case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
1690 case SUBLANG_DUTCH: return "nl_NL";
1691 case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
1692 case SUBLANG_DUTCH_SURINAM: return "nl_SR";
1698 case SUBLANG_DEFAULT: return "bin_NG";
1704 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1705 * English was the language spoken in England.
1708 case SUBLANG_ENGLISH_US: return "en_US";
1709 case SUBLANG_ENGLISH_UK: return "en_GB";
1710 case SUBLANG_ENGLISH_AUS: return "en_AU";
1711 case SUBLANG_ENGLISH_CAN: return "en_CA";
1712 case SUBLANG_ENGLISH_NZ: return "en_NZ";
1713 case SUBLANG_ENGLISH_EIRE: return "en_IE";
1714 case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
1715 case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
1716 case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
1717 case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
1718 case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
1719 case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
1720 case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
1721 case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
1722 case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
1723 case SUBLANG_ENGLISH_INDIA: return "en_IN";
1724 case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
1725 case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
1731 case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
1737 case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
1743 case SUBLANG_FARSI_IRAN: return "fa_IR";
1749 case SUBLANG_FINNISH_FINLAND: return "fi_FI";
1755 case SUBLANG_FRENCH: return "fr_FR";
1756 case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
1757 case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
1758 case SUBLANG_FRENCH_SWISS: return "fr_CH";
1759 case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
1760 case SUBLANG_FRENCH_MONACO: return "fr_MC";
1761 case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
1762 case SUBLANG_FRENCH_REUNION: return "fr_RE";
1763 case SUBLANG_FRENCH_CONGO: return "fr_CG";
1764 case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
1765 case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
1766 case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
1767 case SUBLANG_FRENCH_MALI: return "fr_ML";
1768 case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
1769 case SUBLANG_FRENCH_HAITI: return "fr_HT";
1775 case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
1779 /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
1782 case SUBLANG_DEFAULT: return "ff_NG";
1788 case 0x01: /* SCOTTISH */
1789 /* old, superseded by LANG_SCOTTISH_GAELIC */
1791 case SUBLANG_IRISH_IRELAND: return "ga_IE";
1797 case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
1803 case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
1809 case SUBLANG_GERMAN: return "de_DE";
1810 case SUBLANG_GERMAN_SWISS: return "de_CH";
1811 case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
1812 case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
1813 case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
1819 case SUBLANG_GREEK_GREECE: return "el_GR";
1822 case LANG_GREENLANDIC:
1825 case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
1831 case SUBLANG_DEFAULT: return "gn_PY";
1837 case SUBLANG_GUJARATI_INDIA: return "gu_IN";
1843 case 0x1f: return "ha";
1844 case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
1848 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1849 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
1852 case SUBLANG_DEFAULT: return "cpe_US";
1858 case SUBLANG_HEBREW_ISRAEL: return "he_IL";
1864 case SUBLANG_HINDI_INDIA: return "hi_IN";
1867 case LANG_HUNGARIAN:
1870 case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
1876 case SUBLANG_DEFAULT: return "nic_NG";
1879 case LANG_ICELANDIC:
1882 case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
1888 case SUBLANG_IGBO_NIGERIA: return "ig_NG";
1891 case LANG_INDONESIAN:
1894 case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
1897 case LANG_INUKTITUT:
1900 case 0x1e: return "iu"; /* syllabic */
1901 case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
1902 case 0x1f: return "iu@latin";
1903 case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
1909 case SUBLANG_ITALIAN: return "it_IT";
1910 case SUBLANG_ITALIAN_SWISS: return "it_CH";
1916 case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
1922 case SUBLANG_KANNADA_INDIA: return "kn_IN";
1928 case SUBLANG_DEFAULT: return "kr_NG";
1934 case SUBLANG_DEFAULT: return "ks_PK";
1935 case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
1941 case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
1945 /* FIXME: Adjust this when such locales appear on Unix. */
1948 case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
1951 case LANG_KINYARWANDA:
1954 case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
1958 /* FIXME: Adjust this when such locales appear on Unix. */
1961 case SUBLANG_KONKANI_INDIA: return "kok_IN";
1967 case SUBLANG_DEFAULT: return "ko_KR";
1973 case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
1979 case SUBLANG_LAO_LAOS: return "lo_LA";
1985 case SUBLANG_DEFAULT: return "la_VA";
1991 case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
1994 case LANG_LITHUANIAN:
1997 case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
2000 case LANG_LUXEMBOURGISH:
2003 case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
2006 case LANG_MACEDONIAN:
2009 case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
2015 case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
2016 case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
2019 case LANG_MALAYALAM:
2022 case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
2028 case SUBLANG_MALTESE_MALTA: return "mt_MT";
2032 /* FIXME: Adjust this when such locales appear on Unix. */
2035 case SUBLANG_DEFAULT: return "mni_IN";
2041 case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
2044 case LANG_MAPUDUNGUN:
2047 case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
2053 case SUBLANG_MARATHI_INDIA: return "mr_IN";
2059 case SUBLANG_MOHAWK_CANADA: return "moh_CA";
2062 case LANG_MONGOLIAN:
2065 case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
2066 case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
2068 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
2072 case SUBLANG_NEPALI_NEPAL: return "ne_NP";
2073 case SUBLANG_NEPALI_INDIA: return "ne_IN";
2076 case LANG_NORWEGIAN:
2079 case 0x1f: return "nb";
2080 case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
2081 case 0x1e: return "nn";
2082 case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
2088 case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
2094 case SUBLANG_ORIYA_INDIA: return "or_IN";
2100 case SUBLANG_DEFAULT: return "om_ET";
2103 case LANG_PAPIAMENTU:
2106 case SUBLANG_DEFAULT: return "pap_AN";
2112 case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
2114 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
2118 case SUBLANG_POLISH_POLAND: return "pl_PL";
2121 case LANG_PORTUGUESE:
2124 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
2125 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
2126 case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
2127 case SUBLANG_PORTUGUESE: return "pt_PT";
2133 case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
2134 case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
2138 /* Note: Microsoft uses the non-ISO language code "quz". */
2141 case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
2142 case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
2143 case SUBLANG_QUECHUA_PERU: return "qu_PE";
2149 case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
2150 case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
2156 case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
2162 case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
2163 case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
2165 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
2170 case 0x00: return "se";
2171 case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
2172 case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
2173 case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
2175 case 0x1f: return "smj";
2176 case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
2177 case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
2179 case 0x1e: return "sma";
2180 case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
2181 case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
2183 case 0x1d: return "sms";
2184 case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
2186 case 0x1c: return "smn";
2187 case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
2189 return "se"; /* or "smi"? */
2193 case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
2196 case LANG_SCOTTISH_GAELIC:
2199 case SUBLANG_DEFAULT: return "gd_GB";
2205 case SUBLANG_SINDHI_INDIA: return "sd_IN";
2206 case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
2207 /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
2210 case LANG_SINHALESE:
2213 case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
2219 case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
2222 case LANG_SLOVENIAN:
2225 case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
2231 case SUBLANG_DEFAULT: return "so_SO";
2235 /* FIXME: Adjust this when such locales appear on Unix. */
2239 case 0x00: return "hsb";
2240 case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
2242 case 0x1f: return "dsb";
2243 case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
2247 /* <http://www.microsoft.com/globaldev/reference/lcid-all.mspx> calls
2248 it "Sepedi"; according to
2249 <http://www.ethnologue.com/show_language.asp?code=nso>
2250 <http://www.ethnologue.com/show_language.asp?code=sot>
2251 it's the same as Northern Sotho. */
2254 case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
2260 case SUBLANG_SPANISH: return "es_ES";
2261 case SUBLANG_SPANISH_MEXICAN: return "es_MX";
2262 case SUBLANG_SPANISH_MODERN:
2263 return "es_ES@modern"; /* not seen on Unix */
2264 case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
2265 case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
2266 case SUBLANG_SPANISH_PANAMA: return "es_PA";
2267 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
2268 case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
2269 case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
2270 case SUBLANG_SPANISH_PERU: return "es_PE";
2271 case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
2272 case SUBLANG_SPANISH_ECUADOR: return "es_EC";
2273 case SUBLANG_SPANISH_CHILE: return "es_CL";
2274 case SUBLANG_SPANISH_URUGUAY: return "es_UY";
2275 case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
2276 case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
2277 case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
2278 case SUBLANG_SPANISH_HONDURAS: return "es_HN";
2279 case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
2280 case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
2281 case SUBLANG_SPANISH_US: return "es_US";
2287 case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
2293 case SUBLANG_SWAHILI_KENYA: return "sw_KE";
2299 case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
2300 case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
2306 case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language. */
2312 case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
2314 return "tl"; /* or "fil"? */
2318 case 0x1f: return "tg";
2319 case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
2322 case LANG_TAMAZIGHT:
2323 /* Note: Microsoft uses the non-ISO language code "tmz". */
2326 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
2327 case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
2328 case 0x1f: return "ber@latin";
2329 case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
2335 case SUBLANG_TAMIL_INDIA: return "ta_IN";
2337 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
2341 case SUBLANG_TATAR_RUSSIA: return "tt_RU";
2347 case SUBLANG_TELUGU_INDIA: return "te_IN";
2353 case SUBLANG_THAI_THAILAND: return "th_TH";
2359 case SUBLANG_TIBETAN_PRC:
2360 /* Most Tibetans would not like "bo_CN". But Tibet does not yet
2361 have a country code of its own. */
2363 case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
2369 case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
2370 case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
2376 case SUBLANG_DEFAULT: return "ts_ZA";
2380 /* Spoken in South Africa, Botswana. */
2383 case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
2389 case SUBLANG_TURKISH_TURKEY: return "tr_TR";
2395 case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
2401 case SUBLANG_UIGHUR_PRC: return "ug_CN";
2404 case LANG_UKRAINIAN:
2407 case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
2413 case SUBLANG_URDU_PAKISTAN: return "ur_PK";
2414 case SUBLANG_URDU_INDIA: return "ur_IN";
2420 case 0x1f: return "uz";
2421 case SUBLANG_UZBEK_LATIN: return "uz_UZ";
2422 case 0x1e: return "uz@cyrillic";
2423 case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
2429 case SUBLANG_DEFAULT: return "ve_ZA";
2432 case LANG_VIETNAMESE:
2435 case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
2441 case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
2447 case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
2453 case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
2459 case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
2465 case SUBLANG_YI_PRC: return "ii_CN";
2471 case SUBLANG_DEFAULT: return "yi_IL";
2477 case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
2483 case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
2486 default: return "C";
2491 # if !defined IN_LIBINTL
2495 gl_locale_name_from_win32_LCID (LCID lcid)
2499 /* Strip off the sorting rules, keep only the language part. */
2500 langid = LANGIDFROMLCID (lcid);
2502 return gl_locale_name_from_win32_LANGID (langid);
2508 #if HAVE_USELOCALE /* glibc or MacOS X */
2510 /* Simple hash set of strings. We don't want to drag in lots of hash table
2513 # define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
2515 /* A hash function for NUL-terminated char* strings using
2516 the method described by Bruno Haible.
2517 See http://www.haible.de/bruno/hashfunc.html. */
2519 string_hash (const void *x)
2521 const char *s = (const char *) x;
2525 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
2530 /* A hash table of fixed size. Multiple threads can access it read-only
2531 simultaneously, but only one thread can insert into it at the same time. */
2533 /* A node in a hash bucket collision list. */
2536 struct hash_node * volatile next;
2537 char contents[100]; /* has variable size */
2540 # define HASH_TABLE_SIZE 257
2541 static struct hash_node * volatile struniq_hash_table[HASH_TABLE_SIZE]
2542 /* = { NULL, ..., NULL } */;
2544 /* This lock protects the struniq_hash_table against multiple simultaneous
2546 gl_lock_define_initialized(static, struniq_lock)
2548 /* Store a copy of the given string in a string pool with indefinite extent.
2549 Return a pointer to this copy. */
2551 struniq (const char *string)
2553 size_t hashcode = string_hash (string);
2554 size_t slot = hashcode % HASH_TABLE_SIZE;
2556 struct hash_node *new_node;
2557 struct hash_node *p;
2558 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2559 if (strcmp (p->contents, string) == 0)
2561 size = strlen (string) + 1;
2563 (struct hash_node *)
2564 malloc (offsetof (struct hash_node, contents[0]) + size);
2565 if (new_node == NULL)
2566 /* Out of memory. Return a statically allocated string. */
2568 memcpy (new_node->contents, string, size);
2569 /* Lock while inserting new_node. */
2570 gl_lock_lock (struniq_lock);
2571 /* Check whether another thread already added the string while we were
2572 waiting on the lock. */
2573 for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
2574 if (strcmp (p->contents, string) == 0)
2580 /* Really insert new_node into the hash table. Fill new_node entirely first,
2581 because other threads may be iterating over the linked list. */
2582 new_node->next = struniq_hash_table[slot];
2583 struniq_hash_table[slot] = new_node;
2585 /* Unlock after new_node is inserted. */
2586 gl_lock_unlock (struniq_lock);
2587 return new_node->contents;
2593 #if defined IN_LIBINTL || HAVE_USELOCALE
2595 /* Like gl_locale_name_thread, except that the result is not in storage of
2596 indefinite extent. */
2597 # if !defined IN_LIBINTL
2601 gl_locale_name_thread_unsafe (int category, const char *categoryname)
2605 locale_t thread_locale = uselocale (NULL);
2606 if (thread_locale != LC_GLOBAL_LOCALE)
2608 # if __GLIBC__ >= 2 && !defined __UCLIBC__
2609 /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
2611 See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>. */
2613 nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
2614 if (name[0] == '\0')
2615 /* Fallback code for glibc < 2.4, which did not implement
2616 nl_langinfo (_NL_LOCALE_NAME (category)). */
2617 name = thread_locale->__names[category];
2620 # if defined __APPLE__ && defined __MACH__ /* MacOS X */
2621 /* The locale name is found deep in an undocumented data structure.
2622 Since it's stored in a buffer of size 32 and newlocale() rejects
2623 locale names of length > 31, we can assume that it is NUL terminated
2624 in this buffer. But we need to make a copy of the locale name, of
2625 indefinite extent. */
2626 struct _xlocale_part1_v0 /* used in MacOS X 10.5 */
2629 void (*__free_extra)(void *);
2630 __darwin_mbstate_t __mbs[10];
2633 struct _xlocale_part1_v1 /* used in MacOS X >= 10.6.0 */
2636 void (*__free_extra)(void *);
2637 __darwin_mbstate_t __mbs[10];
2638 /*pthread_lock_t*/ int __lock;
2641 struct _xlocale_part2
2644 unsigned char __collate_load_error;
2645 unsigned char __collate_substitute_nontrivial;
2646 unsigned char _messages_using_locale;
2647 unsigned char _monetary_using_locale;
2648 unsigned char _numeric_using_locale;
2649 unsigned char _time_using_locale;
2650 unsigned char __mlocale_changed;
2651 unsigned char __nlocale_changed;
2652 unsigned char __numeric_fp_cvt;
2653 struct __xlocale_st_collate *__lc_collate;
2654 struct __xlocale_st_runelocale *__lc_ctype;
2655 struct __xlocale_st_messages *__lc_messages;
2656 struct __xlocale_st_monetary *__lc_monetary;
2657 struct __xlocale_st_numeric *__lc_numeric;
2658 struct _xlocale *__lc_numeric_loc;
2659 struct __xlocale_st_time *__lc_time;
2662 struct __xlocale_st_collate
2665 void (*__free_extra)(void *);
2666 char __encoding[32];
2669 struct __xlocale_st_runelocale
2672 void (*__free_extra)(void *);
2673 char __ctype_encoding[32];
2676 struct __xlocale_st_messages
2679 void (*__free_extra)(void *);
2680 char *_messages_locale_buf;
2683 struct __xlocale_st_monetary
2686 void (*__free_extra)(void *);
2687 char *_monetary_locale_buf;
2690 struct __xlocale_st_numeric {
2692 void (*__free_extra)(void *);
2693 char *_numeric_locale_buf;
2696 struct __xlocale_st_time {
2698 void (*__free_extra)(void *);
2699 char *_time_locale_buf;
2702 struct _xlocale_part2 *tlp;
2703 if (((struct _xlocale_part1_v0 *) thread_locale)->__magic
2704 == 0x786C6F63616C6530LL)
2707 (struct _xlocale_part2 *)
2708 &((struct _xlocale_part1_v0 *) thread_locale)->__magic;
2709 else if (((struct _xlocale_part1_v1 *) thread_locale)->__magic
2710 == 0x786C6F63616C6530LL)
2711 /* MacOS X >= 10.6.0 */
2713 (struct _xlocale_part2 *)
2714 &((struct _xlocale_part1_v1 *) thread_locale)->__magic;
2716 /* Unsupported version of MacOS X: The internals of 'struct _xlocale'
2717 have changed again. */
2722 return tlp->__lc_ctype->__ctype_encoding;
2724 return tlp->_numeric_using_locale
2725 ? tlp->__lc_numeric->_numeric_locale_buf
2728 return tlp->_time_using_locale
2729 ? tlp->__lc_time->_time_locale_buf
2732 return !tlp->__collate_load_error
2733 ? tlp->__lc_collate->__encoding
2736 return tlp->_monetary_using_locale
2737 ? tlp->__lc_monetary->_monetary_locale_buf
2740 return tlp->_messages_using_locale
2741 ? tlp->__lc_messages->_messages_locale_buf
2743 default: /* We shouldn't get here. */
2756 gl_locale_name_thread (int category, const char *categoryname)
2759 const char *name = gl_locale_name_thread_unsafe (category, categoryname);
2761 return struniq (name);
2766 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
2767 "Directs 'setlocale()' to query 'category' and return the current
2768 setting of 'local'."
2769 However it does not specify the exact format. Neither do SUSV2 and
2770 ISO C 99. So we can use this feature only on selected systems (e.g.
2771 those using GNU C Library). */
2772 #if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
2773 # define HAVE_LOCALE_NULL
2777 gl_locale_name_posix (int category, const char *categoryname)
2779 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
2780 On some systems this can be done by the 'setlocale' function itself. */
2781 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
2782 return setlocale (category, NULL);
2784 /* On other systems we ignore what setlocale reports and instead look at the
2785 environment variables directly. This is necessary
2786 1. on systems which have a facility for customizing the default locale
2787 (MacOS X, native Windows, Cygwin) and where the system's setlocale()
2788 function ignores this default locale (MacOS X, Cygwin), in two cases:
2789 a. when the user missed to use the setlocale() override from libintl
2790 (for example by not including <libintl.h>),
2791 b. when setlocale supports only the "C" locale, such as on Cygwin
2792 1.5.x. In this case even the override from libintl cannot help.
2793 2. on all systems where setlocale supports only the "C" locale. */
2794 /* Strictly speaking, it is a POSIX violation to look at the environment
2795 variables regardless whether setlocale has been called or not. POSIX
2797 "For C-language programs, the POSIX locale shall be the
2798 default locale when the setlocale() function is not called."
2799 But we assume that all programs that use internationalized APIs call
2800 setlocale (LC_ALL, ""). */
2801 return gl_locale_name_environ (category, categoryname);
2806 gl_locale_name_environ (int category, const char *categoryname)
2810 /* Setting of LC_ALL overrides all other. */
2811 retval = getenv ("LC_ALL");
2812 if (retval != NULL && retval[0] != '\0')
2814 /* Next comes the name of the desired category. */
2815 retval = getenv (categoryname);
2816 if (retval != NULL && retval[0] != '\0')
2818 /* Last possibility is the LANG environment variable. */
2819 retval = getenv ("LANG");
2820 if (retval != NULL && retval[0] != '\0')
2822 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2823 /* MacOS X 10.2 or newer.
2824 Ignore invalid LANG value set by the Terminal application. */
2825 if (strcmp (retval, "UTF-8") != 0)
2827 #if defined __CYGWIN__
2829 Ignore dummy LANG value set by ~/.profile. */
2830 if (strcmp (retval, "C.UTF-8") != 0)
2839 gl_locale_name_default (void)
2842 "All implementations shall define a locale as the default locale, to be
2843 invoked when no environment variables are set, or set to the empty
2844 string. This default locale can be the POSIX locale or any other
2845 implementation-defined locale. Some implementations may provide
2846 facilities for local installation administrators to set the default
2847 locale, customizing it for each location. POSIX:2001 does not require
2850 The systems with such a facility are MacOS X and Windows: They provide a
2851 GUI that allows the user to choose a locale.
2852 - On MacOS X, by default, none of LC_* or LANG are set. Starting with
2853 MacOS X 10.4 or 10.5, LANG is set for processes launched by the
2854 'Terminal' application (but sometimes to an incorrect value "UTF-8").
2855 When no environment variable is set, setlocale (LC_ALL, "") uses the
2857 - On native Windows, by default, none of LC_* or LANG are set.
2858 When no environment variable is set, setlocale (LC_ALL, "") uses the
2859 locale chosen by the user.
2860 - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
2861 When no environment variable is set, setlocale (LC_ALL, "") uses the
2863 - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
2864 ~/.profile is executed.
2865 When no environment variable is set, setlocale (LC_ALL, "") uses the
2866 "C.UTF-8" locale, which operates in the same way as the "C" locale.
2869 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WIN32_NATIVE || defined __CYGWIN__)
2871 /* The system does not have a way of setting the locale, other than the
2872 POSIX specified environment variables. We use C as default locale. */
2877 /* Return an XPG style locale name language[_territory][@modifier].
2878 Don't even bother determining the codeset; it's not useful in this
2879 context, because message catalogs are not specific to a single
2882 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
2883 /* MacOS X 10.2 or newer */
2885 /* Cache the locale name, since CoreFoundation calls are expensive. */
2886 static const char *cached_localename;
2888 if (cached_localename == NULL)
2891 # if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
2892 CFLocaleRef locale = CFLocaleCopyCurrent ();
2893 CFStringRef name = CFLocaleGetIdentifier (locale);
2895 if (CFStringGetCString (name, namebuf, sizeof (namebuf),
2896 kCFStringEncodingASCII))
2898 gl_locale_name_canonicalize (namebuf);
2899 cached_localename = strdup (namebuf);
2902 # elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
2904 CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
2905 kCFPreferencesCurrentApplication);
2907 && CFGetTypeID (value) == CFStringGetTypeID ()
2908 && CFStringGetCString ((CFStringRef)value,
2909 namebuf, sizeof (namebuf),
2910 kCFStringEncodingASCII))
2912 gl_locale_name_canonicalize (namebuf);
2913 cached_localename = strdup (namebuf);
2916 if (cached_localename == NULL)
2917 cached_localename = "C";
2919 return cached_localename;
2924 # if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
2928 /* Use native Win32 API locale ID. */
2929 lcid = GetThreadLocale ();
2931 return gl_locale_name_from_win32_LCID (lcid);
2937 /* Determine the current locale's name, and canonicalize it into XPG syntax
2938 language[_territory][.codeset][@modifier]
2939 The codeset part in the result is not reliable; the locale_charset()
2940 should be used for codeset information instead.
2941 The result must not be freed; it is statically allocated. */
2944 gl_locale_name (int category, const char *categoryname)
2948 retval = gl_locale_name_thread (category, categoryname);
2952 retval = gl_locale_name_posix (category, categoryname);
2956 return gl_locale_name_default ();