diff options
Diffstat (limited to 'intl/finddomain.c')
-rw-r--r-- | intl/finddomain.c | 414 |
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 |