changeset 39392:dac8405aec3c

localcharset: Move mapping tables into the code. * lib/localcharset.h: Document the GNU canonical names for character encodings here. * lib/localcharset.c: Don't include <fcntl.h>, <unistd.h>, relocatable.h, configmake.h. (O_NOFOLLOW, ISSLASH, DIRECTORY_SEPARATOR, getc, volatile): Remove macros. (charset_aliases): Remove variable. (get_charset_aliases): Remove function. (struct table_entry): New type. (alias_table, locale_table): New constants. (locale_charset): Use the alias_table or locale_table to get the canonicalized encoding name. * lib/config.charset: Remove file. * lib/ref-add.sin: Remove file. * lib/ref-del.sin: Remove file. * m4/localcharset.m4 (gl_LOCALCHARSET): Don't require gl_FCNTL_O_FLAGS, AC_CANONICAL_HOST, gl_GLIBC21. Don't check for getc_unlocked. * modules/localcharset (Notice): Remove. (Files): Remove config.charset, ref-add.sin, ref-del.sin, fcntl-o.m4, glibc21.m4. (Depends-on): Remove configmake. (configure.ac): Define LOCALCHARSET_TESTS_ENVIRONMENT to empty. (Makefile.am): Simplify. * build-aux/prefix-gnulib-mk: Remove special code for the removed files.
author Bruno Haible <bruno@clisp.org>
date Sat, 19 May 2018 17:17:32 +0200
parents ebf59ba71a8e
children f046c1a24df1
files ChangeLog build-aux/prefix-gnulib-mk lib/.cvsignore lib/config.charset lib/localcharset.c lib/localcharset.h lib/ref-add.sin lib/ref-del.sin m4/localcharset.m4 modules/localcharset
diffstat 10 files changed, 813 insertions(+), 1044 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat May 19 17:07:34 2018 +0200
+++ b/ChangeLog	Sat May 19 17:17:32 2018 +0200
@@ -1,3 +1,31 @@
+2018-05-19  Bruno Haible  <bruno@clisp.org>
+
+	localcharset: Move mapping tables into the code. Use a binary search.
+	* lib/localcharset.h: Document the GNU canonical names for character
+	encodings here.
+	* lib/localcharset.c: Don't include <fcntl.h>, <unistd.h>,
+	relocatable.h, configmake.h.
+	(O_NOFOLLOW, ISSLASH, DIRECTORY_SEPARATOR, getc, volatile): Remove
+	macros.
+	(charset_aliases): Remove variable.
+	(get_charset_aliases): Remove function.
+	(struct table_entry): New type.
+	(alias_table, locale_table): New constants.
+	(locale_charset): Use the alias_table or locale_table to get the
+	canonicalized encoding name.
+	* lib/config.charset: Remove file.
+	* lib/ref-add.sin: Remove file.
+	* lib/ref-del.sin: Remove file.
+	* m4/localcharset.m4 (gl_LOCALCHARSET): Don't require gl_FCNTL_O_FLAGS,
+	AC_CANONICAL_HOST, gl_GLIBC21. Don't check for getc_unlocked.
+	* modules/localcharset (Notice): Remove.
+	(Files): Remove config.charset, ref-add.sin, ref-del.sin, fcntl-o.m4,
+	glibc21.m4.
+	(Depends-on): Remove configmake.
+	(configure.ac): Define LOCALCHARSET_TESTS_ENVIRONMENT to empty.
+	(Makefile.am): Simplify.
+	* build-aux/prefix-gnulib-mk: Remove special code for the removed files.
+
 2018-05-19  Bruno Haible  <bruno@clisp.org>
 
 	localcharset: Add a manual test.
--- a/build-aux/prefix-gnulib-mk	Sat May 19 17:07:34 2018 +0200
+++ b/build-aux/prefix-gnulib-mk	Sat May 19 17:17:32 2018 +0200
@@ -146,15 +146,6 @@
   s{^([\w.]+\s*\+?=)(.*)$}
    {prefix_assignment($1, $2)}gem;
 
-  # These three guys escape all the other regular rules.
-  # Require the leading white space to avoid inserting the prefix
-  # on a line like this:
-  # charset_alias = $(DESTDIR)$(libdir)/charset.alias
-  # With $(libdir), it would be erroneous.
-  s{(\s)(charset\.alias|ref-add\.sed|ref-del\.sed)}{$1$prefix$2}g;
-  # Unfortunately, as a result we sometimes have lib/lib.
-  s{($prefix){2}}{$1}g;
-
   # $(srcdir)/ is actually $(top_srcdir)/$prefix/.
   # The trailing slash is required to avoid matching this rule:
   #   test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile
--- a/lib/.cvsignore	Sat May 19 17:07:34 2018 +0200
+++ b/lib/.cvsignore	Sat May 19 17:17:32 2018 +0200
@@ -1,7 +1,6 @@
 .deps
 Makefile
 alloca.h
-charset.alias
 fnmatch.h
 fts.h
 getdate.c
