diff options
-rw-r--r-- | ChangeLog | 130 | ||||
-rw-r--r-- | intl/Makefile | 2 | ||||
-rw-r--r-- | intl/bindtextdom.c | 17 | ||||
-rw-r--r-- | intl/dcgettext.c | 5 | ||||
-rw-r--r-- | intl/dcigettext.c | 158 | ||||
-rw-r--r-- | intl/dcngettext.c | 5 | ||||
-rw-r--r-- | intl/dgettext.c | 5 | ||||
-rw-r--r-- | intl/dngettext.c | 5 | ||||
-rw-r--r-- | intl/explodename.c | 5 | ||||
-rw-r--r-- | intl/finddomain.c | 5 | ||||
-rw-r--r-- | intl/gettext.c | 7 | ||||
-rw-r--r-- | intl/gettext.h | 9 | ||||
-rw-r--r-- | intl/gettextP.h | 126 | ||||
-rw-r--r-- | intl/l10nflist.c | 4 | ||||
-rw-r--r-- | intl/loadmsgcat.c | 78 | ||||
-rw-r--r-- | intl/localealias.c | 60 | ||||
-rw-r--r-- | intl/ngettext.c | 5 | ||||
-rw-r--r-- | intl/plural.c | 443 | ||||
-rw-r--r-- | intl/plural.y | 328 | ||||
-rw-r--r-- | intl/textdomain.c | 5 |
20 files changed, 901 insertions, 501 deletions
@@ -1,3 +1,133 @@ +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/loadmsgcat.c (_nl_load_domain) [!_LIBC]: Use fstat, not fstat64. + +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/gettextP.h (struct expression): Add operators lnot, less_than, + greater_than, less_or_equal, greater_or_equal. Replace args2/args3 + union by a 'nargs' counter and an 'args[]' array. + * intl/plural.y: Don't include stdarg.h. + (new_exp): Take an array of arguments instead of varargs. + (new_exp_0, new_exp_1, new_exp_2, new_exp_3): New functions. + ('?' ':'): Make right-associative. + (EQUOP2): New token, replaces '=' and '!'. + (CMPOP2): New token. + (ADDOP2): New token, replaces '+' and '-'. + (MULOP2): New token, replaces '*', '/' and '%'. + ('!'): New token. + (exp): Add rules for CMPOP2 and '!'. Don't call YYABORT. + (start): Call YYABORT here. + (FREE_EXPRESSION): Update. + (yylex): Don't skip "\\n". Recognize comparison and '!' operators. + Update for new token symbols. + * intl/loadmsgcat.c (plvar, plone, germanic_plural, + init_germanic_plural): Update. + * intl/dcigettext.c (_nl_find_msg): Optimize for space. + (plural_eval): Recognize comparison and '!' operators. Optimize for + space. + +2001-03-10 Bruno Haible <haible@clisp.cons.org> + + * intl/loadmsgcat.c (_nl_load_domain): locale_charset() doesn't return + NULL any more. + +2001-01-05 Bruno Haible <haible@clisp.cons.org> + + * intl/loadmsgcat.c: Include headers needed for alloca(). + (freea): New macro. + (_nl_load_domain): Add fallback code for platforms lacking alloca. + * intl/localealias.c: (ADD_BLOCK, FREE_BLOCK): Remove macros. + (freea): New macro. + (read_alias_file): Simplify fallback code for platforms lacking + alloca. + +2001-01-07 Bruno Haible <haible@clisp.cons.org> + + * intl/gettextP.h (__gettextdebug): Remove declaration. + (__gettext_free_exp, __gettextparse): Convert prototype to K&R C + syntax. + (gettext_free_exp__, gettextparse__): New non-libc declarations. + * intl/plural.y [!_LIBC]: Define gettextparse__, gettext_free_exp__, + not __gettextparse, __gettext_free_exp. + * intl/loadmsgcat.c [!_LIBC]: Use gettextparse__, not __gettextparse. + +2001-02-24 Bruno Haible <haible@clisp.cons.org> + + * intl/dcigettext.c: Update comment about HAVE_LOCALE_NULL. + +2001-01-05 Bruno Haible <haible@clisp.cons.org> + + * intl/loadmsgcat.c (_nl_load_domain): Add fallback code for platforms + lacking strtoul, like SunOS4. + +2001-01-05 Bruno Haible <haible@clisp.cons.org> + + * intl/l10nflist.c (_nl_normalize_codeset): Use tolower, not _tolower. + +2001-01-05 Bruno Haible <haible@clisp.cons.org> + + * intl/bindtextdom.c (set_binding_values): Convert prototype to K&R C + syntax. + * intl/dcigettext.c (transcmp): Convert to K&R C syntax. + * intl/explodename.c (_nl_find_language): Convert to K&R C syntax. + * intl/plural.y (__gettext_free_exp, yylex, yyerror): Convert to K&R C + syntax. + +2001-01-07 Bruno Haible <haible@clisp.cons.org> + + * intl/gettextP.h (gettext__, dgettext__, dcgettext__, textdomain__, + bindtextdomain__, bind_textdomain_codeset__): New declarations, from + old libgettext.h. + * intl/bindtextdom.c: Include libgnuintl.h instead of libgettext.h. + * intl/dcgettext.c: Likewise. + * intl/dcigettext.c: Likewise. + * intl/dcngettext.c: Likewise. + * intl/dngettext.c: Likewise. + * intl/finddomain.c: Likewise. + * intl/ngettext.c: Likewise. + * intl/textdomain.c: Likewise. + * intl/dgettext.c: Include libgnuintl.h instead of libgettext.h. + Include gettextP.h. + * intl/gettext.c: Likewise. Don't include locale.h. + +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/gettextP.h (ZERO): New macro. + (struct binding): Always use ZERO. + * intl/bindtextdom.c (offsetof): Provide fallback for platforms that + lack it, like SunOS4. + (set_binding_values): Use offsetof, not sizeof. + * intl/dcigettext.c (offsetof): Provide fallback for platforms that + lack it, like SunOS4. + (ZERO): Remove macro. + (struct transmem_list): Use ZERO. + (DCIGETTEXT): Use offsetof, not sizeof. + +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/gettextP.h: Include <stddef.h>. Include gettext.h, for + nls_uint32. + * intl/bindtextdom.c: Don't include gettext.h. + * intl/dcgettext.c: Likewise. + * intl/dcigettext.c: Likewise. + * intl/dcngettext.c: Likewise. + * intl/dngettext.c: Likewise. + * intl/finddomain.c: Likewise. + * intl/localealias.c: Likewise. + * intl/ngettext.c: Likewise. + * intl/plural.y: Likewise. + * intl/textdomain.c: Likewise. + +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/gettext.h: Don't include <stdio.h>. + +2001-03-17 Bruno Haible <haible@clisp.cons.org> + + * intl/Makefile (CPPFLAGS): Set LOCALEDIR instead of GNULOCALEDIR. + * intl/dcigettext.c (_nl_default_dirname): Initialize with LOCALEDIR. + 2001-03-19 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/i386/i686/tempname.c: New file. diff --git a/intl/Makefile b/intl/Makefile index 29cf14e..fc428c6 100644 --- a/intl/Makefile +++ b/intl/Makefile @@ -81,7 +81,7 @@ CFLAGS-tst-translit.c = -DOBJPFX=\"$(objpfx)\" $(objpfx)tst-translit.out: $(objpfx)tst-gettext.out -CPPFLAGS += -D'GNULOCALEDIR="$(msgcatdir)"' \ +CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \ -D'LOCALE_ALIAS_PATH="$(msgcatdir)"' BISONFLAGS = --yacc --name-prefix=__gettext --output diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c index 45000a6..1b22bfc 100644 --- a/intl/bindtextdom.c +++ b/intl/bindtextdom.c @@ -1,5 +1,5 @@ /* Implementation of the bindtextdomain(3) function - Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. 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 @@ -42,9 +42,8 @@ void free (); #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC @@ -65,6 +64,11 @@ void free (); # define _nl_domain_bindings _nl_domain_bindings__ #endif +/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ +#ifndef offsetof +# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) +#endif + /* @@ end of prolog @@ */ /* Contains the default location of the message catalogs. */ @@ -93,8 +97,9 @@ __libc_rwlock_define (extern, _nl_state_lock) #endif /* Prototypes for local functions. */ -static void set_binding_values (const char *domainname, const char **dirnamep, - const char **codesetp); +static void set_binding_values PARAMS ((const char *domainname, + const char **dirnamep, + const char **codesetp)); /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP to be used for the DOMAINNAME message catalog. @@ -234,7 +239,7 @@ set_binding_values (domainname, dirnamep, codesetp) /* We have to create a new binding. */ size_t len = strlen (domainname) + 1; struct binding *new_binding = - (struct binding *) malloc (sizeof (*new_binding) + len); + (struct binding *) malloc (offsetof (struct binding, domainname) + len); if (__builtin_expect (new_binding == NULL, 0)) goto failed; diff --git a/intl/dcgettext.c b/intl/dcgettext.c index 8115d5c..145de63 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -1,5 +1,5 @@ /* Implementation of the dcgettext(3) function. - Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. 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 @@ -20,12 +20,11 @@ # include <config.h> #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif /* @@ end of prolog @@ */ diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 75aa03a..cd33921 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -89,12 +89,11 @@ void free (); # include <sys/param.h> #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif #include "hash-string.h" @@ -129,6 +128,11 @@ void free (); # define _nl_domain_bindings _nl_domain_bindings__ #endif +/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ +#ifndef offsetof +# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) +#endif + /* @@ end of prolog @@ */ #ifdef _LIBC @@ -190,21 +194,13 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); /* 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). */ + However it does not specify the exact format. Neither do SUSV2 and + ISO C 99. So we can use this feature only on selected systems (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 @@ -241,8 +237,11 @@ static void *root; # endif /* Function to compare two entries in the table of known translations. */ +static int transcmp PARAMS ((const void *p1, const void *p2)); static int -transcmp (const void *p1, const void *p2) +transcmp (p1, p2) + const void *p1; + const void *p2; { const struct known_translation_t *s1; const struct known_translation_t *s2; @@ -274,7 +273,7 @@ const char _nl_default_default_domain[] = "messages"; const char *_nl_current_default_domain = _nl_default_default_domain; /* Contains the default location of the message catalogs. */ -const char _nl_default_dirname[] = GNULOCALEDIR; +const char _nl_default_dirname[] = LOCALEDIR; /* List with bindings of specific domains created by bindtextdomain() calls. */ @@ -336,7 +335,7 @@ struct block_list typedef struct transmem_list { struct transmem_list *next; - char data[0]; + char data[ZERO]; } transmem_block_t; static struct transmem_list *transmem_list; #else @@ -423,8 +422,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) /* Try to find the translation among those which we found at some time. */ - search = - (struct known_translation_t *) alloca (sizeof (*search) + msgid_len); + search = (struct known_translation_t *) + alloca (offsetof (struct known_translation_t, msgid) + msgid_len); memcpy (search->msgid, msgid1, msgid_len); search->domainname = (char *) domainname; search->category = category; @@ -607,8 +606,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) struct known_translation_t *newp; newp = (struct known_translation_t *) - malloc (sizeof (*newp) + msgid_len - + domainname_len + 1 - ZERO); + malloc (offsetof (struct known_translation_t, msgid) + + msgid_len + domainname_len + 1); if (newp != NULL) { newp->domainname = @@ -679,14 +678,15 @@ _nl_find_msg (domain_file, msgid, lengthp) nls_uint32 hash_val = hash_string (msgid); nls_uint32 idx = hash_val % domain->hash_size; nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); - - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; while (1) { + nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); + + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + /* Compare msgid with the original string at index nstr-1. We compare the lengths with >=, not ==, because plural entries are represented by strings with an embedded NUL. */ @@ -704,11 +704,6 @@ _nl_find_msg (domain_file, msgid, lengthp) idx -= domain->hash_size - incr; else idx += incr; - - nstr = W (domain->must_swap, domain->hash_tab[idx]); - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; } /* NOTREACHED */ } @@ -980,43 +975,74 @@ plural_eval (pexp, n) struct expression *pexp; unsigned long int n; { - switch (pexp->operation) + switch (pexp->nargs) { - case var: - return n; - case num: - return pexp->val.num; - case mult: - return (plural_eval (pexp->val.args2.left, n) - * plural_eval (pexp->val.args2.right, n)); - case divide: - return (plural_eval (pexp->val.args2.left, n) - / plural_eval (pexp->val.args2.right, n)); - case module: - return (plural_eval (pexp->val.args2.left, n) - % plural_eval (pexp->val.args2.right, n)); - case plus: - return (plural_eval (pexp->val.args2.left, n) - + plural_eval (pexp->val.args2.right, n)); - case minus: - return (plural_eval (pexp->val.args2.left, n) - - plural_eval (pexp->val.args2.right, n)); - case equal: - return (plural_eval (pexp->val.args2.left, n) - == plural_eval (pexp->val.args2.right, n)); - case not_equal: - return (plural_eval (pexp->val.args2.left, n) - != plural_eval (pexp->val.args2.right, n)); - case land: - return (plural_eval (pexp->val.args2.left, n) - && plural_eval (pexp->val.args2.right, n)); - case lor: - return (plural_eval (pexp->val.args2.left, n) - || plural_eval (pexp->val.args2.right, n)); - case qmop: - return (plural_eval (pexp->val.args3.bexp, n) - ? plural_eval (pexp->val.args3.tbranch, n) - : plural_eval (pexp->val.args3.fbranch, n)); + case 0: + switch (pexp->operation) + { + case var: + return n; + case num: + return pexp->val.num; + default: + break; + } + /* NOTREACHED */ + break; + case 1: + { + /* pexp->operation must be lnot. */ + unsigned long int arg = plural_eval (pexp->val.args[0], n); + return ! arg; + } + case 2: + { + unsigned long int leftarg = plural_eval (pexp->val.args[0], n); + if (pexp->operation == lor) + return leftarg || plural_eval (pexp->val.args[1], n); + else if (pexp->operation == land) + return leftarg && plural_eval (pexp->val.args[1], n); + else + { + unsigned long int rightarg = plural_eval (pexp->val.args[1], n); + + switch (pexp->operation) + { + case mult: + return leftarg * rightarg; + case divide: + return leftarg / rightarg; + case module: + return leftarg % rightarg; + case plus: + return leftarg + rightarg; + case minus: + return leftarg - rightarg; + case less_than: + return leftarg < rightarg; + case greater_than: + return leftarg > rightarg; + case less_or_equal: + return leftarg <= rightarg; + case greater_or_equal: + return leftarg >= rightarg; + case equal: + return leftarg == rightarg; + case not_equal: + return leftarg != rightarg; + default: + break; + } + } + /* NOTREACHED */ + break; + } + case 3: + { + /* pexp->operation must be qmop. */ + unsigned long int boolarg = plural_eval (pexp->val.args[0], n); + return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); + } } /* NOTREACHED */ return 0; diff --git a/intl/dcngettext.c b/intl/dcngettext.c index d10f4a6..0064a7d 100644 --- a/intl/dcngettext.c +++ b/intl/dcngettext.c @@ -1,5 +1,5 @@ /* Implementation of the dcngettext(3) function. - Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. 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 @@ -20,12 +20,11 @@ # include <config.h> #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif /* @@ end of prolog @@ */ diff --git a/intl/dgettext.c b/intl/dgettext.c index 85770d2..a847706 100644 --- a/intl/dgettext.c +++ b/intl/dgettext.c @@ -1,5 +1,5 @@ /* Implementation of the dgettext(3) function. - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 2000, 2001 Free Software Foundation, Inc. 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 @@ -24,10 +24,11 @@ # include <locale.h> #endif +#include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif /* @@ end of prolog @@ */ diff --git a/intl/dngettext.c b/intl/dngettext.c index 0501446..a5e8c7b 100644 --- a/intl/dngettext.c +++ b/intl/dngettext.c @@ -1,5 +1,5 @@ /* Implementation of the dngettext(3) function. - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 2000, 2001 Free Software Foundation, Inc. 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 @@ -24,12 +24,11 @@ # include <locale.h> #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif /* @@ end of prolog @@ */ diff --git a/intl/explodename.c b/intl/explodename.c index f89c7c9..e62128d 100644 --- a/intl/explodename.c +++ b/intl/explodename.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. The GNU C Library is free software; you can redistribute it and/or @@ -45,7 +45,8 @@ /* @@ end of prolog @@ */ char * -_nl_find_language (const char *name) +_nl_find_language (name) + const char *name; { while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '+' && name[0] != ',') diff --git a/intl/finddomain.c b/intl/finddomain.c index 1109c5e..cc82391 100644 --- a/intl/finddomain.c +++ b/intl/finddomain.c @@ -1,5 +1,5 @@ /* Handle list of needed message catalogs - Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Written by Ulrich Drepper <drepper@gnu.org>, 1995. The GNU C Library is free software; you can redistribute it and/or @@ -47,12 +47,11 @@ void free (); # include <unistd.h> #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif /* @@ end of prolog @@ */ diff --git a/intl/gettext.c b/intl/gettext.c index 0607185..7488e92 100644 --- a/intl/gettext.c +++ b/intl/gettext.c @@ -1,5 +1,5 @@ /* Implementation of gettext(3) function. - Copyright (C) 1995, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. 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 @@ -35,14 +35,13 @@ # endif #endif +#include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif -#include <locale.h> - /* @@ end of prolog @@ */ /* Names for the libintl functions are a problem. They must not clash diff --git a/intl/gettext.h b/intl/gettext.h index a8bd7b5..2b66e38 100644 --- a/intl/gettext.h +++ b/intl/gettext.h @@ -1,5 +1,5 @@ /* Internal header for GNU gettext internationalization functions. - Copyright (C) 1995, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. 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 @@ -19,8 +19,6 @@ #ifndef _GETTEXT_H #define _GETTEXT_H 1 -#include <stdio.h> - #if HAVE_LIMITS_H || _LIBC # include <limits.h> #endif @@ -37,9 +35,8 @@ /* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - doing that would require that the configure script compile and *run* - the resulting executable. Locally running cross-compiled executables - is usually not possible. */ + as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work + when cross-compiling. */ #if __STDC__ # define UINT_MAX_32_BITS 4294967295U diff --git a/intl/gettextP.h b/intl/gettextP.h index 8dcbaf2..ef29e1e 100644 --- a/intl/gettextP.h +++ b/intl/gettextP.h @@ -1,5 +1,5 @@ -/* Header describing internals of gettext library - Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. +/* Header describing internals of libintl library. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Written by Ulrich Drepper <drepper@cygnus.com>, 1995. The GNU C Library is free software; you can redistribute it and/or @@ -20,6 +20,8 @@ #ifndef _GETTEXTP_H #define _GETTEXTP_H +#include <stddef.h> /* Get size_t. */ + #ifdef _LIBC # include "../iconv/gconv_int.h" #else @@ -30,6 +32,8 @@ #include "loadinfo.h" +#include "gettext.h" /* Get nls_uint32. */ + /* @@ end of prolog @@ */ #ifndef PARAMS @@ -74,35 +78,35 @@ SWAP (i) plural form. */ struct expression { + int nargs; /* Number of arguments. */ enum operator { + /* Without arguments: */ var, /* The variable "n". */ num, /* Decimal number. */ + /* Unary operators: */ + lnot, /* Logical NOT. */ + /* Binary operators: */ mult, /* Multiplication. */ divide, /* Division. */ module, /* Module operation. */ plus, /* Addition. */ minus, /* Subtraction. */ + less_than, /* Comparison. */ + greater_than, /* Comparison. */ + less_or_equal, /* Comparison. */ + greater_or_equal, /* Comparison. */ equal, /* Comparision for equality. */ not_equal, /* Comparision for inequality. */ land, /* Logical AND. */ lor, /* Logical OR. */ + /* Ternary operators: */ qmop /* Question mark operator. */ } operation; union { unsigned long int num; /* Number value for `num'. */ - struct - { - struct expression *left; /* Left expression in binary operation. */ - struct expression *right; /* Right expression in binary operation. */ - } args2; - struct - { - struct expression *bexp; /* Boolean expression in ?: operation. */ - struct expression *tbranch; /* True-branch in ?: operation. */ - struct expression *fbranch; /* False-branch in ?: operation. */ - } args3; + struct expression *args[3]; /* Up to three arguments. */ } val; }; @@ -115,6 +119,7 @@ struct parse_args }; +/* The representation of an opened message catalog. */ struct loaded_domain { const char *data; @@ -139,18 +144,27 @@ struct loaded_domain unsigned long int nplurals; }; +/* We want to allocate a string at the end of the struct. But ISO C + doesn't allow zero sized arrays. */ +#ifdef __GNUC__ +# define ZERO 0 +#else +# define ZERO 1 +#endif + +/* A set of settings bound to a message domain. Used to store settings + from bindtextdomain() and bind_textdomain_codeset(). */ struct binding { struct binding *next; char *dirname; char *codeset; -#ifdef __GNUC__ - char domainname[0]; -#else - char domainname[1]; -#endif + char domainname[ZERO]; }; +/* A counter which is incremented each time some previous translations + become invalid. + This variable is part of the external ABI of the GNU libintl. */ extern int _nl_msg_cat_cntr; struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, @@ -164,32 +178,62 @@ void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) internal_function; #ifdef _LIBC -extern char *__ngettext PARAMS ((const char *msgid1, const char *msgid2, - unsigned long int n)); -extern char *__dngettext PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, unsigned long int n)); -extern char *__dcngettext PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, unsigned long int n, - int category)); -extern char *__dcigettext PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, int plural, - unsigned long int n, int category)); +extern char *__gettext PARAMS ((const char *__msgid)); +extern char *__dgettext PARAMS ((const char *__domainname, + const char *__msgid)); +extern char *__dcgettext PARAMS ((const char *__domainname, + const char *__msgid, int __category)); +extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, + unsigned long int __n)); +extern char *__dngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int n)); +extern char *__dcngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category)); +extern char *__dcigettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +extern char *__textdomain PARAMS ((const char *__domainname)); +extern char *__bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, + const char *__codeset)); #else -extern char *ngettext__ PARAMS ((const char *msgid1, const char *msgid2, - unsigned long int n)); -extern char *dngettext__ PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, unsigned long int n)); -extern char *dcngettext__ PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, unsigned long int n, - int category)); -extern char *dcigettext__ PARAMS ((const char *domainname, const char *msgid1, - const char *msgid2, int plural, - unsigned long int n, int category)); +extern char *gettext__ PARAMS ((const char *__msgid)); +extern char *dgettext__ PARAMS ((const char *__domainname, + const char *__msgid)); +extern char *dcgettext__ PARAMS ((const char *__domainname, + const char *__msgid, int __category)); +extern char *ngettext__ PARAMS ((const char *__msgid1, const char *__msgid2, + unsigned long int __n)); +extern char *dngettext__ PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n)); +extern char *dcngettext__ PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category)); +extern char *dcigettext__ PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +extern char *textdomain__ PARAMS ((const char *__domainname)); +extern char *bindtextdomain__ PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *bind_textdomain_codeset__ PARAMS ((const char *__domainname, + const char *__codeset)); #endif -extern int __gettextdebug; -extern void __gettext_free_exp (struct expression *exp) internal_function; -extern int __gettextparse (void *arg); +#ifdef _LIBC +extern void __gettext_free_exp PARAMS ((struct expression *exp)) + internal_function; +extern int __gettextparse PARAMS ((void *arg)); +#else +extern void gettext_free_exp__ PARAMS ((struct expression *exp)) + internal_function; +extern int gettextparse__ PARAMS ((void *arg)); +#endif /* @@ begin of epilog @@ */ diff --git a/intl/l10nflist.c b/intl/l10nflist.c index 2017311..9b81a8f 100644 --- a/intl/l10nflist.c +++ b/intl/l10nflist.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. The GNU C Library is free software; you can redistribute it and/or @@ -389,7 +389,7 @@ _nl_normalize_codeset (codeset, name_len) for (cnt = 0; cnt < name_len; ++cnt) if (isalpha (codeset[cnt])) - *wp++ = _tolower (codeset[cnt]); + *wp++ = tolower (codeset[cnt]); else if (isdigit (codeset[cnt])) *wp++ = codeset[cnt]; diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index 6eed739..660dc7b 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -33,6 +33,23 @@ #include <sys/types.h> #include <sys/stat.h> +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + #if defined STDC_HEADERS || defined _LIBC # include <stdlib.h> #endif @@ -81,6 +98,25 @@ # define munmap __munmap #endif +/* 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 PLURAL_PARSE __gettextparse +#else +# define PLURAL_PARSE gettextparse__ +#endif + +/* For those losing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +# define freea(p) /* nothing */ +#else +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif + /* We need a sign, whether a new catalog was loaded, which can be associated with all translations. This is important if the translations are cached by one of GCC's features. */ @@ -93,10 +129,12 @@ int _nl_msg_cat_cntr; form determination. It represents the expression "n != 1". */ static const struct expression plvar = { + .nargs = 0, .operation = var, }; static const struct expression plone = { + .nargs = 0, .operation = num, .val = { @@ -105,13 +143,14 @@ static const struct expression plone = }; static struct expression germanic_plural = { + .nargs = 2, .operation = not_equal, .val = { - .args2 = + .args = { - .left = (struct expression *) &plvar, - .right = (struct expression *) &plone + [0] = (struct expression *) &plvar, + [1] = (struct expression *) &plone } } }; @@ -132,14 +171,17 @@ init_germanic_plural () { if (plone.val.num == 0) { + plvar.nargs = 0; plvar.operation = var; + plone.nargs = 0; plone.operation = num; plone.val.num = 1; + germanic_plural.nargs = 2; germanic_plural.operation = not_equal; - germanic_plural.val.args2.left = &plvar; - germanic_plural.val.args2.right = &plone; + germanic_plural.val.args[0] = &plvar; + germanic_plural.val.args[1] = &plone; } } @@ -157,7 +199,11 @@ _nl_load_domain (domain_file) { int fd; size_t size; +#ifdef _LIBC struct stat64 st; +#else + struct stat st; +#endif struct mo_file_header *data = (struct mo_file_header *) -1; int use_mmap = 0; struct loaded_domain *domain; @@ -180,7 +226,12 @@ _nl_load_domain (domain_file) return; /* We must know about the size of the file. */ - if (__builtin_expect (fstat64 (fd, &st) != 0, 0) + if ( +#ifdef _LIBC + __builtin_expect (fstat64 (fd, &st) != 0, 0) +#else + __builtin_expect (fstat (fd, &st) != 0, 0) +#endif || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) || __builtin_expect (size < sizeof (struct mo_file_header), 0)) { @@ -343,8 +394,6 @@ _nl_load_domain (domain_file) # if HAVE_ICONV extern const char *locale_charset (void); outcharset = locale_charset (); - if (outcharset == NULL) - outcharset = ""; # endif # endif } @@ -363,6 +412,8 @@ _nl_load_domain (domain_file) domain->conv = iconv_open (outcharset, charset); # endif # endif + + freea (charset); } #endif /* _LIBC || HAVE_ICONV */ } @@ -381,12 +432,19 @@ _nl_load_domain (domain_file) { /* First get the number. */ char *endp; + unsigned long int n; struct parse_args args; nplurals += 9; while (*nplurals != '\0' && isspace (*nplurals)) ++nplurals; - domain->nplurals = strtoul (nplurals, &endp, 10); +#if defined HAVE_STRTOUL || defined _LIBC + n = strtoul (nplurals, &endp, 10); +#else + for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++) + n = n * 10 + (*endp - '0'); +#endif + domain->nplurals = n; if (nplurals == endp) goto no_plural; @@ -396,7 +454,7 @@ _nl_load_domain (domain_file) is passed down to the parser. */ plural += 7; args.cp = plural; - if (__gettextparse (&args) != 0) + if (PLURAL_PARSE (&args) != 0) goto no_plural; domain->plural = args.res; } diff --git a/intl/localealias.c b/intl/localealias.c index 63e8069..de34b57 100644 --- a/intl/localealias.c +++ b/intl/localealias.c @@ -1,5 +1,5 @@ /* Handle aliases for locale names. - Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. 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 @@ -73,7 +73,6 @@ void free (); # endif #endif -#include "gettext.h" #include "gettextP.h" /* @@ end of prolog @@ */ @@ -99,40 +98,14 @@ __libc_lock_define_initialized (static, lock); # define internal_function #endif -/* For those loosing systems which don't have `alloca' we have to add +/* For those losing 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 */ +# define freea(p) /* 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 */ +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif #if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED # undef fgets @@ -235,16 +208,12 @@ read_alias_file (fname, fname_len) const char *fname; int fname_len; { -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif FILE *fp; char *full_fname; size_t added; static const char aliasfile[] = "/locale.alias"; full_fname = (char *) alloca (fname_len + sizeof aliasfile); - ADD_BLOCK (block_list, full_fname); #ifdef HAVE_MEMPCPY mempcpy (mempcpy (full_fname, fname, fname_len), aliasfile, sizeof aliasfile); @@ -254,11 +223,9 @@ read_alias_file (fname, fname_len) #endif fp = fopen (full_fname, "r"); + freea (full_fname); if (fp == NULL) - { - FREE_BLOCKS (block_list); - return 0; - } + return 0; added = 0; while (!feof (fp)) @@ -331,10 +298,7 @@ read_alias_file (fname, fname_len) if (nmap >= maxmap) if (__builtin_expect (extend_alias_table (), 0)) - { - FREE_BLOCKS (block_list); - return added; - } + return added; alias_len = strlen (alias) + 1; value_len = strlen (value) + 1; @@ -347,10 +311,7 @@ read_alias_file (fname, fname_len) ? alias_len + value_len : 1024)); char *new_pool = (char *) realloc (string_space, new_size); if (new_pool == NULL) - { - FREE_BLOCKS (block_list); - return added; - } + return added; if (__builtin_expect (string_space != new_pool, 0)) { @@ -389,7 +350,6 @@ read_alias_file (fname, fname_len) qsort (map, nmap, sizeof (struct alias_map), (int (*) PARAMS ((const void *, const void *))) alias_compare); - FREE_BLOCKS (block_list); return added; } diff --git a/intl/ngettext.c b/intl/ngettext.c index 5340732..c97e852 100644 --- a/intl/ngettext.c +++ b/intl/ngettext.c @@ -1,5 +1,5 @@ /* Implementation of ngettext(3) function. - Copyright (C) 1995, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. 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 @@ -35,12 +35,11 @@ # endif #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif #include <locale.h> diff --git a/intl/plural.c b/intl/plural.c index c3eeaeb..b61f581 100644 --- a/intl/plural.c +++ b/intl/plural.c @@ -11,7 +11,11 @@ #define yychar __gettextchar #define yydebug __gettextdebug #define yynerrs __gettextnerrs -#define NUMBER 257 +#define EQUOP2 257 +#define CMPOP2 258 +#define ADDOP2 259 +#define MULOP2 260 +#define NUMBER 261 #line 1 "plural.y" @@ -38,25 +42,127 @@ # include <config.h> #endif -#include <stdarg.h> #include <stdlib.h> -#include "gettext.h" #include "gettextP.h" +/* 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 FREE_EXPRESSION __gettext_free_exp +#else +# define FREE_EXPRESSION gettext_free_exp__ +# define __gettextparse gettextparse__ +#endif + #define YYLEX_PARAM &((struct parse_args *) arg)->cp #define YYPARSE_PARAM arg -#line 36 "plural.y" +#line 45 "plural.y" typedef union { unsigned long int num; + enum operator op; struct expression *exp; } YYSTYPE; -#line 41 "plural.y" +#line 51 "plural.y" /* Prototypes for local functions. */ -static struct expression *new_exp (enum operator op, int n, ...); -static int yylex (YYSTYPE *lval, const char **pexp); -static void yyerror (const char *str); +static struct expression *new_exp PARAMS ((int nargs, enum operator op, + struct expression * const *args)); +static inline struct expression *new_exp_0 PARAMS ((enum operator op)); +static inline struct expression *new_exp_1 PARAMS ((enum operator op, + struct expression *right)); +static struct expression *new_exp_2 PARAMS ((enum operator op, + struct expression *left, + struct expression *right)); +static inline struct expression *new_exp_3 PARAMS ((enum operator op, + struct expression *bexp, + struct expression *tbranch, + struct expression *fbranch)); +static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); +static void yyerror PARAMS ((const char *str)); + +/* Allocation of expressions. */ + +static struct expression * +new_exp (nargs, op, args) + int nargs; + enum operator op; + struct expression * const *args; +{ + int i; + struct expression *newp; + + /* If any of the argument could not be malloc'ed, just return NULL. */ + for (i = nargs - 1; i >= 0; i--) + if (args[i] == NULL) + goto fail; + + /* Allocate a new expression. */ + newp = (struct expression *) malloc (sizeof (*newp)); + if (newp != NULL) + { + newp->nargs = nargs; + newp->operation = op; + for (i = nargs - 1; i >= 0; i--) + newp->val.args[i] = args[i]; + return newp; + } + + fail: + for (i = nargs - 1; i >= 0; i--) + FREE_EXPRESSION (args[i]); + + return NULL; +} + +static inline struct expression * +new_exp_0 (op) + enum operator op; +{ + return new_exp (0, op, NULL); +} + +static inline struct expression * +new_exp_1 (op, right) + enum operator op; + struct expression *right; +{ + struct expression *args[1]; + + args[0] = right; + return new_exp (1, op, args); +} + +static struct expression * +new_exp_2 (op, left, right) + enum operator op; + struct expression *left; + struct expression *right; +{ + struct expression *args[2]; + + args[0] = left; + args[1] = right; + return new_exp (2, op, args); +} + +static inline struct expression * +new_exp_3 (op, bexp, tbranch, fbranch) + enum operator op; + struct expression *bexp; + struct expression *tbranch; + struct expression *fbranch; +{ + struct expression *args[3]; + + args[0] = bexp; + args[1] = tbranch; + args[2] = fbranch; + return new_exp (3, op, args); +} + #include <stdio.h> #ifndef __cplusplus @@ -67,24 +173,24 @@ static void yyerror (const char *str); -#define YYFINAL 31 +#define YYFINAL 27 #define YYFLAG -32768 -#define YYNTBASE 18 +#define YYNTBASE 16 -#define YYTRANSLATE(x) ((unsigned)(x) <= 257 ? yytranslate[x] : 20) +#define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 18) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 7, 2, 2, 2, 12, 5, 2, 16, - 17, 10, 8, 2, 9, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 14, 2, 2, - 6, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 10, 2, 2, 2, 2, 5, 2, 14, + 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 12, 2, 2, + 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -99,30 +205,30 @@ static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 13 + 2, 2, 2, 2, 2, 1, 6, 7, 8, 9, + 11 }; #if YYDEBUG != 0 static const short yyprhs[] = { 0, - 0, 2, 8, 12, 16, 20, 24, 28, 32, 36, - 40, 44, 46, 48 + 0, 2, 8, 12, 16, 20, 24, 28, 32, 35, + 37, 39 }; -static const short yyrhs[] = { 19, - 0, 19, 3, 19, 14, 19, 0, 19, 4, 19, - 0, 19, 5, 19, 0, 19, 6, 19, 0, 19, - 7, 19, 0, 19, 8, 19, 0, 19, 9, 19, - 0, 19, 10, 19, 0, 19, 11, 19, 0, 19, - 12, 19, 0, 15, 0, 13, 0, 16, 19, 17, - 0 +static const short yyrhs[] = { 17, + 0, 17, 3, 17, 12, 17, 0, 17, 4, 17, + 0, 17, 5, 17, 0, 17, 6, 17, 0, 17, + 7, 17, 0, 17, 8, 17, 0, 17, 9, 17, + 0, 10, 17, 0, 13, 0, 11, 0, 14, 17, + 15, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 59, 65, 70, 75, 80, 85, 90, 95, 100, 105, - 110, 115, 120, 126 + 170, 178, 182, 186, 190, 194, 198, 202, 206, 210, + 214, 219 }; #endif @@ -130,67 +236,61 @@ static const short yyrline[] = { 0, #if YYDEBUG != 0 || defined (YYERROR_VERBOSE) static const char * const yytname[] = { "$","error","$undefined.","'?'","'|'", -"'&'","'='","'!'","'+'","'-'","'*'","'/'","'%'","NUMBER","':'","'n'","'('","')'", +"'&'","EQUOP2","CMPOP2","ADDOP2","MULOP2","'!'","NUMBER","':'","'n'","'('","')'", "start","exp", NULL }; #endif static const short yyr1[] = { 0, - 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19 + 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17 }; static const short yyr2[] = { 0, - 1, 5, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 3 + 1, 5, 3, 3, 3, 3, 3, 3, 2, 1, + 1, 3 }; static const short yydefact[] = { 0, - 13, 12, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14, 0, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 0, 2, 0, 0, - 0 + 0, 11, 10, 0, 1, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 3, 4, 5, 6, + 7, 8, 0, 2, 0, 0, 0 }; -static const short yydefgoto[] = { 29, - 4 +static const short yydefgoto[] = { 25, + 5 }; -static const short yypact[] = { 58, --32768,-32768, 58, 37, 10, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58,-32768, 25, 45, 52, 57, - 57, 65, 65,-32768,-32768,-32768, 58, 37, 1, 2, --32768 +static const short yypact[] = { -9, + -9,-32768,-32768, -9, 34,-32768, 11, -9, -9, -9, + -9, -9, -9, -9,-32768, 24, 39, 43, 16, 26, + -3,-32768, -9, 34, 21, 53,-32768 }; static const short yypgoto[] = {-32768, - -3 + -1 }; -#define YYLAST 77 +#define YYLAST 53 -static const short yytable[] = { 5, - 30, 31, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 28, 0, 0, 16, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 0, 27, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 8, - 9, 10, 11, 12, 13, 14, 15, 9, 10, 11, - 12, 13, 14, 15, 11, 12, 13, 14, 15, 0, - 1, 0, 2, 3, 13, 14, 15 +static const short yytable[] = { 6, + 1, 2, 7, 3, 4, 14, 16, 17, 18, 19, + 20, 21, 22, 8, 9, 10, 11, 12, 13, 14, + 26, 24, 12, 13, 14, 15, 8, 9, 10, 11, + 12, 13, 14, 13, 14, 23, 8, 9, 10, 11, + 12, 13, 14, 10, 11, 12, 13, 14, 11, 12, + 13, 14, 27 }; -static const short yycheck[] = { 3, - 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, -1, 27, -1, -1, 17, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, -1, 14, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, - 6, 7, 8, 9, 10, 11, 12, 6, 7, 8, - 9, 10, 11, 12, 8, 9, 10, 11, 12, -1, - 13, -1, 15, 16, 10, 11, 12 +static const short yycheck[] = { 1, + 10, 11, 4, 13, 14, 9, 8, 9, 10, 11, + 12, 13, 14, 3, 4, 5, 6, 7, 8, 9, + 0, 23, 7, 8, 9, 15, 3, 4, 5, 6, + 7, 8, 9, 8, 9, 12, 3, 4, 5, 6, + 7, 8, 9, 5, 6, 7, 8, 9, 6, 7, + 8, 9, 0 }; #define YYPURE 1 @@ -738,100 +838,78 @@ yyreduce: switch (yyn) { case 1: -#line 60 "plural.y" +#line 171 "plural.y" { + if (yyvsp[0].exp == NULL) + YYABORT; ((struct parse_args *) arg)->res = yyvsp[0].exp; ; break;} case 2: -#line 66 "plural.y" +#line 179 "plural.y" { - if ((yyval.exp = new_exp (qmop, 3, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_3 (qmop, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 3: -#line 71 "plural.y" +#line 183 "plural.y" { - if ((yyval.exp = new_exp (lor, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (lor, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 4: -#line 76 "plural.y" +#line 187 "plural.y" { - if ((yyval.exp = new_exp (land, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (land, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 5: -#line 81 "plural.y" +#line 191 "plural.y" { - if ((yyval.exp = new_exp (equal, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 6: -#line 86 "plural.y" +#line 195 "plural.y" { - if ((yyval.exp = new_exp (not_equal, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 7: -#line 91 "plural.y" +#line 199 "plural.y" { - if ((yyval.exp = new_exp (plus, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 8: -#line 96 "plural.y" +#line 203 "plural.y" { - if ((yyval.exp = new_exp (minus, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); ; break;} case 9: -#line 101 "plural.y" +#line 207 "plural.y" { - if ((yyval.exp = new_exp (mult, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_1 (lnot, yyvsp[0].exp); ; break;} case 10: -#line 106 "plural.y" +#line 211 "plural.y" { - if ((yyval.exp = new_exp (divide, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + yyval.exp = new_exp_0 (var); ; break;} case 11: -#line 111 "plural.y" +#line 215 "plural.y" { - if ((yyval.exp = new_exp (module, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) - YYABORT + if ((yyval.exp = new_exp_0 (num)) != NULL) + yyval.exp->val.num = yyvsp[0].num; ; break;} case 12: -#line 116 "plural.y" +#line 220 "plural.y" { - if ((yyval.exp = new_exp (var, 0)) == NULL) - YYABORT - ; - break;} -case 13: -#line 121 "plural.y" -{ - if ((yyval.exp = new_exp (num, 0)) == NULL) - YYABORT; - yyval.exp->val.num = yyvsp[0].num - ; - break;} -case 14: -#line 127 "plural.y" -{ - yyval.exp = yyvsp[-1].exp + yyval.exp = yyvsp[-1].exp; ; break;} } @@ -1056,73 +1134,29 @@ yyerrhandle: } return 1; } -#line 132 "plural.y" - - -static struct expression * -new_exp (enum operator op, int n, ...) -{ - struct expression *newp = (struct expression *) calloc (1, sizeof (*newp)); - va_list va; - - va_start (va, n); +#line 225 "plural.y" - if (newp == NULL) - while (n-- > 0) - __gettext_free_exp (va_arg (va, struct expression *)); - else - { - newp->operation = op; - if (n > 0) - { - newp->val.args3.bexp = va_arg (va, struct expression *); - newp->val.args3.tbranch = va_arg (va, struct expression *); - - if (n > 2) - newp->val.args3.fbranch = va_arg (va, struct expression *); - - if (newp->val.args3.bexp == NULL - || newp->val.args3.tbranch == NULL - || (n > 2 && newp->val.args3.fbranch == NULL)) - { - __gettext_free_exp (newp); - newp = NULL; - } - } - } - - va_end (va); - - return newp; -} void internal_function -__gettext_free_exp (struct expression *exp) +FREE_EXPRESSION (exp) + struct expression *exp; { if (exp == NULL) return; /* Handle the recursive case. */ - switch (exp->operation) + switch (exp->nargs) { - case qmop: - __gettext_free_exp (exp->val.args3.fbranch); + case 3: + FREE_EXPRESSION (exp->val.args[2]); + /* FALLTHROUGH */ + case 2: + FREE_EXPRESSION (exp->val.args[1]); + /* FALLTHROUGH */ + case 1: + FREE_EXPRESSION (exp->val.args[0]); /* FALLTHROUGH */ - - case mult: - case divide: - case module: - case plus: - case minus: - case equal: - case not_equal: - case land: - case lor: - __gettext_free_exp (exp->val.args2.right); - __gettext_free_exp (exp->val.args2.left); - break; - default: break; } @@ -1132,19 +1166,15 @@ __gettext_free_exp (struct expression *exp) static int -yylex (YYSTYPE *lval, const char **pexp) +yylex (lval, pexp) + YYSTYPE *lval; + const char **pexp; { const char *exp = *pexp; int result; while (1) { - if (exp[0] == '\\' && exp[1] == '\n') - { - exp += 2; - continue; - } - if (exp[0] == '\0') { *pexp = exp; @@ -1176,13 +1206,25 @@ yylex (YYSTYPE *lval, const char **pexp) break; case '=': - case '!': if (exp[0] == '=') - ++exp; + { + ++exp; + lval->op = equal; + result = EQUOP2; + } else result = YYERRCODE; break; + case '!': + if (exp[0] == '=') + { + ++exp; + lval->op = not_equal; + result = EQUOP2; + } + break; + case '&': case '|': if (exp[0] == result) @@ -1191,12 +1233,54 @@ yylex (YYSTYPE *lval, const char **pexp) result = YYERRCODE; break; - case 'n': + case '<': + if (exp[0] == '=') + { + ++exp; + lval->op = less_or_equal; + } + else + lval->op = less_than; + result = CMPOP2; + break; + + case '>': + if (exp[0] == '=') + { + ++exp; + lval->op = greater_or_equal; + } + else + lval->op = greater_than; + result = CMPOP2; + break; + case '*': + lval->op = mult; + result = MULOP2; + break; + case '/': + lval->op = divide; + result = MULOP2; + break; + case '%': + lval->op = module; + result = MULOP2; + break; + case '+': + lval->op = plus; + result = ADDOP2; + break; + case '-': + lval->op = minus; + result = ADDOP2; + break; + + case 'n': case '?': case ':': case '(': @@ -1227,7 +1311,8 @@ yylex (YYSTYPE *lval, const char **pexp) static void -yyerror (const char *str) +yyerror (str) + const char *str; { /* Do nothing. We don't print error messages here. */ } diff --git a/intl/plural.y b/intl/plural.y index f14dc29..e85f7b8 100644 --- a/intl/plural.y +++ b/intl/plural.y @@ -22,11 +22,20 @@ # include <config.h> #endif -#include <stdarg.h> #include <stdlib.h> -#include "gettext.h" #include "gettextP.h" +/* 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 FREE_EXPRESSION __gettext_free_exp +#else +# define FREE_EXPRESSION gettext_free_exp__ +# define __gettextparse gettextparse__ +#endif + #define YYLEX_PARAM &((struct parse_args *) arg)->cp #define YYPARSE_PARAM arg %} @@ -35,22 +44,124 @@ %union { unsigned long int num; + enum operator op; struct expression *exp; } %{ /* Prototypes for local functions. */ -static struct expression *new_exp (enum operator op, int n, ...); -static int yylex (YYSTYPE *lval, const char **pexp); -static void yyerror (const char *str); +static struct expression *new_exp PARAMS ((int nargs, enum operator op, + struct expression * const *args)); +static inline struct expression *new_exp_0 PARAMS ((enum operator op)); +static inline struct expression *new_exp_1 PARAMS ((enum operator op, + struct expression *right)); +static struct expression *new_exp_2 PARAMS ((enum operator op, + struct expression *left, + struct expression *right)); +static inline struct expression *new_exp_3 PARAMS ((enum operator op, + struct expression *bexp, + struct expression *tbranch, + struct expression *fbranch)); +static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); +static void yyerror PARAMS ((const char *str)); + +/* Allocation of expressions. */ + +static struct expression * +new_exp (nargs, op, args) + int nargs; + enum operator op; + struct expression * const *args; +{ + int i; + struct expression *newp; + + /* If any of the argument could not be malloc'ed, just return NULL. */ + for (i = nargs - 1; i >= 0; i--) + if (args[i] == NULL) + goto fail; + + /* Allocate a new expression. */ + newp = (struct expression *) malloc (sizeof (*newp)); + if (newp != NULL) + { + newp->nargs = nargs; + newp->operation = op; + for (i = nargs - 1; i >= 0; i--) + newp->val.args[i] = args[i]; + return newp; + } + + fail: + for (i = nargs - 1; i >= 0; i--) + FREE_EXPRESSION (args[i]); + + return NULL; +} + +static inline struct expression * +new_exp_0 (op) + enum operator op; +{ + return new_exp (0, op, NULL); +} + +static inline struct expression * +new_exp_1 (op, right) + enum operator op; + struct expression *right; +{ + struct expression *args[1]; + + args[0] = right; + return new_exp (1, op, args); +} + +static struct expression * +new_exp_2 (op, left, right) + enum operator op; + struct expression *left; + struct expression *right; +{ + struct expression *args[2]; + + args[0] = left; + args[1] = right; + return new_exp (2, op, args); +} + +static inline struct expression * +new_exp_3 (op, bexp, tbranch, fbranch) + enum operator op; + struct expression *bexp; + struct expression *tbranch; + struct expression *fbranch; +{ + struct expression *args[3]; + + args[0] = bexp; + args[1] = tbranch; + args[2] = fbranch; + return new_exp (3, op, args); +} + %} -%left '?' -%left '|' -%left '&' -%left '=', '!' -%left '+', '-' -%left '*', '/', '%' +/* This declares that all operators have the same associativity and the + precedence order as in C. See [Harbison, Steele: C, A Reference Manual]. + There is no unary minus and no bitwise operators. + Operators with the same syntactic behaviour have been merged into a single + token, to save space in the array generated by bison. */ +%right '?' /* ? */ +%left '|' /* || */ +%left '&' /* && */ +%left EQUOP2 /* == != */ +%left CMPOP2 /* < > <= >= */ +%left ADDOP2 /* + - */ +%left MULOP2 /* * / % */ +%right '!' /* ! */ + +%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2 %token <num> NUMBER %type <exp> exp @@ -58,143 +169,81 @@ static void yyerror (const char *str); start: exp { + if ($1 == NULL) + YYABORT; ((struct parse_args *) arg)->res = $1; } ; exp: exp '?' exp ':' exp { - if (($$ = new_exp (qmop, 3, $1, $3, $5)) == NULL) - YYABORT + $$ = new_exp_3 (qmop, $1, $3, $5); } | exp '|' exp { - if (($$ = new_exp (lor, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 (lor, $1, $3); } | exp '&' exp { - if (($$ = new_exp (land, 2, $1, $3)) == NULL) - YYABORT - } - | exp '=' exp - { - if (($$ = new_exp (equal, 2, $1, $3)) == NULL) - YYABORT - } - | exp '!' exp - { - if (($$ = new_exp (not_equal, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 (land, $1, $3); } - | exp '+' exp + | exp EQUOP2 exp { - if (($$ = new_exp (plus, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 ($2, $1, $3); } - | exp '-' exp + | exp CMPOP2 exp { - if (($$ = new_exp (minus, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 ($2, $1, $3); } - | exp '*' exp + | exp ADDOP2 exp { - if (($$ = new_exp (mult, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 ($2, $1, $3); } - | exp '/' exp + | exp MULOP2 exp { - if (($$ = new_exp (divide, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_2 ($2, $1, $3); } - | exp '%' exp + | '!' exp { - if (($$ = new_exp (module, 2, $1, $3)) == NULL) - YYABORT + $$ = new_exp_1 (lnot, $2); } | 'n' { - if (($$ = new_exp (var, 0)) == NULL) - YYABORT + $$ = new_exp_0 (var); } | NUMBER { - if (($$ = new_exp (num, 0)) == NULL) - YYABORT; - $$->val.num = $1 + if (($$ = new_exp_0 (num)) != NULL) + $$->val.num = $1; } | '(' exp ')' { - $$ = $2 + $$ = $2; } ; %% -static struct expression * -new_exp (enum operator op, int n, ...) -{ - struct expression *newp = (struct expression *) calloc (1, sizeof (*newp)); - va_list va; - - va_start (va, n); - - if (newp == NULL) - while (n-- > 0) - __gettext_free_exp (va_arg (va, struct expression *)); - else - { - newp->operation = op; - if (n > 0) - { - newp->val.args3.bexp = va_arg (va, struct expression *); - newp->val.args3.tbranch = va_arg (va, struct expression *); - - if (n > 2) - newp->val.args3.fbranch = va_arg (va, struct expression *); - - if (newp->val.args3.bexp == NULL - || newp->val.args3.tbranch == NULL - || (n > 2 && newp->val.args3.fbranch == NULL)) - { - __gettext_free_exp (newp); - newp = NULL; - } - } - } - - va_end (va); - - return newp; -} - void internal_function -__gettext_free_exp (struct expression *exp) +FREE_EXPRESSION (exp) + struct expression *exp; { if (exp == NULL) return; /* Handle the recursive case. */ - switch (exp->operation) + switch (exp->nargs) { - case qmop: - __gettext_free_exp (exp->val.args3.fbranch); + case 3: + FREE_EXPRESSION (exp->val.args[2]); + /* FALLTHROUGH */ + case 2: + FREE_EXPRESSION (exp->val.args[1]); + /* FALLTHROUGH */ + case 1: + FREE_EXPRESSION (exp->val.args[0]); /* FALLTHROUGH */ - - case mult: - case divide: - case module: - case plus: - case minus: - case equal: - case not_equal: - case land: - case lor: - __gettext_free_exp (exp->val.args2.right); - __gettext_free_exp (exp->val.args2.left); - break; - default: break; } @@ -204,19 +253,15 @@ __gettext_free_exp (struct expression *exp) static int -yylex (YYSTYPE *lval, const char **pexp) +yylex (lval, pexp) + YYSTYPE *lval; + const char **pexp; { const char *exp = *pexp; int result; while (1) { - if (exp[0] == '\\' && exp[1] == '\n') - { - exp += 2; - continue; - } - if (exp[0] == '\0') { *pexp = exp; @@ -248,13 +293,25 @@ yylex (YYSTYPE *lval, const char **pexp) break; case '=': - case '!': if (exp[0] == '=') - ++exp; + { + ++exp; + lval->op = equal; + result = EQUOP2; + } else result = YYERRCODE; break; + case '!': + if (exp[0] == '=') + { + ++exp; + lval->op = not_equal; + result = EQUOP2; + } + break; + case '&': case '|': if (exp[0] == result) @@ -263,12 +320,54 @@ yylex (YYSTYPE *lval, const char **pexp) result = YYERRCODE; break; - case 'n': + case '<': + if (exp[0] == '=') + { + ++exp; + lval->op = less_or_equal; + } + else + lval->op = less_than; + result = CMPOP2; + break; + + case '>': + if (exp[0] == '=') + { + ++exp; + lval->op = greater_or_equal; + } + else + lval->op = greater_than; + result = CMPOP2; + break; + case '*': + lval->op = mult; + result = MULOP2; + break; + case '/': + lval->op = divide; + result = MULOP2; + break; + case '%': + lval->op = module; + result = MULOP2; + break; + case '+': + lval->op = plus; + result = ADDOP2; + break; + case '-': + lval->op = minus; + result = ADDOP2; + break; + + case 'n': case '?': case ':': case '(': @@ -299,7 +398,8 @@ yylex (YYSTYPE *lval, const char **pexp) static void -yyerror (const char *str) +yyerror (str) + const char *str; { /* Do nothing. We don't print error messages here. */ } diff --git a/intl/textdomain.c b/intl/textdomain.c index 02f4a4b..a5b93fa 100644 --- a/intl/textdomain.c +++ b/intl/textdomain.c @@ -1,5 +1,5 @@ /* Implementation of the textdomain(3) function. - Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. 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 @@ -36,9 +36,8 @@ #ifdef _LIBC # include <libintl.h> #else -# include "libgettext.h" +# include "libgnuintl.h" #endif -#include "gettext.h" #include "gettextP.h" #ifdef _LIBC |