diff options
Diffstat (limited to 'intl/finddomain.c')
-rw-r--r-- | intl/finddomain.c | 135 |
1 files changed, 103 insertions, 32 deletions
diff --git a/intl/finddomain.c b/intl/finddomain.c index 07c5f44799..45773ee306 100644 --- a/intl/finddomain.c +++ b/intl/finddomain.c @@ -1,5 +1,5 @@ /* finddomain.c -- handle list of needed message catalogs - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. This program is free software; you can redistribute it and/or modify @@ -63,20 +63,21 @@ void free (); /* Rename the non ANSI C functions. This is required by the standard because some ANSI C functions will require linking with this object file and the name space must not be polluted. */ -# define stpcpy __stpcpy +# 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_CODESET 8 -#define TERRITORY 16 -#define CEN_AUDIENCE 32 -#define XPG_MODIFIER 64 +#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_MODIFIER) +#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) /* List of already loaded domains. */ @@ -88,6 +89,7 @@ static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname, const char *language, const char *territory, const char *codeset, + const char *normalized_codeset, const char *modifier, const char *special, const char *sponsor, @@ -95,9 +97,13 @@ static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname, 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)); +static char *stpcpy__ PARAMS ((char *dest, const char *src)); +# define stpcpy(dest, src) stpcpy__ (dest, src) #endif @@ -116,6 +122,7 @@ _nl_find_domain (dirname, locale, domainname) 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; @@ -141,13 +148,14 @@ _nl_find_domain (dirname, locale, domainname) (2) sponsor (3) special (4) codeset - (5) territory - (6) audience/modifier + (5) normalized codeset + (6) territory + (7) audience/modifier */ /* 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, + retval = make_entry_rec (dirname, 0, locale, NULL, NULL, NULL, NULL, NULL, NULL, NULL, domainname, 0); if (retval != NULL) { @@ -225,6 +233,15 @@ _nl_find_domain (dirname, locale, domainname) ++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; + } } } @@ -297,8 +314,8 @@ _nl_find_domain (dirname, locale, domainname) /* Create all possible locale entries which might be interested in generalzation. */ retval = make_entry_rec (dirname, mask, language, territory, codeset, - modifier, special, sponsor, revision, - domainname, 1); + normalized_codeset, modifier, special, sponsor, + revision, domainname, 1); if (retval == NULL) /* This means we are out of core. */ return NULL; @@ -331,13 +348,15 @@ _nl_find_domain (dirname, locale, domainname) static struct loaded_domain * -make_entry_rec (dirname, mask, language, territory, codeset, modifier, - special, sponsor, revision, domain, do_allocate) +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; @@ -358,23 +377,26 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, 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) + 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) : 0) + ? strlen (territory) + 1 : 0) + ((mask & XPG_CODESET) != 0 - ? strlen (codeset) : 0) + ? strlen (codeset) + 1 : 0) + + ((mask & XPG_NORM_CODESET) != 0 + ? strlen (normalized_codeset) + 1 : 0) + ((mask & XPG_MODIFIER) != 0 ? - strlen (modifier) : 0) + strlen (modifier) + 1 : 0) + ((mask & CEN_SPECIAL) != 0 - ? strlen (special) : 0) + ? strlen (special) + 1 : 0) + ((mask & CEN_SPONSOR) != 0 - ? strlen (sponsor) : 0) + ? strlen (sponsor) + 1 : 0) + ((mask & CEN_REVISION) != 0 - ? strlen (revision) : 0) + 1 + ? strlen (revision) + 1 : 0) + 1 + strlen (domain) + 1); if (filename == NULL) @@ -396,7 +418,12 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, if ((mask & XPG_CODESET) != 0) { *cp++ = '.'; - cp = stpcpy (cp, codeset); + cp = stpcpy (cp, codeset); + } + if ((mask & XPG_NORM_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, normalized_codeset); } if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) { @@ -470,20 +497,64 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, } entries = 0; - for (cnt = 126; cnt >= 0; --cnt) + for (cnt = 254; cnt >= 0; --cnt) if (cnt < mask && (cnt & ~mask) == 0 - && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 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, modifier, - special, sponsor, - revision, domain, 1); + 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 @@ -492,7 +563,7 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * -stpcpy (dest, src) +stpcpy__ (dest, src) char *dest; const char *src; { |