--- a/lib/config.charset	Sat May 19 17:07:34 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,540 +0,0 @@
-#! /bin/sh
-# Output a system dependent table of character encoding aliases.
-#
-#   Copyright (C) 2000-2004, 2006-2018 Free Software Foundation, Inc.
-#
-#   This program is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2, or (at your option)
-#   any later version.
-#
-#   This program is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License along
-#   with this program; if not, see <https://www.gnu.org/licenses/>.
-#
-# The table consists of lines of the form
-#    ALIAS  CANONICAL
-#
-# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)".
-# ALIAS is compared in a case sensitive way.
-#
-# CANONICAL is the GNU canonical name for this character encoding.
-# It must be an encoding supported by libiconv. Support by GNU libc is
-# also desirable. CANONICAL is case insensitive. Usually an upper case
-# MIME charset name is preferred.
-# The current list of GNU canonical charset names is as follows.
-#
-#       name              MIME?             used by which systems
-#                                    (darwin = Mac OS X, woe32 = native Windows)
-#
-#   ASCII, ANSI_X3.4-1968       glibc solaris freebsd netbsd darwin cygwin
-#   ISO-8859-1              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
-#   ISO-8859-2              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
-#   ISO-8859-3              Y   glibc solaris cygwin
-#   ISO-8859-4              Y   osf solaris freebsd netbsd openbsd darwin
-#   ISO-8859-5              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
-#   ISO-8859-6              Y   glibc aix hpux solaris cygwin
-#   ISO-8859-7              Y   glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin
-#   ISO-8859-8              Y   glibc aix hpux osf solaris cygwin
-#   ISO-8859-9              Y   glibc aix hpux irix osf solaris darwin cygwin
-#   ISO-8859-13                 glibc netbsd openbsd darwin cygwin
-#   ISO-8859-14                 glibc cygwin
-#   ISO-8859-15                 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin
-#   KOI8-R                  Y   glibc solaris freebsd netbsd openbsd darwin
-#   KOI8-U                  Y   glibc freebsd netbsd openbsd darwin cygwin
-#   KOI8-T                      glibc
-#   CP437                       dos
-#   CP775                       dos
-#   CP850                       aix osf dos
-#   CP852                       dos
-#   CP855                       dos
-#   CP856                       aix
-#   CP857                       dos
-#   CP861                       dos
-#   CP862                       dos
-#   CP864                       dos
-#   CP865                       dos
-#   CP866                       freebsd netbsd openbsd darwin dos
-#   CP869                       dos
-#   CP874                       woe32 dos
-#   CP922                       aix
-#   CP932                       aix cygwin woe32 dos
-#   CP943                       aix
-#   CP949                       osf darwin woe32 dos
-#   CP950                       woe32 dos
-#   CP1046                      aix
-#   CP1124                      aix
-#   CP1125                      dos
-#   CP1129                      aix
-#   CP1131                      darwin
-#   CP1250                      woe32
-#   CP1251                      glibc solaris netbsd openbsd darwin cygwin woe32
-#   CP1252                      aix woe32
-#   CP1253                      woe32
-#   CP1254                      woe32
-#   CP1255                      glibc woe32
-#   CP1256                      woe32
-#   CP1257                      woe32
-#   GB2312                  Y   glibc aix hpux irix solaris freebsd netbsd darwin
-#   EUC-JP                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
-#   EUC-KR                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin
-#   EUC-TW                      glibc aix hpux irix osf solaris netbsd
-#   BIG5                    Y   glibc aix hpux osf solaris freebsd netbsd darwin cygwin
-#   BIG5-HKSCS                  glibc solaris darwin
-#   GBK                         glibc aix osf solaris darwin cygwin woe32 dos
-#   GB18030                     glibc solaris netbsd darwin
-#   SHIFT_JIS               Y   hpux osf solaris freebsd netbsd darwin
-#   JOHAB                       glibc solaris woe32
-#   TIS-620                     glibc aix hpux osf solaris cygwin
-#   VISCII                  Y   glibc
-#   TCVN5712-1                  glibc
-#   ARMSCII-8                   glibc darwin
-#   GEORGIAN-PS                 glibc cygwin
-#   PT154                       glibc
-#   HP-ROMAN8                   hpux
-#   HP-ARABIC8                  hpux
-#   HP-GREEK8                   hpux
-#   HP-HEBREW8                  hpux
-#   HP-TURKISH8                 hpux
-#   HP-KANA8                    hpux
-#   DEC-KANJI                   osf
-#   DEC-HANYU                   osf
-#   UTF-8                   Y   glibc aix hpux osf solaris netbsd darwin cygwin
-#
-# Note: Names which are not marked as being a MIME name should not be used in
-# Internet protocols for information interchange (mail, news, etc.).
-#
-# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications
-# must understand both names and treat them as equivalent.
-#
-# The first argument passed to this file is the canonical host specification,
-#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-
-host="$1"
-os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'`
-echo "# This file contains a table of character encoding aliases,"
-echo "# suitable for operating system '${os}'."
-echo "# It was automatically generated from config.charset."
-# List of references, updated during installation:
-echo "# Packages using this file: "
-case "$os" in
-  linux* | *-gnu*)
-    # With glibc-2.1 or newer, we don't need any canonicalization,
-    # because glibc has iconv and both glibc and libiconv support all
-    # GNU canonical names directly. Therefore, the Makefile does not
-    # need to install the alias file at all.
-    ;;
-  aix*)
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-6 ISO-8859-6"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-8 ISO-8859-8"
-    echo "ISO8859-9 ISO-8859-9"
-    echo "ISO8859-15 ISO-8859-15"
-    echo "IBM-850 CP850"
-    echo "IBM-856 CP856"
-    echo "IBM-921 ISO-8859-13"
-    echo "IBM-922 CP922"
-    echo "IBM-932 CP932"
-    echo "IBM-943 CP943"
-    echo "IBM-1046 CP1046"
-    echo "IBM-1124 CP1124"
-    echo "IBM-1129 CP1129"
-    echo "IBM-1252 CP1252"
-    echo "IBM-eucCN GB2312"
-    echo "IBM-eucJP EUC-JP"
-    echo "IBM-eucKR EUC-KR"
-    echo "IBM-eucTW EUC-TW"
-    echo "big5 BIG5"
-    echo "GBK GBK"
-    echo "TIS-620 TIS-620"
-    echo "UTF-8 UTF-8"
-    ;;
-  hpux*)
-    echo "iso88591 ISO-8859-1"
-    echo "iso88592 ISO-8859-2"
-    echo "iso88595 ISO-8859-5"
-    echo "iso88596 ISO-8859-6"
-    echo "iso88597 ISO-8859-7"
-    echo "iso88598 ISO-8859-8"
-    echo "iso88599 ISO-8859-9"
-    echo "iso885915 ISO-8859-15"
-    echo "roman8 HP-ROMAN8"
-    echo "arabic8 HP-ARABIC8"
-    echo "greek8 HP-GREEK8"
-    echo "hebrew8 HP-HEBREW8"
-    echo "turkish8 HP-TURKISH8"
-    echo "kana8 HP-KANA8"
-    echo "tis620 TIS-620"
-    echo "big5 BIG5"
-    echo "eucJP EUC-JP"
-    echo "eucKR EUC-KR"
-    echo "eucTW EUC-TW"
-    echo "hp15CN GB2312"
-    #echo "ccdc ?" # what is this?
-    echo "SJIS SHIFT_JIS"
-    echo "utf8 UTF-8"
-    ;;
-  irix*)
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-9 ISO-8859-9"
-    echo "eucCN GB2312"
-    echo "eucJP EUC-JP"
-    echo "eucKR EUC-KR"
-    echo "eucTW EUC-TW"
-    ;;
-  osf*)
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-4 ISO-8859-4"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-8 ISO-8859-8"
-    echo "ISO8859-9 ISO-8859-9"
-    echo "ISO8859-15 ISO-8859-15"
-    echo "cp850 CP850"
-    echo "big5 BIG5"
-    echo "dechanyu DEC-HANYU"
-    echo "dechanzi GB2312"
-    echo "deckanji DEC-KANJI"
-    echo "deckorean EUC-KR"
-    echo "eucJP EUC-JP"
-    echo "eucKR EUC-KR"
-    echo "eucTW EUC-TW"
-    echo "GBK GBK"
-    echo "KSC5601 CP949"
-    echo "sdeckanji EUC-JP"
-    echo "SJIS SHIFT_JIS"
-    echo "TACTIS TIS-620"
-    echo "UTF-8 UTF-8"
-    ;;
-  solaris*)
-    echo "646 ASCII"
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-3 ISO-8859-3"
-    echo "ISO8859-4 ISO-8859-4"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-6 ISO-8859-6"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-8 ISO-8859-8"
-    echo "ISO8859-9 ISO-8859-9"
-    echo "ISO8859-15 ISO-8859-15"
-    echo "koi8-r KOI8-R"
-    echo "ansi-1251 CP1251"
-    echo "BIG5 BIG5"
-    echo "Big5-HKSCS BIG5-HKSCS"
-    echo "gb2312 GB2312"
-    echo "GBK GBK"
-    echo "GB18030 GB18030"
-    echo "cns11643 EUC-TW"
-    echo "5601 EUC-KR"
-    #echo "ko_KR.johap92 JOHAB"
-    echo "eucJP EUC-JP"
-    echo "PCK SHIFT_JIS"
-    echo "TIS620.2533 TIS-620"
-    #echo "sun_eu_greek ?" # what is this?
-    echo "UTF-8 UTF-8"
-    ;;
-  freebsd*)
-    # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore
-    # localcharset.c falls back to using the full locale name
-    # from the environment variables.
-    echo "C ASCII"
-    echo "US-ASCII ASCII"
-    for l in la_LN lt_LN; do
-      echo "$l.ASCII ASCII"
-    done
-    for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
-             fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \
-             lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do
-      echo "$l.ISO_8859-1 ISO-8859-1"
-      echo "$l.DIS_8859-15 ISO-8859-15"
-    done
-    for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do
-      echo "$l.ISO_8859-2 ISO-8859-2"
-    done
-    for l in la_LN lt_LT; do
-      echo "$l.ISO_8859-4 ISO-8859-4"
-    done
-    for l in ru_RU ru_SU; do
-      echo "$l.KOI8-R KOI8-R"
-      echo "$l.ISO_8859-5 ISO-8859-5"
-      echo "$l.CP866 CP866"
-    done
-    echo "uk_UA.KOI8-U KOI8-U"
-    echo "zh_TW.BIG5 BIG5"
-    echo "zh_TW.Big5 BIG5"
-    echo "zh_CN.EUC GB2312"
-    echo "ja_JP.EUC EUC-JP"
-    echo "ja_JP.SJIS SHIFT_JIS"
-    echo "ja_JP.Shift_JIS SHIFT_JIS"
-    echo "ko_KR.EUC EUC-KR"
-    ;;
-  netbsd*)
-    echo "646 ASCII"
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-4 ISO-8859-4"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-13 ISO-8859-13"
-    echo "ISO8859-15 ISO-8859-15"
-    echo "eucCN GB2312"
-    echo "eucJP EUC-JP"
-    echo "eucKR EUC-KR"
-    echo "eucTW EUC-TW"
-    echo "BIG5 BIG5"
-    echo "SJIS SHIFT_JIS"
-    ;;
-  openbsd*)
-    echo "646 ASCII"
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-4 ISO-8859-4"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-13 ISO-8859-13"
-    echo "ISO8859-15 ISO-8859-15"
-    ;;
-  darwin*)
-    # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is
-    # useless:
-    # - It returns the empty string when LANG is set to a locale of the
-    #   form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8
-    #   LC_CTYPE file.
-    # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by
-    #   the system; nl_langinfo(CODESET) returns "US-ASCII" in this case.
-    # - The documentation says:
-    #     "... all code that calls BSD system routines should ensure
-    #      that the const *char parameters of these routines are in UTF-8
-    #      encoding. All BSD system functions expect their string
-    #      parameters to be in UTF-8 encoding and nothing else."
-    #   It also says
-    #     "An additional caveat is that string parameters for files,
-    #      paths, and other file-system entities must be in canonical
-    #      UTF-8. In a canonical UTF-8 Unicode string, all decomposable
-    #      characters are decomposed ..."
-    #   but this is not true: You can pass non-decomposed UTF-8 strings
-    #   to file system functions, and it is the OS which will convert
-    #   them to decomposed UTF-8 before accessing the file system.
-    # - The Apple Terminal application displays UTF-8 by default.
-    # - However, other applications are free to use different encodings:
-    #   - xterm uses ISO-8859-1 by default.
-    #   - TextEdit uses MacRoman by default.
-    # We prefer UTF-8 over decomposed UTF-8-MAC because one should
-    # minimize the use of decomposed Unicode. Unfortunately, through the
-    # Darwin file system, decomposed UTF-8 strings are leaked into user
-    # space nevertheless.
-    # Then there are also the locales with encodings other than US-ASCII
-    # and UTF-8. These locales can be occasionally useful to users (e.g.
-    # when grepping through ISO-8859-1 encoded text files), when all their
-    # file names are in US-ASCII.
-    echo "ISO8859-1 ISO-8859-1"
-    echo "ISO8859-2 ISO-8859-2"
-    echo "ISO8859-4 ISO-8859-4"
-    echo "ISO8859-5 ISO-8859-5"
-    echo "ISO8859-7 ISO-8859-7"
-    echo "ISO8859-9 ISO-8859-9"
-    echo "ISO8859-13 ISO-8859-13"
-    echo "ISO8859-15 ISO-8859-15"
-    echo "KOI8-R KOI8-R"
-    echo "KOI8-U KOI8-U"
-    echo "CP866 CP866"
-    echo "CP949 CP949"
-    echo "CP1131 CP1131"
-    echo "CP1251 CP1251"
-    echo "eucCN GB2312"
-    echo "GB2312 GB2312"
-    echo "eucJP EUC-JP"
-    echo "eucKR EUC-KR"
-    echo "Big5 BIG5"
-    echo "Big5HKSCS BIG5-HKSCS"
-    echo "GBK GBK"
-    echo "GB18030 GB18030"
-    echo "SJIS SHIFT_JIS"
-    echo "ARMSCII-8 ARMSCII-8"
-    echo "PT154 PT154"
-    #echo "ISCII-DEV ?"
-    echo "* UTF-8"
-    ;;
-  beos* | haiku*)
-    # BeOS and Haiku have a single locale, and it has UTF-8 encoding.
-    echo "* UTF-8"
-    ;;
-  msdosdjgpp*)
-    # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore
-    # localcharset.c falls back to using the full locale name
-    # from the environment variables.
-    echo "#"
-    echo "# The encodings given here may not all be correct."
-    echo "# If you find that the encoding given for your language and"
-    echo "# country is not the one your DOS machine actually uses, just"
-    echo "# correct it in this file, and send a mail to"
-    echo "# Juan Manuel Guerrero <juan.guerrero@gmx.de>"
-    echo "# and Bruno Haible <bruno@clisp.org>."
-    echo "#"
-    echo "C ASCII"
-    # ISO-8859-1 languages
-    echo "ca CP850"
-    echo "ca_ES CP850"
-    echo "da CP865"    # not CP850 ??
-    echo "da_DK CP865" # not CP850 ??
-    echo "de CP850"
-    echo "de_AT CP850"
-    echo "de_CH CP850"
-    echo "de_DE CP850"
-    echo "en CP850"
-    echo "en_AU CP850" # not CP437 ??
-    echo "en_CA CP850"
-    echo "en_GB CP850"
-    echo "en_NZ CP437"
-    echo "en_US CP437"
-    echo "en_ZA CP850" # not CP437 ??
-    echo "es CP850"
-    echo "es_AR CP850"
-    echo "es_BO CP850"
-    echo "es_CL CP850"
-    echo "es_CO CP850"
-    echo "es_CR CP850"
-    echo "es_CU CP850"
-    echo "es_DO CP850"
-    echo "es_EC CP850"
-    echo "es_ES CP850"
-    echo "es_GT CP850"
-    echo "es_HN CP850"
-    echo "es_MX CP850"
-    echo "es_NI CP850"
-    echo "es_PA CP850"
-    echo "es_PY CP850"
-    echo "es_PE CP850"
-    echo "es_SV CP850"
-    echo "es_UY CP850"
-    echo "es_VE CP850"
-    echo "et CP850"
-    echo "et_EE CP850"
-    echo "eu CP850"
-    echo "eu_ES CP850"
-    echo "fi CP850"
-    echo "fi_FI CP850"
-    echo "fr CP850"
-    echo "fr_BE CP850"
-    echo "fr_CA CP850"
-    echo "fr_CH CP850"
-    echo "fr_FR CP850"
-    echo "ga CP850"
-    echo "ga_IE CP850"
-    echo "gd CP850"
-    echo "gd_GB CP850"
-    echo "gl CP850"
-    echo "gl_ES CP850"
-    echo "id CP850"    # not CP437 ??
-    echo "id_ID CP850" # not CP437 ??
-    echo "is CP861"    # not CP850 ??
-    echo "is_IS CP861" # not CP850 ??
-    echo "it CP850"
-    echo "it_CH CP850"
-    echo "it_IT CP850"
-    echo "lt CP775"
-    echo "lt_LT CP775"
-    echo "lv CP775"
-    echo "lv_LV CP775"
-    echo "nb CP865"    # not CP850 ??
-    echo "nb_NO CP865" # not CP850 ??
-    echo "nl CP850"
-    echo "nl_BE CP850"
-    echo "nl_NL CP850"
-    echo "nn CP865"    # not CP850 ??
-    echo "nn_NO CP865" # not CP850 ??
-    echo "no CP865"    # not CP850 ??
-    echo "no_NO CP865" # not CP850 ??
-    echo "pt CP850"
-    echo "pt_BR CP850"
-    echo "pt_PT CP850"
-    echo "sv CP850"
-    echo "sv_SE CP850"
-    # ISO-8859-2 languages
-    echo "cs CP852"
-    echo "cs_CZ CP852"
-    echo "hr CP852"
-    echo "hr_HR CP852"
-    echo "hu CP852"
-    echo "hu_HU CP852"
-    echo "pl CP852"
-    echo "pl_PL CP852"
-    echo "ro CP852"
-    echo "ro_RO CP852"
-    echo "sk CP852"
-    echo "sk_SK CP852"
-    echo "sl CP852"
-    echo "sl_SI CP852"
-    echo "sq CP852"
-    echo "sq_AL CP852"
-    echo "sr CP852"    # CP852 or CP866 or CP855 ??
-    echo "sr_CS CP852" # CP852 or CP866 or CP855 ??
-    echo "sr_YU CP852" # CP852 or CP866 or CP855 ??
-    # ISO-8859-3 languages
-    echo "mt CP850"
-    echo "mt_MT CP850"
-    # ISO-8859-5 languages
-    echo "be CP866"
-    echo "be_BE CP866"
-    echo "bg CP866"    # not CP855 ??
-    echo "bg_BG CP866" # not CP855 ??
-    echo "mk CP866"    # not CP855 ??
-    echo "mk_MK CP866" # not CP855 ??
-    echo "ru CP866"
-    echo "ru_RU CP866"
-    echo "uk CP1125"
-    echo "uk_UA CP1125"
-    # ISO-8859-6 languages
-    echo "ar CP864"
-    echo "ar_AE CP864"
-    echo "ar_DZ CP864"
-    echo "ar_EG CP864"
-    echo "ar_IQ CP864"
-    echo "ar_IR CP864"
-    echo "ar_JO CP864"
-    echo "ar_KW CP864"
-    echo "ar_MA CP864"
-    echo "ar_OM CP864"
-    echo "ar_QA CP864"
-    echo "ar_SA CP864"
-    echo "ar_SY CP864"
-    # ISO-8859-7 languages
-    echo "el CP869"
-    echo "el_GR CP869"
-    # ISO-8859-8 languages
-    echo "he CP862"
-    echo "he_IL CP862"
-    # ISO-8859-9 languages
-    echo "tr CP857"
-    echo "tr_TR CP857"
-    # Japanese
-    echo "ja CP932"
-    echo "ja_JP CP932"
-    # Chinese
-    echo "zh_CN GBK"
-    echo "zh_TW CP950" # not CP938 ??
-    # Korean
-    echo "kr CP949"    # not CP934 ??
-    echo "kr_KR CP949" # not CP934 ??
-    # Thai
-    echo "th CP874"
-    echo "th_TH CP874"
-    # Other
-    echo "eo CP850"
-    echo "eo_EO CP850"
-    ;;
-esac
--- a/lib/localcharset.c	Sat May 19 17:07:34 2018 +0200
+++ b/lib/localcharset.c	Sat May 19 17:17:32 2018 +0200
@@ -22,7 +22,6 @@
 /* Specification.  */
 #include "localcharset.h"
 
