summaryrefslogtreecommitdiff
path: root/intl/finddomain.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/finddomain.c')
-rw-r--r--intl/finddomain.c414
1 files changed, 27 insertions, 387 deletions
diff --git a/intl/finddomain.c b/intl/finddomain.c
index 3ced26fa4b..bb4609e864 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