diff options
Diffstat (limited to 'intl')
-rw-r--r-- | intl/Makefile | 15 | ||||
-rw-r--r-- | intl/dcgettext.c | 15 | ||||
-rw-r--r-- | intl/finddomain.c | 221 | ||||
-rw-r--r-- | intl/gettext.c | 2 | ||||
-rw-r--r-- | intl/libintl.h | 109 | ||||
-rw-r--r-- | intl/loadmsgcat.c | 7 | ||||
-rw-r--r-- | intl/localealias.c | 10 |
7 files changed, 268 insertions, 111 deletions
diff --git a/intl/Makefile b/intl/Makefile index f7ef998fca..6e588fc88a 100644 --- a/intl/Makefile +++ b/intl/Makefile @@ -19,6 +19,7 @@ # Cambridge, MA 02139, USA. subdir = intl +headers = libintl.h routines = bindtextdom dcgettext dgettext gettext \ finddomain loadmsgcat localealias textdomain distribute = gettext.h gettextP.h hash-string.h @@ -27,3 +28,17 @@ include ../Rules CPPFLAGS += -D'GNULOCALEDIR="$(localedir)"' \ -D'LOCALE_ALIAS_PATH="$(localedir):$(nlsdir)"' + +ifdef gettext-srcdir + +%:: $(gettext-srcdir)/intl/%.glibc; $(copysrc) +%:: $(gettext-srcdir)/intl/%; $(copysrc) + +define copysrc +cp -f $< $@.new +chmod a-w $@.new +mv -f $@.new $@ +test ! -d CVS || cvs commit -m'Updated from $<' $@ +endef + +endif diff --git a/intl/dcgettext.c b/intl/dcgettext.c index 91025be89b..09e0443494 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -317,14 +317,13 @@ DCGETTEXT (domainname, msgid, category) { int cnt; - for (cnt = 6; cnt >= 0 && retval == NULL; --cnt) - if (domain->successor[cnt] != NULL) - { - retval = find_msg (domain->successor[cnt], msgid); - - if (domain->successor[cnt]->data == NULL) - domain->successor[cnt] = NULL; - } + for (cnt = 0; domain->successor[cnt] != NULL; --cnt) + { + retval = find_msg (domain->successor[cnt], msgid); + + if (retval != NULL) + break; + } } if (retval != NULL) diff --git a/intl/finddomain.c b/intl/finddomain.c index 19cf2d7581..007a87e075 100644 --- a/intl/finddomain.c +++ b/intl/finddomain.c @@ -95,6 +95,11 @@ static struct loaded_domain *make_entry_rec __P ((const char *dirname, const char *domainname, int do_allocate)); +/* Substitution for systems lacking this function in their C library. */ +#if !_LIBC && !HAVE_STPCPY +static char *stpcpy __P ((char *dest, const char *src)); +#endif + /* Return a data structure describing the message catalog described by the DOMAINNAME and CATEGORY parameters with respect to the currently @@ -155,9 +160,9 @@ _nl_find_domain (dirname, locale, domainname) if (retval->data != NULL) return retval; - for (cnt = 6; cnt >= 0; --cnt) + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) { - if (retval->successor[cnt] == 0) + if (retval->successor[cnt]->decided == 0) _nl_load_domain (retval->successor[cnt]); if (retval->successor[cnt]->data != NULL) @@ -279,13 +284,13 @@ _nl_find_domain (dirname, locale, domainname) separator character in the file name, not for XPG syntax. */ if (syntax == xpg) { - if (territory[0] == '\0') + if (territory != NULL && territory[0] == '\0') mask &= ~TERRITORY; - if (codeset[0] == '\0') + if (codeset != NULL && codeset[0] == '\0') mask &= ~XPG_CODESET; - if (modifier[0] == '\0') + if (modifier != NULL && modifier[0] == '\0') mask &= ~XPG_MODIFIER; } @@ -340,107 +345,110 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, const char *domain; int do_allocate; { - struct loaded_domain *retval, *last; - char *filename, *cp; + char *filename = NULL; + struct loaded_domain *last = NULL; + struct loaded_domain *retval; + char *cp; size_t entries; int cnt; - /* Allocate room for the full file name. */ - filename = (char *) malloc (strlen (dirname) + 1 - + strlen (language) - + ((mask & TERRITORY) != 0 - ? strlen (territory) : 0) - + ((mask & XPG_CODESET) != 0 - ? strlen (codeset) : 0) - + ((mask & XPG_MODIFIER) != 0 ? - strlen (modifier) : 0) - + ((mask & CEN_SPECIAL) != 0 - ? strlen (special) : 0) - + ((mask & CEN_SPONSOR) != 0 - ? strlen (sponsor) : 0) - + ((mask & CEN_REVISION) != 0 - ? strlen (revision) : 0) + 1 - + strlen (domain) + 1); - - if (filename == NULL) - return NULL; - retval = NULL; - last = NULL; + /* 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) + { + /* Allocate room for the full file name. */ + filename = (char *) malloc (strlen (dirname) + 1 + + strlen (language) + + ((mask & TERRITORY) != 0 + ? strlen (territory) : 0) + + ((mask & XPG_CODESET) != 0 + ? strlen (codeset) : 0) + + ((mask & XPG_MODIFIER) != 0 ? + strlen (modifier) : 0) + + ((mask & CEN_SPECIAL) != 0 + ? strlen (special) : 0) + + ((mask & CEN_SPONSOR) != 0 + ? strlen (sponsor) : 0) + + ((mask & CEN_REVISION) != 0 + ? strlen (revision) : 0) + 1 + + strlen (domain) + 1); + + if (filename == NULL) + return NULL; - /* 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 -# define stpcpy(p, s) \ - (strcpy (p, s), strchr (p, '\0')) -#endif + retval = NULL; + last = NULL; - /* Construct file name. */ - cp = stpcpy (filename, dirname); - *cp++ = '/'; - cp = stpcpy (cp, language); + /* 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++ = '.'; + if ((mask & TERRITORY) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, territory); + } + if ((mask & XPG_CODESET) != 0) + { + *cp++ = '.'; cp = stpcpy (cp, 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) - { - int compare = strcmp (retval->filename, filename); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) + } + if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) { - /* It's not in the list. */ - retval = NULL; - break; + /* 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); } - last = retval; - } - - if (retval != NULL || do_allocate == 0) - { - free (filename); - return retval; + *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)); @@ -453,8 +461,8 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, if (last == NULL) { retval->next = _nl_loaded_domains; - _nl_loaded_domains = retval; - } + _nl_loaded_domains = retval; + } else { retval->next = last->next; @@ -474,3 +482,22 @@ make_entry_rec (dirname, mask, language, territory, codeset, modifier, return retval; } + + +/* @@ 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/gettext.c b/intl/gettext.c index 204d85ecd4..7bed6369b4 100644 --- a/intl/gettext.c +++ b/intl/gettext.c @@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ # ifdef HAVE_STRING_H # include <string.h> # else -# define NULL 0 +# define NULL ((void *) 0) # endif # endif #endif diff --git a/intl/libintl.h b/intl/libintl.h new file mode 100644 index 0000000000..f9a150d3df --- /dev/null +++ b/intl/libintl.h @@ -0,0 +1,109 @@ +/* libgettext.h -- Message catalogs for internationalization. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ulrich Drepper. +This file is derived from the file libgettext.h in the GNU gettext package. + +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. */ + +#ifndef _LIBINTL_H +#define _LIBINTL_H 1 +#include <features.h> + +#include <locale.h> + +#define __need_NULL +#include <stddef.h> + +/* We define an additional symbol to signal that we use the GNU + implementation of gettext. */ +#define __USE_GNU_GETTEXT 1 + +__BEGIN_DECLS + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +extern char *gettext __P ((const char *__msgid)); +extern char *__gettext __P ((const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current + LC_MESSAGES locale. */ +extern char *dgettext __P ((const char *__domainname, const char *__msgid)); +extern char *__dgettext __P ((const char *__domainname, const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +extern char *dcgettext __P ((const char *__domainname, const char *__msgid, + int __category)); +extern char *__dcgettext __P ((const char *__domainname, const char *__msgid, + int __category)); + + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +extern char *textdomain __P ((const char *__domainname)); +extern char *__textdomain __P ((const char *__domainname)); + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +extern char *bindtextdomain __P ((const char *__domainname, + const char *__dirname)); +extern char *__bindtextdomain __P ((const char *__domainname, + const char *__dirname)); + + +/* Optimized version of the function above. */ +#if defined __OPTIMIZED +/* These must be a macro. Inlined functions are useless because the + `__builtin_constant_p' predicate in dcgettext would always return + false. */ + +# define gettext (msgid) dgettext (NULL, msgid) + +# define dgettext (domainname, msgid) \ + dcgettext (domainname, msgid, LC_MESSAGES) + +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define dcgettext(domainname, msgid, category) \ + (__extension__ \ + ({ \ + char *result; \ + if (__builtin_constant_p (msgid)) \ + { \ + extern int _nl_msg_cat_cntr; \ + static char *__translation__; \ + static int __catalog_counter__; \ + if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \ + { \ + __translation__ = \ + __dcgettext ((domainname), (msgid), (category)); \ + __catalog_counter__ = _nl_msg_cat_cntr; \ + } \ + result = __translation__; \ + } \ + else \ + result = __dcgettext ((domainname), (msgid), (category)); \ + result; \ + })) +# endif +#endif /* Optimizing. */ + + +__END_DECLS + +#endif /* libintl.h */ diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index b05c630724..d98f365bf9 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -75,6 +75,13 @@ _nl_load_domain (domain) domain->decided = 1; domain->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) + return; + /* Try to open the addressed file. */ fd = open (domain->filename, O_RDONLY); if (fd == -1) diff --git a/intl/localealias.c b/intl/localealias.c index fc3bc1238b..47f2cbffa8 100644 --- a/intl/localealias.c +++ b/intl/localealias.c @@ -1,5 +1,5 @@ /* localealias.c -- handle aliases for locale names - Copyright (C) 1995 Software Foundation, Inc. + Copyright (C) 1995 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 @@ -125,7 +125,7 @@ _nl_expand_alias (name) { const char *start; - while (locale_alias_path[0] != '\0' && locale_alias_path[0] == ':') + while (locale_alias_path[0] == ':') ++locale_alias_path; start = locale_alias_path; @@ -239,7 +239,7 @@ read_alias_file (fname, fname_len) } } - /* Possibily not the whole line fits into the buffer. Ignore + /* Possibily not the whole line fitted into the buffer. Ignore the rest of the line. */ while (strchr (cp, '\n') == NULL) { @@ -305,8 +305,8 @@ alias_compare (map1, map2) { /* I know this seems to be odd but the tolower() function in some systems libc cannot handle nonalpha characters. */ - c1 = isalpha (*p1) ? tolower (*p1) : *p1; - c2 = isalpha (*p2) ? tolower (*p2) : *p2; + c1 = isupper (*p1) ? tolower (*p1) : *p1; + c2 = isupper (*p2) ? tolower (*p2) : *p2; if (c1 == '\0') break; } |