-#include <fcntl.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
@@ -45,11 +44,10 @@
 #endif
 
 #if !defined WINDOWS_NATIVE
-# include <unistd.h>
 # if HAVE_LANGINFO_CODESET
 #  include <langinfo.h>
 # else
-#  if 0 /* see comment below */
+#  if 0 /* see comment regarding use of setlocale(), below */
 #   include <locale.h>
 #  endif
 # endif
@@ -71,323 +69,569 @@
 # include <xlocale.h>
 #endif
 
-#if ENABLE_RELOCATABLE
-# include "relocatable.h"
-#else
-# define relocate(pathname) (pathname)
-# define relocate2(pathname,allocatedp) (*(allocatedp) = NULL, (pathname))
-#endif
 
-/* Get LIBDIR.  */
-#ifndef LIBDIR
-# include "configmake.h"
-#endif
-
-/* Define O_NOFOLLOW to 0 on platforms where it does not exist.  */
-#ifndef O_NOFOLLOW
-# define O_NOFOLLOW 0
-#endif
+#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2
 
-#if defined _WIN32 || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
-  /* Native Windows, Cygwin, OS/2, DOS */
-# define ISSLASH(C) ((C) == '/' || (C) == '\\')
-#endif
-
-#ifndef DIRECTORY_SEPARATOR
-# define DIRECTORY_SEPARATOR '/'
-#endif
-
-#ifndef ISSLASH
-# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
-#endif
-
-#if HAVE_DECL_GETC_UNLOCKED
-# undef getc
-# define getc getc_unlocked
-#endif
+/* On these platforms, we use a mapping from non-canonical encoding name
+   to GNU canonical encoding name.  */
 
