aboutsummaryrefslogtreecommitdiff
path: root/intl
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-05-03 17:44:31 +0000
committerRoland McGrath <roland@gnu.org>1996-05-03 17:44:31 +0000
commit7a12c6bba750ca500009854db3a0fcdfb1ad61a7 (patch)
tree52654097781ee98deb03b41dd4f5a805bb9c9e30 /intl
parent9e720468715080bd95edadf10fd45a2c8be5e678 (diff)
downloadglibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.zip
glibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.tar.gz
glibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.tar.bz2
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>cvs/libc-960504
* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in LOCALE_ALIAS_PATH. Fri May 3 03:14:02 1996 Ulrich Drepper <drepper@cygnus.com> * intl/Makefile (routines): Add l10nflist and explodename. (distribute): Add loadinfo.h and locale.alias. (install-others): New variable to install locale.alias. * intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h, intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13. Some code is now shared with the locale implementation. * intl/explodename.c, intl/l10nflist.c, intl/loadinfo.h: New file. Extracted from finddomain.c. This is also used in the locale implementation. * intl/locale.alias: New file. Locale alias database compatible with X Window System's locale alias file. Can now be used in locale and gettext code. * libio/stdio.h: Add prototypes for asprint and vasprintf. * locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c, locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Add new field in structure with name of locale ("C" in this case). * locale/Makefile (routines): Add findlocale. * locale/findlocale.c: New file. Instead of trying to load the directly described file we now try to be much smarter when this fails. Use the same code as gettext does. * locale/loadlocale.c, locale/setlocale.c: Rewrite to know about new loading scheme. * locale/localeinfo.h: Adapt prototypes and declarations for new setlocale implementation. Remove definition of u32_t type. We now use u_int32_t from <sys/types.h>. * locale/programs/charset.h (ILLEGAL_CHAR_VALUE): Provide type with constant. * locale/programs/config.h, locale/lc-collate.c, locale/localeinfo.h, locale/programs/ld-collate.c, locale/programs/ld-ctype.c, locale/programs/ld-messages.c, locale/programs/ld-monetary.c, locale/programs/ld-numeric.c, locale/programs/ld-time.c, locale/weight.h, string/strcoll.c: Change to use u_int32_t and u_int16_t. * locale/programs/localedef.c (construct_output_path): Change name of output locale to contain normalized form of the character set portion. * string/Makefile (routines): Add agrz-ctsep and argz-next. (tests): Add tst-strlen. * string/argz-ctsep.c: New file. Implement reverse operation from argz-stringify. * string/argz-next.c: Non-inline version of function from argz.h. * string/argz.h, string/envz.h: Make usable as global header file. * string/envz.c: Fix declarations to use size_t where prototypes say so. * string/tst-strlen.c: New file. Another test for critical situation in strlen implementations. * sysdeps/i386/i586/strlen.S: Fix bug with highest byte in word being zero. * wctype/test_wctype.c: Fix controlling comparison after change to 32 bit character class array. Fri May 3 12:53:12 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * sysdeps/unix/sysv/linux/sys/socket.h: Remove spurious doubled line. Thu May 2 22:50:52 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/getpriority.c: New file. * sysdeps/unix/sysv/linux/syscalls.list: Add s_getpriority. Thu May 2 22:41:31 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_DEFAULT): Disable all exceptions. Thu May 2 22:33:14 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c, sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c, sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c, sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c, sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c, sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c, sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c, sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c, sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c: Don't define __NO_MATH_INLINES, which is already defined on command line. Thu May 2 22:18:28 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/libm-ieee754/e_j0f.c (__ieee754_j0f, __ieee754_y0f): Replace 0x80000000 by 0x48000000. * sysdeps/libm-ieee754/e_j1f.c (__ieee754_j1f): Likewise. Thu May 2 21:30:33 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sunrpc/svc_simple.c: Make global variable pl local to registerrpc. Thu May 2 00:24:04 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * time/Makefile (tz-cflags): New variable. (CFLAGS-tzfile.c): New variable. (CFLAGS-zic.c): Add $(tz-cflags). (tz-cc): Remove variable. ($(objpfx)tzfile.o, $(objpfx)zic.o): Remove targets. * sysdeps/mach/hurd/getcwd.c: Jump out of both loops when we find a name, instead of checking for reaching end of buffer, which happens when the match is the last entry in the buffer.
Diffstat (limited to 'intl')
-rw-r--r--intl/Makefile13
-rw-r--r--intl/dcgettext.c30
-rw-r--r--intl/explodename.c167
-rw-r--r--intl/finddomain.c414
-rw-r--r--intl/gettextP.h28
-rw-r--r--intl/l10nflist.c262
-rw-r--r--intl/loadinfo.h48
-rw-r--r--intl/loadmsgcat.c34
-rw-r--r--intl/locale.alias52
9 files changed, 612 insertions, 436 deletions
diff --git a/intl/Makefile b/intl/Makefile
index 159d1b1..9d97088 100644
--- a/intl/Makefile
+++ b/intl/Makefile
@@ -21,19 +21,26 @@
subdir = intl
headers = libintl.h
routines = bindtextdom dcgettext dgettext gettext \
- finddomain loadmsgcat localealias textdomain
-distribute = gettext.h gettextP.h hash-string.h
+ finddomain loadmsgcat localealias textdomain \
+ l10nflist explodename
+distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias
+
+install-others = $(localedir)/locale.alias
include ../Rules
CPPFLAGS += -D'GNULOCALEDIR="$(localedir)"' \
- -D'LOCALE_ALIAS_PATH="$(localedir):$(nlsdir)"'
+ -D'LOCALE_ALIAS_PATH="$(localedir):$(i18ndir)"'
+
+$(localedir)/locale.alias: locale.alias
+ $(do-install)
ifdef gettext-srcdir
%.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.glibc; $(copysrc)
%.c:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.c; $(copysrc)
%.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.h; $(copysrc)
+locale.alias:: ../gpl2lgpl.sed $(gettext-srcdir)/misc/locale.alias; $(copysrc)
define copysrc
sed -f $^ > $@.new
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index 7d739d3..6c8963f 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -1,8 +1,6 @@
/* dcgettext.c -- implementation of the dcgettext(3) function
- Copyright (C) 1995 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -16,8 +14,8 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -155,7 +153,7 @@ const char _nl_default_dirname[] = GNULOCALEDIR;
struct binding *_nl_domain_bindings;
/* Prototypes for local functions. */
-static char *find_msg PARAMS ((struct loaded_domain *domain,
+static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
const char *msgid));
static const char *category_to_name PARAMS ((int category));
static const char *guess_category_value PARAMS ((int category,
@@ -180,7 +178,7 @@ DCGETTEXT (domainname, msgid, category)
const char *msgid;
int category;
{
- struct loaded_domain *domain;
+ struct loaded_l10nfile *domain;
struct binding *binding;
const char *categoryname;
const char *categoryvalue;
@@ -355,18 +353,21 @@ weak_alias (__dcgettext, dcgettext);
static char *
-find_msg (domain, msgid)
- struct loaded_domain *domain;
+find_msg (domain_file, msgid)
+ struct loaded_l10nfile *domain_file;
const char *msgid;
{
size_t top, act, bottom;
+ struct loaded_domain *domain;
- if (domain->decided == 0)
- _nl_load_domain (domain);
+ if (domain_file->decided == 0)
+ _nl_load_domain (domain_file);
- if (domain->data == NULL)
+ if (domain_file->data == NULL)
return NULL;
+ domain = (struct loaded_domain *) domain_file->data;
+
/* Locate the MSGID and its translation. */
if (domain->hash_size > 2 && domain->hash_tab != NULL)
{
@@ -439,7 +440,8 @@ find_msg (domain, msgid)
/* Return string representation of locale CATEGORY. */
-static const char *category_to_name (category)
+static const char *
+category_to_name (category)
int category;
{
const char *retval;
diff --git a/intl/explodename.c b/intl/explodename.c
new file mode 100644
index 0000000..2fd8be0
--- /dev/null
+++ b/intl/explodename.c
@@ -0,0 +1,167 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+The GNU C Library 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 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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 the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "loadinfo.h"
+
+int
+_nl_explode_name (name, language, modifier, territory, codeset,
+ normalized_codeset, special, sponsor, revision)
+ char *name;
+ const char **language;
+ const char **modifier;
+ const char **territory;
+ const char **codeset;
+ const char **normalized_codeset;
+ const char **special;
+ const char **sponsor;
+ const char **revision;
+{
+ enum { undecided, xpg, cen } syntax;
+ char *cp;
+ int mask;
+
+ *modifier = NULL;
+ *territory = NULL;
+ *codeset = NULL;
+ *normalized_codeset = NULL;
+ *special = NULL;
+ *sponsor = NULL;
+ *revision = NULL;
+
+ /* Now we determine the single parts of the locale name. First
+ look for the language. Termination symbols are `_' and `@' if
+ we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
+ mask = 0;
+ syntax = undecided;
+ *language = cp = name;
+ while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
+ && cp[0] != '+' && cp[0] != ',')
+ ++cp;
+
+ if (*language == cp)
+ /* This does not make sense: language has to be specified. Use
+ this entry as it is without exploding. Perhaps it is an alias. */
+ cp = strchr (*language, '\0');
+ else if (cp[0] == '_')
+ {
+ /* Next is the territory. */
+ cp[0] = '\0';
+ *territory = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
+ && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= TERRITORY;
+
+ if (cp[0] == '.')
+ {
+ /* Next is the codeset. */
+ syntax = xpg;
+ cp[0] = '\0';
+ *codeset = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '@')
+ ++cp;
+
+ mask |= XPG_CODESET;
+
+ if (*codeset != cp && (*codeset)[0] != '\0')
+ {
+ *normalized_codeset = _nl_normalize_codeset (*codeset,
+ cp - *codeset);
+ if (strcmp (*codeset, *normalized_codeset) == 0)
+ free ((char *) *normalized_codeset);
+ else
+ mask |= XPG_NORM_CODESET;
+ }
+ }
+ }
+
+ if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
+ {
+ /* Next is the modifier. */
+ syntax = cp[0] == '@' ? xpg : cen;
+ cp[0] = '\0';
+ *modifier = ++cp;
+
+ while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
+ && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= XPG_MODIFIER | CEN_AUDIENCE;
+ }
+
+ if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
+ {
+ syntax = cen;
+
+ if (cp[0] == '+')
+ {
+ /* Next is special application (CEN syntax). */
+ cp[0] = '\0';
+ *special = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPECIAL;
+ }
+
+ if (cp[0] == ',')
+ {
+ /* Next is sponsor (CEN syntax). */
+ cp[0] = '\0';
+ *sponsor = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPONSOR;
+ }
+
+ if (cp[0] == '_')
+ {
+ /* Next is revision (CEN syntax). */
+ cp[0] = '\0';
+ *revision = ++cp;
+
+ mask |= CEN_REVISION;
+ }
+ }
+
+ /* For CEN sytnax values it might be important to have the
+ separator character in the file name, not for XPG syntax. */
+ if (syntax == xpg)
+ {
+ if (*territory != NULL && (*territory)[0] == '\0')
+ mask &= ~TERRITORY;
+
+ if (*codeset != NULL && (*codeset)[0] == '\0')
+ mask &= ~XPG_CODESET;
+
+ if (*modifier != NULL && (*modifier)[0] == '\0')
+ mask &= ~XPG_MODIFIER;
+ }
+
+ return mask;
+}
diff --git a/intl/finddomain.c b/intl/finddomain.c
index 3ced26f..bb4609e 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -1,9 +1,6 @@
/* finddomain.c -- handle list of needed message catalogs
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -17,8 +14,8 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -71,39 +68,8 @@ void free ();
# define stpcpy(dest, src) __stpcpy(dest, src)
#endif
-/* Encoding of locale name parts. */
-#define CEN_REVISION 1
-#define CEN_SPONSOR 2
-#define CEN_SPECIAL 4
-#define XPG_NORM_CODESET 8
-#define XPG_CODESET 16
-#define TERRITORY 32
-#define CEN_AUDIENCE 64
-#define XPG_MODIFIER 128
-
-#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
-#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
-
-
/* List of already loaded domains. */
-static struct loaded_domain *_nl_loaded_domains;
-
-/* Prototypes for local functions. */
-static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname,
- int mask,
- const char *language,
- const char *territory,
- const char *codeset,
- const char *normalized_codeset,
- const char *modifier,
- const char *special,
- const char *sponsor,
- const char *revision,
- const char *domainname,
- int do_allocate));
-
-/* Normalize name of selected codeset. */
-static const char *normalize_codeset PARAMS ((const char *codeset));
+static struct loaded_l10nfile *_nl_loaded_domains;
/* Substitution for systems lacking this function in their C library. */
#if !_LIBC && !HAVE_STPCPY
@@ -115,29 +81,25 @@ static char *stpcpy__ PARAMS ((char *dest, const char *src));
/* Return a data structure describing the message catalog described by
the DOMAINNAME and CATEGORY parameters with respect to the currently
established bindings. */
-struct loaded_domain *
+struct loaded_l10nfile *
_nl_find_domain (dirname, locale, domainname)
const char *dirname;
char *locale;
const char *domainname;
{
- enum { undecided, xpg, cen } syntax;
- struct loaded_domain *retval;
+ struct loaded_l10nfile *retval;
const char *language;
- const char *modifier = NULL;
- const char *territory = NULL;
- const char *codeset = NULL;
- const char *normalized_codeset = NULL;
- const char *special = NULL;
- const char *sponsor = NULL;
- const char *revision = NULL;
- const char *alias_value = NULL;
- char *cp;
+ const char *modifier;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *alias_value;
int mask;
- /* CATEGORYVALUE now possibly contains a colon separated list of
- locales. Each single locale can consist of up to four recognized
- parts for the XPG syntax:
+ /* LOCALE can consist of up to four recognized parts for the XPG syntax:
language[_territory[.codeset]][@modifier]
@@ -160,15 +122,16 @@ _nl_find_domain (dirname, locale, domainname)
/* If we have already tested for this locale entry there has to
be one data set in the list of loaded domains. */
- retval = make_entry_rec (dirname, 0, locale, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, domainname, 0);
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, 0, locale, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, domainname, 0);
if (retval != NULL)
{
/* We know something about this locale. */
int cnt;
if (retval->decided == 0)
- _nl_load_domain (retval); /* @@@ */
+ _nl_load_domain (retval);
if (retval->data != NULL)
return retval;
@@ -181,8 +144,6 @@ _nl_find_domain (dirname, locale, domainname)
if (retval->successor[cnt]->data != NULL)
break;
}
-
- /* We really found some usable information. */
return cnt >= 0 ? retval : NULL;
/* NOTREACHED */
}
@@ -204,123 +165,16 @@ _nl_find_domain (dirname, locale, domainname)
/* Now we determine the single parts of the locale name. First
look for the language. Termination symbols are `_' and `@' if
we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
- mask = 0;
- syntax = undecided;
- language = cp = locale;
- while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
- && cp[0] != '+' && cp[0] != ',')
- ++cp;
-
- if (language == cp)
- /* This does not make sense: language has to be specified. Use
- this entry as it is without exploding. Perhaps it is an alias. */
- cp = strchr (language, '\0');
- else if (cp[0] == '_')
- {
- /* Next is the territory. */
- cp[0] = '\0';
- territory = ++cp;
-
- while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
- && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
- ++cp;
-
- mask |= TERRITORY;
-
- if (cp[0] == '.')
- {
- /* Next is the codeset. */
- syntax = xpg;
- cp[0] = '\0';
- codeset = ++cp;
-
- while (cp[0] != '\0' && cp[0] != '@')
- ++cp;
-
- mask |= XPG_CODESET;
-
- if (codeset != cp && codeset[0] != '\0')
- {
- normalized_codeset = normalize_codeset (codeset);
- if (strcmp (codeset, normalized_codeset) == 0)
- free ((char *) normalized_codeset);
- else
- mask |= XPG_NORM_CODESET;
- }
- }
- }
-
- if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
- {
- /* Next is the modifier. */
- syntax = cp[0] == '@' ? xpg : cen;
- cp[0] = '\0';
- modifier = ++cp;
-
- while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
- && cp[0] != ',' && cp[0] != '_')
- ++cp;
-
- mask |= XPG_MODIFIER | CEN_AUDIENCE;
- }
-
- if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
- {
- syntax = cen;
-
- if (cp[0] == '+')
- {
- /* Next is special application (CEN syntax). */
- cp[0] = '\0';
- special = ++cp;
-
- while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
- ++cp;
-
- mask |= CEN_SPECIAL;
- }
-
- if (cp[0] == ',')
- {
- /* Next is sponsor (CEN syntax). */
- cp[0] = '\0';
- sponsor = ++cp;
-
- while (cp[0] != '\0' && cp[0] != '_')
- ++cp;
-
- mask |= CEN_SPONSOR;
- }
-
- if (cp[0] == '_')
- {
- /* Next is revision (CEN syntax). */
- cp[0] = '\0';
- revision = ++cp;
-
- mask |= CEN_REVISION;
- }
- }
-
- /* For CEN sytnax values it might be important to have the
- separator character in the file name, not for XPG syntax. */
- if (syntax == xpg)
- {
- if (territory != NULL && territory[0] == '\0')
- mask &= ~TERRITORY;
-
- if (codeset != NULL && codeset[0] == '\0')
- mask &= ~XPG_CODESET;
-
- if (modifier != NULL && modifier[0] == '\0')
- mask &= ~XPG_MODIFIER;
- }
+ mask = _nl_explode_name (locale, &language, &modifier, &territory,
+ &codeset, &normalized_codeset, &special,
+ &sponsor, &revision);
/* Create all possible locale entries which might be interested in
generalzation. */
- retval = make_entry_rec (dirname, mask, language, territory, codeset,
- normalized_codeset, modifier, special, sponsor,
- revision, domainname, 1);
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, mask, language, territory,
+ codeset, normalized_codeset, modifier, special,
+ sponsor, revision, domainname, 1);
if (retval == NULL)
/* This means we are out of core. */
return NULL;
@@ -336,12 +190,7 @@ _nl_find_domain (dirname, locale, domainname)
_nl_load_domain (retval->successor[cnt]);
if (retval->successor[cnt]->data != NULL)
break;
-
- /* Signal that locale is not available. */
- retval->successor[cnt] = NULL;
}
- if (retval->successor[cnt] == NULL)
- retval = NULL;
}
/* The room for an alias was dynamically allocated. Free it now. */
@@ -351,215 +200,6 @@ _nl_find_domain (dirname, locale, domainname)
return retval;
}
-
-static struct loaded_domain *
-make_entry_rec (dirname, mask, language, territory, codeset,
- normalized_codeset, modifier, special, sponsor, revision,
- domain, do_allocate)
- const char *dirname;
- int mask;
- const char *language;
- const char *territory;
- const char *codeset;
- const char *normalized_codeset;
- const char *modifier;
- const char *special;
- const char *sponsor;
- const char *revision;
- const char *domain;
- int do_allocate;
-{
- char *filename = NULL;
- struct loaded_domain *last = NULL;
- struct loaded_domain *retval;
- char *cp;
- size_t entries;
- int cnt;
-
-
- /* Process the current entry described by the MASK only when it is
- valid. Because the mask can have in the first call bits from
- both syntaces set this is necessary to prevent constructing
- illegal local names. */
- /* FIXME: Rewrite because test is necessary only in first round. */
- if ((mask & CEN_SPECIFIC) == 0 || (mask & XPG_SPECIFIC) == 0
- || ((mask & XPG_CODESET) != 0 && (mask & XPG_NORM_CODESET) != 0))
- {
- /* Allocate room for the full file name. */
- filename = (char *) malloc (strlen (dirname) + 1
- + strlen (language)
- + ((mask & TERRITORY) != 0
- ? strlen (territory) + 1 : 0)
- + ((mask & XPG_CODESET) != 0
- ? strlen (codeset) + 1 : 0)
- + ((mask & XPG_NORM_CODESET) != 0
- ? strlen (normalized_codeset) + 1 : 0)
- + ((mask & XPG_MODIFIER) != 0 ?
- strlen (modifier) + 1 : 0)
- + ((mask & CEN_SPECIAL) != 0
- ? strlen (special) + 1 : 0)
- + ((mask & CEN_SPONSOR) != 0
- ? strlen (sponsor) + 1 : 0)
- + ((mask & CEN_REVISION) != 0
- ? strlen (revision) + 1 : 0) + 1
- + strlen (domain) + 1);
-
- if (filename == NULL)
- return NULL;
-
- retval = NULL;
- last = NULL;
-
- /* Construct file name. */
- cp = stpcpy (filename, dirname);
- *cp++ = '/';
- cp = stpcpy (cp, language);
-
- if ((mask & TERRITORY) != 0)
- {
- *cp++ = '_';
- cp = stpcpy (cp, territory);
- }
- if ((mask & XPG_CODESET) != 0)
- {
- *cp++ = '.';
- cp = stpcpy (cp, codeset);
- }
- if ((mask & XPG_NORM_CODESET) != 0)
- {
- *cp++ = '.';
- cp = stpcpy (cp, normalized_codeset);
- }
- if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
- {
- /* This component can be part of both syntaces but has different
- leading characters. For CEN we use `+', else `@'. */
- *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
- cp = stpcpy (cp, modifier);
- }
- if ((mask & CEN_SPECIAL) != 0)
- {
- *cp++ = '+';
- cp = stpcpy (cp, special);
- }
- if ((mask & CEN_SPONSOR) != 0)
- {
- *cp++ = ',';
- cp = stpcpy (cp, sponsor);
- }
- if ((mask & CEN_REVISION) != 0)
- {
- *cp++ = '_';
- cp = stpcpy (cp, revision);
- }
-
- *cp++ = '/';
- stpcpy (cp, domain);
-
- /* Look in list of already loaded domains whether it is already
- available. */
- last = NULL;
- for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
- if (retval->filename != NULL)
- {
- int compare = strcmp (retval->filename, filename);
- if (compare == 0)
- /* We found it! */
- break;
- if (compare < 0)
- {
- /* It's not in the list. */
- retval = NULL;
- break;
- }
-
- last = retval;
- }
-
- if (retval != NULL || do_allocate == 0)
- {
- free (filename);
- return retval;
- }
- }
-
- retval = (struct loaded_domain *) malloc (sizeof (*retval));
- if (retval == NULL)
- return NULL;
-
- retval->filename = filename;
- retval->decided = 0;
-
- if (last == NULL)
- {
- retval->next = _nl_loaded_domains;
- _nl_loaded_domains = retval;
- }
- else
- {
- retval->next = last->next;
- last->next = retval;
- }
-
- entries = 0;
- for (cnt = 254; cnt >= 0; --cnt)
- if (cnt < mask && (cnt & ~mask) == 0
- && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
- && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
- retval->successor[entries++] = make_entry_rec (dirname, cnt,
- language, territory,
- codeset,
- normalized_codeset,
- modifier, special,
- sponsor, revision,
- domain, 1);
- retval->successor[entries] = NULL;
-
- return retval;
-}
-
-
-static const char *
-normalize_codeset (codeset)
- const char *codeset;
-{
- int len = 0;
- int only_digit = 1;
- const char *cp;
- char *retval;
- char *wp;
-
- for (cp = codeset; cp[0] != '\0'; ++cp)
- if (isalnum (cp[0]))
- {
- ++len;
-
- if (isalpha (cp[0]))
- only_digit = 0;
- }
-
- retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
-
- if (retval != NULL)
- {
- if (only_digit)
- wp = stpcpy (retval, "ISO");
- else
- wp = retval;
-
- for (cp = codeset; cp[0] != '\0'; ++cp)
- if (isalpha (cp[0]))
- *wp++ = toupper (cp[0]);
- else if (isdigit (cp[0]))
- *wp++ = cp[0];
-
- *wp = '\0';
- }
-
- return (const char *) retval;
-}
-
-
/* @@ begin of epilog @@ */
/* We don't want libintl.a to depend on any other library. So we
diff --git a/intl/gettextP.h b/intl/gettextP.h
index 34196a0..c37adab 100644
--- a/intl/gettextP.h
+++ b/intl/gettextP.h
@@ -1,8 +1,6 @@
/* gettextP.h -- header describing internals of gettext library
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -16,12 +14,14 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifndef _GETTEXTP_H
#define _GETTEXTP_H
+#include "loadinfo.h"
+
/* @@ end of prolog @@ */
#ifndef PARAMS
@@ -49,12 +49,6 @@ SWAP (i)
struct loaded_domain
{
- struct loaded_domain *next;
- struct loaded_domain *successor[63];
-
- const char *filename;
- int decided;
-
const char *data;
int must_swap;
nls_uint32 nstrings;
@@ -71,12 +65,10 @@ struct binding
char *dirname;
};
-struct loaded_domain *_nl_find_domain PARAMS ((const char *__dirname,
- char *__locale,
- const char *__domainname));
-void _nl_load_domain PARAMS ((struct loaded_domain *__domain));
-
-const char *_nl_expand_alias PARAMS ((const char *__name));
+struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+ char *__locale,
+ const char *__domainname));
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
/* @@ begin of epilog @@ */
diff --git a/intl/l10nflist.c b/intl/l10nflist.c
new file mode 100644
index 0000000..b0fdf51
--- /dev/null
+++ b/intl/l10nflist.c
@@ -0,0 +1,262 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+The GNU C Library 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 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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 the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <argz.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "loadinfo.h"
+
+/* Return number of bits set in X. */
+static int pop __P ((int x));
+
+static inline int
+pop (x)
+ int x;
+{
+ /* We assume that no more than 16 bits are used. */
+ x = ((x & ~0x5555) >> 1) + (x & 0x5555);
+ x = ((x & ~0x3333) >> 2) + (x & 0x3333);
+ x = ((x >> 4) + x) & 0x0f0f;
+ x = ((x >> 8) + x) & 0xff;
+
+ return x;
+}
+
+
+struct loaded_l10nfile *
+_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+ territory, codeset, normalized_codeset, modifier, special,
+ sponsor, revision, filename, do_allocate)
+ struct loaded_l10nfile **l10nfile_list;
+ const char *dirlist;
+ size_t dirlist_len;
+ int mask;
+ const char *language;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *modifier;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *filename;
+ int do_allocate;
+{
+ char *abs_filename;
+ struct loaded_l10nfile *last = NULL;
+ struct loaded_l10nfile *retval;
+ char *cp;
+ size_t entries;
+ int cnt;
+
+ /* Allocate room for the full file name. */
+ abs_filename = (char *) malloc (dirlist_len
+ + strlen (language)
+ + ((mask & TERRITORY) != 0
+ ? strlen (territory) + 1 : 0)
+ + ((mask & XPG_CODESET) != 0
+ ? strlen (codeset) + 1 : 0)
+ + ((mask & XPG_NORM_CODESET) != 0
+ ? strlen (normalized_codeset) + 1 : 0)
+ + (((mask & XPG_MODIFIER) != 0
+ || (mask & CEN_AUDIENCE) != 0) ?
+ strlen (modifier) + 1 : 0)
+ + ((mask & CEN_SPECIAL) != 0
+ ? strlen (special) + 1 : 0)
+ + ((mask & CEN_SPONSOR) != 0
+ ? strlen (sponsor) + 1 : 0)
+ + ((mask & CEN_REVISION) != 0
+ ? strlen (revision) + 1 : 0)
+ + 1 + strlen (filename) + 1);
+
+ if (abs_filename == NULL)
+ return NULL;
+
+ retval = NULL;
+ last = NULL;
+
+ /* Construct file name. */
+ memcpy (abs_filename, dirlist, dirlist_len);
+ __argz_stringify (abs_filename, dirlist_len, ':');
+ cp = abs_filename + (dirlist_len - 1);
+ *cp++ = '/';
+ cp = stpcpy (cp, language);
+
+ if ((mask & TERRITORY) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, territory);
+ }
+ if ((mask & XPG_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, codeset);
+ }
+ if ((mask & XPG_NORM_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, normalized_codeset);
+ }
+ if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
+ {
+ /* This component can be part of both syntaces but has different
+ leading characters. For CEN we use `+', else `@'. */
+ *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
+ cp = stpcpy (cp, modifier);
+ }
+ if ((mask & CEN_SPECIAL) != 0)
+ {
+ *cp++ = '+';
+ cp = stpcpy (cp, special);
+ }
+ if ((mask & CEN_SPONSOR) != 0)
+ {
+ *cp++ = ',';
+ cp = stpcpy (cp, sponsor);
+ }
+ if ((mask & CEN_REVISION) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, revision);
+ }
+
+ *cp++ = '/';
+ stpcpy (cp, filename);
+
+ /* Look in list of already loaded domains whether it is already
+ available. */
+ last = NULL;
+ for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
+ if (retval->filename != NULL)
+ {
+ int compare = strcmp (retval->filename, abs_filename);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It's not in the list. */
+ retval = NULL;
+ break;
+ }
+
+ last = retval;
+ }
+
+ if (retval != NULL || do_allocate == 0)
+ {
+ free (abs_filename);
+ return retval;
+ }
+
+ retval = (struct loaded_l10nfile *)
+ malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
+ * (1 << pop (mask))
+ * sizeof (struct loaded_l10nfile *)));
+ if (retval == NULL)
+ return NULL;
+
+ retval->filename = abs_filename;
+ retval->decided = (__argz_count (dirlist, dirlist_len) != 1
+ || ((mask & XPG_CODESET) != 0
+ && (mask & XPG_NORM_CODESET) != 0));
+ retval->data = NULL;
+
+ if (last == NULL)
+ {
+ retval->next = *l10nfile_list;
+ *l10nfile_list = retval;
+ }
+ else
+ {
+ retval->next = last->next;
+ last->next = retval;
+ }
+
+ entries = 0;
+ /* If the DIRLIST is a real list the RETVAL entry correcponds not to
+ a real file. So we have to use the DIRLIST separation machanism
+ of the inner loop. */
+ cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
+ for (; cnt >= 0; --cnt)
+ if ((cnt & ~mask) == 0
+ && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
+ && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
+ {
+ /* Iterate over all elements of the DIRLIST. */
+ char *dir = NULL;
+
+ while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
+ != NULL)
+ retval->successor[entries++]
+ = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
+ language, territory, codeset,
+ normalized_codeset, modifier, special,
+ sponsor, revision, filename, 1);
+ }
+ retval->successor[entries] = NULL;
+
+ return retval;
+}
+
+/* Normalize codeset name. There is no standard for the codeset
+ names. Normalization allows the user to use any of the common
+ names. */
+const char *
+_nl_normalize_codeset (codeset, name_len)
+ const char *codeset;
+ size_t name_len;
+{
+ int len = 0;
+ int only_digit = 1;
+ char *retval;
+ char *wp;
+ size_t cnt;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalnum (codeset[cnt]))
+ {
+ ++len;
+
+ if (isalpha (codeset[cnt]))
+ only_digit = 0;
+ }
+
+ retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
+
+ if (retval != NULL)
+ {
+ if (only_digit)
+ wp = stpcpy (retval, "ISO");
+ else
+ wp = retval;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalpha (codeset[cnt]))
+ *wp++ = tolower (codeset[cnt]);
+ else if (isdigit (codeset[cnt]))
+ *wp++ = codeset[cnt];
+
+ *wp = '\0';
+ }
+
+ return (const char *) retval;
+}
diff --git a/intl/loadinfo.h b/intl/loadinfo.h
new file mode 100644
index 0000000..00aa1c9
--- /dev/null
+++ b/intl/loadinfo.h
@@ -0,0 +1,48 @@
+/* Encoding of locale name parts. */
+#define CEN_REVISION 1
+#define CEN_SPONSOR 2
+#define CEN_SPECIAL 4
+#define XPG_NORM_CODESET 8
+#define XPG_CODESET 16
+#define TERRITORY 32
+#define CEN_AUDIENCE 64
+#define XPG_MODIFIER 128
+
+#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
+#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
+
+
+struct loaded_l10nfile
+{
+ const char *filename;
+ int decided;
+
+ const void *data;
+
+ struct loaded_l10nfile *next;
+ struct loaded_l10nfile *successor[1];
+};
+
+
+extern const char *_nl_normalize_codeset __P ((const char *codeset,
+ size_t name_len));
+
+extern struct loaded_l10nfile *
+_nl_make_l10nflist __P ((struct loaded_l10nfile **l10nfile_list,
+ const char *dirlist, size_t dirlist_len, int mask,
+ const char *language, const char *territory,
+ const char *codeset, const char *normalized_codeset,
+ const char *modifier, const char *special,
+ const char *sponsor, const char *revision,
+ const char *filename, int do_allocate));
+
+
+extern const char *_nl_expand_alias __P ((const char *name));
+
+extern int _nl_explode_name __P ((char *name, const char **language,
+ const char **modifier,
+ const char **territory,
+ const char **codeset,
+ const char **normalized_codeset,
+ const char **special, const char **sponsor,
+ const char **revision));
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 0f5bfd5..1daf72a 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,8 +1,6 @@
/* loadmsgcat.c -- load needed message catalogs
- Copyright (C) 1995 Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -16,8 +14,8 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -65,8 +63,8 @@ int _nl_msg_cat_cntr;
/* Load the message catalogs specified by FILENAME. If it is no valid
message catalog do nothing. */
void
-_nl_load_domain (domain)
- struct loaded_domain *domain;
+_nl_load_domain (domain_file)
+ struct loaded_l10nfile *domain_file;
{
int fd;
struct stat st;
@@ -75,19 +73,20 @@ _nl_load_domain (domain)
|| defined _LIBC
int use_mmap = 0;
#endif
+ struct loaded_domain *domain;
- domain->decided = 1;
- domain->data = NULL;
+ domain_file->decided = 1;
+ domain_file->data = NULL;
/* If the record does not represent a valid locale the FILENAME
might be NULL. This can happen when according to the given
specification the locale file name is different for XPG and CEN
syntax. */
- if (domain->filename == NULL)
+ if (domain_file->filename == NULL)
return;
/* Try to open the addressed file. */
- fd = open (domain->filename, O_RDONLY);
+ fd = open (domain_file->filename, O_RDONLY);
if (fd == -1)
return;
@@ -160,6 +159,12 @@ _nl_load_domain (domain)
return;
}
+ domain_file->data
+ = (struct loaded_domain *) malloc (sizeof (struct loaded_domain *));
+ if (domain->data == NULL)
+ return;
+
+ domain = (struct loaded_domain *) domain_file->data;
domain->data = (char *) data;
domain->must_swap = data->magic != _MAGIC;
@@ -185,11 +190,12 @@ _nl_load_domain (domain)
else
#endif
free (data);
- domain->data = NULL;
+ free (domain);
+ domain_file->data = NULL;
return;
}
/* Show that one domain is changed. This might make some cached
- translation invalid. */
+ translations invalid. */
++_nl_msg_cat_cntr;
}
diff --git a/intl/locale.alias b/intl/locale.alias
new file mode 100644
index 0000000..cf1f6ee
--- /dev/null
+++ b/intl/locale.alias
@@ -0,0 +1,52 @@
+# Locale name alias data base
+# Copyright (C) 1996 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# The format of this file is the same as for the corresponding file of
+# the X Window System, which normally can be found in
+# /usr/lib/X11/locale/locale.alias
+# A single line contains two fields: an alias and a substitution value.
+# All entries are case independent.
+
+# Note: This file is far from being complete. If you have a value for
+# your own site which you think might be useful for others too, share it
+# with the rest of us. Send it to bug-gnu-utils@prep.ai.mit.edu.
+
+czech cz_CZ.ISO-8859-2
+danish da_DK.ISO-8859-1
+dansk da_DK.ISO-8859-1
+deutsch de_DE.ISO-8859-1
+dutch nl_NL.ISO-8859-1
+finnish fi_FI.ISO-8859-1
+français fr_FR.ISO-8859-1
+french fr_FR.ISO-8859-1
+german de_DE.ISO-8859-1
+greek el_GR.ISO-8859-7
+hebrew iw_IL.ISO-8859-8
+hungarian hu_HU.ISO-8859-2
+icelandic is_IS.ISO-8859-1
+italian it_CH.ISO-8859-1
+japanese ja_JP.EUC
+norwegian no_NO.ISO-8859-1
+polish pl_PL.ISO-8859-2
+portuguese pt_PT.ISO-8859-1
+rumanian ro_RO.ISO-8859-2
+russian ru_SU.ISO-8859-5
+slovak sk_SK.ISO-8859-2
+slovene sl_CS.ISO-8859-2
+spanish es_ES.ISO-8859-1
+swedish sv_SE.ISO-8859-1
+turkish tr_TR.ISO-8859-9