1 /* Determine the current selected locale.
2 Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published
6 by the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 /* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */
20 /* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
21 /* MacOS X code written by Bruno Haible <bruno@clisp.org>. */
30 #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
32 # include <CFString.h>
33 # if HAVE_CFLOCALECOPYCURRENT
34 # include <CFLocale.h>
35 # elif HAVE_CFPREFERENCESCOPYAPPVALUE
36 # include <CFPreferences.h>
40 #if defined _WIN32 || defined __WIN32__
41 # undef WIN32 /* avoid warning on mingw32 */
46 # define WIN32_LEAN_AND_MEAN
48 /* List of language codes, sorted by value:
71 0x17 LANG_RHAETO_ROMANCE
74 0x1a LANG_CROATIAN == LANG_SERBIAN
166 /* Mingw headers don't have latest language and sublanguage codes. */
167 # ifndef LANG_AFRIKAANS
168 # define LANG_AFRIKAANS 0x36
170 # ifndef LANG_ALBANIAN
171 # define LANG_ALBANIAN 0x1c
173 # ifndef LANG_AMHARIC
174 # define LANG_AMHARIC 0x5e
177 # define LANG_ARABIC 0x01
179 # ifndef LANG_ARMENIAN
180 # define LANG_ARMENIAN 0x2b
182 # ifndef LANG_ASSAMESE
183 # define LANG_ASSAMESE 0x4d
186 # define LANG_AZERI 0x2c
189 # define LANG_BASQUE 0x2d
191 # ifndef LANG_BELARUSIAN
192 # define LANG_BELARUSIAN 0x23
194 # ifndef LANG_BENGALI
195 # define LANG_BENGALI 0x45
197 # ifndef LANG_BURMESE
198 # define LANG_BURMESE 0x55
200 # ifndef LANG_CAMBODIAN
201 # define LANG_CAMBODIAN 0x53
203 # ifndef LANG_CATALAN
204 # define LANG_CATALAN 0x03
206 # ifndef LANG_CHEROKEE
207 # define LANG_CHEROKEE 0x5c
210 # define LANG_DIVEHI 0x65
213 # define LANG_EDO 0x66
215 # ifndef LANG_ESTONIAN
216 # define LANG_ESTONIAN 0x25
218 # ifndef LANG_FAEROESE
219 # define LANG_FAEROESE 0x38
222 # define LANG_FARSI 0x29
224 # ifndef LANG_FRISIAN
225 # define LANG_FRISIAN 0x62
227 # ifndef LANG_FULFULDE
228 # define LANG_FULFULDE 0x67
231 # define LANG_GAELIC 0x3c
233 # ifndef LANG_GALICIAN
234 # define LANG_GALICIAN 0x56
236 # ifndef LANG_GEORGIAN
237 # define LANG_GEORGIAN 0x37
239 # ifndef LANG_GUARANI
240 # define LANG_GUARANI 0x74
242 # ifndef LANG_GUJARATI
243 # define LANG_GUJARATI 0x47
246 # define LANG_HAUSA 0x68
248 # ifndef LANG_HAWAIIAN
249 # define LANG_HAWAIIAN 0x75
252 # define LANG_HEBREW 0x0d
255 # define LANG_HINDI 0x39
258 # define LANG_IBIBIO 0x69
261 # define LANG_IGBO 0x70
263 # ifndef LANG_INDONESIAN
264 # define LANG_INDONESIAN 0x21
266 # ifndef LANG_INUKTITUT
267 # define LANG_INUKTITUT 0x5d
269 # ifndef LANG_KANNADA
270 # define LANG_KANNADA 0x4b
273 # define LANG_KANURI 0x71
275 # ifndef LANG_KASHMIRI
276 # define LANG_KASHMIRI 0x60
279 # define LANG_KAZAK 0x3f
281 # ifndef LANG_KONKANI
282 # define LANG_KONKANI 0x57
285 # define LANG_KYRGYZ 0x40
288 # define LANG_LAO 0x54
291 # define LANG_LATIN 0x76
293 # ifndef LANG_LATVIAN
294 # define LANG_LATVIAN 0x26
296 # ifndef LANG_LITHUANIAN
297 # define LANG_LITHUANIAN 0x27
299 # ifndef LANG_MACEDONIAN
300 # define LANG_MACEDONIAN 0x2f
303 # define LANG_MALAY 0x3e
305 # ifndef LANG_MALAYALAM
306 # define LANG_MALAYALAM 0x4c
308 # ifndef LANG_MALTESE
309 # define LANG_MALTESE 0x3a
311 # ifndef LANG_MANIPURI
312 # define LANG_MANIPURI 0x58
314 # ifndef LANG_MARATHI
315 # define LANG_MARATHI 0x4e
317 # ifndef LANG_MONGOLIAN
318 # define LANG_MONGOLIAN 0x50
321 # define LANG_NEPALI 0x61
324 # define LANG_ORIYA 0x48
327 # define LANG_OROMO 0x72
329 # ifndef LANG_PAPIAMENTU
330 # define LANG_PAPIAMENTU 0x79
333 # define LANG_PASHTO 0x63
335 # ifndef LANG_PUNJABI
336 # define LANG_PUNJABI 0x46
338 # ifndef LANG_RHAETO_ROMANCE
339 # define LANG_RHAETO_ROMANCE 0x17
342 # define LANG_SAAMI 0x3b
344 # ifndef LANG_SANSKRIT
345 # define LANG_SANSKRIT 0x4f
347 # ifndef LANG_SERBIAN
348 # define LANG_SERBIAN 0x1a
351 # define LANG_SINDHI 0x59
353 # ifndef LANG_SINHALESE
354 # define LANG_SINHALESE 0x5b
357 # define LANG_SLOVAK 0x1b
360 # define LANG_SOMALI 0x77
362 # ifndef LANG_SORBIAN
363 # define LANG_SORBIAN 0x2e
366 # define LANG_SUTU 0x30
368 # ifndef LANG_SWAHILI
369 # define LANG_SWAHILI 0x41
372 # define LANG_SYRIAC 0x5a
374 # ifndef LANG_TAGALOG
375 # define LANG_TAGALOG 0x64
378 # define LANG_TAJIK 0x28
380 # ifndef LANG_TAMAZIGHT
381 # define LANG_TAMAZIGHT 0x5f
384 # define LANG_TAMIL 0x49
387 # define LANG_TATAR 0x44
390 # define LANG_TELUGU 0x4a
393 # define LANG_THAI 0x1e
395 # ifndef LANG_TIBETAN
396 # define LANG_TIBETAN 0x51
398 # ifndef LANG_TIGRINYA
399 # define LANG_TIGRINYA 0x73
402 # define LANG_TSONGA 0x31
405 # define LANG_TSWANA 0x32
407 # ifndef LANG_TURKMEN
408 # define LANG_TURKMEN 0x42
410 # ifndef LANG_UKRAINIAN
411 # define LANG_UKRAINIAN 0x22
414 # define LANG_URDU 0x20
417 # define LANG_UZBEK 0x43
420 # define LANG_VENDA 0x33
422 # ifndef LANG_VIETNAMESE
423 # define LANG_VIETNAMESE 0x2a
426 # define LANG_WELSH 0x52
429 # define LANG_XHOSA 0x34
432 # define LANG_YI 0x78
434 # ifndef LANG_YIDDISH
435 # define LANG_YIDDISH 0x3d
438 # define LANG_YORUBA 0x6a
441 # define LANG_ZULU 0x35
443 # ifndef SUBLANG_ARABIC_SAUDI_ARABIA
444 # define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
446 # ifndef SUBLANG_ARABIC_IRAQ
447 # define SUBLANG_ARABIC_IRAQ 0x02
449 # ifndef SUBLANG_ARABIC_EGYPT
450 # define SUBLANG_ARABIC_EGYPT 0x03
452 # ifndef SUBLANG_ARABIC_LIBYA
453 # define SUBLANG_ARABIC_LIBYA 0x04
455 # ifndef SUBLANG_ARABIC_ALGERIA
456 # define SUBLANG_ARABIC_ALGERIA 0x05
458 # ifndef SUBLANG_ARABIC_MOROCCO
459 # define SUBLANG_ARABIC_MOROCCO 0x06
461 # ifndef SUBLANG_ARABIC_TUNISIA
462 # define SUBLANG_ARABIC_TUNISIA 0x07
464 # ifndef SUBLANG_ARABIC_OMAN
465 # define SUBLANG_ARABIC_OMAN 0x08
467 # ifndef SUBLANG_ARABIC_YEMEN
468 # define SUBLANG_ARABIC_YEMEN 0x09
470 # ifndef SUBLANG_ARABIC_SYRIA
471 # define SUBLANG_ARABIC_SYRIA 0x0a
473 # ifndef SUBLANG_ARABIC_JORDAN
474 # define SUBLANG_ARABIC_JORDAN 0x0b
476 # ifndef SUBLANG_ARABIC_LEBANON
477 # define SUBLANG_ARABIC_LEBANON 0x0c
479 # ifndef SUBLANG_ARABIC_KUWAIT
480 # define SUBLANG_ARABIC_KUWAIT 0x0d
482 # ifndef SUBLANG_ARABIC_UAE
483 # define SUBLANG_ARABIC_UAE 0x0e
485 # ifndef SUBLANG_ARABIC_BAHRAIN
486 # define SUBLANG_ARABIC_BAHRAIN 0x0f
488 # ifndef SUBLANG_ARABIC_QATAR
489 # define SUBLANG_ARABIC_QATAR 0x10
491 # ifndef SUBLANG_AZERI_LATIN
492 # define SUBLANG_AZERI_LATIN 0x01
494 # ifndef SUBLANG_AZERI_CYRILLIC
495 # define SUBLANG_AZERI_CYRILLIC 0x02
497 # ifndef SUBLANG_BENGALI_INDIA
498 # define SUBLANG_BENGALI_INDIA 0x00
500 # ifndef SUBLANG_BENGALI_BANGLADESH
501 # define SUBLANG_BENGALI_BANGLADESH 0x01
503 # ifndef SUBLANG_CHINESE_MACAU
504 # define SUBLANG_CHINESE_MACAU 0x05
506 # ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
507 # define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
509 # ifndef SUBLANG_ENGLISH_JAMAICA
510 # define SUBLANG_ENGLISH_JAMAICA 0x08
512 # ifndef SUBLANG_ENGLISH_CARIBBEAN
513 # define SUBLANG_ENGLISH_CARIBBEAN 0x09
515 # ifndef SUBLANG_ENGLISH_BELIZE
516 # define SUBLANG_ENGLISH_BELIZE 0x0a
518 # ifndef SUBLANG_ENGLISH_TRINIDAD
519 # define SUBLANG_ENGLISH_TRINIDAD 0x0b
521 # ifndef SUBLANG_ENGLISH_ZIMBABWE
522 # define SUBLANG_ENGLISH_ZIMBABWE 0x0c
524 # ifndef SUBLANG_ENGLISH_PHILIPPINES
525 # define SUBLANG_ENGLISH_PHILIPPINES 0x0d
527 # ifndef SUBLANG_ENGLISH_INDONESIA
528 # define SUBLANG_ENGLISH_INDONESIA 0x0e
530 # ifndef SUBLANG_ENGLISH_HONGKONG
531 # define SUBLANG_ENGLISH_HONGKONG 0x0f
533 # ifndef SUBLANG_ENGLISH_INDIA
534 # define SUBLANG_ENGLISH_INDIA 0x10
536 # ifndef SUBLANG_ENGLISH_MALAYSIA
537 # define SUBLANG_ENGLISH_MALAYSIA 0x11
539 # ifndef SUBLANG_ENGLISH_SINGAPORE
540 # define SUBLANG_ENGLISH_SINGAPORE 0x12
542 # ifndef SUBLANG_FRENCH_LUXEMBOURG
543 # define SUBLANG_FRENCH_LUXEMBOURG 0x05
545 # ifndef SUBLANG_FRENCH_MONACO
546 # define SUBLANG_FRENCH_MONACO 0x06
548 # ifndef SUBLANG_FRENCH_WESTINDIES
549 # define SUBLANG_FRENCH_WESTINDIES 0x07
551 # ifndef SUBLANG_FRENCH_REUNION
552 # define SUBLANG_FRENCH_REUNION 0x08
554 # ifndef SUBLANG_FRENCH_CONGO
555 # define SUBLANG_FRENCH_CONGO 0x09
557 # ifndef SUBLANG_FRENCH_SENEGAL
558 # define SUBLANG_FRENCH_SENEGAL 0x0a
560 # ifndef SUBLANG_FRENCH_CAMEROON
561 # define SUBLANG_FRENCH_CAMEROON 0x0b
563 # ifndef SUBLANG_FRENCH_COTEDIVOIRE
564 # define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
566 # ifndef SUBLANG_FRENCH_MALI
567 # define SUBLANG_FRENCH_MALI 0x0d
569 # ifndef SUBLANG_FRENCH_MOROCCO
570 # define SUBLANG_FRENCH_MOROCCO 0x0e
572 # ifndef SUBLANG_FRENCH_HAITI
573 # define SUBLANG_FRENCH_HAITI 0x0f
575 # ifndef SUBLANG_GERMAN_LUXEMBOURG
576 # define SUBLANG_GERMAN_LUXEMBOURG 0x04
578 # ifndef SUBLANG_GERMAN_LIECHTENSTEIN
579 # define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
581 # ifndef SUBLANG_KASHMIRI_INDIA
582 # define SUBLANG_KASHMIRI_INDIA 0x02
584 # ifndef SUBLANG_MALAY_MALAYSIA
585 # define SUBLANG_MALAY_MALAYSIA 0x01
587 # ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
588 # define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
590 # ifndef SUBLANG_NEPALI_INDIA
591 # define SUBLANG_NEPALI_INDIA 0x02
593 # ifndef SUBLANG_PUNJABI_INDIA
594 # define SUBLANG_PUNJABI_INDIA 0x00
596 # ifndef SUBLANG_PUNJABI_PAKISTAN
597 # define SUBLANG_PUNJABI_PAKISTAN 0x01
599 # ifndef SUBLANG_ROMANIAN_ROMANIA
600 # define SUBLANG_ROMANIAN_ROMANIA 0x00
602 # ifndef SUBLANG_ROMANIAN_MOLDOVA
603 # define SUBLANG_ROMANIAN_MOLDOVA 0x01
605 # ifndef SUBLANG_SERBIAN_LATIN
606 # define SUBLANG_SERBIAN_LATIN 0x02
608 # ifndef SUBLANG_SERBIAN_CYRILLIC
609 # define SUBLANG_SERBIAN_CYRILLIC 0x03
611 # ifndef SUBLANG_SINDHI_INDIA
612 # define SUBLANG_SINDHI_INDIA 0x00
614 # ifndef SUBLANG_SINDHI_PAKISTAN
615 # define SUBLANG_SINDHI_PAKISTAN 0x01
617 # ifndef SUBLANG_SPANISH_GUATEMALA
618 # define SUBLANG_SPANISH_GUATEMALA 0x04
620 # ifndef SUBLANG_SPANISH_COSTA_RICA
621 # define SUBLANG_SPANISH_COSTA_RICA 0x05
623 # ifndef SUBLANG_SPANISH_PANAMA
624 # define SUBLANG_SPANISH_PANAMA 0x06
626 # ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
627 # define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
629 # ifndef SUBLANG_SPANISH_VENEZUELA
630 # define SUBLANG_SPANISH_VENEZUELA 0x08
632 # ifndef SUBLANG_SPANISH_COLOMBIA
633 # define SUBLANG_SPANISH_COLOMBIA 0x09
635 # ifndef SUBLANG_SPANISH_PERU
636 # define SUBLANG_SPANISH_PERU 0x0a
638 # ifndef SUBLANG_SPANISH_ARGENTINA
639 # define SUBLANG_SPANISH_ARGENTINA 0x0b
641 # ifndef SUBLANG_SPANISH_ECUADOR
642 # define SUBLANG_SPANISH_ECUADOR 0x0c
644 # ifndef SUBLANG_SPANISH_CHILE
645 # define SUBLANG_SPANISH_CHILE 0x0d
647 # ifndef SUBLANG_SPANISH_URUGUAY
648 # define SUBLANG_SPANISH_URUGUAY 0x0e
650 # ifndef SUBLANG_SPANISH_PARAGUAY
651 # define SUBLANG_SPANISH_PARAGUAY 0x0f
653 # ifndef SUBLANG_SPANISH_BOLIVIA
654 # define SUBLANG_SPANISH_BOLIVIA 0x10
656 # ifndef SUBLANG_SPANISH_EL_SALVADOR
657 # define SUBLANG_SPANISH_EL_SALVADOR 0x11
659 # ifndef SUBLANG_SPANISH_HONDURAS
660 # define SUBLANG_SPANISH_HONDURAS 0x12
662 # ifndef SUBLANG_SPANISH_NICARAGUA
663 # define SUBLANG_SPANISH_NICARAGUA 0x13
665 # ifndef SUBLANG_SPANISH_PUERTO_RICO
666 # define SUBLANG_SPANISH_PUERTO_RICO 0x14
668 # ifndef SUBLANG_SWEDISH_FINLAND
669 # define SUBLANG_SWEDISH_FINLAND 0x02
671 # ifndef SUBLANG_TAMAZIGHT_ARABIC
672 # define SUBLANG_TAMAZIGHT_ARABIC 0x01
674 # ifndef SUBLANG_TAMAZIGHT_LATIN
675 # define SUBLANG_TAMAZIGHT_LATIN 0x02
677 # ifndef SUBLANG_TIGRINYA_ETHIOPIA
678 # define SUBLANG_TIGRINYA_ETHIOPIA 0x00
680 # ifndef SUBLANG_TIGRINYA_ERITREA
681 # define SUBLANG_TIGRINYA_ERITREA 0x01
683 # ifndef SUBLANG_URDU_PAKISTAN
684 # define SUBLANG_URDU_PAKISTAN 0x01
686 # ifndef SUBLANG_URDU_INDIA
687 # define SUBLANG_URDU_INDIA 0x02
689 # ifndef SUBLANG_UZBEK_LATIN
690 # define SUBLANG_UZBEK_LATIN 0x01
692 # ifndef SUBLANG_UZBEK_CYRILLIC
693 # define SUBLANG_UZBEK_CYRILLIC 0x02
697 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
698 /* MacOS X 10.2 or newer */
700 /* Canonicalize a MacOS X locale name to a Unix locale name.
701 NAME is a sufficiently large buffer.
702 On input, it contains the MacOS X locale name.
703 On output, it contains the Unix locale name. */
705 _nl_locale_name_canonicalize (char *name)
707 /* This conversion is based on a posting by
708 Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
709 http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
711 /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
712 ISO 3166) names. Prior to MacOS X 10.3, there is no API for doing this.
713 Therefore we do it ourselves, using a table based on the results of the
714 MacOS X 10.3.8 function
715 CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
716 typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
718 static const legacy_entry legacy_table[] = {
719 { "Afrikaans", "af" },
720 { "Albanian", "sq" },
723 { "Armenian", "hy" },
724 { "Assamese", "as" },
726 { "Azerbaijani", "az" },
728 { "Belarusian", "be" },
729 { "Belorussian", "be" },
731 { "Brazilian Portugese", "pt_BR" },
732 { "Brazilian Portuguese", "pt_BR" },
734 { "Bulgarian", "bg" },
736 { "Byelorussian", "be" },
739 { "Chichewa", "ny" },
741 { "Chinese, Simplified", "zh_CN" },
742 { "Chinese, Traditional", "zh_TW" },
743 { "Chinese, Tradtional", "zh_TW" },
744 { "Croatian", "hr" },
748 { "Dzongkha", "dz" },
750 { "Esperanto", "eo" },
751 { "Estonian", "et" },
755 { "Flemish", "nl_BE" },
757 { "Galician", "gl" },
758 { "Gallegan", "gl" },
759 { "Georgian", "ka" },
762 { "Greenlandic", "kl" },
764 { "Gujarati", "gu" },
765 { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
768 { "Hungarian", "hu" },
769 { "Icelandic", "is" },
770 { "Indonesian", "id" },
771 { "Inuktitut", "iu" },
774 { "Japanese", "ja" },
775 { "Javanese", "jv" },
776 { "Kalaallisut", "kl" },
778 { "Kashmiri", "ks" },
781 { "Kinyarwanda", "rw" },
787 { "Lithuanian", "lt" },
788 { "Macedonian", "mk" },
789 { "Malagasy", "mg" },
791 { "Malayalam", "ml" },
795 { "Moldavian", "mo" },
796 { "Mongolian", "mn" },
798 { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
807 { "Portuguese", "pt" },
808 { "Portuguese, Brazilian", "pt_BR" },
812 { "Romanian", "ro" },
816 { "Sami", "se_NO" }, /* Not just "se". */
817 { "Sanskrit", "sa" },
818 { "Scottish", "gd" },
820 { "Simplified Chinese", "zh_CN" },
822 { "Sinhalese", "si" },
824 { "Slovenian", "sl" },
827 { "Sundanese", "su" },
838 { "Tigrinya", "ti" },
840 { "Traditional Chinese", "zh_TW" },
844 { "Ukrainian", "uk" },
847 { "Vietnamese", "vi" },
852 /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
853 to Unix (ISO 639 and ISO 3166) names. */
854 typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
856 static const langtag_entry langtag_table[] = {
857 /* MacOS X has "az-Arab", "az-Cyrl", "az-Latn".
858 The default script for az on Unix is Latin. */
860 /* MacOS X has "ga-dots". Does not yet exist on Unix. */
862 /* MacOS X has "kk-Cyrl". Does not yet exist on Unix. */
863 /* MacOS X has "mn-Cyrl", "mn-Mong".
864 The default script for mn on Unix is Cyrillic. */
866 /* MacOS X has "ms-Arab", "ms-Latn".
867 The default script for ms on Unix is Latin. */
869 /* MacOS X has "tg-Cyrl".
870 The default script for tg on Unix is Cyrillic. */
872 /* MacOS X has "tk-Cyrl". Does not yet exist on Unix. */
873 /* MacOS X has "tt-Cyrl".
874 The default script for tt on Unix is Cyrillic. */
876 /* MacOS X has "zh-Hans", "zh-Hant".
877 Country codes are used to distinguish these on Unix. */
878 { "zh-Hans", "zh_CN" },
879 { "zh-Hant", "zh_TW" }
882 /* Convert script names (ISO 15924) to Unix conventions.
883 See http://www.unicode.org/iso15924/iso15924-codes.html */
884 typedef struct { const char script[4+1]; const char unixy[9+1]; }
886 static const script_entry script_table[] = {
887 { "Arab", "arabic" },
888 { "Cyrl", "cyrillic" },
889 { "Mong", "mongolian" }
892 /* Step 1: Convert using legacy_table. */
893 if (name[0] >= 'A' && name[0] <= 'Z')
897 i2 = sizeof (legacy_table) / sizeof (legacy_entry);
900 /* At this point we know that if name occurs in legacy_table,
901 its index must be >= i1 and < i2. */
902 unsigned int i = (i1 + i2) >> 1;
903 const legacy_entry *p = &legacy_table[i];
904 if (strcmp (name, p->legacy) < 0)
909 if (strcmp (name, legacy_table[i1].legacy) == 0)
911 strcpy (name, legacy_table[i1].unixy);
916 /* Step 2: Convert using langtag_table and script_table. */
917 if (strlen (name) == 7 && name[2] == '-')
921 i2 = sizeof (langtag_table) / sizeof (langtag_entry);
924 /* At this point we know that if name occurs in langtag_table,
925 its index must be >= i1 and < i2. */
926 unsigned int i = (i1 + i2) >> 1;
927 const langtag_entry *p = &langtag_table[i];
928 if (strcmp (name, p->langtag) < 0)
933 if (strcmp (name, langtag_table[i1].langtag) == 0)
935 strcpy (name, langtag_table[i1].unixy);
940 i2 = sizeof (script_table) / sizeof (script_entry);
943 /* At this point we know that if (name + 3) occurs in script_table,
944 its index must be >= i1 and < i2. */
945 unsigned int i = (i1 + i2) >> 1;
946 const script_entry *p = &script_table[i];
947 if (strcmp (name + 3, p->script) < 0)
952 if (strcmp (name + 3, script_table[i1].script) == 0)
955 strcpy (name + 3, script_table[i1].unixy);
960 /* Step 3: Convert new-style dash to Unix underscore. */
963 for (p = name; *p != '\0'; p++)
971 /* XPG3 defines the result of 'setlocale (category, NULL)' as:
972 "Directs 'setlocale()' to query 'category' and return the current
974 However it does not specify the exact format. Neither do SUSV2 and
975 ISO C 99. So we can use this feature only on selected systems (e.g.
976 those using GNU C Library). */
977 #if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2)
978 # define HAVE_LOCALE_NULL
981 /* Determine the current locale's name, and canonicalize it into XPG syntax
982 language[_territory[.codeset]][@modifier]
983 The codeset part in the result is not reliable; the locale_charset()
984 should be used for codeset information instead.
985 The result must not be freed; it is statically allocated. */
988 _nl_locale_name_posix (int category, const char *categoryname)
990 /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
991 On some systems this can be done by the 'setlocale' function itself. */
992 #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
993 return setlocale (category, NULL);
997 /* Setting of LC_ALL overrides all other. */
998 retval = getenv ("LC_ALL");
999 if (retval != NULL && retval[0] != '\0')
1001 /* Next comes the name of the desired category. */
1002 retval = getenv (categoryname);
1003 if (retval != NULL && retval[0] != '\0')
1005 /* Last possibility is the LANG environment variable. */
1006 retval = getenv ("LANG");
1007 if (retval != NULL && retval[0] != '\0')
1015 _nl_locale_name_default (void)
1018 "All implementations shall define a locale as the default locale, to be
1019 invoked when no environment variables are set, or set to the empty
1020 string. This default locale can be the POSIX locale or any other
1021 implementation-defined locale. Some implementations may provide
1022 facilities for local installation administrators to set the default
1023 locale, customizing it for each location. POSIX:2001 does not require
1026 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32))
1028 /* The system does not have a way of setting the locale, other than the
1029 POSIX specified environment variables. We use C as default locale. */
1034 /* Return an XPG style locale name language[_territory][@modifier].
1035 Don't even bother determining the codeset; it's not useful in this
1036 context, because message catalogs are not specific to a single
1039 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
1040 /* MacOS X 10.2 or newer */
1042 /* Cache the locale name, since CoreFoundation calls are expensive. */
1043 static const char *cached_localename;
1045 if (cached_localename == NULL)
1048 # if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
1049 CFLocaleRef locale = CFLocaleCopyCurrent ();
1050 CFStringRef name = CFLocaleGetIdentifier (locale);
1052 if (CFStringGetCString (name, namebuf, sizeof(namebuf),
1053 kCFStringEncodingASCII))
1055 _nl_locale_name_canonicalize (namebuf);
1056 cached_localename = strdup (namebuf);
1059 # elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
1061 CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
1062 kCFPreferencesCurrentApplication);
1064 && CFGetTypeID (value) == CFStringGetTypeID ()
1065 && CFStringGetCString ((CFStringRef)value, namebuf, sizeof(namebuf),
1066 kCFStringEncodingASCII))
1068 _nl_locale_name_canonicalize (namebuf);
1069 cached_localename = strdup (namebuf);
1072 if (cached_localename == NULL)
1073 cached_localename = "C";
1075 return cached_localename;
1080 # if defined(WIN32) /* WIN32 */
1086 /* Use native Win32 API locale ID. */
1087 lcid = GetThreadLocale ();
1089 /* Strip off the sorting rules, keep only the language part. */
1090 langid = LANGIDFROMLCID (lcid);
1092 /* Split into language and territory part. */
1093 primary = PRIMARYLANGID (langid);
1094 sub = SUBLANGID (langid);
1096 /* Dispatch on language.
1097 See also http://www.unicode.org/unicode/onlinedat/languages.html .
1098 For details about languages, see http://www.ethnologue.com/ . */
1101 case LANG_AFRIKAANS: return "af_ZA";
1102 case LANG_ALBANIAN: return "sq_AL";
1103 case LANG_AMHARIC: return "am_ET";
1107 case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
1108 case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
1109 case SUBLANG_ARABIC_EGYPT: return "ar_EG";
1110 case SUBLANG_ARABIC_LIBYA: return "ar_LY";
1111 case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
1112 case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
1113 case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
1114 case SUBLANG_ARABIC_OMAN: return "ar_OM";
1115 case SUBLANG_ARABIC_YEMEN: return "ar_YE";
1116 case SUBLANG_ARABIC_SYRIA: return "ar_SY";
1117 case SUBLANG_ARABIC_JORDAN: return "ar_JO";
1118 case SUBLANG_ARABIC_LEBANON: return "ar_LB";
1119 case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
1120 case SUBLANG_ARABIC_UAE: return "ar_AE";
1121 case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
1122 case SUBLANG_ARABIC_QATAR: return "ar_QA";
1125 case LANG_ARMENIAN: return "hy_AM";
1126 case LANG_ASSAMESE: return "as_IN";
1130 /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
1131 case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
1132 case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
1138 case SUBLANG_DEFAULT: return "eu_ES";
1140 return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
1141 case LANG_BELARUSIAN: return "be_BY";
1145 case SUBLANG_BENGALI_INDIA: return "bn_IN";
1146 case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
1149 case LANG_BULGARIAN: return "bg_BG";
1150 case LANG_BURMESE: return "my_MM";
1151 case LANG_CAMBODIAN: return "km_KH";
1152 case LANG_CATALAN: return "ca_ES";
1153 case LANG_CHEROKEE: return "chr_US";
1157 case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
1158 case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
1159 case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
1160 case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
1161 case SUBLANG_CHINESE_MACAU: return "zh_MO";
1164 case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN
1165 * What used to be called Serbo-Croatian
1166 * should really now be two separate
1167 * languages because of political reasons.
1168 * (Says tml, who knows nothing about Serbian
1170 * (I can feel those flames coming already.)
1174 case SUBLANG_DEFAULT: return "hr_HR";
1175 case SUBLANG_SERBIAN_LATIN: return "sr_CS";
1176 case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
1179 case LANG_CZECH: return "cs_CZ";
1180 case LANG_DANISH: return "da_DK";
1181 case LANG_DIVEHI: return "dv_MV";
1185 case SUBLANG_DUTCH: return "nl_NL";
1186 case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
1189 case LANG_EDO: return "bin_NG";
1193 /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
1194 * English was the language spoken in England.
1197 case SUBLANG_ENGLISH_US: return "en_US";
1198 case SUBLANG_ENGLISH_UK: return "en_GB";
1199 case SUBLANG_ENGLISH_AUS: return "en_AU";
1200 case SUBLANG_ENGLISH_CAN: return "en_CA";
1201 case SUBLANG_ENGLISH_NZ: return "en_NZ";
1202 case SUBLANG_ENGLISH_EIRE: return "en_IE";
1203 case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
1204 case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
1205 case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
1206 case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
1207 case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
1208 case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
1209 case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
1210 case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
1211 case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
1212 case SUBLANG_ENGLISH_INDIA: return "en_IN";
1213 case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
1214 case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
1217 case LANG_ESTONIAN: return "et_EE";
1218 case LANG_FAEROESE: return "fo_FO";
1219 case LANG_FARSI: return "fa_IR";
1220 case LANG_FINNISH: return "fi_FI";
1224 case SUBLANG_FRENCH: return "fr_FR";
1225 case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
1226 case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
1227 case SUBLANG_FRENCH_SWISS: return "fr_CH";
1228 case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
1229 case SUBLANG_FRENCH_MONACO: return "fr_MC";
1230 case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
1231 case SUBLANG_FRENCH_REUNION: return "fr_RE";
1232 case SUBLANG_FRENCH_CONGO: return "fr_CG";
1233 case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
1234 case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
1235 case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
1236 case SUBLANG_FRENCH_MALI: return "fr_ML";
1237 case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
1238 case SUBLANG_FRENCH_HAITI: return "fr_HT";
1241 case LANG_FRISIAN: return "fy_NL";
1243 /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
1248 case 0x01: /* SCOTTISH */ return "gd_GB";
1249 case 0x02: /* IRISH */ return "ga_IE";
1252 case LANG_GALICIAN: return "gl_ES";
1253 case LANG_GEORGIAN: return "ka_GE";
1257 case SUBLANG_GERMAN: return "de_DE";
1258 case SUBLANG_GERMAN_SWISS: return "de_CH";
1259 case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
1260 case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
1261 case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
1264 case LANG_GREEK: return "el_GR";
1265 case LANG_GUARANI: return "gn_PY";
1266 case LANG_GUJARATI: return "gu_IN";
1267 case LANG_HAUSA: return "ha_NG";
1269 /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
1270 or Hawaii Creole English ("cpe_US", 600000 speakers)? */
1272 case LANG_HEBREW: return "he_IL";
1273 case LANG_HINDI: return "hi_IN";
1274 case LANG_HUNGARIAN: return "hu_HU";
1275 case LANG_IBIBIO: return "nic_NG";
1276 case LANG_ICELANDIC: return "is_IS";
1277 case LANG_IGBO: return "ig_NG";
1278 case LANG_INDONESIAN: return "id_ID";
1279 case LANG_INUKTITUT: return "iu_CA";
1283 case SUBLANG_ITALIAN: return "it_IT";
1284 case SUBLANG_ITALIAN_SWISS: return "it_CH";
1287 case LANG_JAPANESE: return "ja_JP";
1288 case LANG_KANNADA: return "kn_IN";
1289 case LANG_KANURI: return "kr_NG";
1293 case SUBLANG_DEFAULT: return "ks_PK";
1294 case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
1297 case LANG_KAZAK: return "kk_KZ";
1299 /* FIXME: Adjust this when such locales appear on Unix. */
1301 case LANG_KOREAN: return "ko_KR";
1302 case LANG_KYRGYZ: return "ky_KG";
1303 case LANG_LAO: return "lo_LA";
1304 case LANG_LATIN: return "la_VA";
1305 case LANG_LATVIAN: return "lv_LV";
1306 case LANG_LITHUANIAN: return "lt_LT";
1307 case LANG_MACEDONIAN: return "mk_MK";
1311 case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
1312 case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
1315 case LANG_MALAYALAM: return "ml_IN";
1316 case LANG_MALTESE: return "mt_MT";
1318 /* FIXME: Adjust this when such locales appear on Unix. */
1320 case LANG_MARATHI: return "mr_IN";
1321 case LANG_MONGOLIAN:
1324 case SUBLANG_DEFAULT: return "mn_MN";
1326 return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
1330 case SUBLANG_DEFAULT: return "ne_NP";
1331 case SUBLANG_NEPALI_INDIA: return "ne_IN";
1334 case LANG_NORWEGIAN:
1337 case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
1338 case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
1341 case LANG_ORIYA: return "or_IN";
1342 case LANG_OROMO: return "om_ET";
1343 case LANG_PAPIAMENTU: return "pap_AN";
1345 return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
1346 case LANG_POLISH: return "pl_PL";
1347 case LANG_PORTUGUESE:
1350 case SUBLANG_PORTUGUESE: return "pt_PT";
1351 /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
1352 Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
1353 case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
1359 case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
1360 case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
1363 case LANG_RHAETO_ROMANCE: return "rm_CH";
1367 case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
1368 case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
1374 case SUBLANG_DEFAULT: return "ru_RU";
1376 return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
1377 case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
1378 case LANG_SANSKRIT: return "sa_IN";
1382 case SUBLANG_SINDHI_INDIA: return "sd_IN";
1383 case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
1386 case LANG_SINHALESE: return "si_LK";
1387 case LANG_SLOVAK: return "sk_SK";
1388 case LANG_SLOVENIAN: return "sl_SI";
1389 case LANG_SOMALI: return "so_SO";
1391 /* FIXME: Adjust this when such locales appear on Unix. */
1396 case SUBLANG_SPANISH: return "es_ES";
1397 case SUBLANG_SPANISH_MEXICAN: return "es_MX";
1398 case SUBLANG_SPANISH_MODERN:
1399 return "es_ES@modern"; /* not seen on Unix */
1400 case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
1401 case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
1402 case SUBLANG_SPANISH_PANAMA: return "es_PA";
1403 case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
1404 case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
1405 case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
1406 case SUBLANG_SPANISH_PERU: return "es_PE";
1407 case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
1408 case SUBLANG_SPANISH_ECUADOR: return "es_EC";
1409 case SUBLANG_SPANISH_CHILE: return "es_CL";
1410 case SUBLANG_SPANISH_URUGUAY: return "es_UY";
1411 case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
1412 case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
1413 case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
1414 case SUBLANG_SPANISH_HONDURAS: return "es_HN";
1415 case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
1416 case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
1419 case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
1420 case LANG_SWAHILI: return "sw_KE";
1424 case SUBLANG_DEFAULT: return "sv_SE";
1425 case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
1428 case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */
1429 case LANG_TAGALOG: return "tl_PH";
1430 case LANG_TAJIK: return "tg_TJ";
1431 case LANG_TAMAZIGHT:
1434 /* FIXME: Adjust this when Tamazight locales appear on Unix. */
1435 case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
1436 case SUBLANG_TAMAZIGHT_LATIN: return "ber_MA@latin";
1442 case SUBLANG_DEFAULT: return "ta_IN";
1444 return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
1445 case LANG_TATAR: return "tt_RU";
1446 case LANG_TELUGU: return "te_IN";
1447 case LANG_THAI: return "th_TH";
1448 case LANG_TIBETAN: return "bo_CN";
1452 case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
1453 case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
1456 case LANG_TSONGA: return "ts_ZA";
1457 case LANG_TSWANA: return "tn_BW";
1458 case LANG_TURKISH: return "tr_TR";
1459 case LANG_TURKMEN: return "tk_TM";
1460 case LANG_UKRAINIAN: return "uk_UA";
1464 case SUBLANG_URDU_PAKISTAN: return "ur_PK";
1465 case SUBLANG_URDU_INDIA: return "ur_IN";
1471 case SUBLANG_UZBEK_LATIN: return "uz_UZ";
1472 case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
1475 case LANG_VENDA: return "ve_ZA";
1476 case LANG_VIETNAMESE: return "vi_VN";
1477 case LANG_WELSH: return "cy_GB";
1478 case LANG_XHOSA: return "xh_ZA";
1479 case LANG_YI: return "sit_CN";
1480 case LANG_YIDDISH: return "yi_IL";
1481 case LANG_YORUBA: return "yo_NG";
1482 case LANG_ZULU: return "zu_ZA";
1483 default: return "C";
1491 _nl_locale_name (int category, const char *categoryname)
1495 retval = _nl_locale_name_posix (category, categoryname);
1499 return _nl_locale_name_default ();