-/* The following static variable is declared 'volatile' to avoid a
-   possible multithread problem in the function get_charset_aliases. If we
-   are running in a threaded environment, and if two threads initialize
-   'charset_aliases' simultaneously, both will produce the same value,
-   and everything will be ok if the two assignments to 'charset_aliases'
-   are atomic. But I don't know what will happen if the two assignments mix.  */
-#if __STDC__ != 1
-# define volatile /* empty */
-#endif
-/* Pointer to the contents of the charset.alias file, if it has already been
-   read, else NULL.  Its format is:
-   ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0'  */
-static const char * volatile charset_aliases;
-
-/* Return a pointer to the contents of the charset.alias file.  */
-static const char *
-get_charset_aliases (void)
-{
-  const char *cp;
+/* With glibc-2.1 or newer, we don't need any canonicalization,
+   because glibc has iconv and both glibc and libiconv support all
+   GNU canonical names directly.  */
+# if !((defined __GNU_LIBRARY__ && __GLIBC__ >= 2) || defined __UCLIBC__)
 
-  cp = charset_aliases;
-  if (cp == NULL)
-    {
-#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__ || defined OS2)
-      char *malloc_dir = NULL;
-      const char *dir;
-      const char *base = "charset.alias";
-      char *file_name;
-
-      /* Make it possible to override the charset.alias location.  This is
-         necessary for running the testsuite before "make install".  */
-      dir = getenv ("CHARSETALIASDIR");
-      if (dir == NULL || dir[0] == '\0')
-        dir = relocate2 (LIBDIR, &malloc_dir);
-
-      /* Concatenate dir and base into freshly allocated file_name.  */
-      {
-        size_t dir_len = strlen (dir);
-        size_t base_len = strlen (base);
-        int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
-        file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
-        if (file_name != NULL)
-          {
-            memcpy (file_name, dir, dir_len);
-            if (add_slash)
-              file_name[dir_len] = DIRECTORY_SEPARATOR;
-            memcpy (file_name + dir_len + add_slash, base, base_len + 1);
-          }
-      }
-
-      free (malloc_dir);
+struct table_entry
+{
+  const char alias[11+1];
+  const char canonical[11+1];
+};
 
-      if (file_name == NULL)
-        /* Out of memory.  Treat the file as empty.  */
-        cp = "";
-      else
-        {
-          int fd;
-
-          /* Open the file.  Reject symbolic links on platforms that support
-             O_NOFOLLOW.  This is a security feature.  Without it, an attacker
-             could retrieve parts of the contents (namely, the tail of the
-             first line that starts with "* ") of an arbitrary file by placing
-             a symbolic link to that file under the name "charset.alias" in
-             some writable directory and defining the environment variable
-             CHARSETALIASDIR to point to that directory.  */
-          fd = open (file_name,
-                     O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0));
-          if (fd < 0)
-            /* File not found.  Treat it as empty.  */
-            cp = "";
-          else
-            {
-              FILE *fp;
-
-              fp = fdopen (fd, "r");
-              if (fp == NULL)
-                {
-                  /* Out of memory.  Treat the file as empty.  */
-                  close (fd);
-                  cp = "";
-                }
-              else
-                {
-                  /* Parse the file's contents.  */
-                  char *res_ptr = NULL;
-                  size_t res_size = 0;
-
-                  for (;;)
-                    {
-                      int c;
-                      char buf1[50+1];
-                      char buf2[50+1];
-                      size_t l1, l2;
-                      char *old_res_ptr;
+/* Table of platform-dependent mappings, sorted in ascending order.  */
+static const struct table_entry alias_table[] =
+  {
+#  if defined __FreeBSD__                                   /* FreeBSD */
+    { "C",        "ASCII" },
+    { "US-ASCII", "ASCII" }
+#   define alias_table_defined
+#  endif
+#  if defined __NetBSD__                                    /* NetBSD */
+    { "646",        "ASCII" },
+    { "BIG5",       "BIG5" },
+    { "ISO8859-1",  "ISO-8859-1" },
+    { "ISO8859-13", "ISO-8859-13" },
+    { "ISO8859-15", "ISO-8859-15" },
+    { "ISO8859-2",  "ISO-8859-2" },
+    { "ISO8859-4",  "ISO-8859-4" },
+    { "ISO8859-5",  "ISO-8859-5" },
+    { "ISO8859-7",  "ISO-8859-7" },
+    { "SJIS",       "SHIFT_JIS" },
+    { "eucCN",      "GB2312" },
+    { "eucJP",      "EUC-JP" },
+    { "eucKR",      "EUC-KR" },
+    { "eucTW",      "EUC-TW" }
+#   define alias_table_defined
+#  endif
+#  if defined __OpenBSD__                                   /* OpenBSD */
+    { "646",        "ASCII" },
+    { "ISO8859-1",  "ISO-8859-1" },
+    { "ISO8859-13", "ISO-8859-13" },
+    { "ISO8859-15", "ISO-8859-15" },
+    { "ISO8859-2",  "ISO-8859-2" },
+    { "ISO8859-4",  "ISO-8859-4" },
+    { "ISO8859-5",  "ISO-8859-5" },
+    { "ISO8859-7",  "ISO-8859-7" }
+#   define alias_table_defined
+#  endif
+#  if defined __APPLE__ && defined __MACH__                 /* Mac OS X */
+    /* Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is
+       useless:
+       - It returns the empty string when LANG is set to a locale of the
+         form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8
+         LC_CTYPE file.
+       - The environment variables LANG, LC_CTYPE, LC_ALL are not set by
+         the system; nl_langinfo(CODESET) returns "US-ASCII" in this case.
+       - The documentation says:
+           "... all code that calls BSD system routines should ensure
+            that the const *char parameters of these routines are in UTF-8
+            encoding. All BSD system functions expect their string
+            parameters to be in UTF-8 encoding and nothing else."
+         It also says
+           "An additional caveat is that string parameters for files,
+            paths, and other file-system entities must be in canonical
+            UTF-8. In a canonical UTF-8 Unicode string, all decomposable
+            characters are decomposed ..."
+         but this is not true: You can pass non-decomposed UTF-8 strings
+         to file system functions, and it is the OS which will convert
+         them to decomposed UTF-8 before accessing the file system.
+       - The Apple Terminal application displays UTF-8 by default.
+       - However, other applications are free to use different encodings:
+         - xterm uses ISO-8859-1 by default.
+         - TextEdit uses MacRoman by default.
+       We prefer UTF-8 over decomposed UTF-8-MAC because one should
+       minimize the use of decomposed Unicode. Unfortunately, through the
+       Darwin file system, decomposed UTF-8 strings are leaked into user
+       space nevertheless.
+       Then there are also the locales with encodings other than US-ASCII
+       and UTF-8. These locales can be occasionally useful to users (e.g.
+       when grepping through ISO-8859-1 encoded text files), when all their
+       file names are in US-ASCII.
+     */
+    { "ARMSCII-8",  "ARMSCII-8" },
+    { "Big5",       "BIG5" },
+    { "Big5HKSCS",  "BIG5-HKSCS" },
+    { "CP1131",     "CP1131" },
+    { "CP1251",     "CP1251" },
+    { "CP866",      "CP866" },
+    { "CP949",      "CP949" },
+    { "GB18030",    "GB18030" },
+    { "GB2312",     "GB2312" },
+    { "GBK",        "GBK" },
+  /*{ "ISCII-DEV",  "?" },*/
+    { "ISO8859-1",  "ISO-8859-1" },
+    { "ISO8859-13", "ISO-8859-13" },
+    { "ISO8859-15", "ISO-8859-15" },
+    { "ISO8859-2",  "ISO-8859-2" },
+    { "ISO8859-4",  "ISO-8859-4" },
+    { "ISO8859-5",  "ISO-8859-5" },
+    { "ISO8859-7",  "ISO-8859-7" },
+    { "ISO8859-9",  "ISO-8859-9" },
+    { "KOI8-R",     "KOI8-R" },
+    { "KOI8-U",     "KOI8-U" },
+    { "PT154",      "PT154" },
+    { "SJIS",       "SHIFT_JIS" },
+    { "eucCN",      "GB2312" },
+    { "eucJP",      "EUC-JP" },
+    { "eucKR",      "EUC-KR" }
+#   define alias_table_defined
+#  endif
+#  if defined _AIX                                          /* AIX */
+    { "GBK",        "GBK" },
+    { "IBM-1046",   "CP1046" },
+    { "IBM-1124",   "CP1124" },
+    { "IBM-1129",   "CP1129" },
+    { "IBM-1252",   "CP1252" },
+    { "IBM-850",    "CP850" },
+    { "IBM-856",    "CP856" },
+    { "IBM-921",    "ISO-8859-13" },
+    { "IBM-922",    "CP922" },
+    { "IBM-932",    "CP932" },
+    { "IBM-943",    "CP943" },
+    { "IBM-eucCN",  "GB2312" },
+    { "IBM-eucJP",  "EUC-JP" },
+    { "IBM-eucKR",  "EUC-KR" },
+    { "IBM-eucTW",  "EUC-TW" },
+    { "ISO8859-1",  "ISO-8859-1" },
+    { "ISO8859-15", "ISO-8859-15" },
+    { "ISO8859-2",  "ISO-8859-2" },
+    { "ISO8859-5",  "ISO-8859-5" },
+    { "ISO8859-6",  "ISO-8859-6" },
+    { "ISO8859-7",  "ISO-8859-7" },
+    { "ISO8859-8",  "ISO-8859-8" },
+    { "ISO8859-9",  "ISO-8859-9" },
+    { "TIS-620",    "TIS-620" },
+    { "UTF-8",      "UTF-8" },
+    { "big5",       "BIG5" }
+#   define alias_table_defined
+#  endif
+#  if defined __hpux                                        /* HP-UX */
+    { "SJIS",      "SHIFT_JIS" },
+    { "arabic8",   "HP-ARABIC8" },
+    { "big5",      "BIG5" },
+    { "eucJP",     "EUC-JP" },
+    { "eucKR",     "EUC-KR" },
+    { "eucTW",     "EUC-TW" },
+    { "greek8",    "HP-GREEK8" },
+    { "hebrew8",   "HP-HEBREW8" },
+    { "hp15CN",    "GB2312" },
+    { "iso88591",  "ISO-8859-1" },
+    { "iso885915", "ISO-8859-15" },
+    { "iso88592",  "ISO-8859-2" },
+    { "iso88595",  "ISO-8859-5" },
+    { "iso88596",  "ISO-8859-6" },
+    { "iso88597",  "ISO-8859-7" },
+    { "iso88598",  "ISO-8859-8" },
+    { "iso88599",  "ISO-8859-9" },
+    { "kana8",     "HP-KANA8" },
+    { "roman8",    "HP-ROMAN8" },
+    { "tis620",    "TIS-620" },
+    { "turkish8",  "HP-TURKISH8" },
+    { "utf8",      "UTF-8" }
+#   define alias_table_defined
+#  endif
+#  if defined __sgi                                         /* IRIX */
+    { "ISO8859-1", "ISO-8859-1" },
+    { "ISO8859-2", "ISO-8859-2" },
+    { "ISO8859-5", "ISO-8859-5" },
+    { "ISO8859-7", "ISO-8859-7" },
+    { "ISO8859-9", "ISO-8859-9" },
+    { "eucCN",     "GB2312" },
+    { "eucJP",     "EUC-JP" },
+    { "eucKR",     "EUC-KR" },
+    { "eucTW",     "EUC-TW" }
+#   define alias_table_defined
+#  endif
+#  if defined __osf__                                       /* OSF/1 */
+    { "GBK",        "GBK" },
+    { "ISO8859-1",  "ISO-8859-1" },
+    { "ISO8859-15", "ISO-8859-15" },
+    { "ISO8859-2",  "ISO-8859-2" },
+    { "ISO8859-4",  "ISO-8859-4" },
+    { "ISO8859-5",  "ISO-8859-5" },
+    { "ISO8859-7",  "ISO-8859-7" },
+    { "ISO8859-8",  "ISO-8859-8" },
+    { "ISO8859-9",  "ISO-8859-9" },
+    { "KSC5601",    "CP949" },
+    { "SJIS",       "SHIFT_JIS" },
+    { "TACTIS",     "TIS-620" },
+    { "UTF-8",      "UTF-8" },
+    { "big5",       "BIG5" },
+    { "cp850",      "CP850" },
+    { "dechanyu",   "DEC-HANYU" },
+    { "dechanzi",   "GB2312" },
+    { "deckanji",   "DEC-KANJI" },
+    { "deckorean",  "EUC-KR" },
+    { "eucJP",      "EUC-JP" },
+    { "eucKR",      "EUC-KR" },
+    { "eucTW",      "EUC-TW" },
+    { "sdeckanji",  "EUC-JP" }
+#   define alias_table_defined
+#  endif
+#  if defined __sun                                         /* Solaris */
+    { "5601",        "EUC-KR" },
+    { "646",         "ASCII" },
+    { "BIG5",        "BIG5" },
+    { "Big5-HKSCS",  "BIG5-HKSCS" },
+    { "GB18030",     "GB18030" },
+    { "GBK",         "GBK" },
+    { "ISO8859-1",   "ISO-8859-1" },
+    { "ISO8859-15",  "ISO-8859-15" },
+    { "ISO8859-2",   "ISO-8859-2" },
+    { "ISO8859-3",   "ISO-8859-3" },
+    { "ISO8859-4",   "ISO-8859-4" },
+    { "ISO8859-5",   "ISO-8859-5" },
+    { "ISO8859-6",   "ISO-8859-6" },
+    { "ISO8859-7",   "ISO-8859-7" },
+    { "ISO8859-8",   "ISO-8859-8" },
+    { "ISO8859-9",   "ISO-8859-9" },
+    { "PCK",         "SHIFT_JIS" },
+    { "TIS620.2533", "TIS-620" },
+    { "UTF-8",       "UTF-8" },
+    { "ansi-1251",   "CP1251" },
+    { "cns11643",    "EUC-TW" },
+    { "eucJP",       "EUC-JP" },
+    { "gb2312",      "GB2312" },
+    { "koi8-r",      "KOI8-R" }
+#   define alias_table_defined
+#  endif
+#  if defined WINDOWS_NATIVE || defined __CYGWIN__          /* Windows */
+    { "CP1361",  "JOHAB" },
+    { "CP20127", "ASCII" },
+    { "CP20866", "KOI8-R" },
+    { "CP20936", "GB2312" },
+    { "CP21866", "KOI8-RU" },
+    { "CP28591", "ISO-8859-1" },
+    { "CP28592", "ISO-8859-2" },
+    { "CP28593", "ISO-8859-3" },
+    { "CP28594", "ISO-8859-4" },
+    { "CP28595", "ISO-8859-5" },
+    { "CP28596", "ISO-8859-6" },
+    { "CP28597", "ISO-8859-7" },
+    { "CP28598", "ISO-8859-8" },
+    { "CP28599", "ISO-8859-9" },
+    { "CP28605", "ISO-8859-15" },
+    { "CP38598", "ISO-8859-8" },
+    { "CP51932", "EUC-JP" },
+    { "CP51936", "GB2312" },
+    { "CP51949", "EUC-KR" },
+    { "CP51950", "EUC-TW" },
+    { "CP54936", "GB18030" },
+    { "CP65001", "UTF-8" },
+    { "CP936",   "GBK" }
+#   define alias_table_defined
+#  endif
+#  if defined OS2                                           /* OS/2 */
+    /* The list of encodings is taken from "List of OS/2 Codepages"
+       by Alex Taylor:
+       <http://altsan.org/os2/toolkits/uls/index.html#codepages>.
+       See also "IBM Globalization - Code page identifiers":
+       <https://www-01.ibm.com/software/globalization/cp/cp_cpgid.html>.  */
+    { "CP1089", "ISO-8859-6" },
+    { "CP1208", "UTF-8" },
+    { "CP1381", "GB2312" },
+    { "CP1386", "GBK" },
+    { "CP3372", "EUC-JP" },
+    { "CP813",  "ISO-8859-7" },
+    { "CP819",  "ISO-8859-1" },
+    { "CP878",  "KOI8-R" },
+    { "CP912",  "ISO-8859-2" },
+    { "CP913",  "ISO-8859-3" },
+    { "CP914",  "ISO-8859-4" },
+    { "CP915",  "ISO-8859-5" },
+    { "CP916",  "ISO-8859-8" },
+    { "CP920",  "ISO-8859-9" },
+    { "CP921",  "ISO-8859-13" },
+    { "CP923",  "ISO-8859-15" },
+    { "CP954",  "EUC-JP" },
+    { "CP964",  "EUC-TW" },
+    { "CP970",  "EUC-KR" }
+#   define alias_table_defined
+#  endif
+#  if defined VMS                                           /* OpenVMS */
+    /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
+       "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
+       section 10.7 "Handling Different Character Sets".  */
+    { "DECHANYU",  "DEC-HANYU" },
+    { "DECHANZI",  "GB2312" },
+    { "DECKANJI",  "DEC-KANJI" },
+    { "DECKOREAN", "EUC-KR" },
+    { "ISO8859-1", "ISO-8859-1" },
+    { "ISO8859-2", "ISO-8859-2" },
+    { "ISO8859-5", "ISO-8859-5" },
+    { "ISO8859-7", "ISO-8859-7" },
+    { "ISO8859-8", "ISO-8859-8" },
+    { "ISO8859-9", "ISO-8859-9" },
+    { "SDECKANJI", "EUC-JP" },
+    { "SJIS",      "SHIFT_JIS" },
+    { "eucJP",     "EUC-JP" },
+    { "eucTW",     "EUC-TW" }
+#   define alias_table_defined
+#  endif
+#  ifndef alias_table_defined
+    /* Just a dummy entry, to avoid a C syntax error.  */
+    { "", "" }
+#  endif
+  };
 
-                      c = getc (fp);
-                      if (c == EOF)
-                        break;
-                      if (c == '\n' || c == ' ' || c == '\t')
-                        continue;
-                      if (c == '#')
-                        {
-                          /* Skip comment, to end of line.  */
-                          do
-                            c = getc (fp);
-                          while (!(c == EOF || c == '\n'));
-                          if (c == EOF)
-                            break;
-                          continue;
-                        }
-                      ungetc (c, fp);
-                      if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
-                        break;
-                      l1 = strlen (buf1);
-                      l2 = strlen (buf2);
-                      old_res_ptr = res_ptr;
-                      if (res_size == 0)
-                        {
-                          res_size = l1 + 1 + l2 + 1;
-                          res_ptr = (char *) malloc (res_size + 1);
-                        }
-                      else
-                        {
-                          res_size += l1 + 1 + l2 + 1;
-                          res_ptr = (char *) realloc (res_ptr, res_size + 1);
-                        }
-                      if (res_ptr == NULL)
-                        {
-                          /* Out of memory. */
-                          res_size = 0;
-                          free (old_res_ptr);
-                          break;
-                        }
-                      strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
-                      strcpy (res_ptr + res_size - (l2 + 1), buf2);
-                    }
-                  fclose (fp);
-                  if (res_size == 0)
-                    cp = "";
-                  else
-                    {
-                      *(res_ptr + res_size) = '\0';
-                      cp = res_ptr;
-                    }
-                }
-            }
-
-          free (file_name);
-        }
+# endif
 
 #else
 
-# if defined DARWIN7
-      /* To avoid the trouble of installing a file that is shared by many
-         GNU packages -- many packaging systems have problems with this --,
-         simply inline the aliases here.
-         For speed, map the most frequent case first.  */
-      cp = "UTF-8" "\0" "UTF-8" "\0"
-           "ISO8859-1" "\0" "ISO-8859-1" "\0"
-           "ISO8859-2" "\0" "ISO-8859-2" "\0"
-           "ISO8859-4" "\0" "ISO-8859-4" "\0"
-           "ISO8859-5" "\0" "ISO-8859-5" "\0"
-           "ISO8859-7" "\0" "ISO-8859-7" "\0"
-           "ISO8859-9" "\0" "ISO-8859-9" "\0"
-           "ISO8859-13" "\0" "ISO-8859-13" "\0"
-           "ISO8859-15" "\0" "ISO-8859-15" "\0"
-           "KOI8-R" "\0" "KOI8-R" "\0"
-           "KOI8-U" "\0" "KOI8-U" "\0"
-           "CP866" "\0" "CP866" "\0"
-           "CP949" "\0" "CP949" "\0"
-           "CP1131" "\0" "CP1131" "\0"
-           "CP1251" "\0" "CP1251" "\0"
-           "eucCN" "\0" "GB2312" "\0"
-           "GB2312" "\0" "GB2312" "\0"
-           "eucJP" "\0" "EUC-JP" "\0"
-           "eucKR" "\0" "EUC-KR" "\0"
-           "Big5" "\0" "BIG5" "\0"
-           "Big5HKSCS" "\0" "BIG5-HKSCS" "\0"
-           "GBK" "\0" "GBK" "\0"
-           "GB18030" "\0" "GB18030" "\0"
-           "SJIS" "\0" "SHIFT_JIS" "\0"
-           "ARMSCII-8" "\0" "ARMSCII-8" "\0"
-           "PT154" "\0" "PT154" "\0"
-         /*"ISCII-DEV" "\0" "?" "\0"*/
-           "*" "\0" "UTF-8" "\0";
-# endif
+/* On these platforms, we use a mapping from locale name to GNU canonical
+   encoding name.  */
 
-# if defined VMS
-      /* To avoid the troubles of an extra file charset.alias_vms in the
-         sources of many GNU packages, simply inline the aliases here.  */
-      /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
-         "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
-         section 10.7 "Handling Different Character Sets".  */
-      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
-           "ISO8859-2" "\0" "ISO-8859-2" "\0"
-           "ISO8859-5" "\0" "ISO-8859-5" "\0"
-           "ISO8859-7" "\0" "ISO-8859-7" "\0"
-           "ISO8859-8" "\0" "ISO-8859-8" "\0"
-           "ISO8859-9" "\0" "ISO-8859-9" "\0"
-           /* Japanese */
-           "eucJP" "\0" "EUC-JP" "\0"
-           "SJIS" "\0" "SHIFT_JIS" "\0"
-           "DECKANJI" "\0" "DEC-KANJI" "\0"
-           "SDECKANJI" "\0" "EUC-JP" "\0"
-           /* Chinese */
-           "eucTW" "\0" "EUC-TW" "\0"
-           "DECHANYU" "\0" "DEC-HANYU" "\0"
-           "DECHANZI" "\0" "GB2312" "\0"
-           /* Korean */
-           "DECKOREAN" "\0" "EUC-KR" "\0";
-# endif
+struct table_entry
+{
+  const char locale[17+1];
+  const char canonical[11+1];
+};
 
-# if defined WINDOWS_NATIVE || defined __CYGWIN__
-      /* To avoid the troubles of installing a separate file in the same
-         directory as the DLL and of retrieving the DLL's directory at
-         runtime, simply inline the aliases here.  */
-
-      cp = "CP936" "\0" "GBK" "\0"
-           "CP1361" "\0" "JOHAB" "\0"
-           "CP20127" "\0" "ASCII" "\0"
-           "CP20866" "\0" "KOI8-R" "\0"
-           "CP20936" "\0" "GB2312" "\0"
-           "CP21866" "\0" "KOI8-RU" "\0"
-           "CP28591" "\0" "ISO-8859-1" "\0"
-           "CP28592" "\0" "ISO-8859-2" "\0"
-           "CP28593" "\0" "ISO-8859-3" "\0"
-           "CP28594" "\0" "ISO-8859-4" "\0"
-           "CP28595" "\0" "ISO-8859-5" "\0"
-           "CP28596" "\0" "ISO-8859-6" "\0"
-           "CP28597" "\0" "ISO-8859-7" "\0"
-           "CP28598" "\0" "ISO-8859-8" "\0"
-           "CP28599" "\0" "ISO-8859-9" "\0"
-           "CP28605" "\0" "ISO-8859-15" "\0"
-           "CP38598" "\0" "ISO-8859-8" "\0"
-           "CP51932" "\0" "EUC-JP" "\0"
-           "CP51936" "\0" "GB2312" "\0"
-           "CP51949" "\0" "EUC-KR" "\0"
-           "CP51950" "\0" "EUC-TW" "\0"
-           "CP54936" "\0" "GB18030" "\0"
-           "CP65001" "\0" "UTF-8" "\0";
+/* Table of platform-dependent mappings, sorted in ascending order.  */
+static const struct table_entry locale_table[] =
+  {
+# if defined __FreeBSD__                                    /* FreeBSD 4.2 */
+    { "cs_CZ.ISO_8859-2",  "ISO-8859-2" },
+    { "da_DK.DIS_8859-15", "ISO-8859-15" },
+    { "da_DK.ISO_8859-1",  "ISO-8859-1" },
+    { "de_AT.DIS_8859-15", "ISO-8859-15" },
+    { "de_AT.ISO_8859-1",  "ISO-8859-1" },
+    { "de_CH.DIS_8859-15", "ISO-8859-15" },
+    { "de_CH.ISO_8859-1",  "ISO-8859-1" },
+    { "de_DE.DIS_8859-15", "ISO-8859-15" },
+    { "de_DE.ISO_8859-1",  "ISO-8859-1" },
+    { "en_AU.DIS_8859-15", "ISO-8859-15" },
+    { "en_AU.ISO_8859-1",  "ISO-8859-1" },
+    { "en_CA.DIS_8859-15", "ISO-8859-15" },
+    { "en_CA.ISO_8859-1",  "ISO-8859-1" },
+    { "en_GB.DIS_8859-15", "ISO-8859-15" },
+    { "en_GB.ISO_8859-1",  "ISO-8859-1" },
+    { "en_US.DIS_8859-15", "ISO-8859-15" },
+    { "en_US.ISO_8859-1",  "ISO-8859-1" },
+    { "es_ES.DIS_8859-15", "ISO-8859-15" },
+    { "es_ES.ISO_8859-1",  "ISO-8859-1" },
+    { "fi_FI.DIS_8859-15", "ISO-8859-15" },
+    { "fi_FI.ISO_8859-1",  "ISO-8859-1" },
+    { "fr_BE.DIS_8859-15", "ISO-8859-15" },
+    { "fr_BE.ISO_8859-1",  "ISO-8859-1" },
+    { "fr_CA.DIS_8859-15", "ISO-8859-15" },
+    { "fr_CA.ISO_8859-1",  "ISO-8859-1" },
+    { "fr_CH.DIS_8859-15", "ISO-8859-15" },
+    { "fr_CH.ISO_8859-1",  "ISO-8859-1" },
+    { "fr_FR.DIS_8859-15", "ISO-8859-15" },
+    { "fr_FR.ISO_8859-1",  "ISO-8859-1" },
+    { "hr_HR.ISO_8859-2",  "ISO-8859-2" },
+    { "hu_HU.ISO_8859-2",  "ISO-8859-2" },
+    { "is_IS.DIS_8859-15", "ISO-8859-15" },
+    { "is_IS.ISO_8859-1",  "ISO-8859-1" },
+    { "it_CH.DIS_8859-15", "ISO-8859-15" },
+    { "it_CH.ISO_8859-1",  "ISO-8859-1" },
+    { "it_IT.DIS_8859-15", "ISO-8859-15" },
+    { "it_IT.ISO_8859-1",  "ISO-8859-1" },
+    { "ja_JP.EUC",         "EUC-JP" },
+    { "ja_JP.SJIS",        "SHIFT_JIS" },
+    { "ja_JP.Shift_JIS",   "SHIFT_JIS" },
+    { "ko_KR.EUC",         "EUC-KR" },
+    { "la_LN.ASCII",       "ASCII" },
+    { "la_LN.DIS_8859-15", "ISO-8859-15" },
+    { "la_LN.ISO_8859-1",  "ISO-8859-1" },
+    { "la_LN.ISO_8859-2",  "ISO-8859-2" },
+    { "la_LN.ISO_8859-4",  "ISO-8859-4" },
+    { "lt_LN.ASCII",       "ASCII" },
+    { "lt_LN.DIS_8859-15", "ISO-8859-15" },
+    { "lt_LN.ISO_8859-1",  "ISO-8859-1" },
+    { "lt_LN.ISO_8859-2",  "ISO-8859-2" },
+    { "lt_LT.ISO_8859-4",  "ISO-8859-4" },
+    { "nl_BE.DIS_8859-15", "ISO-8859-15" },
+    { "nl_BE.ISO_8859-1",  "ISO-8859-1" },
+    { "nl_NL.DIS_8859-15", "ISO-8859-15" },
+    { "nl_NL.ISO_8859-1",  "ISO-8859-1" },
+    { "no_NO.DIS_8859-15", "ISO-8859-15" },
+    { "no_NO.ISO_8859-1",  "ISO-8859-1" },
+    { "pl_PL.ISO_8859-2",  "ISO-8859-2" },
+    { "pt_PT.DIS_8859-15", "ISO-8859-15" },
+    { "pt_PT.ISO_8859-1",  "ISO-8859-1" },
+    { "ru_RU.CP866",       "CP866" },
+    { "ru_RU.ISO_8859-5",  "ISO-8859-5" },
+    { "ru_RU.KOI8-R",      "KOI8-R" },
+    { "ru_SU.CP866",       "CP866" },
+    { "ru_SU.ISO_8859-5",  "ISO-8859-5" },
+    { "ru_SU.KOI8-R",      "KOI8-R" },
+    { "sl_SI.ISO_8859-2",  "ISO-8859-2" },
+    { "sv_SE.DIS_8859-15", "ISO-8859-15" },
+    { "sv_SE.ISO_8859-1",  "ISO-8859-1" },
+    { "uk_UA.KOI8-U",      "KOI8-U" },
+    { "zh_CN.EUC",         "GB2312" },
+    { "zh_TW.BIG5",        "BIG5" },
+    { "zh_TW.Big5",        "BIG5" }
+#  define locale_table_defined
 # endif
-# if defined OS2
-      /* To avoid the troubles of installing a separate file in the same
-         directory as the DLL and of retrieving the DLL's directory at
-         runtime, simply inline the aliases here.  */
+# if defined __DJGPP__                                      /* DOS / DJGPP 2.03 */
+    /* The encodings given here may not all be correct.
+       If you find that the encoding given for your language and
+       country is not the one your DOS machine actually uses, just
+       correct it in this file, and send a mail to
+       Juan Manuel Guerrero <juan.guerrero@gmx.de>
+       and <bug-gnulib@gnu.org>.  */
+    { "C",     "ASCII" },
+    { "ar",    "CP864" },
+    { "ar_AE", "CP864" },
+    { "ar_DZ", "CP864" },
+    { "ar_EG", "CP864" },
+    { "ar_IQ", "CP864" },
+    { "ar_IR", "CP864" },
+    { "ar_JO", "CP864" },
+    { "ar_KW", "CP864" },
+    { "ar_MA", "CP864" },
+    { "ar_OM", "CP864" },
+    { "ar_QA", "CP864" },
+    { "ar_SA", "CP864" },
+    { "ar_SY", "CP864" },
+    { "be",    "CP866" },
+    { "be_BE", "CP866" },
+    { "bg",    "CP866" }, /* not CP855 ?? */
+    { "bg_BG", "CP866" }, /* not CP855 ?? */
+    { "ca",    "CP850" },
+    { "ca_ES", "CP850" },
+    { "cs",    "CP852" },
+    { "cs_CZ", "CP852" },
+    { "da",    "CP865" }, /* not CP850 ?? */
+    { "da_DK", "CP865" }, /* not CP850 ?? */
+    { "de",    "CP850" },
+    { "de_AT", "CP850" },
+    { "de_CH", "CP850" },
+    { "de_DE", "CP850" },
+    { "el",    "CP869" },
+    { "el_GR", "CP869" },
+    { "en",    "CP850" },
+    { "en_AU", "CP850" }, /* not CP437 ?? */
+    { "en_CA", "CP850" },
+    { "en_GB", "CP850" },
+    { "en_NZ", "CP437" },
+    { "en_US", "CP437" },
+    { "en_ZA", "CP850" }, /* not CP437 ?? */
+    { "eo",    "CP850" },
+    { "eo_EO", "CP850" },
+    { "es",    "CP850" },
+    { "es_AR", "CP850" },
+    { "es_BO", "CP850" },
+    { "es_CL", "CP850" },
+    { "es_CO", "CP850" },
+    { "es_CR", "CP850" },
+    { "es_CU", "CP850" },
+    { "es_DO", "CP850" },
+    { "es_EC", "CP850" },
+    { "es_ES", "CP850" },
+    { "es_GT", "CP850" },
+    { "es_HN", "CP850" },
+    { "es_MX", "CP850" },
+    { "es_NI", "CP850" },
+    { "es_PA", "CP850" },
+    { "es_PE", "CP850" },
+    { "es_PY", "CP850" },
+    { "es_SV", "CP850" },
+    { "es_UY", "CP850" },
+    { "es_VE", "CP850" },
+    { "et",    "CP850" },
+    { "et_EE", "CP850" },
+    { "eu",    "CP850" },
+    { "eu_ES", "CP850" },
+    { "fi",    "CP850" },
+    { "fi_FI", "CP850" },
+    { "fr",    "CP850" },
+    { "fr_BE", "CP850" },
+    { "fr_CA", "CP850" },
+    { "fr_CH", "CP850" },
+    { "fr_FR", "CP850" },
+    { "ga",    "CP850" },
+    { "ga_IE", "CP850" },
+    { "gd",    "CP850" },
+    { "gd_GB", "CP850" },
+    { "gl",    "CP850" },
+    { "gl_ES", "CP850" },
+    { "he",    "CP862" },
+    { "he_IL", "CP862" },
+    { "hr",    "CP852" },
+    { "hr_HR", "CP852" },
+    { "hu",    "CP852" },
+    { "hu_HU", "CP852" },
+    { "id",    "CP850" }, /* not CP437 ?? */
+    { "id_ID", "CP850" }, /* not CP437 ?? */
+    { "is",    "CP861" }, /* not CP850 ?? */
+    { "is_IS", "CP861" }, /* not CP850 ?? */
+    { "it",    "CP850" },
+    { "it_CH", "CP850" },
+    { "it_IT", "CP850" },
+    { "ja",    "CP932" },
+    { "ja_JP", "CP932" },
+    { "kr",    "CP949" }, /* not CP934 ?? */
+    { "kr_KR", "CP949" }, /* not CP934 ?? */
+    { "lt",    "CP775" },
+    { "lt_LT", "CP775" },
+    { "lv",    "CP775" },
+    { "lv_LV", "CP775" },
+    { "mk",    "CP866" }, /* not CP855 ?? */
+    { "mk_MK", "CP866" }, /* not CP855 ?? */
+    { "mt",    "CP850" },
+    { "mt_MT", "CP850" },
+    { "nb",    "CP865" }, /* not CP850 ?? */
+    { "nb_NO", "CP865" }, /* not CP850 ?? */
+    { "nl",    "CP850" },
+    { "nl_BE", "CP850" },
+    { "nl_NL", "CP850" },
+    { "nn",    "CP865" }, /* not CP850 ?? */
+    { "nn_NO", "CP865" }, /* not CP850 ?? */
+    { "no",    "CP865" }, /* not CP850 ?? */
+    { "no_NO", "CP865" }, /* not CP850 ?? */
+    { "pl",    "CP852" },
+    { "pl_PL", "CP852" },
+    { "pt",    "CP850" },
+    { "pt_BR", "CP850" },
+    { "pt_PT", "CP850" },
+    { "ro",    "CP852" },
+    { "ro_RO", "CP852" },
+    { "ru",    "CP866" },
+    { "ru_RU", "CP866" },
+    { "sk",    "CP852" },
+    { "sk_SK", "CP852" },
+    { "sl",    "CP852" },
+    { "sl_SI", "CP852" },
+    { "sq",    "CP852" },
+    { "sq_AL", "CP852" },
+    { "sr",    "CP852" }, /* CP852 or CP866 or CP855 ?? */
+    { "sr_CS", "CP852" }, /* CP852 or CP866 or CP855 ?? */
+    { "sr_YU", "CP852" }, /* CP852 or CP866 or CP855 ?? */
+    { "sv",    "CP850" },
+    { "sv_SE", "CP850" },
+    { "th",    "CP874" },
+    { "th_TH", "CP874" },
+    { "tr",    "CP857" },
+    { "tr_TR", "CP857" },
+    { "uk",    "CP1125" },
+    { "uk_UA", "CP1125" },
+    { "zh_CN", "GBK" },
+    { "zh_TW", "CP950" } /* not CP938 ?? */
+#  define locale_table_defined
+# endif
+# ifndef locale_table_defined
+    /* Just a dummy entry, to avoid a C syntax error.  */
+    { "", "" }
+# endif
+  };
 
-      /* The list of encodings is taken from "List of OS/2 Codepages"
-         by Alex Taylor:
-         <http://altsan.org/os2/toolkits/uls/index.html#codepages>.
-         See also "IBM Globalization - Code page identifiers":
-         <https://www-01.ibm.com/software/globalization/cp/cp_cpgid.html>.  */
-      cp = "CP813" "\0" "ISO-8859-7" "\0"
-           "CP878" "\0" "KOI8-R" "\0"
-           "CP819" "\0" "ISO-8859-1" "\0"
-           "CP912" "\0" "ISO-8859-2" "\0"
-           "CP913" "\0" "ISO-8859-3" "\0"
-           "CP914" "\0" "ISO-8859-4" "\0"
-           "CP915" "\0" "ISO-8859-5" "\0"
-           "CP916" "\0" "ISO-8859-8" "\0"
-           "CP920" "\0" "ISO-8859-9" "\0"
-           "CP921" "\0" "ISO-8859-13" "\0"
-           "CP923" "\0" "ISO-8859-15" "\0"
-           "CP954" "\0" "EUC-JP" "\0"
-           "CP964" "\0" "EUC-TW" "\0"
-           "CP970" "\0" "EUC-KR" "\0"
-           "CP1089" "\0" "ISO-8859-6" "\0"
-           "CP1208" "\0" "UTF-8" "\0"
-           "CP1381" "\0" "GB2312" "\0"
-           "CP1386" "\0" "GBK" "\0"
-           "CP3372" "\0" "EUC-JP" "\0";
-# endif
 #endif
 
-      charset_aliases = cp;
-    }
-
-  return cp;
-}
 
 /* Determine the current locale's character encoding, and canonicalize it
-   into one of the canonical names listed in config.charset.
+   into one of the canonical names listed in localcharset.h.
    The result must not be freed; it is statically allocated.
    If the canonical name cannot be determined, the result is a non-canonical
    name.  */
