Blame lib/localcharset.c

Packit Service a2489d
/* Determine a canonical name for the current locale's character encoding.
Packit Service a2489d
Packit Service a2489d
   Copyright (C) 2000-2006, 2008-2018 Free Software Foundation, Inc.
Packit Service a2489d
Packit Service a2489d
   This program is free software; you can redistribute it and/or modify
Packit Service a2489d
   it under the terms of the GNU General Public License as published by
Packit Service a2489d
   the Free Software Foundation; either version 3, or (at your option)
Packit Service a2489d
   any later version.
Packit Service a2489d
Packit Service a2489d
   This program is distributed in the hope that it will be useful,
Packit Service a2489d
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2489d
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a2489d
   GNU General Public License for more details.
Packit Service a2489d
Packit Service a2489d
   You should have received a copy of the GNU General Public License along
Packit Service a2489d
   with this program; if not, see <https://www.gnu.org/licenses/>.  */
Packit Service a2489d
Packit Service a2489d
/* Written by Bruno Haible <bruno@clisp.org>.  */
Packit Service a2489d
Packit Service a2489d
#include <config.h>
Packit Service a2489d
Packit Service a2489d
/* Specification.  */
Packit Service a2489d
#include "localcharset.h"
Packit Service a2489d
Packit Service a2489d
#include <stddef.h>
Packit Service a2489d
#include <stdio.h>
Packit Service a2489d
#include <string.h>
Packit Service a2489d
#include <stdlib.h>
Packit Service a2489d
Packit Service a2489d
#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET
Packit Service a2489d
# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
#if defined _WIN32 && !defined __CYGWIN__
Packit Service a2489d
# define WINDOWS_NATIVE
Packit Service a2489d
# include <locale.h>
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
#if defined __EMX__
Packit Service a2489d
/* Assume EMX program runs on OS/2, even if compiled under DOS.  */
Packit Service a2489d
# ifndef OS2
Packit Service a2489d
#  define OS2
Packit Service a2489d
# endif
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
#if !defined WINDOWS_NATIVE
Packit Service a2489d
# if HAVE_LANGINFO_CODESET
Packit Service a2489d
#  include <langinfo.h>
Packit Service a2489d
# else
Packit Service a2489d
#  if 0 /* see comment regarding use of setlocale(), below */
Packit Service a2489d
#   include <locale.h>
Packit Service a2489d
#  endif
Packit Service a2489d
# endif
Packit Service a2489d
# ifdef __CYGWIN__
Packit Service a2489d
#  define WIN32_LEAN_AND_MEAN
Packit Service a2489d
#  include <windows.h>
Packit Service a2489d
# endif
Packit Service a2489d
#elif defined WINDOWS_NATIVE
Packit Service a2489d
# define WIN32_LEAN_AND_MEAN
Packit Service a2489d
# include <windows.h>
Packit Service a2489d
#endif
Packit Service a2489d
#if defined OS2
Packit Service a2489d
# define INCL_DOS
Packit Service a2489d
# include <os2.h>
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
/* For MB_CUR_MAX_L */
Packit Service a2489d
#if defined DARWIN7
Packit Service a2489d
# include <xlocale.h>
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
Packit Service a2489d
#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2
Packit Service a2489d
Packit Service a2489d
/* On these platforms, we use a mapping from non-canonical encoding name
Packit Service a2489d
   to GNU canonical encoding name.  */
Packit Service a2489d
Packit Service a2489d
/* With glibc-2.1 or newer, we don't need any canonicalization,
Packit Service a2489d
   because glibc has iconv and both glibc and libiconv support all
Packit Service a2489d
   GNU canonical names directly.  */
Packit Service a2489d
# if !((defined __GNU_LIBRARY__ && __GLIBC__ >= 2) || defined __UCLIBC__)
Packit Service a2489d
Packit Service a2489d
struct table_entry
Packit Service a2489d
{
Packit Service a2489d
  const char alias[11+1];
Packit Service a2489d
  const char canonical[11+1];
Packit Service a2489d
};
Packit Service a2489d
Packit Service a2489d
/* Table of platform-dependent mappings, sorted in ascending order.  */
Packit Service a2489d
static const struct table_entry alias_table[] =
Packit Service a2489d
  {
Packit Service a2489d
#  if defined __FreeBSD__                                   /* FreeBSD */
Packit Service a2489d
  /*{ "ARMSCII-8",  "ARMSCII-8" },*/
Packit Service a2489d
    { "Big5",       "BIG5" },
Packit Service a2489d
    { "C",          "ASCII" },
Packit Service a2489d
  /*{ "CP1131",     "CP1131" },*/
Packit Service a2489d
  /*{ "CP1251",     "CP1251" },*/
Packit Service a2489d
  /*{ "CP866",      "CP866" },*/
Packit Service a2489d
  /*{ "GB18030",    "GB18030" },*/
Packit Service a2489d
  /*{ "GB2312",     "GB2312" },*/
Packit Service a2489d
  /*{ "GBK",        "GBK" },*/
Packit Service a2489d
  /*{ "ISCII-DEV",  "?" },*/
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-13", "ISO-8859-13" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-9",  "ISO-8859-9" },
Packit Service a2489d
  /*{ "KOI8-R",     "KOI8-R" },*/
Packit Service a2489d
  /*{ "KOI8-U",     "KOI8-U" },*/
Packit Service a2489d
    { "SJIS",       "SHIFT_JIS" },
Packit Service a2489d
    { "US-ASCII",   "ASCII" },
Packit Service a2489d
    { "eucCN",      "GB2312" },
Packit Service a2489d
    { "eucJP",      "EUC-JP" },
