From: Bruno Haible Date: Fri, 16 Jun 2000 19:01:17 +0000 (+0000) Subject: Implementation of the locale_charset function. X-Git-Tag: v0.10.36~276 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abd5754eacd67b2c627a75d5ea574f0fbbdafbe2;p=thirdparty%2Fgettext.git Implementation of the locale_charset function. --- diff --git a/intl/ChangeLog b/intl/ChangeLog index c58e11f59..dd40f28cf 100644 --- a/intl/ChangeLog +++ b/intl/ChangeLog @@ -1,5 +1,16 @@ 2000-06-16 Bruno Haible + * Makefile.in (COMSRCS): Add localcharset.c. + (OBJECTS): Add localcharset.$lo. + (DEFS): Add -DLIBDIR. + (all-yes): Add charset.alias, ref-{add,del}.sed. + (.SUFFIXES): Add .sin and .sed. + (.sin.sed, charset.alias): New rules. + (install-exec, uninstall): Install/deinstall charset.alias. + * localcharset.c: New file, from fileutils-4.0u. + * config.charset: New file, from fileutils-4.0u. + * red-add.sin, ref-del.sin: New files, from fileutils-4.0u. + * intlh.inst.in (bind_textdomain_codeset): New declaration. * libgettext.h (bind_textdomain_codeset, bind_textdomain_codeset__): New declarations. diff --git a/intl/Makefile.in b/intl/Makefile.in index 8313aac7b..4e197144e 100644 --- a/intl/Makefile.in +++ b/intl/Makefile.in @@ -1,5 +1,5 @@ # Makefile for directory with message catalog handling in GNU NLS Utilities. -# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1995, 1996, 1997, 1998, 2000 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 @@ -51,7 +51,7 @@ YACC = @YACC@ -d YFLAGS = --name-prefix=__gettext DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \ --DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@ +-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" -DLIBDIR=\"$(libdir)\" @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ @@ -63,11 +63,12 @@ COMHDRS = gettext.h gettextP.h hash-string.h SOURCES = $(COMSRCS) intl-compat.c cat-compat.c COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ -explodename.c dcigettext.c dcngettext.c dngettext.c ngettext.c plural.y +explodename.c dcigettext.c dcngettext.c dngettext.c ngettext.c plural.y \ +localcharset.c OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ explodename.$lo dcigettext.$lo dcngettext.$lo dngettext.$lo ngettext.$lo \ -plural.$lo +plural.$lo localcharset.$lo CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo GETTOBJS = intl-compat.$lo DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ @@ -76,7 +77,7 @@ DISTFILES.normal = VERSION DISTFILES.gettext = libintl.glibc intlh.inst.in plural.c .SUFFIXES: -.SUFFIXES: .y .c .o .lo +.SUFFIXES: .y .c .o .lo .sin .sed .c.o: $(COMPILE) $< .c.lo: @@ -85,11 +86,15 @@ DISTFILES.gettext = libintl.glibc intlh.inst.in plural.c .y.c: $(YACC) $(YFLAGS) --output $@ $^ +.sin.sed: + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@ + mv t-$@ $@ + INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib all: all-@USE_INCLUDED_LIBINTL@ -all-yes: libintl.$la intlh.inst +all-yes: libintl.$la intlh.inst charset.alias ref-add.sed ref-del.sed all-no: libintl.a: $(OBJECTS) @@ -104,6 +109,10 @@ libintl.la: $(OBJECTS) ../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot cd ../po && $(MAKE) cat-id-tbl.$lo +charset.alias: config.charset + $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + mv t-$@ $@ + check: all # This installation goal is only used in GNU gettext. Packages which @@ -128,6 +137,20 @@ install-exec: all $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ else \ : ; \ + fi; \ + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(libdir); \ + else \ + $(top_srcdir)/mkinstalldirs $(libdir); \ + fi; \ + test -f $(libdir)/charset.alias && orig=$(libdir)/charset.alias \ + || orig=charset.alias; \ + sed -f ref-add.sed $$orig > $(libdir)/t-charset.alias; \ + $(INSTALL_DATA) $(libdir)/t-charset.alias $(libdir)/charset.alias; \ + rm -f $(libdir)/t-charset.alias; \ + else \ + : ; \ fi install-data: all if test "$(PACKAGE)" = "gettext"; then \ @@ -143,6 +166,18 @@ install-data: all done; \ else \ : ; \ + fi; \ + if test '@USE_INCLUDED_LIBINTL@' = yes \ + && test -f $(libdir)/charset.alias; then \ + sed -f ref-del.sed $(libdir)/charset.alias > $(libdir)/t-charset.alias; \ + if grep '^# Packages using this file: $$' $(libdir)/t-charset.alias > /dev/null; then \ + rm -f $(libdir)/t-charset.alias; \ + else \ + $(INSTALL_DATA) $(libdir)/t-charset.alias $(libdir)/charset.alias; \ + fi; \ + rm -f $(libdir)/t-charset.alias; \ + else \ + : ; \ fi # Define this as empty until I found a useful application. diff --git a/intl/config.charset b/intl/config.charset new file mode 100755 index 000000000..83f0b791e --- /dev/null +++ b/intl/config.charset @@ -0,0 +1,186 @@ +#! /bin/sh +# Output a system dependent table of character encoding aliases. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# +# 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 used by which systems a MIME name? +# ASCII, ANSI_X3.4-1968 glibc solaris +# ISO-8859-1 glibc aix hpux irix osf solaris yes +# ISO-8859-2 glibc aix hpux irix solaris yes +# ISO-8859-4 solaris yes +# ISO-8859-5 glibc aix hpux irix solaris yes +# ISO-8859-6 aix hpux solaris yes +# ISO-8859-7 glibc aix hpux irix osf solaris yes +# ISO-8859-8 glibc aix hpux solaris yes +# ISO-8859-9 glibc aix hpux irix osf solaris yes +# ISO-8859-13 glibc +# ISO-8859-15 aix solaris +# KOI8-R glibc solaris yes +# KOI8-U glibc yes +# CP850 aix osf +# CP856 aix +# CP922 aix +# CP932 aix +# CP943 aix +# CP1046 aix +# CP1124 aix +# CP1129 aix +# CP1252 aix +# EUC-CN aix hpux solaris +# EUC-JP aix hpux solaris yes +# EUC-KR aix hpux solaris yes +# EUC-TW aix hpux solaris +# BIG5 aix hpux solaris yes +# GBK aix +# SJIS hpux solaris +# TIS-620 aix hpux solaris +# HP-ROMAN8 hpux +# HP-ARABIC8 hpux +# HP-GREEK8 hpux +# HP-HEBREW8 hpux +# HP-TURKISH8 hpux +# HP-KANA8 hpux +# UTF-8 glibc aix hpux solaris yes +# +# 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. + # The following applies only to glibc-2.0.x and older libcs. + echo "ISO_646.IRV:1983 ASCII" + ;; + 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 EUC-CN" + 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 "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 EUC-CN" + #echo "ccdc ?" # what is this? + echo "SJIS SJIS" + 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" + ;; + osf*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "cp850 CP850" + ;; + solaris*) + 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-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 "BIG5 BIG5" + echo "gb2312 EUC-CN" + echo "cns11643 EUC-TW" + echo "5601 EUC-KR" + echo "eucJP EUC-JP" + echo "PCK SJIS" + echo "TIS620.2533 TIS-620" + #echo "sun_eu_greek ?" # what is this? + echo "UTF-8 UTF-8" + ;; +esac diff --git a/intl/localcharset.c b/intl/localcharset.c new file mode 100644 index 000000000..932473c5b --- /dev/null +++ b/intl/localcharset.c @@ -0,0 +1,228 @@ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Written by Bruno Haible . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if HAVE_STDDEF_H +# include +#endif + +#include +#if HAVE_STRING_H +# include +#else +# include +#endif +#if HAVE_STDLIB_H +# include +#endif + +#if HAVE_LANGINFO_CODESET +# include +#else +# if HAVE_SETLOCALE +# include +# endif +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +/* 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. */ +/* 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 char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +static const char * +get_charset_aliases () +{ + char *cp; + + cp = charset_aliases; + if (cp == NULL) + { + FILE *fp; + const char *dir = LIBDIR; + const char *base = "charset.alias"; + char *file_name; + + /* 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); + } + } + + if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) + /* Out of memory or file not found, treat it as empty. */ + cp = ""; + else + { + /* Parse the file's contents. */ + int c; + char buf1[50+1]; + char buf2[50+1]; + char *res_ptr = NULL; + size_t res_size = 0; + size_t l1, l2; + + for (;;) + { + 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); + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + 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; + } + } + + charset_aliases = cp; + if (file_name != NULL) + free (file_name); + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name or NULL. */ + +#ifdef STATIC +STATIC +#endif +const char * +locale_charset () +{ + const char *codeset; + const char *aliases; + +#if HAVE_LANGINFO_CODESET + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +#else + + /* On old systems which lack it, use setlocale and getenv. */ + const char *locale = NULL; + +# if HAVE_SETLOCALE + 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 + + if (codeset != NULL && codeset[0] != '\0') + { + /* Resolve alias. */ + for (aliases = get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (!strcmp (codeset, aliases)) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + } + + return codeset; +} diff --git a/intl/ref-add.sin b/intl/ref-add.sin new file mode 100644 index 000000000..167374e3c --- /dev/null +++ b/intl/ref-add.sin @@ -0,0 +1,31 @@ +# Add this package to a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + ta + :a + s/ @PACKAGE@ / @PACKAGE@ / + tb + s/ $/ @PACKAGE@ / + :b + s/^/# Packages using this file:/ +} diff --git a/intl/ref-del.sin b/intl/ref-del.sin new file mode 100644 index 000000000..613cf37f3 --- /dev/null +++ b/intl/ref-del.sin @@ -0,0 +1,26 @@ +# Remove this package from a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + s/ @PACKAGE@ / / + s/^/# Packages using this file:/ +}