@@ -399,9 +643,8 @@
 locale_charset (void)
 {
   const char *codeset;
-  const char *aliases;
 
-#if !(defined WINDOWS_NATIVE || defined OS2)
+#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2
 
 # if HAVE_LANGINFO_CODESET
 
@@ -464,37 +707,11 @@
     }
 #  endif
 
-# else
-
-  /* On old systems which lack it, use setlocale or getenv.  */
-  const char *locale = NULL;
+  if (codeset == NULL)
+    /* The canonical name cannot be determined.  */
+    codeset = "";
 
-  /* But most old systems don't have a complete set of locales.  Some
-     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
-     use setlocale here; it would return "C" when it doesn't support the
-     locale name the user has set.  */
-#  if 0
-  locale = setlocale (LC_CTYPE, NULL);
-#  endif
-  if (locale == NULL || locale[0] == '\0')
-    {
-      locale = getenv ("LC_ALL");
-      if (locale == NULL || locale[0] == '\0')
-        {
-          locale = getenv ("LC_CTYPE");
-          if (locale == NULL || locale[0] == '\0')
-            locale = getenv ("LANG");
-        }
-    }
-
-  /* On some old systems, one used to set locale = "iso8859_1". On others,
-     you set it to "language_COUNTRY.charset". In any case, we resolve it
-     through the charset.alias file.  */
-  codeset = locale;
-
-# endif
-
-#elif defined WINDOWS_NATIVE
+# elif defined WINDOWS_NATIVE
 
   static char buf[2 + 10 + 1];
 
