Blame gnulib-tests/setlocale.c

Packit 33f14e
/* Set the current locale.  -*- coding: utf-8 -*-
Packit 33f14e
   Copyright (C) 2009, 2011-2017 Free Software Foundation, Inc.
Packit 33f14e
Packit 33f14e
   This program is free software: you can redistribute it and/or modify
Packit 33f14e
   it under the terms of the GNU General Public License as published by
Packit 33f14e
   the Free Software Foundation; either version 3 of the License, or
Packit 33f14e
   (at your option) any later version.
Packit 33f14e
Packit 33f14e
   This program is distributed in the hope that it will be useful,
Packit 33f14e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 33f14e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 33f14e
   GNU General Public License for more details.
Packit 33f14e
Packit 33f14e
   You should have received a copy of the GNU General Public License
Packit 33f14e
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 33f14e
Packit 33f14e
/* Written by Bruno Haible <bruno@clisp.org>, 2009.  */
Packit 33f14e
Packit 33f14e
#include <config.h>
Packit 33f14e
Packit 33f14e
/* Override setlocale() so that when the default locale is requested
Packit 33f14e
   (locale = ""), the environment variables LC_ALL, LC_*, and LANG are
Packit 33f14e
   considered.
Packit 33f14e
   Also include all the functionality from libintl's setlocale() override.  */
Packit 33f14e
Packit 33f14e
/* Please keep this file in sync with
Packit 33f14e
   gettext/gettext-runtime/intl/setlocale.c !  */
