diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2000-01-22 05:50:49 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2000-01-22 05:50:49 +0000 |
| commit | abbffdf981c8bb03312024107715d58902914f11 (patch) | |
| tree | 168a2fd362a2c159507b4ed0d2391b6ff3f1e575 /intl | |
| parent | 0b9fbf003af00a2a22164333bbe709aa9abbcdc9 (diff) | |
| download | glibc-abbffdf981c8bb03312024107715d58902914f11.tar.xz glibc-abbffdf981c8bb03312024107715d58902914f11.zip | |
Update.
2000-01-21 Ulrich Drepper <drepper@cygnus.com>
* intl/Makefile (routines): Add dcigettext, dcngettext, dngettxt,
ngettext, and plural.
(distribute): Add plural.y, po2test.sed, and tst-gettext.sh.
(test-srcs): Add tst-gettext.
(before-compile): Add $(objpfx)msgs.h.
Add rules for plural.c and msgs.h generation and running tst-gettext.\
* intl/Versions [GLIBC_2.2]: Add __dcngettext, dcngettext, dngettext,
and ngettext.
* intl/dcgettext.c: Move most code into dcigettext.c. Add call
dcigettext with appropriate parameters.
* intl/dcigettext.c: New file.
* intl/dcngettext.c: New file.
* intl/dngettext.c: New file.
* intl/ngettext.c: New file.
* intl/gettextP.h (struct expression): Define.
(struct loaded_domain): Add plural and nplurals members.
Add prototypes for new internal functions.
* intl/libintl.h: Declare new functions. Add optimizations for them.
* intl/loadinfo.h: Add new parameter to _nl_find_msg declaration.
* intl/loadmsgcat.c (_nl_load_domain): Search for plural information in
header entry and parse and store the expression.
* intl/plural.y: New file.
* intl/po2test.sed: New file.
* intl/tst-gettext.c: New file.
* intl/tst-gettext.sh: New file.
* intl/gettext.c: Call __dcgettext directly.
Diffstat (limited to 'intl')
| -rw-r--r-- | intl/Makefile | 30 | ||||
| -rw-r--r-- | intl/Versions | 10 | ||||
| -rw-r--r-- | intl/dcgettext.c | 835 | ||||
| -rw-r--r-- | intl/dcigettext.c | 1000 | ||||
| -rw-r--r-- | intl/dcngettext.c | 64 | ||||
| -rw-r--r-- | intl/dngettext.c | 67 | ||||
| -rw-r--r-- | intl/gettext.c | 8 | ||||
| -rw-r--r-- | intl/gettextP.h | 78 | ||||
| -rw-r--r-- | intl/libintl.h | 25 | ||||
| -rw-r--r-- | intl/loadinfo.h | 4 | ||||
| -rw-r--r-- | intl/loadmsgcat.c | 84 | ||||
| -rw-r--r-- | intl/ngettext.c | 78 | ||||
| -rw-r--r-- | intl/plural.c | 1218 | ||||
| -rw-r--r-- | intl/plural.y | 290 | ||||
| -rw-r--r-- | intl/po2test.sed | 70 | ||||
| -rw-r--r-- | intl/tst-gettext.c | 322 | ||||
| -rwxr-xr-x | intl/tst-gettext.sh | 41 |
17 files changed, 3378 insertions, 846 deletions
diff --git a/intl/Makefile b/intl/Makefile index 4712179290..21c73e7566 100644 --- a/intl/Makefile +++ b/intl/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +# Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -21,16 +21,40 @@ subdir = intl headers = libintl.h routines = bindtextdom dcgettext dgettext gettext \ + dcigettext dcngettext dngettext ngettext \ finddomain loadmsgcat localealias textdomain \ - l10nflist explodename -distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias + l10nflist explodename plural +distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias \ + plural.y po2test.sed tst-gettext.sh + +test-srcs := tst-gettext + +before-compile = $(objpfx)msgs.h install-others = $(inst_msgcatdir)/locale.alias +plural.c: plural.y + $(YACC) $(YFLAGS) $@ $^ +ifeq ($(with-cvs),yes) + test ! -d CVS || cvs $(CVSOPTS) commit -m'$(YACC) $(YFLAGS) $@ $^' $@ +endif +$(objpfx)plural.o: plural.c + include ../Rules +.PHONY: do-gettext-test +tests: do-gettext-test +do-gettext-test: tst-gettext.sh $(objpfx)tst-gettext + $(SHELL) -e $< $(common-objpfx) $(objpfx) + +$(objpfx)msgs.h: po2test.sed ../po/de.po + sed -f $^ > $@ + +CFLAGS-tst-gettext.c = -DTESTSTRS_H=\"$(objpfx)msgs.h\" + CPPFLAGS += -D'GNULOCALEDIR="$(msgcatdir)"' \ -D'LOCALE_ALIAS_PATH="$(msgcatdir):$(i18ndir)"' +YFLAGS = --name-prefix=__gettext --output $(inst_msgcatdir)/locale.alias: locale.alias $(+force) $(do-install) diff --git a/intl/Versions b/intl/Versions index acf0ce0ed9..c784f67a66 100644 --- a/intl/Versions +++ b/intl/Versions @@ -18,4 +18,14 @@ libc { # t* textdomain; } + GLIBC_2.2 { + # functions used in inline functions or macros + __dcngettext; + + # d* + dcngettext; dngettext; + + # n* + ngettext; + } } diff --git a/intl/dcgettext.c b/intl/dcgettext.c index 8e51970495..5be8e4ff70 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -1,5 +1,5 @@ /* Implementation of the dcgettext(3) function. - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. @@ -23,70 +23,6 @@ # include <config.h> #endif -#include <sys/types.h> - -#if defined __GNUC__ && !defined C_ALLOCA -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# if (defined HAVE_ALLOCA_H || defined _LIBC) && !defined C_ALLOCA -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -#endif - -#include <errno.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#if defined STDC_HEADERS || defined _LIBC -# include <stdlib.h> -#else -char *getenv (); -# ifdef HAVE_MALLOC_H -# include <malloc.h> -# else -void free (); -# endif -#endif - -#if defined HAVE_STRING_H || defined _LIBC -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -# endif -# include <string.h> -#else -# include <strings.h> -#endif -#if !HAVE_STRCHR && !defined _LIBC -# ifndef strchr -# define strchr index -# endif -#endif - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#if defined HAVE_LOCALE_H || defined _LIBC -# include <locale.h> -#endif - -#if defined HAVE_SYS_PARAM_H || defined _LIBC -# include <sys/param.h> -#endif - #include "gettext.h" #include "gettextP.h" #ifdef _LIBC @@ -94,225 +30,19 @@ void free (); #else # include "libgettext.h" #endif -#include "hash-string.h" - -/* Thread safetyness. */ -#ifdef _LIBC -# include <bits/libc-lock.h> -#endif /* @@ end of prolog @@ */ -#ifdef _LIBC -/* 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 getcwd __getcwd -# ifndef stpcpy -# define stpcpy __stpcpy -# endif -#else -# if !defined HAVE_GETCWD -char *getwd (); -# define getcwd(buf, max) getwd (buf) -# else -char *getcwd (); -# endif -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -# ifndef HAVE_MEMPCPY -static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); -# endif -#endif - -/* Amount to increase buffer size by in each try. */ -#define PATH_INCR 32 - -/* The following is from pathmax.h. */ -/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define - PATH_MAX but might cause redefinition warnings when sys/param.h is - later included (as on MORE/BSD 4.3). */ -#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__) -# include <limits.h> -#endif - -#ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 255 -#endif - -#if !defined PATH_MAX && defined _PC_PATH_MAX -# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) -#endif - -/* Don't include sys/param.h if it already has been. */ -#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN -# include <sys/param.h> -#endif - -#if !defined PATH_MAX && defined MAXPATHLEN -# define PATH_MAX MAXPATHLEN -#endif - -#ifndef PATH_MAX -# define PATH_MAX _POSIX_PATH_MAX -#endif - -/* XPG3 defines the result of `setlocale (category, NULL)' as: - ``Directs `setlocale()' to query `category' and return the current - setting of `local'.'' - However it does not specify the exact format. And even worse: POSIX - defines this not at all. So we can use this feature only on selected - system (e.g. those using GNU C Library). */ -#ifdef _LIBC -# define HAVE_LOCALE_NULL -#endif - -/* We want to allocate a string at the end of the struct. gcc makes - this easy. */ -#ifdef __GNUC__ -# define ZERO 0 -#else -# define ZERO 1 -#endif - -/* This is the type used for the search tree where known translations - are stored. */ -struct known_translation_t -{ - /* Domain in which to search. */ - char *domain; - - /* The category. */ - int category; - - /* State of the catalog counter at the point the string was found. */ - int counter; - - /* And finally the translation. */ - const char *translation; - - /* Pointer to the string in question. */ - char msgid[ZERO]; -}; - -/* Root of the search tree with known translations. We can use this - only if the system provides the `tsearch' function family. */ -#if defined HAVE_TSEARCH || defined _LIBC -# include <search.h> - -static void *root; - -# ifdef _LIBC -# define tsearch __tsearch -# endif - -/* Function to compare two entries in the table of known translations. */ -static int -transcmp (const void *p1, const void *p2) -{ - struct known_translation_t *s1 = (struct known_translation_t *) p1; - struct known_translation_t *s2 = (struct known_translation_t *) p2; - int result; - - result = strcmp (s1->msgid, s2->msgid); - if (result == 0) - { - result = strcmp (s1->msgid, s2->msgid); - if (result == 0) - /* We compare the category last (though this is the cheapest - operation) since it is hopefully always the same (namely - LC_MESSAGES). */ - result = s1->category - s2->category; - } - - return result; -} -#endif - -/* Name of the default domain used for gettext(3) prior any call to - textdomain(3). The default value for this is "messages". */ -const char _nl_default_default_domain[] = "messages"; - -/* Value used as the default domain for gettext(3). */ -const char *_nl_current_default_domain = _nl_default_default_domain; - -/* Contains the default location of the message catalogs. */ -const char _nl_default_dirname[] = GNULOCALEDIR; - -/* List with bindings of specific domains created by bindtextdomain() - calls. */ -struct binding *_nl_domain_bindings; - -/* Prototypes for local functions. */ -static const char *category_to_name PARAMS ((int category)) internal_function; -static const char *guess_category_value PARAMS ((int category, - const char *categoryname)) - internal_function; - - -/* For those loosing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -/* Nothing has to be done. */ -# define ADD_BLOCK(list, address) /* nothing */ -# define FREE_BLOCKS(list) /* nothing */ -#else -struct block_list -{ - void *address; - struct block_list *next; -}; -# define ADD_BLOCK(list, addr) \ - do { \ - struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ - /* If we cannot get a free block we cannot add the new element to \ - the list. */ \ - if (newp != NULL) { \ - newp->address = (addr); \ - newp->next = (list); \ - (list) = newp; \ - } \ - } while (0) -# define FREE_BLOCKS(list) \ - do { \ - while (list != NULL) { \ - struct block_list *old = list; \ - list = list->next; \ - free (old); \ - } \ - } while (0) -# undef alloca -# define alloca(size) (malloc (size)) -#endif /* have alloca */ - - /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define DCGETTEXT __dcgettext +# define DCIGETTEXT __dcigettext #else # define DCGETTEXT dcgettext__ -#endif - -/* Checking whether the binaries runs SUID must be done and glibc provides - easier methods therefore we make a difference here. */ -#ifdef _LIBC -# define ENABLE_SECURE __libc_enable_secure -# define DETERMINE_SECURE -#else -static int enable_secure; -# define ENABLE_SECURE (enable_secure == 1) -# define DETERMINE_SECURE \ - if (enable_secure == 0) \ - { \ - if (getuid () != geteuid () || getgid () != getegid ()) \ - enable_secure = 1; \ - else \ - enable_secure = -1; \ - } +# define DCIGETTEXT dcigettext__ #endif /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY @@ -323,567 +53,10 @@ DCGETTEXT (domainname, msgid, category) const char *msgid; int category; { -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif - struct loaded_l10nfile *domain; - struct binding *binding; - const char *categoryname; - const char *categoryvalue; - char *dirname, *xdomainname; - char *single_locale; - char *retval; - int saved_errno; -#if defined HAVE_TSEARCH || defined _LIBC - struct known_translation_t *search; - struct known_translation_t **foundp; - size_t msgid_len = strlen (msgid) + 1; -#endif - size_t domainname_len; - - /* If no real MSGID is given return NULL. */ - if (msgid == NULL) - return NULL; - -#if defined HAVE_TSEARCH || defined _LIBC - /* Try to find the translation among those which we found at some time. */ - search = (struct known_translation_t *) alloca (sizeof (*search) - + msgid_len); - memcpy (search->msgid, msgid, msgid_len); - search->domain = (char *) domainname; - search->category = category; - - foundp = (struct known_translation_t **) tfind (search, &root, transcmp); - if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) - return (char *) (*foundp)->translation; -#endif - - /* Preserve the `errno' value. */ - saved_errno = errno; - - /* See whether this is a SUID binary or not. */ - DETERMINE_SECURE; - - /* If DOMAINNAME is NULL, we are interested in the default domain. If - CATEGORY is not LC_MESSAGES this might not make much sense but the - definition left this undefined. */ - if (domainname == NULL) - domainname = _nl_current_default_domain; - - /* First find matching binding. */ - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding == NULL) - dirname = (char *) _nl_default_dirname; - else if (binding->dirname[0] == '/') - dirname = binding->dirname; - else - { - /* We have a relative path. Make it absolute now. */ - size_t dirname_len = strlen (binding->dirname) + 1; - size_t path_max; - char *ret; - - path_max = (unsigned int) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ - - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - - __set_errno (0); - while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE) - { - path_max += PATH_INCR; - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - __set_errno (0); - } - - if (ret == NULL) - { - /* We cannot get the current working directory. Don't signal an - error but simply return the default string. */ - FREE_BLOCKS (block_list); - __set_errno (saved_errno); - return (char *) msgid; - } - - stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); - } - - /* Now determine the symbolic name of CATEGORY and its value. */ - categoryname = category_to_name (category); - categoryvalue = guess_category_value (category, categoryname); - - domainname_len = strlen (domainname); - xdomainname = (char *) alloca (strlen (categoryname) - + domainname_len + 5); - ADD_BLOCK (block_list, xdomainname); - - stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), - domainname, domainname_len), - ".mo"); - - /* Creating working area. */ - single_locale = (char *) alloca (strlen (categoryvalue) + 1); - ADD_BLOCK (block_list, single_locale); - - - /* Search for the given string. This is a loop because we perhaps - got an ordered list of languages to consider for the translation. */ - while (1) - { - /* Make CATEGORYVALUE point to the next element of the list. */ - while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') - ++categoryvalue; - if (categoryvalue[0] == '\0') - { - /* The whole contents of CATEGORYVALUE has been searched but - no valid entry has been found. We solve this situation - by implicitly appending a "C" entry, i.e. no translation - will take place. */ - single_locale[0] = 'C'; - single_locale[1] = '\0'; - } - else - { - char *cp = single_locale; - while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') - *cp++ = *categoryvalue++; - *cp = '\0'; - - /* When this is a SUID binary we must not allow accessing files - outside the dedicated directories. */ - if (ENABLE_SECURE - && (memchr (single_locale, '/', - _nl_find_language (single_locale) - single_locale) - != NULL)) - /* Ingore this entry. */ - continue; - } - - /* If the current locale value is C (or POSIX) we don't load a - domain. Return the MSGID. */ - if (strcmp (single_locale, "C") == 0 - || strcmp (single_locale, "POSIX") == 0) - { - FREE_BLOCKS (block_list); - __set_errno (saved_errno); - return (char *) msgid; - } - - - /* Find structure describing the message catalog matching the - DOMAINNAME and CATEGORY. */ - domain = _nl_find_domain (dirname, single_locale, xdomainname); - - if (domain != NULL) - { - retval = _nl_find_msg (domain, msgid); - - if (retval == NULL) - { - int cnt; - - for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) - { - retval = _nl_find_msg (domain->successor[cnt], msgid); - - if (retval != NULL) - break; - } - } - - if (retval != NULL) - { - FREE_BLOCKS (block_list); - __set_errno (saved_errno); -#if defined HAVE_TSEARCH || defined _LIBC - if (foundp == NULL) - { - /* Create a new entry and add it to the search tree. */ - struct known_translation_t *newp; - - newp = (struct known_translation_t *) - malloc (sizeof (*newp) + msgid_len - + domainname_len + 1 - ZERO); - if (newp != NULL) - { - newp->domain = mempcpy (newp->msgid, msgid, msgid_len); - memcpy (newp->domain, domainname, domainname_len + 1); - newp->category = category; - newp->counter = _nl_msg_cat_cntr; - newp->translation = retval; - - /* Insert the entry in the search tree. */ - foundp = (struct known_translation_t **) - tsearch (newp, &root, transcmp); - if (&newp != foundp) - /* The insert failed. */ - free (newp); - } - } - else - { - /* We can update the existing entry. */ - (*foundp)->counter = _nl_msg_cat_cntr; - (*foundp)->translation = retval; - } -#endif - return retval; - } - } - } - /* NOTREACHED */ + return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__dcgettext, dcgettext); #endif - - -char * |