@@ -528,7 +745,7 @@
     }
   codeset = buf;
 
-#elif defined OS2
+# elif defined OS2
 
   const char *locale;
   static char buf[2 + 10 + 1];
@@ -585,28 +802,144 @@
         }
     }
 
-#endif
+# else
+
+#  error "Add code for other platforms here."
+
+# endif
 
-  if (codeset == NULL)
-    /* The canonical name cannot be determined.  */
-    codeset = "";
+  /* Resolve alias.  */
+  {
+# ifdef alias_table_defined
+    /* On some platforms, UTF-8 locales are the most frequently used ones.
+       Speed up the common case and slow down the less common cases by
+       testing for this case first.  */
+#  if defined __OpenBSD__ || (defined __APPLE__ && defined __MACH__) || defined __sun || defined __CYGWIN__
+    if (strcmp (codeset, "UTF-8") == 0)
+      goto done_table_lookup;
+    else
+#  endif
+      {
+        const struct table_entry * const table = alias_table;
+        size_t const table_size =
+          sizeof (alias_table) / sizeof (struct table_entry);
+        /* The table is sorted.  Perform a binary search.  */
+        size_t hi = table_size;
+        size_t lo = 0;
+        while (lo < hi)
+          {
+            /* Invariant:
+               for i < lo, strcmp (table[i].alias, codeset) < 0,
+               for i >= hi, strcmp (table[i].alias, codeset) > 0.  */
+            size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
+            int cmp = strcmp (table[mid].alias, codeset);
+            if (cmp < 0)
+              lo = mid + 1;
+            else if (cmp > 0)
+              hi = mid;
+            else
+              {
+                /* Found an i with
+                     strcmp (table[i].alias, codeset) == 0.  */
+                codeset = table[mid].canonical;
+                goto done_table_lookup;
+              }
+          }
+      }
+    if (0)
+      done_table_lookup: ;
+    else
+# endif
+      {
+        /* Did not find it in the table.  */
+        /* On Mac OS X, all modern locales use the UTF-8 encoding.
+           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */
+# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__
+        codeset = "UTF-8";
+# else
+        /* Don't return an empty string.  GNU libc and GNU libiconv interpret
+           the empty string as denoting "the locale's character encoding",
+           thus GNU libiconv would call this function a second time.  */
+        if (codeset[0] == '\0')
+          codeset = "ASCII";
+# endif
+      }
+  }
+
+#else
+
+  /* On old systems which lack it, use setlocale or getenv.  */
+  const char *locale = NULL;
 
