summaryrefslogtreecommitdiffstats
path: root/intl
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1996-06-07 02:58:04 +0000
committerJim Meyering <jim@meyering.net>1996-06-07 02:58:04 +0000
commit0eb8d8c2216a0e141386d9d0893054bf416b0463 (patch)
tree2f57d45bfeb9a714894be646ce65d32454b10532 /intl
parentc8d8d1d8bd3887bad23cff9e687802ca0eab8e34 (diff)
downloadidutils-0eb8d8c2216a0e141386d9d0893054bf416b0463.tar.gz
idutils-0eb8d8c2216a0e141386d9d0893054bf416b0463.tar.bz2
idutils-0eb8d8c2216a0e141386d9d0893054bf416b0463.zip
Update from gettext-0.10.16.
Diffstat (limited to 'intl')
-rw-r--r--intl/ChangeLog77
-rw-r--r--intl/Makefile.in86
-rw-r--r--intl/VERSION2
-rw-r--r--intl/dcgettext.c112
-rw-r--r--intl/finddomain.c415
-rw-r--r--intl/gettextP.h18
-rw-r--r--intl/loadmsgcat.c26
-rw-r--r--intl/localealias.c56
8 files changed, 315 insertions, 477 deletions
diff --git a/intl/ChangeLog b/intl/ChangeLog
index 34a50a8..6b9e9f5 100644
--- a/intl/ChangeLog
+++ b/intl/ChangeLog
@@ -1,3 +1,78 @@
+Thu Jun 6 01:49:52 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not
+ all-@USE_NLS@.
+
+ * Makefile.in (install): intlh.inst comes from local dir, not
+ $(srcdir).
+
+ * Makefile.in (intlh.inst): Special handling of this goal. If
+ used in gettext, this is really a rul to construct this file. If
+ used in any other package it is defined as a .PHONY rule with
+ empty body.
+
+ * finddomain.c: Extract locale file information handling into
+ l10nfile.c. Rename local stpcpy__ function to stpcpy.
+
+ * dcgettext.c (stpcpy): Add local definition.
+
+ * l10nflist.c: Solve some portability problems. Patches partly by
+ Thomas Esken. Add local definition of stpcpy.
+
+Tue Jun 4 02:47:49 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in: Don't depend including <locale.h> on
+ HAVE_LOCALE_H. Instead configure must rewrite this fiile
+ depending on the result of the configure run.
+
+ * Makefile.in (install): libintl.inst is now called intlh.inst.
+ Add rules for updating intlh.inst from intlh.inst.in.
+
+ * libintl.inst: Renamed to intlh.inst.in.
+
+ * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1
+ because gcc has __buitlin_alloca.
+ Reported by Roland McGrath.
+
+Mon Jun 3 00:32:16 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (installcheck): New goal to fulfill needs of
+ automake's distcheck.
+
+ * Makefile.in (install): Reorder commands so that VERSION is
+ found.
+
+ * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in
+ @datadir@/gettext.
+ (COMSRCS): Add l10nfile.c.
+ (OBJECTS): Add l10nfile.o.
+ (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common).
+ (DISTFILE.gettext): Remove $(DISTFILES.common).
+ (all-gettext): Remove goal.
+ (install): If $(PACKAGE) = gettext install, otherwose do nothing. No
+ package but gettext itself should install libintl.h + headers.
+ (dist): Extend goal to work for gettext, too.
+ (dist-gettext): Remove goal.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc.
+
+Sun Jun 2 17:33:06 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * loadmsgcat.c (_nl_load_domain): Parameter is now comes from
+ find_l10nfile.
+
+Sat Jun 1 02:23:03 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c (__argz_next): Add definition.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca
+ code. Use new l10nfile handling.
+
+ * localealias.c [!HAVE_ALLOCA]: Add code for handling missing
+ alloca code.
+
+ * l10nflist.c: Initial revision.
+
Tue Apr 2 18:51:18 1996 Ulrich Drepper <drepper@myware>
* Makefile.in (all-gettext): New goal. Same as all-yes.
@@ -767,5 +842,3 @@ Sun Jul 2 02:06:50 1995 Ulrich Drepper <drepper@myware>
which allow to use the X/Open catgets function with an interface
like the Uniforum gettext function. For system which does not
have neither of those a complete implementation is provided.
-
-
diff --git a/intl/Makefile.in b/intl/Makefile.in
index 34bed63..0c4d40d 100644
--- a/intl/Makefile.in
+++ b/intl/Makefile.in
@@ -32,7 +32,7 @@ includedir = $(prefix)/include
datadir = $(prefix)/@DATADIRNAME@
localedir = $(datadir)/locale
gnulocaledir = $(prefix)/share/locale
-gettextsrcdir = @datadir@/gettext
+gettextsrcdir = @datadir@/gettext/intl
aliaspath = $(localedir):.
subdir = intl
@@ -49,19 +49,21 @@ CFLAGS = @CFLAGS@
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
-HEADERS = $(COMHDRS) libgettext.h
+HEADERS = $(COMHDRS) libgettext.h loadinfo.h
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
+finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
+explodename.c
OBJECTS = @INTLOBJS@ bindtextdom.o dcgettext.o dgettext.o gettext.o \
-finddomain.o loadmsgcat.o localealias.o textdomain.o
+finddomain.o loadmsgcat.o localealias.o textdomain.o l10nflist.o \
+explodename.o
CATOBJS = cat-compat.o ../po/cat-id-tbl.o
GETTOBJS = intl-compat.o
DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \
xopen-msg.sed $(HEADERS) $(SOURCES)
-DISTFILES = $(DISTFILES.common) VERSION
-DISTFILES.gettext = $(DISTFILES.common) libintl.glibc libintl.inst
+DISTFILES.normal = VERSION
+DISTFILES.gettext = libintl.glibc intlh.inst.in
.SUFFIXES:
.SUFFIXES: .c .o
@@ -70,9 +72,9 @@ DISTFILES.gettext = $(DISTFILES.common) libintl.glibc libintl.inst
INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib
-all: all-@USE_NLS@
+all: all-@USE_INCLUDED_LIBINTL@
-all-yes all-gettext: libintl.a
+all-yes: libintl.a intlh.inst
all-no:
libintl.a: $(OBJECTS)
@@ -83,9 +85,7 @@ libintl.a: $(OBJECTS)
../po/cat-id-tbl.o: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot
cd ../po && $(MAKE) cat-id-tbl.o
-check install: all
-
-installcheck:
+check: all
# This installation goal is only used in GNU gettext. Packages which
# only use the library should use install instead.
@@ -95,19 +95,24 @@ installcheck:
# separate library or use the catgets interface. A special case is
# where configure found a previously installed GNU gettext library.
# If you want to use the one which comes with this version of the
-# package, you have to use `configure --with-gnu-gettext'.
-install-src: install
- $(top_srcdir)/mkinstalldirs $(libdir) $(includedir) $(gettextsrcdir)
- if test '@INTLOBJS@' = '$(GETTOBJS)'; then \
- $(INSTALL_DATA) $(srcdir)/libintl.inst \
- $(includedir)/libintl.h; \
- $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
+# package, you have to use `configure --with-included-gettext'.
+install: all
+ if test "$(PACKAGE)" = "gettext"; then \
+ $(top_srcdir)/mkinstalldirs $(libdir) $(includedir) \
+ $(gettextsrcdir); \
+ if test '@INTLOBJS@' = '$(GETTOBJS)'; then \
+ $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \
+ $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
+ fi; \
+ $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \
+ cd $(srcdir) && \
+ for file in $(DISTFILES.common); do \
+ $(INSTALL_DATA) $$file $(gettextsrcdir)/$$file; \
+ done; \
fi
- cd $(srcdir) && \
- for file in $(DISTFILES.common); do \
- $(INSTALL_DATA) $$file $(gettextsrcdir)/intl-$$file; \
- done
- $(INSTALL_DATA) VERSION $(gettextsrcdir)/intl-VERSION
+
+# Define this as empty until I found a useful application.
+installcheck:
uninstall:
for file in $(DISTFILES); do \
@@ -117,8 +122,8 @@ uninstall:
info dvi:
$(OBJECTS): ../config.h libgettext.h
-bindtextdom.o finddomain.o loadmsgcat.o: gettextP.h gettext.h
-dcgettext.o: gettextP.h gettext.h hash-string.h
+bindtextdom.o finddomain.o loadmsgcat.o: gettextP.h gettext.h loadinfo.h
+dcgettext.o: gettextP.h gettext.h hash-string.h loadinfo.h
tags: TAGS
@@ -144,19 +149,16 @@ maintainer-clean: distclean
@echo "it deletes files that may require special tools to rebuild."
-.PHONY: distdir
+# GNU gettext needs not contain the file `VERSION' but contains some
+# other files which should not be distributed in other packages.
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
-distdir: Makefile $(DISTFILES)
- for file in $(DISTFILES); do \
- ln $(srcdir)/$$file $(distdir) 2> /dev/null \
- || cp -p $(srcdir)/$$file $(distdir); \
- done
-
-# This dist goal is only used in GNU gettext. GNU gettext needs not contain
-# the file `VERSION' but contains some other files which should not be
-# distributed in other packages.
-dist-gettext: Makefile $(DISTFILES.gettext)
- for file in $(DISTFILES.gettext); do \
+dist distdir: Makefile $(DISTFILES)
+ if test "$(PACKAGE)" = gettext; then \
+ additional="$(DISTFILES.gettext)"; \
+ else \
+ additional="$(DISTFILES.normal)"; \
+ fi; \
+ for file in $(DISTFILES.common) $$additional; do \
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir); \
done
@@ -168,6 +170,16 @@ Makefile: Makefile.in ../config.status
cd .. \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+# The dependency for intlh.inst is different in gettext and all other
+# packages. Because we cannot you GNU make features we have to solve
+# the problem while rewriting Makefile.in.
+@GT_YES@intlh.inst: intlh.inst.in ../config.status
+@GT_YES@ cd .. \
+@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \
+@GT_YES@ $(SHELL) ./config.status
+@GT_NO@.PHONY: intlh.inst
+@GT_NO@inthl.inst:
+
# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/intl/VERSION b/intl/VERSION
index a17083c..2e966b5 100644
--- a/intl/VERSION
+++ b/intl/VERSION
@@ -1 +1 @@
-GNU gettext library from gettext-0.10.12
+GNU gettext library from gettext-0.10.16
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index 7562f69..c3adee3 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -1,5 +1,5 @@
/* dcgettext.c -- implementation of the dcgettext(3) function
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 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
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef __GNUC__
# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
#else
# if defined HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
@@ -85,13 +86,16 @@ void free ();
file and the name space must not be polluted. */
# define getcwd __getcwd
# define stpcpy __stpcpy
-#endif
-
-#if !defined HAVE_GETCWD && !defined _LIBC
-char *getwd ();
-# define getcwd(buf, max) getwd (buf)
#else
+# if !defined HAVE_GETCWD
+char *getwd ();
+# define getcwd(buf, max) getwd (buf)
+# else
char *getcwd ();
+# endif
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
#endif
/* Amount to increase buffer size by in each try. */
@@ -151,13 +155,49 @@ 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,
const char *categoryname));
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+#endif /* have alloca */
+
+
/* Names for the libintl functions are a problem. They must not clash
with existing names and they should follow ANSI C. But this source
code is also used in GNU C Library where the names have a __
@@ -176,7 +216,10 @@ DCGETTEXT (domainname, msgid, category)
const char *msgid;
int category;
{
- struct loaded_domain *domain;
+#ifndef HAVE_ALLOCA
+ struct block_list *alloca_list = NULL;
+#endif
+ struct loaded_l10nfile *domain;
struct binding *binding;
const char *categoryname;
const char *categoryvalue;
@@ -225,12 +268,14 @@ DCGETTEXT (domainname, msgid, category)
path_max += 2; /* The getcwd docs say to do this. */
dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
errno = 0;
while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
{
path_max += PATH_INCR;
dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
errno = 0;
}
@@ -238,6 +283,7 @@ DCGETTEXT (domainname, msgid, category)
{
/* We cannot get the current working directory. Don't signal an
error but simply return the default string. */
+ FREE_BLOCKS (block_list);
errno = saved_errno;
return (char *) msgid;
}
@@ -246,12 +292,7 @@ DCGETTEXT (domainname, msgid, category)
we avoid the non-standard function stpcpy. In GNU C Library
this function is available, though. Also allow the symbol
HAVE_STPCPY to be defined. */
-#if defined _LIBC || defined HAVE_STPCPY
stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
-#else
- strcat (dirname, "/");
- strcat (dirname, binding->dirname);
-#endif
}
/* Now determine the symbolic name of CATEGORY and its value. */
@@ -260,23 +301,18 @@ DCGETTEXT (domainname, msgid, category)
xdomainname = (char *) alloca (strlen (categoryname)
+ strlen (domainname) + 5);
+ ADD_BLOCK (block_list, xdomainname);
/* We don't want libintl.a to depend on any other library. So we
avoid the non-standard function stpcpy. In GNU C Library this
function is available, though. Also allow the symbol HAVE_STPCPY
to be defined. */
-#if defined _LIBC || defined HAVE_STPCPY
stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
domainname),
".mo");
-#else
- strcpy (xdomainname, categoryname);
- strcat (xdomainname, "/");
- strcat (xdomainname, domainname);
- strcat (xdomainname, ".mo");
-#endif
/* Creating working area. */
single_locale = (char *) alloca (strlen (categoryvalue) + 1);
+ ADD_BLOCK (block_list, single_locale);
/* Search for the given string. This is a loop because we perhaps
@@ -308,6 +344,7 @@ DCGETTEXT (domainname, msgid, category)
if (strcmp (single_locale, "C") == 0
|| strcmp (single_locale, "POSIX") == 0)
{
+ FREE_BLOCKS (block_list);
errno = saved_errno;
return (char *) msgid;
}
@@ -336,6 +373,7 @@ DCGETTEXT (domainname, msgid, category)
if (retval != NULL)
{
+ FREE_BLOCKS (block_list);
errno = saved_errno;
return retval;
}
@@ -351,18 +389,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)
{
@@ -435,7 +476,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;
@@ -531,3 +573,21 @@ static const char *guess_category_value (category, categoryname)
return "C";
#endif
}
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/intl/finddomain.c b/intl/finddomain.c
index e41833e..a1b2a2e 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -65,75 +65,38 @@ void free ();
because some ANSI C functions will require linking with this object
file and the name space must not be polluted. */
# define stpcpy(dest, src) __stpcpy(dest, src)
+#else
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
#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));
-
-/* Substitution for systems lacking this function in their C library. */
-#if !_LIBC && !HAVE_STPCPY
-static char *stpcpy__ PARAMS ((char *dest, const char *src));
-# define stpcpy(dest, src) stpcpy__ (dest, src)
-#endif
+static struct loaded_l10nfile *_nl_loaded_domains;
/* 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]
@@ -156,15 +119,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;
@@ -177,8 +141,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 */
}
@@ -200,123 +162,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;
@@ -332,12 +187,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. */
@@ -347,215 +197,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
@@ -564,7 +205,7 @@ normalize_codeset (codeset)
to be defined. */
#if !_LIBC && !HAVE_STPCPY
static char *
-stpcpy__ (dest, src)
+stpcpy (dest, src)
char *dest;
const char *src;
{
diff --git a/intl/gettextP.h b/intl/gettextP.h
index 2d4536b..74a76f5 100644
--- a/intl/gettextP.h
+++ b/intl/gettextP.h
@@ -18,6 +18,8 @@ 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
@@ -45,12 +47,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;
@@ -67,12 +63,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/loadmsgcat.c b/intl/loadmsgcat.c
index d98f365..4b98ec8 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,5 +1,5 @@
/* loadmsgcat.c -- load needed message catalogs
- Copyright (C) 1995 Software Foundation, Inc.
+ Copyright (C) 1995, 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
@@ -61,8 +61,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;
@@ -71,19 +71,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;
@@ -156,6 +157,12 @@ _nl_load_domain (domain)
return;
}
+ domain_file->data
+ = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
+ if (domain_file->data == NULL)
+ return;
+
+ domain = (struct loaded_domain *) domain_file->data;
domain->data = (char *) data;
domain->must_swap = data->magic != _MAGIC;
@@ -181,11 +188,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/localealias.c b/intl/localealias.c
index 02fa8a7..fb5c26c 100644
--- a/intl/localealias.c
+++ b/intl/localealias.c
@@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef __GNUC__
# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
#else
# if defined HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
@@ -73,6 +74,41 @@ void free ();
# define strcasecmp __strcasecmp
#endif
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+#endif /* have alloca */
+
+
struct alias_map
{
const char *alias;
@@ -147,18 +183,25 @@ read_alias_file (fname, fname_len)
const char *fname;
int fname_len;
{
+#ifndef HAVE_ALLOCA
+ struct block_list *alloca_list = NULL;
+#endif
FILE *fp;
char *full_fname;
size_t added;
static const char aliasfile[] = "/locale.alias";
full_fname = (char *) alloca (fname_len + sizeof aliasfile);
+ ADD_BLOCK (block_list, full_fname);
memcpy (full_fname, fname, fname_len);
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
fp = fopen (full_fname, "r");
if (fp == NULL)
- return 0;
+ {
+ FREE_BLOCKS (block_list);
+ return 0;
+ }
added = 0;
while (!feof (fp))
@@ -223,14 +266,20 @@ read_alias_file (fname, fname_len)
len = strlen (alias) + 1;
tp = (char *) malloc (len);
if (tp == NULL)
- return added;
+ {
+ FREE_BLOCKS (block_list);
+ return added;
+ }
memcpy (tp, alias, len);
map[nmap].alias = tp;
len = strlen (value) + 1;
tp = (char *) malloc (len);
if (tp == NULL)
- return added;
+ {
+ FREE_BLOCKS (block_list);
+ return added;
+ }
memcpy (tp, value, len);
map[nmap].value = tp;
@@ -259,6 +308,7 @@ read_alias_file (fname, fname_len)
qsort (map, nmap, sizeof (struct alias_map),
(int (*) PARAMS ((const void *, const void *))) alias_compare);
+ FREE_BLOCKS (block_list);
return added;
}