diff options
Diffstat (limited to 'intl')
-rw-r--r-- | intl/Makefile | 13 | ||||
-rw-r--r-- | intl/dcgettext.c | 30 | ||||
-rw-r--r-- | intl/explodename.c | 167 | ||||
-rw-r--r-- | intl/finddomain.c | 414 | ||||
-rw-r--r-- | intl/gettextP.h | 28 | ||||
-rw-r--r-- | intl/l10nflist.c | 262 | ||||
-rw-r--r-- | intl/loadinfo.h | 48 | ||||
-rw-r--r-- | intl/loadmsgcat.c | 34 | ||||
-rw-r--r-- | intl/locale.alias | 52 |
9 files changed, 612 insertions, 436 deletions
diff --git a/intl/Makefile b/intl/Makefile index 159d1b1534..9d97088d4a 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 7d739d32c3..6c8963f720 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 0000000000..2fd8be014d --- /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 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 diff --git a/intl/gettextP.h b/intl/gettextP.h index 34196a0859..c37adaba0f 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 0000000000..b0fdf51d73 --- /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 0000000000..00aa1c9d85 --- /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 0f5bfd5b9d..1daf72a09f 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 0000000000..cf1f6eea83 --- /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 |