Packit Service a2489d
    { "eucKR",      "EUC-KR" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __NetBSD__                                    /* NetBSD */
Packit Service a2489d
    { "646",        "ASCII" },
Packit Service a2489d
  /*{ "ARMSCII-8",  "ARMSCII-8" },*/
Packit Service a2489d
  /*{ "BIG5",       "BIG5" },*/
Packit Service a2489d
    { "Big5-HKSCS", "BIG5-HKSCS" },
Packit Service a2489d
  /*{ "CP1251",     "CP1251" },*/
Packit Service a2489d
  /*{ "CP866",      "CP866" },*/
Packit Service a2489d
  /*{ "GB18030",    "GB18030" },*/
Packit Service a2489d
  /*{ "GB2312",     "GB2312" },*/
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-13", "ISO-8859-13" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
  /*{ "KOI8-R",     "KOI8-R" },*/
Packit Service a2489d
  /*{ "KOI8-U",     "KOI8-U" },*/
Packit Service a2489d
  /*{ "PT154",      "PT154" },*/
Packit Service a2489d
    { "SJIS",       "SHIFT_JIS" },
Packit Service a2489d
    { "eucCN",      "GB2312" },
Packit Service a2489d
    { "eucJP",      "EUC-JP" },
Packit Service a2489d
    { "eucKR",      "EUC-KR" },
Packit Service a2489d
    { "eucTW",      "EUC-TW" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __OpenBSD__                                   /* OpenBSD */
Packit Service a2489d
    { "646",        "ASCII" },
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-13", "ISO-8859-13" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __APPLE__ && defined __MACH__                 /* Mac OS X */
Packit Service a2489d
    /* Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is
Packit Service a2489d
       useless:
Packit Service a2489d
       - It returns the empty string when LANG is set to a locale of the
Packit Service a2489d
         form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8
Packit Service a2489d
         LC_CTYPE file.
Packit Service a2489d
       - The environment variables LANG, LC_CTYPE, LC_ALL are not set by
Packit Service a2489d
         the system; nl_langinfo(CODESET) returns "US-ASCII" in this case.
Packit Service a2489d
       - The documentation says:
Packit Service a2489d
           "... all code that calls BSD system routines should ensure
Packit Service a2489d
            that the const *char parameters of these routines are in UTF-8
Packit Service a2489d
            encoding. All BSD system functions expect their string
Packit Service a2489d
            parameters to be in UTF-8 encoding and nothing else."
Packit Service a2489d
         It also says
Packit Service a2489d
           "An additional caveat is that string parameters for files,
Packit Service a2489d
            paths, and other file-system entities must be in canonical
Packit Service a2489d
            UTF-8. In a canonical UTF-8 Unicode string, all decomposable
Packit Service a2489d
            characters are decomposed ..."
Packit Service a2489d
         but this is not true: You can pass non-decomposed UTF-8 strings
Packit Service a2489d
         to file system functions, and it is the OS which will convert
Packit Service a2489d
         them to decomposed UTF-8 before accessing the file system.
Packit Service a2489d
       - The Apple Terminal application displays UTF-8 by default.
Packit Service a2489d
       - However, other applications are free to use different encodings:
Packit Service a2489d
         - xterm uses ISO-8859-1 by default.
Packit Service a2489d
         - TextEdit uses MacRoman by default.
Packit Service a2489d
       We prefer UTF-8 over decomposed UTF-8-MAC because one should
Packit Service a2489d
       minimize the use of decomposed Unicode. Unfortunately, through the
Packit Service a2489d
       Darwin file system, decomposed UTF-8 strings are leaked into user
Packit Service a2489d
       space nevertheless.
Packit Service a2489d
       Then there are also the locales with encodings other than US-ASCII
Packit Service a2489d
       and UTF-8. These locales can be occasionally useful to users (e.g.
Packit Service a2489d
       when grepping through ISO-8859-1 encoded text files), when all their
Packit Service a2489d
       file names are in US-ASCII.
Packit Service a2489d
     */
Packit Service a2489d
    { "ARMSCII-8",  "ARMSCII-8" },
Packit Service a2489d
    { "Big5",       "BIG5" },
Packit Service a2489d
    { "Big5HKSCS",  "BIG5-HKSCS" },
Packit Service a2489d
    { "CP1131",     "CP1131" },
Packit Service a2489d
    { "CP1251",     "CP1251" },
Packit Service a2489d
    { "CP866",      "CP866" },
Packit Service a2489d
    { "CP949",      "CP949" },
Packit Service a2489d
    { "GB18030",    "GB18030" },
Packit Service a2489d
    { "GB2312",     "GB2312" },
Packit Service a2489d
    { "GBK",        "GBK" },
Packit Service a2489d
  /*{ "ISCII-DEV",  "?" },*/
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-13", "ISO-8859-13" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-9",  "ISO-8859-9" },
Packit Service a2489d
    { "KOI8-R",     "KOI8-R" },
Packit Service a2489d
    { "KOI8-U",     "KOI8-U" },
Packit Service a2489d
    { "PT154",      "PT154" },
Packit Service a2489d
    { "SJIS",       "SHIFT_JIS" },
Packit Service a2489d
    { "eucCN",      "GB2312" },
Packit Service a2489d
    { "eucJP",      "EUC-JP" },
Packit Service a2489d
    { "eucKR",      "EUC-KR" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined _AIX                                          /* AIX */
Packit Service a2489d
  /*{ "GBK",        "GBK" },*/
Packit Service a2489d
    { "IBM-1046",   "CP1046" },
Packit Service a2489d
    { "IBM-1124",   "CP1124" },
Packit Service a2489d
    { "IBM-1129",   "CP1129" },
Packit Service a2489d
    { "IBM-1252",   "CP1252" },
Packit Service a2489d
    { "IBM-850",    "CP850" },
Packit Service a2489d
    { "IBM-856",    "CP856" },
Packit Service a2489d
    { "IBM-921",    "ISO-8859-13" },
Packit Service a2489d
    { "IBM-922",    "CP922" },
Packit Service a2489d
    { "IBM-932",    "CP932" },
Packit Service a2489d
    { "IBM-943",    "CP943" },
Packit Service a2489d
    { "IBM-eucCN",  "GB2312" },
Packit Service a2489d
    { "IBM-eucJP",  "EUC-JP" },
Packit Service a2489d
    { "IBM-eucKR",  "EUC-KR" },
Packit Service a2489d
    { "IBM-eucTW",  "EUC-TW" },
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-6",  "ISO-8859-6" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-8",  "ISO-8859-8" },
Packit Service a2489d
    { "ISO8859-9",  "ISO-8859-9" },
Packit Service a2489d
    { "TIS-620",    "TIS-620" },
Packit Service a2489d
  /*{ "UTF-8",      "UTF-8" },*/
Packit Service a2489d
    { "big5",       "BIG5" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __hpux                                        /* HP-UX */
Packit Service a2489d
    { "SJIS",      "SHIFT_JIS" },
Packit Service a2489d
    { "arabic8",   "HP-ARABIC8" },
Packit Service a2489d
    { "big5",      "BIG5" },
Packit Service a2489d
    { "cp1251",    "CP1251" },
Packit Service a2489d
    { "eucJP",     "EUC-JP" },
Packit Service a2489d
    { "eucKR",     "EUC-KR" },
Packit Service a2489d
    { "eucTW",     "EUC-TW" },
Packit Service a2489d
    { "gb18030",   "GB18030" },
Packit Service a2489d
    { "greek8",    "HP-GREEK8" },
Packit Service a2489d
    { "hebrew8",   "HP-HEBREW8" },
Packit Service a2489d
    { "hkbig5",    "BIG5-HKSCS" },
Packit Service a2489d
    { "hp15CN",    "GB2312" },
Packit Service a2489d
    { "iso88591",  "ISO-8859-1" },
Packit Service a2489d
    { "iso885913", "ISO-8859-13" },
Packit Service a2489d
    { "iso885915", "ISO-8859-15" },
Packit Service a2489d
    { "iso88592",  "ISO-8859-2" },
Packit Service a2489d
    { "iso88594",  "ISO-8859-4" },
Packit Service a2489d
    { "iso88595",  "ISO-8859-5" },
Packit Service a2489d
    { "iso88596",  "ISO-8859-6" },
Packit Service a2489d
    { "iso88597",  "ISO-8859-7" },
Packit Service a2489d
    { "iso88598",  "ISO-8859-8" },
Packit Service a2489d
    { "iso88599",  "ISO-8859-9" },
Packit Service a2489d
    { "kana8",     "HP-KANA8" },
Packit Service a2489d
    { "koi8r",     "KOI8-R" },
Packit Service a2489d
    { "roman8",    "HP-ROMAN8" },
Packit Service a2489d
    { "tis620",    "TIS-620" },
Packit Service a2489d
    { "turkish8",  "HP-TURKISH8" },
Packit Service a2489d
    { "utf8",      "UTF-8" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __sgi                                         /* IRIX */
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-9",  "ISO-8859-9" },
Packit Service a2489d
    { "eucCN",      "GB2312" },
Packit Service a2489d
    { "eucJP",      "EUC-JP" },
Packit Service a2489d
    { "eucKR",      "EUC-KR" },
Packit Service a2489d
    { "eucTW",      "EUC-TW" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __osf__                                       /* OSF/1 */
Packit Service a2489d
  /*{ "GBK",        "GBK" },*/
Packit Service a2489d
    { "ISO8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "ISO8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7",  "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-8",  "ISO-8859-8" },
Packit Service a2489d
    { "ISO8859-9",  "ISO-8859-9" },
Packit Service a2489d
    { "KSC5601",    "CP949" },
Packit Service a2489d
    { "SJIS",       "SHIFT_JIS" },
Packit Service a2489d
    { "TACTIS",     "TIS-620" },
Packit Service a2489d
  /*{ "UTF-8",      "UTF-8" },*/
Packit Service a2489d
    { "big5",       "BIG5" },
Packit Service a2489d
    { "cp850",      "CP850" },
Packit Service a2489d
    { "dechanyu",   "DEC-HANYU" },
Packit Service a2489d
    { "dechanzi",   "GB2312" },
Packit Service a2489d
    { "deckanji",   "DEC-KANJI" },
Packit Service a2489d
    { "deckorean",  "EUC-KR" },
Packit Service a2489d
    { "eucJP",      "EUC-JP" },
Packit Service a2489d
    { "eucKR",      "EUC-KR" },
Packit Service a2489d
    { "eucTW",      "EUC-TW" },
Packit Service a2489d
    { "sdeckanji",  "EUC-JP" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __sun                                         /* Solaris */
Packit Service a2489d
    { "5601",        "EUC-KR" },
Packit Service a2489d
    { "646",         "ASCII" },
Packit Service a2489d
  /*{ "BIG5",        "BIG5" },*/
Packit Service a2489d
    { "Big5-HKSCS",  "BIG5-HKSCS" },
Packit Service a2489d
    { "GB18030",     "GB18030" },
Packit Service a2489d
  /*{ "GBK",         "GBK" },*/
Packit Service a2489d
    { "ISO8859-1",   "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-11",  "TIS-620" },
Packit Service a2489d
    { "ISO8859-13",  "ISO-8859-13" },
Packit Service a2489d
    { "ISO8859-15",  "ISO-8859-15" },
Packit Service a2489d
    { "ISO8859-2",   "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-3",   "ISO-8859-3" },
Packit Service a2489d
    { "ISO8859-4",   "ISO-8859-4" },
Packit Service a2489d
    { "ISO8859-5",   "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-6",   "ISO-8859-6" },
Packit Service a2489d
    { "ISO8859-7",   "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-8",   "ISO-8859-8" },
Packit Service a2489d
    { "ISO8859-9",   "ISO-8859-9" },
Packit Service a2489d
    { "PCK",         "SHIFT_JIS" },
Packit Service a2489d
    { "TIS620.2533", "TIS-620" },
Packit Service a2489d
  /*{ "UTF-8",       "UTF-8" },*/
Packit Service a2489d
    { "ansi-1251",   "CP1251" },
Packit Service a2489d
    { "cns11643",    "EUC-TW" },
Packit Service a2489d
    { "eucJP",       "EUC-JP" },
Packit Service a2489d
    { "gb2312",      "GB2312" },
Packit Service a2489d
    { "koi8-r",      "KOI8-R" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined __minix                                       /* Minix */
Packit Service a2489d
    { "646", "ASCII" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined WINDOWS_NATIVE || defined __CYGWIN__          /* Windows */
Packit Service a2489d
    { "CP1361",  "JOHAB" },
Packit Service a2489d
    { "CP20127", "ASCII" },
Packit Service a2489d
    { "CP20866", "KOI8-R" },
Packit Service a2489d
    { "CP20936", "GB2312" },
Packit Service a2489d
    { "CP21866", "KOI8-RU" },
Packit Service a2489d
    { "CP28591", "ISO-8859-1" },
Packit Service a2489d
    { "CP28592", "ISO-8859-2" },
Packit Service a2489d
    { "CP28593", "ISO-8859-3" },
Packit Service a2489d
    { "CP28594", "ISO-8859-4" },
Packit Service a2489d
    { "CP28595", "ISO-8859-5" },
Packit Service a2489d
    { "CP28596", "ISO-8859-6" },
Packit Service a2489d
    { "CP28597", "ISO-8859-7" },
Packit Service a2489d
    { "CP28598", "ISO-8859-8" },
Packit Service a2489d
    { "CP28599", "ISO-8859-9" },
Packit Service a2489d
    { "CP28605", "ISO-8859-15" },
Packit Service a2489d
    { "CP38598", "ISO-8859-8" },
Packit Service a2489d
    { "CP51932", "EUC-JP" },
Packit Service a2489d
    { "CP51936", "GB2312" },
Packit Service a2489d
    { "CP51949", "EUC-KR" },
Packit Service a2489d
    { "CP51950", "EUC-TW" },
Packit Service a2489d
    { "CP54936", "GB18030" },
Packit Service a2489d
    { "CP65001", "UTF-8" },
Packit Service a2489d
    { "CP936",   "GBK" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined OS2                                           /* OS/2 */
Packit Service a2489d
    /* The list of encodings is taken from "List of OS/2 Codepages"
Packit Service a2489d
       by Alex Taylor:
Packit Service a2489d
       <http://altsan.org/os2/toolkits/uls/index.html#codepages>.
Packit Service a2489d
       See also "IBM Globalization - Code page identifiers":
Packit Service a2489d
       <https://www-01.ibm.com/software/globalization/cp/cp_cpgid.html>.  */
Packit Service a2489d
    { "CP1089", "ISO-8859-6" },
Packit Service a2489d
    { "CP1208", "UTF-8" },
Packit Service a2489d
    { "CP1381", "GB2312" },
Packit Service a2489d
    { "CP1386", "GBK" },
Packit Service a2489d
    { "CP3372", "EUC-JP" },
Packit Service a2489d
    { "CP813",  "ISO-8859-7" },
Packit Service a2489d
    { "CP819",  "ISO-8859-1" },
Packit Service a2489d
    { "CP878",  "KOI8-R" },
Packit Service a2489d
    { "CP912",  "ISO-8859-2" },
Packit Service a2489d
    { "CP913",  "ISO-8859-3" },
Packit Service a2489d
    { "CP914",  "ISO-8859-4" },
Packit Service a2489d
    { "CP915",  "ISO-8859-5" },
Packit Service a2489d
    { "CP916",  "ISO-8859-8" },
Packit Service a2489d
    { "CP920",  "ISO-8859-9" },
Packit Service a2489d
    { "CP921",  "ISO-8859-13" },
Packit Service a2489d
    { "CP923",  "ISO-8859-15" },
Packit Service a2489d
    { "CP954",  "EUC-JP" },
Packit Service a2489d
    { "CP964",  "EUC-TW" },
Packit Service a2489d
    { "CP970",  "EUC-KR" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  if defined VMS                                           /* OpenVMS */
Packit Service a2489d
    /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
Packit Service a2489d
       "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
Packit Service a2489d
       section 10.7 "Handling Different Character Sets".  */
Packit Service a2489d
    { "DECHANYU",  "DEC-HANYU" },
Packit Service a2489d
    { "DECHANZI",  "GB2312" },
Packit Service a2489d
    { "DECKANJI",  "DEC-KANJI" },
Packit Service a2489d
    { "DECKOREAN", "EUC-KR" },
Packit Service a2489d
    { "ISO8859-1", "ISO-8859-1" },
Packit Service a2489d
    { "ISO8859-2", "ISO-8859-2" },
Packit Service a2489d
    { "ISO8859-5", "ISO-8859-5" },
Packit Service a2489d
    { "ISO8859-7", "ISO-8859-7" },
Packit Service a2489d
    { "ISO8859-8", "ISO-8859-8" },
Packit Service a2489d
    { "ISO8859-9", "ISO-8859-9" },
Packit Service a2489d
    { "SDECKANJI", "EUC-JP" },
Packit Service a2489d
    { "SJIS",      "SHIFT_JIS" },
Packit Service a2489d
    { "eucJP",     "EUC-JP" },
Packit Service a2489d
    { "eucTW",     "EUC-TW" }
Packit Service a2489d
#   define alias_table_defined
Packit Service a2489d
#  endif
Packit Service a2489d
#  ifndef alias_table_defined
Packit Service a2489d
    /* Just a dummy entry, to avoid a C syntax error.  */
Packit Service a2489d
    { "", "" }
Packit Service a2489d
#  endif
Packit Service a2489d
  };
Packit Service a2489d
Packit Service a2489d
# endif
Packit Service a2489d
Packit Service a2489d
#else
Packit Service a2489d
Packit Service a2489d
/* On these platforms, we use a mapping from locale name to GNU canonical
Packit Service a2489d
   encoding name.  */
Packit Service a2489d
Packit Service a2489d
struct table_entry
Packit Service a2489d
{
Packit Service a2489d
  const char locale[17+1];
Packit Service a2489d
  const char canonical[11+1];
Packit Service a2489d
};
Packit Service a2489d
Packit Service a2489d
/* Table of platform-dependent mappings, sorted in ascending order.  */
Packit Service a2489d
static const struct table_entry locale_table[] =
Packit Service a2489d
  {
Packit Service a2489d
# if defined __FreeBSD__                                    /* FreeBSD 4.2 */
Packit Service a2489d
    { "cs_CZ.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "da_DK.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "da_DK.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "de_AT.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "de_AT.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "de_CH.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "de_CH.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "de_DE.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "de_DE.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "en_AU.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "en_AU.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "en_CA.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "en_CA.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "en_GB.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "en_GB.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "en_US.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "en_US.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "es_ES.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "es_ES.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "fi_FI.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "fi_FI.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "fr_BE.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "fr_BE.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "fr_CA.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "fr_CA.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "fr_CH.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "fr_CH.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "fr_FR.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "fr_FR.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "hr_HR.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "hu_HU.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "is_IS.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "is_IS.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "it_CH.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "it_CH.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "it_IT.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "it_IT.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ja_JP.EUC",         "EUC-JP" },
Packit Service a2489d
    { "ja_JP.SJIS",        "SHIFT_JIS" },
Packit Service a2489d
    { "ja_JP.Shift_JIS",   "SHIFT_JIS" },
Packit Service a2489d
    { "ko_KR.EUC",         "EUC-KR" },
Packit Service a2489d
    { "la_LN.ASCII",       "ASCII" },
Packit Service a2489d
    { "la_LN.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "la_LN.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "la_LN.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "la_LN.ISO_8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "lt_LN.ASCII",       "ASCII" },
Packit Service a2489d
    { "lt_LN.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "lt_LN.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "lt_LN.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "lt_LT.ISO_8859-4",  "ISO-8859-4" },
Packit Service a2489d
    { "nl_BE.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "nl_BE.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "nl_NL.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "nl_NL.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "no_NO.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "no_NO.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "pl_PL.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "pt_PT.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "pt_PT.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "ru_RU.CP866",       "CP866" },
Packit Service a2489d
    { "ru_RU.ISO_8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ru_RU.KOI8-R",      "KOI8-R" },
Packit Service a2489d
    { "ru_SU.CP866",       "CP866" },
Packit Service a2489d
    { "ru_SU.ISO_8859-5",  "ISO-8859-5" },
Packit Service a2489d
    { "ru_SU.KOI8-R",      "KOI8-R" },
Packit Service a2489d
    { "sl_SI.ISO_8859-2",  "ISO-8859-2" },
Packit Service a2489d
    { "sv_SE.DIS_8859-15", "ISO-8859-15" },
Packit Service a2489d
    { "sv_SE.ISO_8859-1",  "ISO-8859-1" },
Packit Service a2489d
    { "uk_UA.KOI8-U",      "KOI8-U" },
Packit Service a2489d
    { "zh_CN.EUC",         "GB2312" },
Packit Service a2489d
    { "zh_TW.BIG5",        "BIG5" },
Packit Service a2489d
    { "zh_TW.Big5",        "BIG5" }
Packit Service a2489d
#  define locale_table_defined
Packit Service a2489d
# endif
Packit Service a2489d
# if defined __DJGPP__                                      /* DOS / DJGPP 2.03 */
Packit Service a2489d
    /* The encodings given here may not all be correct.
Packit Service a2489d
       If you find that the encoding given for your language and
Packit Service a2489d
       country is not the one your DOS machine actually uses, just
Packit Service a2489d
       correct it in this file, and send a mail to
Packit Service a2489d
       Juan Manuel Guerrero <juan.guerrero@gmx.de>
Packit Service a2489d
       and <bug-gnulib@gnu.org>.  */
Packit Service a2489d
    { "C",     "ASCII" },
Packit Service a2489d
    { "ar",    "CP864" },
Packit Service a2489d
    { "ar_AE", "CP864" },
Packit Service a2489d
    { "ar_DZ", "CP864" },
Packit Service a2489d
    { "ar_EG", "CP864" },
Packit Service a2489d
    { "ar_IQ", "CP864" },
Packit Service a2489d
    { "ar_IR", "CP864" },
Packit Service a2489d
    { "ar_JO", "CP864" },
Packit Service a2489d
    { "ar_KW", "CP864" },
Packit Service a2489d
    { "ar_MA", "CP864" },
Packit Service a2489d
    { "ar_OM", "CP864" },
Packit Service a2489d
    { "ar_QA", "CP864" },
Packit Service a2489d
    { "ar_SA", "CP864" },
Packit Service a2489d
    { "ar_SY", "CP864" },
Packit Service a2489d
    { "be",    "CP866" },
Packit Service a2489d
    { "be_BE", "CP866" },
Packit Service a2489d
    { "bg",    "CP866" }, /* not CP855 ?? */
Packit Service a2489d
    { "bg_BG", "CP866" }, /* not CP855 ?? */
Packit Service a2489d
    { "ca",    "CP850" },
Packit Service a2489d
    { "ca_ES", "CP850" },
Packit Service a2489d
    { "cs",    "CP852" },
Packit Service a2489d
    { "cs_CZ", "CP852" },
Packit Service a2489d
    { "da",    "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "da_DK", "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "de",    "CP850" },
Packit Service a2489d
    { "de_AT", "CP850" },
Packit Service a2489d
    { "de_CH", "CP850" },
Packit Service a2489d
    { "de_DE", "CP850" },
Packit Service a2489d
    { "el",    "CP869" },
Packit Service a2489d
    { "el_GR", "CP869" },
Packit Service a2489d
    { "en",    "CP850" },
Packit Service a2489d
    { "en_AU", "CP850" }, /* not CP437 ?? */
Packit Service a2489d
    { "en_CA", "CP850" },
Packit Service a2489d
    { "en_GB", "CP850" },
Packit Service a2489d
    { "en_NZ", "CP437" },
Packit Service a2489d
    { "en_US", "CP437" },
Packit Service a2489d
    { "en_ZA", "CP850" }, /* not CP437 ?? */
Packit Service a2489d
    { "eo",    "CP850" },
Packit Service a2489d
    { "eo_EO", "CP850" },
Packit Service a2489d
    { "es",    "CP850" },
Packit Service a2489d
    { "es_AR", "CP850" },
Packit Service a2489d
    { "es_BO", "CP850" },
Packit Service a2489d
    { "es_CL", "CP850" },
Packit Service a2489d
    { "es_CO", "CP850" },
Packit Service a2489d
    { "es_CR", "CP850" },
Packit Service a2489d
    { "es_CU", "CP850" },
Packit Service a2489d
    { "es_DO", "CP850" },
Packit Service a2489d
    { "es_EC", "CP850" },
Packit Service a2489d
    { "es_ES", "CP850" },
Packit Service a2489d
    { "es_GT", "CP850" },
Packit Service a2489d
    { "es_HN", "CP850" },
Packit Service a2489d
    { "es_MX", "CP850" },
Packit Service a2489d
    { "es_NI", "CP850" },
Packit Service a2489d
    { "es_PA", "CP850" },
Packit Service a2489d
    { "es_PE", "CP850" },
Packit Service a2489d
    { "es_PY", "CP850" },
Packit Service a2489d
    { "es_SV", "CP850" },
Packit Service a2489d
    { "es_UY", "CP850" },
Packit Service a2489d
    { "es_VE", "CP850" },
Packit Service a2489d
    { "et",    "CP850" },
Packit Service a2489d
    { "et_EE", "CP850" },
Packit Service a2489d
    { "eu",    "CP850" },
Packit Service a2489d
    { "eu_ES", "CP850" },
Packit Service a2489d
    { "fi",    "CP850" },
Packit Service a2489d
    { "fi_FI", "CP850" },
Packit Service a2489d
    { "fr",    "CP850" },
Packit Service a2489d
    { "fr_BE", "CP850" },
Packit Service a2489d
    { "fr_CA", "CP850" },
Packit Service a2489d
    { "fr_CH", "CP850" },
Packit Service a2489d
    { "fr_FR", "CP850" },
Packit Service a2489d
    { "ga",    "CP850" },
Packit Service a2489d
    { "ga_IE", "CP850" },
Packit Service a2489d
    { "gd",    "CP850" },
Packit Service a2489d
    { "gd_GB", "CP850" },
Packit Service a2489d
    { "gl",    "CP850" },
Packit Service a2489d
    { "gl_ES", "CP850" },
Packit Service a2489d
    { "he",    "CP862" },
Packit Service a2489d
    { "he_IL", "CP862" },
Packit Service a2489d
    { "hr",    "CP852" },
Packit Service a2489d
    { "hr_HR", "CP852" },
Packit Service a2489d
    { "hu",    "CP852" },
Packit Service a2489d
    { "hu_HU", "CP852" },
Packit Service a2489d
    { "id",    "CP850" }, /* not CP437 ?? */
Packit Service a2489d
    { "id_ID", "CP850" }, /* not CP437 ?? */
Packit Service a2489d
    { "is",    "CP861" }, /* not CP850 ?? */
Packit Service a2489d
    { "is_IS", "CP861" }, /* not CP850 ?? */
Packit Service a2489d
    { "it",    "CP850" },
Packit Service a2489d
    { "it_CH", "CP850" },
Packit Service a2489d
    { "it_IT", "CP850" },
Packit Service a2489d
    { "ja",    "CP932" },
Packit Service a2489d
    { "ja_JP", "CP932" },
Packit Service a2489d
    { "kr",    "CP949" }, /* not CP934 ?? */
Packit Service a2489d
    { "kr_KR", "CP949" }, /* not CP934 ?? */
Packit Service a2489d
    { "lt",    "CP775" },
Packit Service a2489d
    { "lt_LT", "CP775" },
Packit Service a2489d
    { "lv",    "CP775" },
Packit Service a2489d
    { "lv_LV", "CP775" },
Packit Service a2489d
    { "mk",    "CP866" }, /* not CP855 ?? */
Packit Service a2489d
    { "mk_MK", "CP866" }, /* not CP855 ?? */
Packit Service a2489d
    { "mt",    "CP850" },
Packit Service a2489d
    { "mt_MT", "CP850" },
Packit Service a2489d
    { "nb",    "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "nb_NO", "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "nl",    "CP850" },
Packit Service a2489d
    { "nl_BE", "CP850" },
Packit Service a2489d
    { "nl_NL", "CP850" },
Packit Service a2489d
    { "nn",    "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "nn_NO", "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "no",    "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "no_NO", "CP865" }, /* not CP850 ?? */
Packit Service a2489d
    { "pl",    "CP852" },
Packit Service a2489d
    { "pl_PL", "CP852" },
Packit Service a2489d
    { "pt",    "CP850" },
Packit Service a2489d
    { "pt_BR", "CP850" },
Packit Service a2489d
    { "pt_PT", "CP850" },
Packit Service a2489d
    { "ro",    "CP852" },
Packit Service a2489d
    { "ro_RO", "CP852" },
Packit Service a2489d
    { "ru",    "CP866" },
Packit Service a2489d
    { "ru_RU", "CP866" },
Packit Service a2489d
    { "sk",    "CP852" },
Packit Service a2489d
    { "sk_SK", "CP852" },
Packit Service a2489d
    { "sl",    "CP852" },
Packit Service a2489d
    { "sl_SI", "CP852" },
Packit Service a2489d
    { "sq",    "CP852" },
Packit Service a2489d
    { "sq_AL", "CP852" },
Packit Service a2489d
    { "sr",    "CP852" }, /* CP852 or CP866 or CP855 ?? */
Packit Service a2489d
    { "sr_CS", "CP852" }, /* CP852 or CP866 or CP855 ?? */
Packit Service a2489d
    { "sr_YU", "CP852" }, /* CP852 or CP866 or CP855 ?? */
Packit Service a2489d
    { "sv",    "CP850" },
Packit Service a2489d
    { "sv_SE", "CP850" },
Packit Service a2489d
    { "th",    "CP874" },
Packit Service a2489d
    { "th_TH", "CP874" },
Packit Service a2489d
    { "tr",    "CP857" },
Packit Service a2489d
    { "tr_TR", "CP857" },
Packit Service a2489d
    { "uk",    "CP1125" },
Packit Service a2489d
    { "uk_UA", "CP1125" },
Packit Service a2489d
    { "zh_CN", "GBK" },
Packit Service a2489d
    { "zh_TW", "CP950" } /* not CP938 ?? */
Packit Service a2489d
#  define locale_table_defined
Packit Service a2489d
# endif
Packit Service a2489d
# ifndef locale_table_defined
Packit Service a2489d
    /* Just a dummy entry, to avoid a C syntax error.  */
Packit Service a2489d
    { "", "" }
Packit Service a2489d
# endif
Packit Service a2489d
  };
Packit Service a2489d
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
Packit Service a2489d
/* Determine the current locale's character encoding, and canonicalize it
Packit Service a2489d
   into one of the canonical names listed in localcharset.h.
Packit Service a2489d
   The result must not be freed; it is statically allocated.
Packit Service a2489d
   If the canonical name cannot be determined, the result is a non-canonical
Packit Service a2489d
   name.  */
Packit Service a2489d
Packit Service a2489d
#ifdef STATIC
Packit Service a2489d
STATIC
Packit Service a2489d
#endif
Packit Service a2489d
const char *
Packit Service a2489d
locale_charset (void)
Packit Service a2489d
{
Packit Service a2489d
  const char *codeset;
Packit Service a2489d
Packit Service a2489d
#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2
Packit Service a2489d
Packit Service a2489d
# if HAVE_LANGINFO_CODESET
Packit Service a2489d
Packit Service a2489d
  /* Most systems support nl_langinfo (CODESET) nowadays.  */
Packit Service a2489d
  codeset = nl_langinfo (CODESET);
Packit Service a2489d
Packit Service a2489d
#  ifdef __CYGWIN__
Packit Service a2489d
  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always
Packit Service a2489d
     returns "US-ASCII".  Return the suffix of the locale name from the
Packit Service a2489d
     environment variables (if present) or the codepage as a number.  */
Packit Service a2489d
  if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
Packit Service a2489d
    {
Packit Service a2489d
      const char *locale;
Packit Service a2489d
      static char buf[2 + 10 + 1];
Packit Service a2489d
Packit Service a2489d
      locale = getenv ("LC_ALL");
Packit Service a2489d
      if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
        {
Packit Service a2489d
          locale = getenv ("LC_CTYPE");
Packit Service a2489d
          if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
            locale = getenv ("LANG");
Packit Service a2489d
        }
Packit Service a2489d
      if (locale != NULL && locale[0] != '\0')
Packit Service a2489d
        {
Packit Service a2489d
          /* If the locale name contains an encoding after the dot, return
Packit Service a2489d
             it.  */
Packit Service a2489d
          const char *dot = strchr (locale, '.');
Packit Service a2489d
Packit Service a2489d
          if (dot != NULL)
Packit Service a2489d
            {
Packit Service a2489d
              const char *modifier;
Packit Service a2489d
Packit Service a2489d
              dot++;
Packit Service a2489d
              /* Look for the possible @... trailer and remove it, if any.  */
Packit Service a2489d
              modifier = strchr (dot, '@');
Packit Service a2489d
              if (modifier == NULL)
Packit Service a2489d
                return dot;
Packit Service a2489d
              if (modifier - dot < sizeof (buf))
Packit Service a2489d
                {
Packit Service a2489d
                  memcpy (buf, dot, modifier - dot);
Packit Service a2489d
                  buf [modifier - dot] = '\0';
Packit Service a2489d
                  return buf;
Packit Service a2489d
                }
Packit Service a2489d
            }
Packit Service a2489d
        }
Packit Service a2489d
Packit Service a2489d
      /* The Windows API has a function returning the locale's codepage as a
Packit Service a2489d
         number: GetACP().  This encoding is used by Cygwin, unless the user
Packit Service a2489d
         has set the environment variable CYGWIN=codepage:oem (which very few
Packit Service a2489d
         people do).
Packit Service a2489d
         Output directed to console windows needs to be converted (to
Packit Service a2489d
         GetOEMCP() if the console is using a raster font, or to
Packit Service a2489d
         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
Packit Service a2489d
         this conversion transparently (see winsup/cygwin/fhandler_console.cc),
Packit Service a2489d
         converting to GetConsoleOutputCP().  This leads to correct results,
Packit Service a2489d
         except when SetConsoleOutputCP has been called and a raster font is
Packit Service a2489d
         in use.  */
Packit Service a2489d
      sprintf (buf, "CP%u", GetACP ());
Packit Service a2489d
      codeset = buf;
Packit Service a2489d
    }
Packit Service a2489d
#  endif
Packit Service a2489d
Packit Service a2489d
  if (codeset == NULL)
Packit Service a2489d
    /* The canonical name cannot be determined.  */
Packit Service a2489d
    codeset = "";
Packit Service a2489d
Packit Service a2489d
# elif defined WINDOWS_NATIVE
Packit Service a2489d
Packit Service a2489d
  static char buf[2 + 10 + 1];
Packit Service a2489d
Packit Service a2489d
  /* The Windows API has a function returning the locale's codepage as
Packit Service a2489d
     a number, but the value doesn't change according to what the
Packit Service a2489d
     'setlocale' call specified.  So we use it as a last resort, in
Packit Service a2489d
     case the string returned by 'setlocale' doesn't specify the
Packit Service a2489d
     codepage.  */
Packit Service a2489d
  char *current_locale = setlocale (LC_ALL, NULL);
Packit Service a2489d
  char *pdot;
Packit Service a2489d
Packit Service a2489d
  /* If they set different locales for different categories,
Packit Service a2489d
     'setlocale' will return a semi-colon separated list of locale
Packit Service a2489d
     values.  To make sure we use the correct one, we choose LC_CTYPE.  */
Packit Service a2489d
  if (strchr (current_locale, ';'))
Packit Service a2489d
    current_locale = setlocale (LC_CTYPE, NULL);
Packit Service a2489d
Packit Service a2489d
  pdot = strrchr (current_locale, '.');
Packit Service a2489d
  if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf))
Packit Service a2489d
    sprintf (buf, "CP%s", pdot + 1);
Packit Service a2489d
  else
Packit Service a2489d
    {
Packit Service a2489d
      /* The Windows API has a function returning the locale's codepage as a
Packit Service a2489d
        number: GetACP().
Packit Service a2489d
        When the output goes to a console window, it needs to be provided in
Packit Service a2489d
        GetOEMCP() encoding if the console is using a raster font, or in
Packit Service a2489d
        GetConsoleOutputCP() encoding if it is using a TrueType font.
Packit Service a2489d
        But in GUI programs and for output sent to files and pipes, GetACP()
Packit Service a2489d
        encoding is the best bet.  */
Packit Service a2489d
      sprintf (buf, "CP%u", GetACP ());
Packit Service a2489d
    }
Packit Service a2489d
  codeset = buf;
Packit Service a2489d
Packit Service a2489d
# elif defined OS2
Packit Service a2489d
Packit Service a2489d
  const char *locale;
Packit Service a2489d
  static char buf[2 + 10 + 1];
Packit Service a2489d
  ULONG cp[3];
Packit Service a2489d
  ULONG cplen;
Packit Service a2489d
Packit Service a2489d
  codeset = NULL;
Packit Service a2489d
Packit Service a2489d
  /* Allow user to override the codeset, as set in the operating system,
Packit Service a2489d
     with standard language environment variables.  */
Packit Service a2489d
  locale = getenv ("LC_ALL");
Packit Service a2489d
  if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
    {
Packit Service a2489d
      locale = getenv ("LC_CTYPE");
Packit Service a2489d
      if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
        locale = getenv ("LANG");
Packit Service a2489d
    }
Packit Service a2489d
  if (locale != NULL && locale[0] != '\0')
Packit Service a2489d
    {
Packit Service a2489d
      /* If the locale name contains an encoding after the dot, return it.  */
Packit Service a2489d
      const char *dot = strchr (locale, '.');
Packit Service a2489d
Packit Service a2489d
      if (dot != NULL)
Packit Service a2489d
        {
Packit Service a2489d
          const char *modifier;
Packit Service a2489d
Packit Service a2489d
          dot++;
Packit Service a2489d
          /* Look for the possible @... trailer and remove it, if any.  */
Packit Service a2489d
          modifier = strchr (dot, '@');
Packit Service a2489d
          if (modifier == NULL)
Packit Service a2489d
            return dot;
Packit Service a2489d
          if (modifier - dot < sizeof (buf))
Packit Service a2489d
            {
Packit Service a2489d
              memcpy (buf, dot, modifier - dot);
Packit Service a2489d
              buf [modifier - dot] = '\0';
Packit Service a2489d
              return buf;
Packit Service a2489d
            }
Packit Service a2489d
        }
Packit Service a2489d
Packit Service a2489d
      /* For the POSIX locale, don't use the system's codepage.  */
Packit Service a2489d
      if (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0)
Packit Service a2489d
        codeset = "";
Packit Service a2489d
    }
Packit Service a2489d
Packit Service a2489d
  if (codeset == NULL)
Packit Service a2489d
    {
Packit Service a2489d
      /* OS/2 has a function returning the locale's codepage as a number.  */
Packit Service a2489d
      if (DosQueryCp (sizeof (cp), cp, &cplen))
Packit Service a2489d
        codeset = "";
Packit Service a2489d
      else
Packit Service a2489d
        {
Packit Service a2489d
          sprintf (buf, "CP%u", cp[0]);
Packit Service a2489d
          codeset = buf;
Packit Service a2489d
        }
Packit Service a2489d
    }
Packit Service a2489d
Packit Service a2489d
# else
Packit Service a2489d
Packit Service a2489d
#  error "Add code for other platforms here."
Packit Service a2489d
Packit Service a2489d
# endif
Packit Service a2489d
Packit Service a2489d
  /* Resolve alias.  */
Packit Service a2489d
  {
Packit Service a2489d
# ifdef alias_table_defined
Packit Service a2489d
    /* On some platforms, UTF-8 locales are the most frequently used ones.
Packit Service a2489d
       Speed up the common case and slow down the less common cases by
Packit Service a2489d
       testing for this case first.  */
Packit Service a2489d
#  if defined __OpenBSD__ || (defined __APPLE__ && defined __MACH__) || defined __sun || defined __CYGWIN__
Packit Service a2489d
    if (strcmp (codeset, "UTF-8") == 0)
Packit Service a2489d
      goto done_table_lookup;
Packit Service a2489d
    else
Packit Service a2489d
#  endif
Packit Service a2489d
      {
Packit Service a2489d
        const struct table_entry * const table = alias_table;
Packit Service a2489d
        size_t const table_size =
Packit Service a2489d
          sizeof (alias_table) / sizeof (struct table_entry);
Packit Service a2489d
        /* The table is sorted.  Perform a binary search.  */
Packit Service a2489d
        size_t hi = table_size;
Packit Service a2489d
        size_t lo = 0;
Packit Service a2489d
        while (lo < hi)
Packit Service a2489d
          {
Packit Service a2489d
            /* Invariant:
Packit Service a2489d
               for i < lo, strcmp (table[i].alias, codeset) < 0,
Packit Service a2489d
               for i >= hi, strcmp (table[i].alias, codeset) > 0.  */
Packit Service a2489d
            size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
Packit Service a2489d
            int cmp = strcmp (table[mid].alias, codeset);
Packit Service a2489d
            if (cmp < 0)
Packit Service a2489d
              lo = mid + 1;
Packit Service a2489d
            else if (cmp > 0)
Packit Service a2489d
              hi = mid;
Packit Service a2489d
            else
Packit Service a2489d
              {
Packit Service a2489d
                /* Found an i with
Packit Service a2489d
                     strcmp (table[i].alias, codeset) == 0.  */
Packit Service a2489d
                codeset = table[mid].canonical;
Packit Service a2489d
                goto done_table_lookup;
Packit Service a2489d
              }
Packit Service a2489d
          }
Packit Service a2489d
      }
Packit Service a2489d
    if (0)
Packit Service a2489d
      done_table_lookup: ;
Packit Service a2489d
    else
Packit Service a2489d
# endif
Packit Service a2489d
      {
Packit Service a2489d
        /* Did not find it in the table.  */
Packit Service a2489d
        /* On Mac OS X, all modern locales use the UTF-8 encoding.
Packit Service a2489d
           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */
Packit Service a2489d
# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__
Packit Service a2489d
        codeset = "UTF-8";
Packit Service a2489d
# else
Packit Service a2489d
        /* Don't return an empty string.  GNU libc and GNU libiconv interpret
Packit Service a2489d
           the empty string as denoting "the locale's character encoding",
Packit Service a2489d
           thus GNU libiconv would call this function a second time.  */
Packit Service a2489d
        if (codeset[0] == '\0')
Packit Service a2489d
          codeset = "ASCII";
Packit Service a2489d
# endif
Packit Service a2489d
      }
Packit Service a2489d
  }
Packit Service a2489d
Packit Service a2489d
#else
Packit Service a2489d
Packit Service a2489d
  /* On old systems which lack it, use setlocale or getenv.  */
Packit Service a2489d
  const char *locale = NULL;
Packit Service a2489d
Packit Service a2489d
  /* But most old systems don't have a complete set of locales.  Some
Packit Service a2489d
     (like DJGPP) have only the C locale.  Therefore we don't use setlocale
Packit Service a2489d
     here; it would return "C" when it doesn't support the locale name the
Packit Service a2489d
     user has set.  */
Packit Service a2489d
# if 0
Packit Service a2489d
  locale = setlocale (LC_CTYPE, NULL);
Packit Service a2489d
# endif
Packit Service a2489d
  if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
    {
Packit Service a2489d
      locale = getenv ("LC_ALL");
Packit Service a2489d
      if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
        {
Packit Service a2489d
          locale = getenv ("LC_CTYPE");
Packit Service a2489d
          if (locale == NULL || locale[0] == '\0')
Packit Service a2489d
            locale = getenv ("LANG");
Packit Service a2489d
            if (locale == NULL)
Packit Service a2489d
              locale = "";
Packit Service a2489d
        }
Packit Service a2489d
    }
Packit Service a2489d
Packit Service a2489d
  /* Map locale name to canonical encoding name.  */
Packit Service a2489d
  {
Packit Service a2489d
# ifdef locale_table_defined
Packit Service a2489d
    const struct table_entry * const table = locale_table;
Packit Service a2489d
    size_t const table_size =
Packit Service a2489d
      sizeof (locale_table) / sizeof (struct table_entry);
Packit Service a2489d
    /* The table is sorted.  Perform a binary search.  */
Packit Service a2489d
    size_t hi = table_size;
Packit Service a2489d
    size_t lo = 0;
Packit Service a2489d
    while (lo < hi)
Packit Service a2489d
      {
Packit Service a2489d
        /* Invariant:
Packit Service a2489d
           for i < lo, strcmp (table[i].locale, locale) < 0,
Packit Service a2489d
           for i >= hi, strcmp (table[i].locale, locale) > 0.  */
Packit Service a2489d
        size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
Packit Service a2489d
        int cmp = strcmp (table[mid].locale, locale);
Packit Service a2489d
        if (cmp < 0)
Packit Service a2489d
          lo = mid + 1;
Packit Service a2489d
        else if (cmp > 0)
Packit Service a2489d
          hi = mid;
Packit Service a2489d
        else
Packit Service a2489d
          {
Packit Service a2489d
            /* Found an i with
Packit Service a2489d
                 strcmp (table[i].locale, locale) == 0.  */
Packit Service a2489d
            codeset = table[mid].canonical;
Packit Service a2489d
            goto done_table_lookup;
Packit Service a2489d
          }
Packit Service a2489d
      }
Packit Service a2489d
    if (0)
Packit Service a2489d
      done_table_lookup: ;
Packit Service a2489d
    else
Packit Service a2489d
# endif
Packit Service a2489d
      {
Packit Service a2489d
        /* Did not find it in the table.  */
Packit Service a2489d
        /* On Mac OS X, all modern locales use the UTF-8 encoding.
Packit Service a2489d
           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */
Packit Service a2489d
# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__
Packit Service a2489d
        codeset = "UTF-8";
Packit Service a2489d
# else
Packit Service a2489d
        /* The canonical name cannot be determined.  */
Packit Service a2489d
        /* Don't return an empty string.  GNU libc and GNU libiconv interpret
Packit Service a2489d
           the empty string as denoting "the locale's character encoding",
Packit Service a2489d
           thus GNU libiconv would call this function a second time.  */
Packit Service a2489d
        codeset = "ASCII";
Packit Service a2489d
# endif
Packit Service a2489d
      }
Packit Service a2489d
  }
Packit Service a2489d
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
#ifdef DARWIN7
Packit Service a2489d
  /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8"
Packit Service a2489d
     (the default codeset) does not work when MB_CUR_MAX is 1.  */
Packit Service a2489d
  if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1)
Packit Service a2489d
    codeset = "ASCII";
Packit Service a2489d
#endif
Packit Service a2489d
Packit Service a2489d
  return codeset;
Packit Service a2489d
}