-  /* Resolve alias. */
-  for (aliases = get_charset_aliases ();
-       *aliases != '\0';
-       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
-    if (strcmp (codeset, aliases) == 0
-        || (aliases[0] == '*' && aliases[1] == '\0'))
+  /* But most old systems don't have a complete set of locales.  Some
+     (like DJGPP) have only the C locale.  Therefore we don't use setlocale
+     here; it would return "C" when it doesn't support the locale name the
+     user has set.  */
+# if 0
+  locale = setlocale (LC_CTYPE, NULL);
+# endif
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_ALL");
+      if (locale == NULL || locale[0] == '\0')
+        {
+          locale = getenv ("LC_CTYPE");
+          if (locale == NULL || locale[0] == '\0')
+            locale = getenv ("LANG");
+            if (locale == NULL)
+              locale = "";
+        }
+    }
+
+  /* Map locale name to canonical encoding name.  */
+  {
+# ifdef locale_table_defined
+    const struct table_entry * const table = locale_table;
+    size_t const table_size =
+      sizeof (locale_table) / sizeof (struct table_entry);
+    /* The table is sorted.  Perform a binary search.  */
+    size_t hi = table_size;
+    size_t lo = 0;
+    while (lo < hi)
       {
-        codeset = aliases + strlen (aliases) + 1;
-        break;
+        /* Invariant:
+           for i < lo, strcmp (table[i].locale, locale) < 0,
+           for i >= hi, strcmp (table[i].locale, locale) > 0.  */
+        size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
+        int cmp = strcmp (table[mid].locale, locale);
+        if (cmp < 0)
+          lo = mid + 1;
+        else if (cmp > 0)
+          hi = mid;
+        else
+          {
+            /* Found an i with
+                 strcmp (table[i].locale, locale) == 0.  */
+            codeset = table[mid].canonical;
+            goto done_table_lookup;
+          }
       }
+    if (0)
+      done_table_lookup: ;
+    else
+# endif
+      {
+        /* Did not find it in the table.  */
+        /* On Mac OS X, all modern locales use the UTF-8 encoding.
+           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */
+# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__
+        codeset = "UTF-8";
+# else
+        /* The canonical name cannot be determined.  */
+        /* Don't return an empty string.  GNU libc and GNU libiconv interpret
+           the empty string as denoting "the locale's character encoding",
+           thus GNU libiconv would call this function a second time.  */
+        codeset = "ASCII";
+# endif
+      }
+  }
 