Packit 33f14e
Packit 33f14e
/* Specification.  */
Packit 33f14e
#include <locale.h>
Packit 33f14e
Packit 33f14e
#include <stdlib.h>
Packit 33f14e
#include <string.h>
Packit 33f14e
Packit 33f14e
#include "localename.h"
Packit 33f14e
Packit 33f14e
#if 1
Packit 33f14e
Packit 33f14e
# undef setlocale
Packit 33f14e
Packit 33f14e
/* Return string representation of locale category CATEGORY.  */
Packit 33f14e
static const char *
Packit 33f14e
category_to_name (int category)
Packit 33f14e
{
Packit 33f14e
  const char *retval;
Packit 33f14e
Packit 33f14e
  switch (category)
Packit 33f14e
  {
Packit 33f14e
  case LC_COLLATE:
Packit 33f14e
    retval = "LC_COLLATE";
Packit 33f14e
    break;
Packit 33f14e
  case LC_CTYPE:
Packit 33f14e
    retval = "LC_CTYPE";
Packit 33f14e
    break;
Packit 33f14e
  case LC_MONETARY:
Packit 33f14e
    retval = "LC_MONETARY";
Packit 33f14e
    break;
Packit 33f14e
  case LC_NUMERIC:
Packit 33f14e
    retval = "LC_NUMERIC";
Packit 33f14e
    break;
Packit 33f14e
  case LC_TIME:
Packit 33f14e
    retval = "LC_TIME";
Packit 33f14e
    break;
Packit 33f14e
  case LC_MESSAGES:
Packit 33f14e
    retval = "LC_MESSAGES";
Packit 33f14e
    break;
Packit 33f14e
  default:
Packit 33f14e
    /* If you have a better idea for a default value let me know.  */
Packit 33f14e
    retval = "LC_XXX";
Packit 33f14e
  }
Packit 33f14e
Packit 33f14e
  return retval;
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit 33f14e
Packit 33f14e
/* The native Windows setlocale() function expects locale names of the form
Packit 33f14e
   "German" or "German_Germany" or "DEU", but not "de" or "de_DE".  We need
Packit 33f14e
   to convert the names from the form with ISO 639 language code and ISO 3166
Packit 33f14e
   country code to the form with English names or with three-letter identifier.
Packit 33f14e
   The three-letter identifiers known by a Windows XP SP2 or SP3 are:
Packit 33f14e
     AFK  Afrikaans_South Africa.1252
Packit 33f14e
     ARA  Arabic_Saudi Arabia.1256
Packit 33f14e
     ARB  Arabic_Lebanon.1256
Packit 33f14e
     ARE  Arabic_Egypt.1256
Packit 33f14e
     ARG  Arabic_Algeria.1256
Packit 33f14e
     ARH  Arabic_Bahrain.1256
Packit 33f14e
     ARI  Arabic_Iraq.1256
Packit 33f14e
     ARJ  Arabic_Jordan.1256
Packit 33f14e
     ARK  Arabic_Kuwait.1256
Packit 33f14e
     ARL  Arabic_Libya.1256
Packit 33f14e
     ARM  Arabic_Morocco.1256
Packit 33f14e
     ARO  Arabic_Oman.1256
Packit 33f14e
     ARQ  Arabic_Qatar.1256
Packit 33f14e
     ARS  Arabic_Syria.1256
Packit 33f14e
     ART  Arabic_Tunisia.1256
Packit 33f14e
     ARU  Arabic_U.A.E..1256
Packit 33f14e
     ARY  Arabic_Yemen.1256
Packit 33f14e
     AZE  Azeri (Latin)_Azerbaijan.1254
Packit 33f14e
     BEL  Belarusian_Belarus.1251
Packit 33f14e
     BGR  Bulgarian_Bulgaria.1251
Packit 33f14e
     BSB  Bosnian_Bosnia and Herzegovina.1250
Packit 33f14e
     BSC  Bosnian (Cyrillic)_Bosnia and Herzegovina.1250  (wrong encoding!)
Packit 33f14e
     CAT  Catalan_Spain.1252
Packit 33f14e
     CHH  Chinese_Hong Kong S.A.R..950
Packit 33f14e
     CHI  Chinese_Singapore.936
Packit 33f14e
     CHS  Chinese_People's Republic of China.936
Packit 33f14e
     CHT  Chinese_Taiwan.950
Packit 33f14e
     CSY  Czech_Czech Republic.1250
Packit 33f14e
     CYM  Welsh_United Kingdom.1252
Packit 33f14e
     DAN  Danish_Denmark.1252
Packit 33f14e
     DEA  German_Austria.1252
Packit 33f14e
     DEC  German_Liechtenstein.1252
Packit 33f14e
     DEL  German_Luxembourg.1252
Packit 33f14e
     DES  German_Switzerland.1252
Packit 33f14e
     DEU  German_Germany.1252
Packit 33f14e
     ELL  Greek_Greece.1253
Packit 33f14e
     ENA  English_Australia.1252
Packit 33f14e
     ENB  English_Caribbean.1252
Packit 33f14e
     ENC  English_Canada.1252
Packit 33f14e
     ENG  English_United Kingdom.1252
Packit 33f14e
     ENI  English_Ireland.1252
Packit 33f14e
     ENJ  English_Jamaica.1252
Packit 33f14e
     ENL  English_Belize.1252
Packit 33f14e
     ENP  English_Republic of the Philippines.1252
Packit 33f14e
     ENS  English_South Africa.1252
Packit 33f14e
     ENT  English_Trinidad and Tobago.1252
Packit 33f14e
     ENU  English_United States.1252
Packit 33f14e
     ENW  English_Zimbabwe.1252
Packit 33f14e
     ENZ  English_New Zealand.1252
Packit 33f14e
     ESA  Spanish_Panama.1252
Packit 33f14e
     ESB  Spanish_Bolivia.1252
Packit 33f14e
     ESC  Spanish_Costa Rica.1252
Packit 33f14e
     ESD  Spanish_Dominican Republic.1252
Packit 33f14e
     ESE  Spanish_El Salvador.1252
Packit 33f14e
     ESF  Spanish_Ecuador.1252
Packit 33f14e
     ESG  Spanish_Guatemala.1252
Packit 33f14e
     ESH  Spanish_Honduras.1252
Packit 33f14e
     ESI  Spanish_Nicaragua.1252
Packit 33f14e
     ESL  Spanish_Chile.1252
Packit 33f14e
     ESM  Spanish_Mexico.1252
Packit 33f14e
     ESN  Spanish_Spain.1252
Packit 33f14e
     ESO  Spanish_Colombia.1252
Packit 33f14e
     ESP  Spanish_Spain.1252
Packit 33f14e
     ESR  Spanish_Peru.1252
Packit 33f14e
     ESS  Spanish_Argentina.1252
Packit 33f14e
     ESU  Spanish_Puerto Rico.1252
Packit 33f14e
     ESV  Spanish_Venezuela.1252
Packit 33f14e
     ESY  Spanish_Uruguay.1252
Packit 33f14e
     ESZ  Spanish_Paraguay.1252
Packit 33f14e
     ETI  Estonian_Estonia.1257
Packit 33f14e
     EUQ  Basque_Spain.1252
Packit 33f14e
     FAR  Farsi_Iran.1256
Packit 33f14e
     FIN  Finnish_Finland.1252
Packit 33f14e
     FOS  Faroese_Faroe Islands.1252
Packit 33f14e
     FPO  Filipino_Philippines.1252
Packit 33f14e
     FRA  French_France.1252
Packit 33f14e
     FRB  French_Belgium.1252
Packit 33f14e
     FRC  French_Canada.1252
Packit 33f14e
     FRL  French_Luxembourg.1252
Packit 33f14e
     FRM  French_Principality of Monaco.1252
Packit 33f14e
     FRS  French_Switzerland.1252
Packit 33f14e
     FYN  Frisian_Netherlands.1252
Packit 33f14e
     GLC  Galician_Spain.1252
Packit 33f14e
     HEB  Hebrew_Israel.1255
Packit 33f14e
     HRB  Croatian_Bosnia and Herzegovina.1250
Packit 33f14e
     HRV  Croatian_Croatia.1250
Packit 33f14e
     HUN  Hungarian_Hungary.1250
Packit 33f14e
     IND  Indonesian_Indonesia.1252
Packit 33f14e
     IRE  Irish_Ireland.1252
Packit 33f14e
     ISL  Icelandic_Iceland.1252
Packit 33f14e
     ITA  Italian_Italy.1252
Packit 33f14e
     ITS  Italian_Switzerland.1252
Packit 33f14e
     IUK  Inuktitut (Latin)_Canada.1252
Packit 33f14e
     JPN  Japanese_Japan.932
Packit 33f14e
     KKZ  Kazakh_Kazakhstan.1251
Packit 33f14e
     KOR  Korean_Korea.949
Packit 33f14e
     KYR  Kyrgyz_Kyrgyzstan.1251
Packit 33f14e
     LBX  Luxembourgish_Luxembourg.1252
Packit 33f14e
     LTH  Lithuanian_Lithuania.1257
Packit 33f14e
     LVI  Latvian_Latvia.1257
Packit 33f14e
     MKI  FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251
Packit 33f14e
     MON  Mongolian_Mongolia.1251
Packit 33f14e
     MPD  Mapudungun_Chile.1252
Packit 33f14e
     MSB  Malay_Brunei Darussalam.1252
Packit 33f14e
     MSL  Malay_Malaysia.1252
Packit 33f14e
     MWK  Mohawk_Canada.1252
Packit 33f14e
     NLB  Dutch_Belgium.1252
Packit 33f14e
     NLD  Dutch_Netherlands.1252
Packit 33f14e
     NON  Norwegian-Nynorsk_Norway.1252
Packit 33f14e
     NOR  Norwegian (Bokmål)_Norway.1252
Packit 33f14e
     NSO  Northern Sotho_South Africa.1252
Packit 33f14e
     PLK  Polish_Poland.1250
Packit 33f14e
     PTB  Portuguese_Brazil.1252
Packit 33f14e
     PTG  Portuguese_Portugal.1252
Packit 33f14e
     QUB  Quechua_Bolivia.1252
Packit 33f14e
     QUE  Quechua_Ecuador.1252
Packit 33f14e
     QUP  Quechua_Peru.1252
Packit 33f14e
     RMC  Romansh_Switzerland.1252
Packit 33f14e
     ROM  Romanian_Romania.1250
Packit 33f14e
     RUS  Russian_Russia.1251
Packit 33f14e
     SKY  Slovak_Slovakia.1250
Packit 33f14e
     SLV  Slovenian_Slovenia.1250
Packit 33f14e
     SMA  Sami (Southern)_Norway.1252
Packit 33f14e
     SMB  Sami (Southern)_Sweden.1252
Packit 33f14e
     SME  Sami (Northern)_Norway.1252
Packit 33f14e
     SMF  Sami (Northern)_Sweden.1252
Packit 33f14e
     SMG  Sami (Northern)_Finland.1252
Packit 33f14e
     SMJ  Sami (Lule)_Norway.1252
Packit 33f14e
     SMK  Sami (Lule)_Sweden.1252
Packit 33f14e
     SMN  Sami (Inari)_Finland.1252
Packit 33f14e
     SMS  Sami (Skolt)_Finland.1252
Packit 33f14e
     SQI  Albanian_Albania.1250
Packit 33f14e
     SRB  Serbian (Cyrillic)_Serbia and Montenegro.1251
Packit 33f14e
     SRL  Serbian (Latin)_Serbia and Montenegro.1250
Packit 33f14e
     SRN  Serbian (Cyrillic)_Bosnia and Herzegovina.1251
Packit 33f14e
     SRS  Serbian (Latin)_Bosnia and Herzegovina.1250
Packit 33f14e
     SVE  Swedish_Sweden.1252
Packit 33f14e
     SVF  Swedish_Finland.1252
Packit 33f14e
     SWK  Swahili_Kenya.1252
Packit 33f14e
     THA  Thai_Thailand.874
Packit 33f14e
     TRK  Turkish_Turkey.1254
Packit 33f14e
     TSN  Tswana_South Africa.1252
Packit 33f14e
     TTT  Tatar_Russia.1251
Packit 33f14e
     UKR  Ukrainian_Ukraine.1251
Packit 33f14e
     URD  Urdu_Islamic Republic of Pakistan.1256
Packit 33f14e
     USA  English_United States.1252
Packit 33f14e
     UZB  Uzbek (Latin)_Uzbekistan.1254
Packit 33f14e
     VIT  Vietnamese_Viet Nam.1258
Packit 33f14e
     XHO  Xhosa_South Africa.1252
Packit 33f14e
     ZHH  Chinese_Hong Kong S.A.R..950
Packit 33f14e
     ZHI  Chinese_Singapore.936
Packit 33f14e
     ZHM  Chinese_Macau S.A.R..950
Packit 33f14e
     ZUL  Zulu_South Africa.1252
Packit 33f14e
 */
Packit 33f14e
Packit 33f14e
/* Table from ISO 639 language code, optionally with country or script suffix,
Packit 33f14e
   to English name.
Packit 33f14e
   Keep in sync with the gl_locale_name_from_win32_LANGID function in
Packit 33f14e
   localename.c!  */
Packit 33f14e
struct table_entry
Packit 33f14e
{
Packit 33f14e
  const char *code;
Packit 33f14e
  const char *english;
Packit 33f14e
};
Packit 33f14e
static const struct table_entry language_table[] =
Packit 33f14e
  {
Packit 33f14e
    { "af", "Afrikaans" },
Packit 33f14e
    { "am", "Amharic" },
Packit 33f14e
    { "ar", "Arabic" },
Packit 33f14e
    { "arn", "Mapudungun" },
Packit 33f14e
    { "as", "Assamese" },
Packit 33f14e
    { "az@cyrillic", "Azeri (Cyrillic)" },
Packit 33f14e
    { "az@latin", "Azeri (Latin)" },
Packit 33f14e
    { "ba", "Bashkir" },
Packit 33f14e
    { "be", "Belarusian" },
Packit 33f14e
    { "ber", "Tamazight" },
Packit 33f14e
    { "ber@arabic", "Tamazight (Arabic)" },
Packit 33f14e
    { "ber@latin", "Tamazight (Latin)" },
Packit 33f14e
    { "bg", "Bulgarian" },
Packit 33f14e
    { "bin", "Edo" },
Packit 33f14e
    { "bn", "Bengali" },
Packit 33f14e
    { "bn_BD", "Bengali (Bangladesh)" },
Packit 33f14e
    { "bn_IN", "Bengali (India)" },
Packit 33f14e
    { "bnt", "Sutu" },
Packit 33f14e
    { "bo", "Tibetan" },
Packit 33f14e
    { "br", "Breton" },
Packit 33f14e
    { "bs", "BSB" }, /* "Bosnian (Latin)" */
Packit 33f14e
    { "bs@cyrillic", "BSC" }, /* Bosnian (Cyrillic) */
Packit 33f14e
    { "ca", "Catalan" },
Packit 33f14e
    { "chr", "Cherokee" },
Packit 33f14e
    { "co", "Corsican" },
Packit 33f14e
    { "cpe", "Hawaiian" },
Packit 33f14e
    { "cs", "Czech" },
Packit 33f14e
    { "cy", "Welsh" },
Packit 33f14e
    { "da", "Danish" },
Packit 33f14e
    { "de", "German" },
Packit 33f14e
    { "dsb", "Lower Sorbian" },
Packit 33f14e
    { "dv", "Divehi" },
Packit 33f14e
    { "el", "Greek" },
Packit 33f14e
    { "en", "English" },
Packit 33f14e
    { "es", "Spanish" },
Packit 33f14e
    { "et", "Estonian" },
Packit 33f14e
    { "eu", "Basque" },
Packit 33f14e
    { "fa", "Farsi" },
Packit 33f14e
    { "ff", "Fulfulde" },
Packit 33f14e
    { "fi", "Finnish" },
Packit 33f14e
    { "fo", "Faroese" }, /* "Faeroese" does not work */
Packit 33f14e
    { "fr", "French" },
Packit 33f14e
    { "fy", "Frisian" },
Packit 33f14e
    { "ga", "IRE" }, /* Gaelic (Ireland) */
Packit 33f14e
    { "gd", "Gaelic (Scotland)" },
Packit 33f14e
    { "gd", "Scottish Gaelic" },
Packit 33f14e
    { "gl", "Galician" },
Packit 33f14e
    { "gn", "Guarani" },
Packit 33f14e
    { "gsw", "Alsatian" },
Packit 33f14e
    { "gu", "Gujarati" },
Packit 33f14e
    { "ha", "Hausa" },
Packit 33f14e
    { "he", "Hebrew" },
Packit 33f14e
    { "hi", "Hindi" },
Packit 33f14e
    { "hr", "Croatian" },
Packit 33f14e
    { "hsb", "Upper Sorbian" },
Packit 33f14e
    { "hu", "Hungarian" },
Packit 33f14e
    { "hy", "Armenian" },
Packit 33f14e
    { "id", "Indonesian" },
Packit 33f14e
    { "ig", "Igbo" },
Packit 33f14e
    { "ii", "Yi" },
Packit 33f14e
    { "is", "Icelandic" },
Packit 33f14e
    { "it", "Italian" },
Packit 33f14e
    { "iu", "IUK" }, /* Inuktitut */
Packit 33f14e
    { "ja", "Japanese" },
Packit 33f14e
    { "ka", "Georgian" },
Packit 33f14e
    { "kk", "Kazakh" },
Packit 33f14e
    { "kl", "Greenlandic" },
Packit 33f14e
    { "km", "Cambodian" },
Packit 33f14e
    { "km", "Khmer" },
Packit 33f14e
    { "kn", "Kannada" },
Packit 33f14e
    { "ko", "Korean" },
Packit 33f14e
    { "kok", "Konkani" },
Packit 33f14e
    { "kr", "Kanuri" },
Packit 33f14e
    { "ks", "Kashmiri" },
Packit 33f14e
    { "ks_IN", "Kashmiri_India" },
Packit 33f14e
    { "ks_PK", "Kashmiri (Arabic)_Pakistan" },
Packit 33f14e
    { "ky", "Kyrgyz" },
Packit 33f14e
    { "la", "Latin" },
Packit 33f14e
    { "lb", "Luxembourgish" },
Packit 33f14e
    { "lo", "Lao" },
Packit 33f14e
    { "lt", "Lithuanian" },
Packit 33f14e
    { "lv", "Latvian" },
Packit 33f14e
    { "mi", "Maori" },
Packit 33f14e
    { "mk", "FYRO Macedonian" },
Packit 33f14e
    { "mk", "Macedonian" },
Packit 33f14e
    { "ml", "Malayalam" },
Packit 33f14e
    { "mn", "Mongolian" },
Packit 33f14e
    { "mni", "Manipuri" },
Packit 33f14e
    { "moh", "Mohawk" },
Packit 33f14e
    { "mr", "Marathi" },
Packit 33f14e
    { "ms", "Malay" },
Packit 33f14e
    { "mt", "Maltese" },
Packit 33f14e
    { "my", "Burmese" },
Packit 33f14e
    { "nb", "NOR" }, /* Norwegian Bokmål */
Packit 33f14e
    { "ne", "Nepali" },
Packit 33f14e
    { "nic", "Ibibio" },
Packit 33f14e
    { "nl", "Dutch" },
Packit 33f14e
    { "nn", "NON" }, /* Norwegian Nynorsk */
Packit 33f14e
    { "no", "Norwegian" },
Packit 33f14e
    { "nso", "Northern Sotho" },
Packit 33f14e
    { "nso", "Sepedi" },
Packit 33f14e
    { "oc", "Occitan" },
Packit 33f14e
    { "om", "Oromo" },
Packit 33f14e
    { "or", "Oriya" },
Packit 33f14e
    { "pa", "Punjabi" },
Packit 33f14e
    { "pap", "Papiamentu" },
Packit 33f14e
    { "pl", "Polish" },
Packit 33f14e
    { "prs", "Dari" },
Packit 33f14e
    { "ps", "Pashto" },
Packit 33f14e
    { "pt", "Portuguese" },
Packit 33f14e
    { "qu", "Quechua" },
Packit 33f14e
    { "qut", "K'iche'" },
Packit 33f14e
    { "rm", "Romansh" },
Packit 33f14e
    { "ro", "Romanian" },
Packit 33f14e
    { "ru", "Russian" },
Packit 33f14e
    { "rw", "Kinyarwanda" },
Packit 33f14e
    { "sa", "Sanskrit" },
Packit 33f14e
    { "sah", "Yakut" },
Packit 33f14e
    { "sd", "Sindhi" },
Packit 33f14e
    { "se", "Sami (Northern)" },
Packit 33f14e
    { "se", "Northern Sami" },
Packit 33f14e
    { "si", "Sinhalese" },
Packit 33f14e
    { "sk", "Slovak" },
Packit 33f14e
    { "sl", "Slovenian" },
Packit 33f14e
    { "sma", "Sami (Southern)" },
Packit 33f14e
    { "sma", "Southern Sami" },
Packit 33f14e
    { "smj", "Sami (Lule)" },
Packit 33f14e
    { "smj", "Lule Sami" },
Packit 33f14e
    { "smn", "Sami (Inari)" },
Packit 33f14e
    { "smn", "Inari Sami" },
Packit 33f14e
    { "sms", "Sami (Skolt)" },
Packit 33f14e
    { "sms", "Skolt Sami" },
Packit 33f14e
    { "so", "Somali" },
Packit 33f14e
    { "sq", "Albanian" },
Packit 33f14e
    { "sr", "Serbian (Latin)" },
Packit 33f14e
    { "sr@cyrillic", "SRB" }, /* Serbian (Cyrillic) */
Packit 33f14e
    { "sv", "Swedish" },
Packit 33f14e
    { "sw", "Swahili" },
Packit 33f14e
    { "syr", "Syriac" },
Packit 33f14e
    { "ta", "Tamil" },
Packit 33f14e
    { "te", "Telugu" },
Packit 33f14e
    { "tg", "Tajik" },
Packit 33f14e
    { "th", "Thai" },
Packit 33f14e
    { "ti", "Tigrinya" },
Packit 33f14e
    { "tk", "Turkmen" },
Packit 33f14e
    { "tl", "Filipino" },
Packit 33f14e
    { "tn", "Tswana" },
Packit 33f14e
    { "tr", "Turkish" },
Packit 33f14e
    { "ts", "Tsonga" },
Packit 33f14e
    { "tt", "Tatar" },
Packit 33f14e
    { "ug", "Uighur" },
Packit 33f14e
    { "uk", "Ukrainian" },
Packit 33f14e
    { "ur", "Urdu" },
Packit 33f14e
    { "uz", "Uzbek" },
Packit 33f14e
    { "uz", "Uzbek (Latin)" },
Packit 33f14e
    { "uz@cyrillic", "Uzbek (Cyrillic)" },
Packit 33f14e
    { "ve", "Venda" },
Packit 33f14e
    { "vi", "Vietnamese" },
Packit 33f14e
    { "wen", "Sorbian" },
Packit 33f14e
    { "wo", "Wolof" },
Packit 33f14e
    { "xh", "Xhosa" },
Packit 33f14e
    { "yi", "Yiddish" },
Packit 33f14e
    { "yo", "Yoruba" },
Packit 33f14e
    { "zh", "Chinese" },
Packit 33f14e
    { "zu", "Zulu" }
Packit 33f14e
  };
Packit 33f14e
Packit 33f14e
/* Table from ISO 3166 country code to English name.
Packit 33f14e
   Keep in sync with the gl_locale_name_from_win32_LANGID function in
Packit 33f14e
   localename.c!  */
Packit 33f14e
static const struct table_entry country_table[] =
Packit 33f14e
  {
Packit 33f14e
    { "AE", "U.A.E." },
Packit 33f14e
    { "AF", "Afghanistan" },
Packit 33f14e
    { "AL", "Albania" },
Packit 33f14e
    { "AM", "Armenia" },
Packit 33f14e
    { "AN", "Netherlands Antilles" },
Packit 33f14e
    { "AR", "Argentina" },
Packit 33f14e
    { "AT", "Austria" },
Packit 33f14e
    { "AU", "Australia" },
Packit 33f14e
    { "AZ", "Azerbaijan" },
Packit 33f14e
    { "BA", "Bosnia and Herzegovina" },
Packit 33f14e
    { "BD", "Bangladesh" },
Packit 33f14e
    { "BE", "Belgium" },
Packit 33f14e
    { "BG", "Bulgaria" },
Packit 33f14e
    { "BH", "Bahrain" },
Packit 33f14e
    { "BN", "Brunei Darussalam" },
Packit 33f14e
    { "BO", "Bolivia" },
Packit 33f14e
    { "BR", "Brazil" },
Packit 33f14e
    { "BT", "Bhutan" },
Packit 33f14e
    { "BY", "Belarus" },
Packit 33f14e
    { "BZ", "Belize" },
Packit 33f14e
    { "CA", "Canada" },
Packit 33f14e
    { "CG", "Congo" },
Packit 33f14e
    { "CH", "Switzerland" },
Packit 33f14e
    { "CI", "Cote d'Ivoire" },
Packit 33f14e
    { "CL", "Chile" },
Packit 33f14e
    { "CM", "Cameroon" },
Packit 33f14e
    { "CN", "People's Republic of China" },
Packit 33f14e
    { "CO", "Colombia" },
Packit 33f14e
    { "CR", "Costa Rica" },
Packit 33f14e
    { "CS", "Serbia and Montenegro" },
Packit 33f14e
    { "CZ", "Czech Republic" },
Packit 33f14e
    { "DE", "Germany" },
Packit 33f14e
    { "DK", "Denmark" },
Packit 33f14e
    { "DO", "Dominican Republic" },
Packit 33f14e
    { "DZ", "Algeria" },
Packit 33f14e
    { "EC", "Ecuador" },
Packit 33f14e
    { "EE", "Estonia" },
Packit 33f14e
    { "EG", "Egypt" },
Packit 33f14e
    { "ER", "Eritrea" },
Packit 33f14e
    { "ES", "Spain" },
Packit 33f14e
    { "ET", "Ethiopia" },
Packit 33f14e
    { "FI", "Finland" },
Packit 33f14e
    { "FO", "Faroe Islands" },
Packit 33f14e
    { "FR", "France" },
Packit 33f14e
    { "GB", "United Kingdom" },
Packit 33f14e
    { "GD", "Caribbean" },
Packit 33f14e
    { "GE", "Georgia" },
Packit 33f14e
    { "GL", "Greenland" },
Packit 33f14e
    { "GR", "Greece" },
Packit 33f14e
    { "GT", "Guatemala" },
Packit 33f14e
    { "HK", "Hong Kong" },
Packit 33f14e
    { "HK", "Hong Kong S.A.R." },
Packit 33f14e
    { "HN", "Honduras" },
Packit 33f14e
    { "HR", "Croatia" },
Packit 33f14e
    { "HT", "Haiti" },
Packit 33f14e
    { "HU", "Hungary" },
Packit 33f14e
    { "ID", "Indonesia" },
Packit 33f14e
    { "IE", "Ireland" },
Packit 33f14e
    { "IL", "Israel" },
Packit 33f14e
    { "IN", "India" },
Packit 33f14e
    { "IQ", "Iraq" },
Packit 33f14e
    { "IR", "Iran" },
Packit 33f14e
    { "IS", "Iceland" },
Packit 33f14e
    { "IT", "Italy" },
Packit 33f14e
    { "JM", "Jamaica" },
Packit 33f14e
    { "JO", "Jordan" },
Packit 33f14e
    { "JP", "Japan" },
Packit 33f14e
    { "KE", "Kenya" },
Packit 33f14e
    { "KG", "Kyrgyzstan" },
Packit 33f14e
    { "KH", "Cambodia" },
Packit 33f14e
    { "KR", "South Korea" },
Packit 33f14e
    { "KW", "Kuwait" },
Packit 33f14e
    { "KZ", "Kazakhstan" },
Packit 33f14e
    { "LA", "Laos" },
Packit 33f14e
    { "LB", "Lebanon" },
Packit 33f14e
    { "LI", "Liechtenstein" },
Packit 33f14e
    { "LK", "Sri Lanka" },
Packit 33f14e
    { "LT", "Lithuania" },
Packit 33f14e
    { "LU", "Luxembourg" },
Packit 33f14e
    { "LV", "Latvia" },
Packit 33f14e
    { "LY", "Libya" },
Packit 33f14e
    { "MA", "Morocco" },
Packit 33f14e
    { "MC", "Principality of Monaco" },
Packit 33f14e
    { "MD", "Moldava" },
Packit 33f14e
    { "MD", "Moldova" },
Packit 33f14e
    { "ME", "Montenegro" },
Packit 33f14e
    { "MK", "Former Yugoslav Republic of Macedonia" },
Packit 33f14e
    { "ML", "Mali" },
Packit 33f14e
    { "MM", "Myanmar" },
Packit 33f14e
    { "MN", "Mongolia" },
Packit 33f14e
    { "MO", "Macau S.A.R." },
Packit 33f14e
    { "MT", "Malta" },
Packit 33f14e
    { "MV", "Maldives" },
Packit 33f14e
    { "MX", "Mexico" },
Packit 33f14e
    { "MY", "Malaysia" },
Packit 33f14e
    { "NG", "Nigeria" },
Packit 33f14e
    { "NI", "Nicaragua" },
Packit 33f14e
    { "NL", "Netherlands" },
Packit 33f14e
    { "NO", "Norway" },
Packit 33f14e
    { "NP", "Nepal" },
Packit 33f14e
    { "NZ", "New Zealand" },
Packit 33f14e
    { "OM", "Oman" },
Packit 33f14e
    { "PA", "Panama" },
Packit 33f14e
    { "PE", "Peru" },
Packit 33f14e
    { "PH", "Philippines" },
Packit 33f14e
    { "PK", "Islamic Republic of Pakistan" },
Packit 33f14e
    { "PL", "Poland" },
Packit 33f14e
    { "PR", "Puerto Rico" },
Packit 33f14e
    { "PT", "Portugal" },
Packit 33f14e
    { "PY", "Paraguay" },
Packit 33f14e
    { "QA", "Qatar" },
Packit 33f14e
    { "RE", "Reunion" },
Packit 33f14e
    { "RO", "Romania" },
Packit 33f14e
    { "RS", "Serbia" },
Packit 33f14e
    { "RU", "Russia" },
Packit 33f14e
    { "RW", "Rwanda" },
Packit 33f14e
    { "SA", "Saudi Arabia" },
Packit 33f14e
    { "SE", "Sweden" },
Packit 33f14e
    { "SG", "Singapore" },
Packit 33f14e
    { "SI", "Slovenia" },
Packit 33f14e
    { "SK", "Slovak" },
Packit 33f14e
    { "SN", "Senegal" },
Packit 33f14e
    { "SO", "Somalia" },
Packit 33f14e
    { "SR", "Suriname" },
Packit 33f14e
    { "SV", "El Salvador" },
Packit 33f14e
    { "SY", "Syria" },
Packit 33f14e
    { "TH", "Thailand" },
Packit 33f14e
    { "TJ", "Tajikistan" },
Packit 33f14e
    { "TM", "Turkmenistan" },
Packit 33f14e
    { "TN", "Tunisia" },
Packit 33f14e
    { "TR", "Turkey" },
Packit 33f14e
    { "TT", "Trinidad and Tobago" },
Packit 33f14e
    { "TW", "Taiwan" },
Packit 33f14e
    { "TZ", "Tanzania" },
Packit 33f14e
    { "UA", "Ukraine" },
Packit 33f14e
    { "US", "United States" },
Packit 33f14e
    { "UY", "Uruguay" },
Packit 33f14e
    { "VA", "Vatican" },
Packit 33f14e
    { "VE", "Venezuela" },
Packit 33f14e
    { "VN", "Viet Nam" },
Packit 33f14e
    { "YE", "Yemen" },
Packit 33f14e
    { "ZA", "South Africa" },
Packit 33f14e
    { "ZW", "Zimbabwe" }
Packit 33f14e
  };
Packit 33f14e
Packit 33f14e
/* Given a string STRING, find the set of indices i such that TABLE[i].code is
Packit 33f14e
   the given STRING.  It is a range [lo,hi-1].  */
Packit 33f14e
typedef struct { size_t lo; size_t hi; } range_t;
Packit 33f14e
static void
Packit 33f14e
search (const struct table_entry *table, size_t table_size, const char *string,
Packit 33f14e
        range_t *result)
Packit 33f14e
{
Packit 33f14e
  /* The table is sorted.  Perform a binary search.  */
Packit 33f14e
  size_t hi = table_size;
Packit 33f14e
  size_t lo = 0;
Packit 33f14e
  while (lo < hi)
Packit 33f14e
    {
Packit 33f14e
      /* Invariant:
Packit 33f14e
         for i < lo, strcmp (table[i].code, string) < 0,
Packit 33f14e
         for i >= hi, strcmp (table[i].code, string) > 0.  */
Packit 33f14e
      size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
Packit 33f14e
      int cmp = strcmp (table[mid].code, string);
Packit 33f14e
      if (cmp < 0)
Packit 33f14e
        lo = mid + 1;
Packit 33f14e
      else if (cmp > 0)
Packit 33f14e
        hi = mid;
Packit 33f14e
      else
Packit 33f14e
        {
Packit 33f14e
          /* Found an i with
Packit 33f14e
               strcmp (language_table[i].code, string) == 0.
Packit 33f14e
             Find the entire interval of such i.  */
Packit 33f14e
          {
Packit 33f14e
            size_t i;
Packit 33f14e
Packit 33f14e
            for (i = mid; i > lo; )
Packit 33f14e
              {
Packit 33f14e
                i--;
Packit 33f14e
                if (strcmp (table[i].code, string) < 0)
Packit 33f14e
                  {
Packit 33f14e
                    lo = i + 1;
Packit 33f14e
                    break;
Packit 33f14e
                  }
Packit 33f14e
              }
Packit 33f14e
          }
Packit 33f14e
          {
Packit 33f14e
            size_t i;
Packit 33f14e
Packit 33f14e
            for (i = mid; i < hi; i++)
Packit 33f14e
              {
Packit 33f14e
                if (strcmp (table[i].code, string) > 0)
Packit 33f14e
                  {
Packit 33f14e
                    hi = i;
Packit 33f14e
                    break;
Packit 33f14e
                  }
Packit 33f14e
              }
Packit 33f14e
          }
Packit 33f14e
          /* The set of i with
Packit 33f14e
               strcmp (language_table[i].code, string) == 0
Packit 33f14e
             is the interval [lo, hi-1].  */
Packit 33f14e
          break;
Packit 33f14e
        }
Packit 33f14e
    }
Packit 33f14e
  result->lo = lo;
Packit 33f14e
  result->hi = hi;
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
/* Like setlocale, but accept also locale names in the form ll or ll_CC,
Packit 33f14e
   where ll is an ISO 639 language code and CC is an ISO 3166 country code.  */
Packit 33f14e
static char *
Packit 33f14e
setlocale_unixlike (int category, const char *locale)
Packit 33f14e
{
Packit 33f14e
  char *result;
Packit 33f14e
  char llCC_buf[64];
Packit 33f14e
  char ll_buf[64];
Packit 33f14e
  char CC_buf[64];
Packit 33f14e
Packit 33f14e
  /* The native Windows implementation of setlocale understands the special
Packit 33f14e
     locale name "C", but not "POSIX".  Therefore map "POSIX" to "C".  */
Packit 33f14e
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
Packit 33f14e
  if (locale != NULL && strcmp (locale, "POSIX") == 0)
Packit 33f14e
    locale = "C";
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
  /* First, try setlocale with the original argument unchanged.  */
Packit 33f14e
  result = setlocale (category, locale);
Packit 33f14e
  if (result != NULL)
Packit 33f14e
    return result;
Packit 33f14e
Packit 33f14e
  /* Otherwise, assume the argument is in the form
Packit 33f14e
       language[_territory][.codeset][@modifier]
Packit 33f14e
     and try to map it using the tables.  */
Packit 33f14e
  if (strlen (locale) < sizeof (llCC_buf))
Packit 33f14e
    {
Packit 33f14e
      /* Second try: Remove the codeset part.  */
Packit 33f14e
      {
Packit 33f14e
        const char *p = locale;
Packit 33f14e
        char *q = llCC_buf;
Packit 33f14e
Packit 33f14e
        /* Copy the part before the dot.  */
Packit 33f14e
        for (; *p != '\0' && *p != '.'; p++, q++)
Packit 33f14e
          *q = *p;
Packit 33f14e
        if (*p == '.')
Packit 33f14e
          /* Skip the part up to the '@', if any.  */
Packit 33f14e
          for (; *p != '\0' && *p != '@'; p++)
Packit 33f14e
            ;
Packit 33f14e
        /* Copy the part starting with '@', if any.  */
Packit 33f14e
        for (; *p != '\0'; p++, q++)
Packit 33f14e
          *q = *p;
Packit 33f14e
        *q = '\0';
Packit 33f14e
      }
Packit 33f14e
      /* llCC_buf now contains
Packit 33f14e
           language[_territory][@modifier]
Packit 33f14e
       */
Packit 33f14e
      if (strcmp (llCC_buf, locale) != 0)
Packit 33f14e
        {
Packit 33f14e
          result = setlocale (category, llCC_buf);
Packit 33f14e
          if (result != NULL)
Packit 33f14e
            return result;
Packit 33f14e
        }
Packit 33f14e
      /* Look it up in language_table.  */
Packit 33f14e
      {
Packit 33f14e
        range_t range;
Packit 33f14e
        size_t i;
Packit 33f14e
Packit 33f14e
        search (language_table,
Packit 33f14e
                sizeof (language_table) / sizeof (language_table[0]),
Packit 33f14e
                llCC_buf,
Packit 33f14e
                &range);
Packit 33f14e
Packit 33f14e
        for (i = range.lo; i < range.hi; i++)
Packit 33f14e
          {
Packit 33f14e
            /* Try the replacement in language_table[i].  */
Packit 33f14e
            result = setlocale (category, language_table[i].english);
Packit 33f14e
            if (result != NULL)
Packit 33f14e
              return result;
Packit 33f14e
          }
Packit 33f14e
      }
Packit 33f14e
      /* Split language[_territory][@modifier]
Packit 33f14e
         into  ll_buf = language[@modifier]
Packit 33f14e
         and   CC_buf = territory
Packit 33f14e
       */
Packit 33f14e
      {
Packit 33f14e
        const char *underscore = strchr (llCC_buf, '_');
Packit 33f14e
        if (underscore != NULL)
Packit 33f14e
          {
Packit 33f14e
            const char *territory_start = underscore + 1;
Packit 33f14e
            const char *territory_end = strchr (territory_start, '@');
Packit 33f14e
            if (territory_end == NULL)
Packit 33f14e
              territory_end = territory_start + strlen (territory_start);
Packit 33f14e
Packit 33f14e
            memcpy (ll_buf, llCC_buf, underscore - llCC_buf);
Packit 33f14e
            strcpy (ll_buf + (underscore - llCC_buf), territory_end);
Packit 33f14e
Packit 33f14e
            memcpy (CC_buf, territory_start, territory_end - territory_start);
Packit 33f14e
            CC_buf[territory_end - territory_start] = '\0';
Packit 33f14e
Packit 33f14e
            {
Packit 33f14e
              /* Look up ll_buf in language_table
Packit 33f14e
                 and CC_buf in country_table.  */
Packit 33f14e
              range_t language_range;
Packit 33f14e
Packit 33f14e
              search (language_table,
Packit 33f14e
                      sizeof (language_table) / sizeof (language_table[0]),
Packit 33f14e
                      ll_buf,
Packit 33f14e
                      &language_range);
Packit 33f14e
              if (language_range.lo < language_range.hi)
Packit 33f14e
                {
Packit 33f14e
                  range_t country_range;
Packit 33f14e
Packit 33f14e
                  search (country_table,
Packit 33f14e
                          sizeof (country_table) / sizeof (country_table[0]),
Packit 33f14e
                          CC_buf,
Packit 33f14e
                          &country_range);
Packit 33f14e
                  if (country_range.lo < country_range.hi)
Packit 33f14e
                    {
Packit 33f14e
                      size_t i;
Packit 33f14e
                      size_t j;
Packit 33f14e
Packit 33f14e
                      for (i = language_range.lo; i < language_range.hi; i++)
Packit 33f14e
                        for (j = country_range.lo; j < country_range.hi; j++)
Packit 33f14e
                          {
Packit 33f14e
                            /* Concatenate the replacements.  */
Packit 33f14e
                            const char *part1 = language_table[i].english;
Packit 33f14e
                            size_t part1_len = strlen (part1);
Packit 33f14e
                            const char *part2 = country_table[j].english;
Packit 33f14e
                            size_t part2_len = strlen (part2) + 1;
Packit 33f14e
                            char buf[64+64];
Packit 33f14e
Packit 33f14e
                            if (!(part1_len + 1 + part2_len <= sizeof (buf)))
Packit 33f14e
                              abort ();
Packit 33f14e
                            memcpy (buf, part1, part1_len);
Packit 33f14e
                            buf[part1_len] = '_';
Packit 33f14e
                            memcpy (buf + part1_len + 1, part2, part2_len);
Packit 33f14e
Packit 33f14e
                            /* Try the concatenated replacements.  */
Packit 33f14e
                            result = setlocale (category, buf);
Packit 33f14e
                            if (result != NULL)
Packit 33f14e
                              return result;
Packit 33f14e
                          }
Packit 33f14e
                    }
Packit 33f14e
Packit 33f14e
                  /* Try omitting the country entirely.  This may set a locale
Packit 33f14e
                     corresponding to the wrong country, but is better than
Packit 33f14e
                     failing entirely.  */
Packit 33f14e
                  {
Packit 33f14e
                    size_t i;
Packit 33f14e
Packit 33f14e
                    for (i = language_range.lo; i < language_range.hi; i++)
Packit 33f14e
                      {
Packit 33f14e
                        /* Try only the language replacement.  */
Packit 33f14e
                        result =
Packit 33f14e
                          setlocale (category, language_table[i].english);
Packit 33f14e
                        if (result != NULL)
Packit 33f14e
                          return result;
Packit 33f14e
                      }
Packit 33f14e
                  }
Packit 33f14e
                }
Packit 33f14e
            }
Packit 33f14e
          }
Packit 33f14e
      }
Packit 33f14e
    }
Packit 33f14e
Packit 33f14e
  /* Failed.  */
Packit 33f14e
  return NULL;
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
# else
Packit 33f14e
#  define setlocale_unixlike setlocale
Packit 33f14e
# endif
Packit 33f14e
Packit 33f14e
# if LC_MESSAGES == 1729
Packit 33f14e
Packit 33f14e
/* The system does not store an LC_MESSAGES locale category.  Do it here.  */
Packit 33f14e
static char lc_messages_name[64] = "C";
Packit 33f14e
Packit 33f14e
/* Like setlocale, but support also LC_MESSAGES.  */
Packit 33f14e
static char *
Packit 33f14e
setlocale_single (int category, const char *locale)
Packit 33f14e
{
Packit 33f14e
  if (category == LC_MESSAGES)
Packit 33f14e
    {
Packit 33f14e
      if (locale != NULL)
Packit 33f14e
        {
Packit 33f14e
          lc_messages_name[sizeof (lc_messages_name) - 1] = '\0';
Packit 33f14e
          strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1);
Packit 33f14e
        }
Packit 33f14e
      return lc_messages_name;
Packit 33f14e
    }
Packit 33f14e
  else
Packit 33f14e
    return setlocale_unixlike (category, locale);
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
# else
Packit 33f14e
#  define setlocale_single setlocale_unixlike
Packit 33f14e
# endif
Packit 33f14e
Packit 33f14e
char *
Packit 33f14e
rpl_setlocale (int category, const char *locale)
Packit 33f14e
{
Packit 33f14e
  if (locale != NULL && locale[0] == '\0')
Packit 33f14e
    {
Packit 33f14e
      /* A request to the set the current locale to the default locale.  */
Packit 33f14e
      if (category == LC_ALL)
Packit 33f14e
        {
Packit 33f14e
          /* Set LC_CTYPE first.  Then the other categories.  */
Packit 33f14e
          static int const categories[] =
Packit 33f14e
            {
Packit 33f14e
              LC_NUMERIC,
Packit 33f14e
              LC_TIME,
Packit 33f14e
              LC_COLLATE,
Packit 33f14e
              LC_MONETARY,
Packit 33f14e
              LC_MESSAGES
Packit 33f14e
            };
Packit 33f14e
          char *saved_locale;
Packit 33f14e
          const char *base_name;
Packit 33f14e
          unsigned int i;
Packit 33f14e
Packit 33f14e
          /* Back up the old locale, in case one of the steps fails.  */
Packit 33f14e
          saved_locale = setlocale (LC_ALL, NULL);
Packit 33f14e
          if (saved_locale == NULL)
Packit 33f14e
            return NULL;
Packit 33f14e
          saved_locale = strdup (saved_locale);
Packit 33f14e
          if (saved_locale == NULL)
Packit 33f14e
            return NULL;
Packit 33f14e
Packit 33f14e
          /* Set LC_CTYPE category.  Set all other categories (except possibly
Packit 33f14e
             LC_MESSAGES) to the same value in the same call; this is likely to
Packit 33f14e
             save calls.  */
Packit 33f14e
          base_name =
Packit 33f14e
            gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
Packit 33f14e
          if (base_name == NULL)
Packit 33f14e
            base_name = gl_locale_name_default ();
Packit 33f14e
Packit 33f14e
          if (setlocale_unixlike (LC_ALL, base_name) == NULL)
Packit 33f14e
            goto fail;
Packit 33f14e
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit 33f14e
          /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
Packit 33f14e
             LC_CTYPE category to an invalid value ("C") when it does not
Packit 33f14e
             support the specified encoding.  Report a failure instead.  */
Packit 33f14e
          if (strchr (base_name, '.') != NULL
Packit 33f14e
              && strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
Packit 33f14e
            goto fail;
Packit 33f14e
# endif
Packit 33f14e
Packit 33f14e
          for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
Packit 33f14e
            {
Packit 33f14e
              int cat = categories[i];
Packit 33f14e
              const char *name;
Packit 33f14e
Packit 33f14e
              name = gl_locale_name_environ (cat, category_to_name (cat));
Packit 33f14e
              if (name == NULL)
Packit 33f14e
                name = gl_locale_name_default ();
Packit 33f14e
Packit 33f14e
              /* If name is the same as base_name, it has already been set
Packit 33f14e
                 through the setlocale call before the loop.  */
Packit 33f14e
              if (strcmp (name, base_name) != 0
Packit 33f14e
# if LC_MESSAGES == 1729
Packit 33f14e
                  || cat == LC_MESSAGES
Packit 33f14e
# endif
Packit 33f14e
                 )
Packit 33f14e
                if (setlocale_single (cat, name) == NULL)
Packit 33f14e
                  goto fail;
Packit 33f14e
            }
Packit 33f14e
Packit 33f14e
          /* All steps were successful.  */
Packit 33f14e
          free (saved_locale);
Packit 33f14e
          return setlocale (LC_ALL, NULL);
Packit 33f14e
Packit 33f14e
        fail:
Packit 33f14e
          if (saved_locale[0] != '\0') /* don't risk an endless recursion */
Packit 33f14e
            setlocale (LC_ALL, saved_locale);
Packit 33f14e
          free (saved_locale);
Packit 33f14e
          return NULL;
Packit 33f14e
        }
Packit 33f14e
      else
Packit 33f14e
        {
Packit 33f14e
          const char *name =
Packit 33f14e
            gl_locale_name_environ (category, category_to_name (category));
Packit 33f14e
          if (name == NULL)
Packit 33f14e
            name = gl_locale_name_default ();
Packit 33f14e
Packit 33f14e
          return setlocale_single (category, name);
Packit 33f14e
        }
Packit 33f14e
    }
Packit 33f14e
  else
Packit 33f14e
    {
Packit 33f14e
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit 33f14e
      if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
Packit 33f14e
        {
Packit 33f14e
          char *saved_locale;
Packit 33f14e
Packit 33f14e
          /* Back up the old locale.  */
Packit 33f14e
          saved_locale = setlocale (LC_ALL, NULL);
Packit 33f14e
          if (saved_locale == NULL)
Packit 33f14e
            return NULL;
Packit 33f14e
          saved_locale = strdup (saved_locale);
Packit 33f14e
          if (saved_locale == NULL)
Packit 33f14e
            return NULL;
Packit 33f14e
Packit 33f14e
          if (setlocale_unixlike (LC_ALL, locale) == NULL)
Packit 33f14e
            {
Packit 33f14e
              free (saved_locale);
Packit 33f14e
              return NULL;
Packit 33f14e
            }
Packit 33f14e
Packit 33f14e
          /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
Packit 33f14e
             LC_CTYPE category to an invalid value ("C") when it does not
Packit 33f14e
             support the specified encoding.  Report a failure instead.  */
Packit 33f14e
          if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
Packit 33f14e
            {
Packit 33f14e
              if (saved_locale[0] != '\0') /* don't risk an endless recursion */
Packit 33f14e
                setlocale (LC_ALL, saved_locale);
Packit 33f14e
              free (saved_locale);
Packit 33f14e
              return NULL;
Packit 33f14e
            }
Packit 33f14e
Packit 33f14e
          /* It was really successful.  */
Packit 33f14e
          free (saved_locale);
Packit 33f14e
          return setlocale (LC_ALL, NULL);
Packit 33f14e
        }
Packit 33f14e
      else
Packit 33f14e
# endif
Packit 33f14e
        return setlocale_single (category, locale);
Packit 33f14e
    }
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
#endif