-  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
-     the empty string as denoting "the locale's character encoding",
-     thus GNU libiconv would call this function a second time.  */
-  if (codeset[0] == '\0')
-    codeset = "ASCII";
+#endif
 
 #ifdef DARWIN7
   /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8"
--- a/lib/localcharset.h	Sat May 19 17:07:34 2018 +0200
+++ b/lib/localcharset.h	Sat May 19 17:17:32 2018 +0200
@@ -25,12 +25,106 @@
 
 
 /* Determine the current locale's character encoding, and canonicalize it
-   into one of the canonical names listed in config.charset.
+   into one of the canonical names listed below.
    The result must not be freed; it is statically allocated.
    If the canonical name cannot be determined, the result is a non-canonical
    name.  */
 extern const char * locale_charset (void);
 
+/* About GNU canonical names for character encodings:
+
+   Every canonical name must be supported by GNU libiconv.  Support by GNU libc
+   is also desirable.
+
+   The name is case insensitive.  Usually an upper case MIME charset name is
+   preferred.
+
+   The current list of these GNU canonical names is:
+
+       name              MIME?             used by which systems
+                                    (darwin = Mac OS X, windows = native Windows)
+
+   ASCII, ANSI_X3.4-1968       glibc solaris freebsd netbsd darwin cygwin
+   ISO-8859-1              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+   ISO-8859-2              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+   ISO-8859-3              Y   glibc solaris cygwin
+   ISO-8859-4              Y   osf solaris freebsd netbsd openbsd darwin
+   ISO-8859-5              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+   ISO-8859-6              Y   glibc aix hpux solaris cygwin
+   ISO-8859-7              Y   glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin
+   ISO-8859-8              Y   glibc aix hpux osf solaris cygwin
+   ISO-8859-9              Y   glibc aix hpux irix osf solaris darwin cygwin
+   ISO-8859-13                 glibc netbsd openbsd darwin cygwin
+   ISO-8859-14                 glibc cygwin
+   ISO-8859-15                 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin
+   KOI8-R                  Y   glibc solaris freebsd netbsd openbsd darwin
+   KOI8-U                  Y   glibc freebsd netbsd openbsd darwin cygwin
+   KOI8-T                      glibc
+   CP437                       dos
+   CP775                       dos
+   CP850                       aix osf dos
+   CP852                       dos
+   CP855                       dos
+   CP856                       aix
+   CP857                       dos
+   CP861                       dos
+   CP862                       dos
+   CP864                       dos
+   CP865                       dos
+   CP866                       freebsd netbsd openbsd darwin dos
+   CP869                       dos
+   CP874                       windows dos
+   CP922                       aix
+   CP932                       aix cygwin windows dos
+   CP943                       aix
+   CP949                       osf darwin windows dos
+   CP950                       windows dos
+   CP1046                      aix
+   CP1124                      aix
+   CP1125                      dos
+   CP1129                      aix
+   CP1131                      darwin
+   CP1250                      windows
+   CP1251                      glibc solaris netbsd openbsd darwin cygwin windows
+   CP1252                      aix windows
+   CP1253                      windows
+   CP1254                      windows
+   CP1255                      glibc windows
+   CP1256                      windows
+   CP1257                      windows
+   GB2312                  Y   glibc aix hpux irix solaris freebsd netbsd darwin
+   EUC-JP                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+   EUC-KR                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin
+   EUC-TW                      glibc aix hpux irix osf solaris netbsd
+   BIG5                    Y   glibc aix hpux osf solaris freebsd netbsd darwin cygwin
+   BIG5-HKSCS                  glibc solaris darwin
+   GBK                         glibc aix osf solaris darwin cygwin windows dos
+   GB18030                     glibc solaris netbsd darwin
+   SHIFT_JIS               Y   hpux osf solaris freebsd netbsd darwin
+   JOHAB                       glibc solaris windows
+   TIS-620                     glibc aix hpux osf solaris cygwin
+   VISCII                  Y   glibc
+   TCVN5712-1                  glibc
+   ARMSCII-8                   glibc darwin
+   GEORGIAN-PS                 glibc cygwin
+   PT154                       glibc
+   HP-ROMAN8                   hpux
+   HP-ARABIC8                  hpux
+   HP-GREEK8                   hpux
+   HP-HEBREW8                  hpux
+   HP-TURKISH8                 hpux
+   HP-KANA8                    hpux
+   DEC-KANJI                   osf
+   DEC-HANYU                   osf
+   UTF-8                   Y   glibc aix hpux osf solaris netbsd darwin cygwin
+
+   Note: Names which are not marked as being a MIME name should not be used in
+   Internet protocols for information interchange (mail, news, etc.).
+
+   Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names.  Applications
+   must understand both names and treat them as equivalent.
+ */
+
 
 #ifdef __cplusplus
 }
--- a/lib/ref-add.sin	Sat May 19 17:07:34 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-# Add this package to a list of references stored in a text file.
-#
-#   Copyright (C) 2000, 2009-2018 Free Software Foundation, Inc.
-#
-#   This program is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2, or (at your option)
-#   any later version.
-#
-#   This program is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License along
-#   with this program; if not, see <https://www.gnu.org/licenses/>.
-#
-# Written by Bruno Haible <haible@clisp.cons.org>.
-#
-/^# Packages using this file: / {
-  s/# Packages using this file://
-  ta
-  :a
-  s/ @PACKAGE@ / @PACKAGE@ /
-  tb
-  s/ $/ @PACKAGE@ /
-  :b
-  s/^/# Packages using this file:/
-}
--- a/lib/ref-del.sin	Sat May 19 17:07:34 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-# Remove this package from a list of references stored in a text file.
-#
-#   Copyright (C) 2000, 2009-2018 Free Software Foundation, Inc.
-#
-#   This program is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2, or (at your option)
-#   any later version.
-#
-#   This program is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License along
-#   with this program; if not, see <https://www.gnu.org/licenses/>.
-#
-# Written by Bruno Haible <haible@clisp.cons.org>.
-#
-/^# Packages using this file: / {
-  s/# Packages using this file://
-  s/ @PACKAGE@ / /
-  s/^/# Packages using this file:/
-}
--- a/m4/localcharset.m4	Sat May 19 17:07:34 2018 +0200
+++ b/m4/localcharset.m4	Sat May 19 17:17:32 2018 +0200
@@ -1,4 +1,4 @@
-# localcharset.m4 serial 7
+# localcharset.m4 serial 8
 dnl Copyright (C) 2002, 2004, 2006, 2009-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,10 +8,4 @@
 [
   dnl Prerequisites of lib/localcharset.c.
   AC_REQUIRE([AM_LANGINFO_CODESET])
-  AC_REQUIRE([gl_FCNTL_O_FLAGS])
-  AC_CHECK_DECLS_ONCE([getc_unlocked])
-
-  dnl Prerequisites of the lib/Makefile.am snippet.
-  AC_REQUIRE([AC_CANONICAL_HOST])
-  AC_REQUIRE([gl_GLIBC21])
 ])
--- a/modules/localcharset	Sat May 19 17:07:34 2018 +0200
+++ b/modules/localcharset	Sat May 19 17:17:32 2018 +0200
@@ -1,100 +1,23 @@
 Description:
 Return current locale's character encoding.
 
-Notice:
-If your package's tests make use of the locale_charset() function directly or
-indirectly, you may need to define the CHARSETALIASDIR environment variable,
-so that "make check" works before "make install". In Makefile.am syntax:
-TESTS_ENVIRONMENT += @LOCALCHARSET_TESTS_ENVIRONMENT@
-
 Files:
 lib/localcharset.h
 lib/localcharset.c
-lib/config.charset
-lib/ref-add.sin
-lib/ref-del.sin
 m4/codeset.m4
-m4/fcntl-o.m4
-m4/glibc21.m4
 m4/localcharset.m4
 
 Depends-on:
-configmake
 extensions
 
 configure.ac:
 gl_LOCALCHARSET
-LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\""
+dnl For backward compatibility. Some packages still use this.
+LOCALCHARSET_TESTS_ENVIRONMENT=
 AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
 
 Makefile.am:
-lib_SOURCES += localcharset.h localcharset.c
-
-# We need the following in order to install a simple file in $(libdir)
-# which is shared with other installed packages. We use a list of referencing
-# packages so that "make uninstall" will remove the file if and only if it
-# is not used by another installed package.
-# On systems with glibc-2.1 or newer, the file is redundant, therefore we
-# avoid installing it.
-
-all-local: charset.alias ref-add.sed ref-del.sed
-
-charset_alias = $(DESTDIR)$(libdir)/charset.alias
-charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
-install-exec-local: install-exec-localcharset
-install-exec-localcharset: all-local
-	if test $(GLIBC21) = no; then \
-	  case '$(host_os)' in \
-	    darwin[56]*) \
-	      need_charset_alias=true ;; \
-	    darwin* | cygwin* | mingw* | pw32* | cegcc*) \
-	      need_charset_alias=false ;; \
-	    *) \
-	      need_charset_alias=true ;; \
-	  esac ; \
-	else \
-	  need_charset_alias=false ; \
-	fi ; \
-	if $$need_charset_alias; then \
-	  $(mkinstalldirs) $(DESTDIR)$(libdir) ; \
-	fi ; \
-	if test -f $(charset_alias); then \
-	  sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \
-	  $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
-	  rm -f $(charset_tmp) ; \
-	else \
-	  if $$need_charset_alias; then \
-	    sed -f ref-add.sed charset.alias > $(charset_tmp) ; \
-	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
-	    rm -f $(charset_tmp) ; \
-	  fi ; \
-	fi
-
-uninstall-local: uninstall-localcharset
-uninstall-localcharset: all-local
-	if test -f $(charset_alias); then \
-	  sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \
-	  if grep '^# Packages using this file: $$' $(charset_tmp) \
-	      > /dev/null; then \
-	    rm -f $(charset_alias); \
-	  else \
-	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \
-	  fi; \
-	  rm -f $(charset_tmp); \
-	fi
-
-charset.alias: config.charset
-	$(AM_V_GEN)rm -f t-$@ $@ && \
-	$(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \
-	mv t-$@ $@
-
-SUFFIXES += .sed .sin
-.sin.sed:
-	$(AM_V_GEN)rm -f t-$@ $@ && \
-	sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \
-	mv t-$@ $@
-
-CLEANFILES += charset.alias ref-add.sed ref-del.sed
+lib_SOURCES += localcharset.c
 
 Include:
 "localcharset.h"