1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
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.
This commit is contained in:
Ulrich Drepper
2001-03-20 01:00:20 +00:00
parent f2615995a7
commit 4a4d50f372
20 changed files with 901 additions and 501 deletions

130
ChangeLog
View File

@ -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> 2001-03-19 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/i386/i686/tempname.c: New file. * sysdeps/unix/i386/i686/tempname.c: New file.

View File

@ -81,7 +81,7 @@ CFLAGS-tst-translit.c = -DOBJPFX=\"$(objpfx)\"
$(objpfx)tst-translit.out: $(objpfx)tst-gettext.out $(objpfx)tst-translit.out: $(objpfx)tst-gettext.out
CPPFLAGS += -D'GNULOCALEDIR="$(msgcatdir)"' \ CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"' -D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
BISONFLAGS = --yacc --name-prefix=__gettext --output BISONFLAGS = --yacc --name-prefix=__gettext --output

View File

@ -1,5 +1,5 @@
/* Implementation of the bindtextdomain(3) function /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -42,9 +42,8 @@ void free ();
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
@ -65,6 +64,11 @@ void free ();
# define _nl_domain_bindings _nl_domain_bindings__ # define _nl_domain_bindings _nl_domain_bindings__
#endif #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 @@ */ /* @@ end of prolog @@ */
/* Contains the default location of the message catalogs. */ /* Contains the default location of the message catalogs. */
@ -93,8 +97,9 @@ __libc_rwlock_define (extern, _nl_state_lock)
#endif #endif
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static void set_binding_values (const char *domainname, const char **dirnamep, static void set_binding_values PARAMS ((const char *domainname,
const char **codesetp); const char **dirnamep,
const char **codesetp));
/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
to be used for the DOMAINNAME message catalog. 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. */ /* We have to create a new binding. */
size_t len = strlen (domainname) + 1; size_t len = strlen (domainname) + 1;
struct binding *new_binding = 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)) if (__builtin_expect (new_binding == NULL, 0))
goto failed; goto failed;

View File

@ -1,5 +1,5 @@
/* Implementation of the dcgettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -20,12 +20,11 @@
# include <config.h> # include <config.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -89,12 +89,11 @@ void free ();
# include <sys/param.h> # include <sys/param.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
#include "hash-string.h" #include "hash-string.h"
@ -129,6 +128,11 @@ void free ();
# define _nl_domain_bindings _nl_domain_bindings__ # define _nl_domain_bindings _nl_domain_bindings__
#endif #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 @@ */ /* @@ end of prolog @@ */
#ifdef _LIBC #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: /* XPG3 defines the result of `setlocale (category, NULL)' as:
``Directs `setlocale()' to query `category' and return the current ``Directs `setlocale()' to query `category' and return the current
setting of `local'.'' setting of `local'.''
However it does not specify the exact format. And even worse: POSIX However it does not specify the exact format. Neither do SUSV2 and
defines this not at all. So we can use this feature only on selected ISO C 99. So we can use this feature only on selected systems (e.g.
system (e.g. those using GNU C Library). */ those using GNU C Library). */
#ifdef _LIBC #ifdef _LIBC
# define HAVE_LOCALE_NULL # define HAVE_LOCALE_NULL
#endif #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 /* This is the type used for the search tree where known translations
are stored. */ are stored. */
struct known_translation_t struct known_translation_t
@ -241,8 +237,11 @@ static void *root;
# endif # endif
/* Function to compare two entries in the table of known translations. */ /* Function to compare two entries in the table of known translations. */
static int transcmp PARAMS ((const void *p1, const void *p2));
static int 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 *s1;
const struct known_translation_t *s2; 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; const char *_nl_current_default_domain = _nl_default_default_domain;
/* Contains the default location of the message catalogs. */ /* 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() /* List with bindings of specific domains created by bindtextdomain()
calls. */ calls. */
@ -336,7 +335,7 @@ struct block_list
typedef struct transmem_list typedef struct transmem_list
{ {
struct transmem_list *next; struct transmem_list *next;
char data[0]; char data[ZERO];
} transmem_block_t; } transmem_block_t;
static struct transmem_list *transmem_list; static struct transmem_list *transmem_list;
#else #else
@ -423,8 +422,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
/* Try to find the translation among those which we found at /* Try to find the translation among those which we found at
some time. */ some time. */
search = search = (struct known_translation_t *)
(struct known_translation_t *) alloca (sizeof (*search) + msgid_len); alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
memcpy (search->msgid, msgid1, msgid_len); memcpy (search->msgid, msgid1, msgid_len);
search->domainname = (char *) domainname; search->domainname = (char *) domainname;
search->category = category; search->category = category;
@ -607,8 +606,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
struct known_translation_t *newp; struct known_translation_t *newp;
newp = (struct known_translation_t *) newp = (struct known_translation_t *)
malloc (sizeof (*newp) + msgid_len malloc (offsetof (struct known_translation_t, msgid)
+ domainname_len + 1 - ZERO); + msgid_len + domainname_len + 1);
if (newp != NULL) if (newp != NULL)
{ {
newp->domainname = newp->domainname =
@ -679,14 +678,15 @@ _nl_find_msg (domain_file, msgid, lengthp)
nls_uint32 hash_val = hash_string (msgid); nls_uint32 hash_val = hash_string (msgid);
nls_uint32 idx = hash_val % domain->hash_size; nls_uint32 idx = hash_val % domain->hash_size;
nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); 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) 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. /* Compare msgid with the original string at index nstr-1.
We compare the lengths with >=, not ==, because plural entries We compare the lengths with >=, not ==, because plural entries
are represented by strings with an embedded NUL. */ are represented by strings with an embedded NUL. */
@ -704,11 +704,6 @@ _nl_find_msg (domain_file, msgid, lengthp)
idx -= domain->hash_size - incr; idx -= domain->hash_size - incr;
else else
idx += incr; idx += incr;
nstr = W (domain->must_swap, domain->hash_tab[idx]);
if (nstr == 0)
/* Hash table entry is empty. */
return NULL;
} }
/* NOTREACHED */ /* NOTREACHED */
} }
@ -980,43 +975,74 @@ plural_eval (pexp, n)
struct expression *pexp; struct expression *pexp;
unsigned long int n; unsigned long int n;
{ {
switch (pexp->operation) switch (pexp->nargs)
{ {
case var: case 0:
return n; switch (pexp->operation)
case num: {
return pexp->val.num; case var:
case mult: return n;
return (plural_eval (pexp->val.args2.left, n) case num:
* plural_eval (pexp->val.args2.right, n)); return pexp->val.num;
case divide: default:
return (plural_eval (pexp->val.args2.left, n) break;
/ plural_eval (pexp->val.args2.right, n)); }
case module: /* NOTREACHED */
return (plural_eval (pexp->val.args2.left, n) break;
% plural_eval (pexp->val.args2.right, n)); case 1:
case plus: {
return (plural_eval (pexp->val.args2.left, n) /* pexp->operation must be lnot. */
+ plural_eval (pexp->val.args2.right, n)); unsigned long int arg = plural_eval (pexp->val.args[0], n);
case minus: return ! arg;
return (plural_eval (pexp->val.args2.left, n) }
- plural_eval (pexp->val.args2.right, n)); case 2:
case equal: {
return (plural_eval (pexp->val.args2.left, n) unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
== plural_eval (pexp->val.args2.right, n)); if (pexp->operation == lor)
case not_equal: return leftarg || plural_eval (pexp->val.args[1], n);
return (plural_eval (pexp->val.args2.left, n) else if (pexp->operation == land)
!= plural_eval (pexp->val.args2.right, n)); return leftarg && plural_eval (pexp->val.args[1], n);
case land: else
return (plural_eval (pexp->val.args2.left, n) {
&& plural_eval (pexp->val.args2.right, n)); unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
case lor:
return (plural_eval (pexp->val.args2.left, n) switch (pexp->operation)
|| plural_eval (pexp->val.args2.right, n)); {
case qmop: case mult:
return (plural_eval (pexp->val.args3.bexp, n) return leftarg * rightarg;
? plural_eval (pexp->val.args3.tbranch, n) case divide:
: plural_eval (pexp->val.args3.fbranch, n)); 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 */ /* NOTREACHED */
return 0; return 0;

View File

@ -1,5 +1,5 @@
/* Implementation of the dcngettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -20,12 +20,11 @@
# include <config.h> # include <config.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -1,5 +1,5 @@
/* Implementation of the dgettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -24,10 +24,11 @@
# include <locale.h> # include <locale.h>
#endif #endif
#include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -1,5 +1,5 @@
/* Implementation of the dngettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -24,12 +24,11 @@
# include <locale.h> # include <locale.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -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. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -45,7 +45,8 @@
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
char * char *
_nl_find_language (const char *name) _nl_find_language (name)
const char *name;
{ {
while (name[0] != '\0' && name[0] != '_' && name[0] != '@' while (name[0] != '\0' && name[0] != '_' && name[0] != '@'
&& name[0] != '+' && name[0] != ',') && name[0] != '+' && name[0] != ',')

View File

@ -1,5 +1,5 @@
/* Handle list of needed message catalogs /* 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. Written by Ulrich Drepper <drepper@gnu.org>, 1995.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -47,12 +47,11 @@ void free ();
# include <unistd.h> # include <unistd.h>
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */

View File

@ -1,5 +1,5 @@
/* Implementation of gettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -35,14 +35,13 @@
# endif # endif
#endif #endif
#include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
#include <locale.h>
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
/* Names for the libintl functions are a problem. They must not clash /* Names for the libintl functions are a problem. They must not clash

View File

@ -1,5 +1,5 @@
/* Internal header for GNU gettext internationalization functions. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -19,8 +19,6 @@
#ifndef _GETTEXT_H #ifndef _GETTEXT_H
#define _GETTEXT_H 1 #define _GETTEXT_H 1
#include <stdio.h>
#if HAVE_LIMITS_H || _LIBC #if HAVE_LIMITS_H || _LIBC
# include <limits.h> # include <limits.h>
#endif #endif
@ -37,9 +35,8 @@
/* The following contortions are an attempt to use the C preprocessor /* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An to determine an unsigned integral type that is 32 bits wide. An
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
doing that would require that the configure script compile and *run* as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work
the resulting executable. Locally running cross-compiled executables when cross-compiling. */
is usually not possible. */
#if __STDC__ #if __STDC__
# define UINT_MAX_32_BITS 4294967295U # define UINT_MAX_32_BITS 4294967295U

View File

@ -1,5 +1,5 @@
/* Header describing internals of gettext library /* Header describing internals of libintl library.
Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc. Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@cygnus.com>, 1995. Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -20,6 +20,8 @@
#ifndef _GETTEXTP_H #ifndef _GETTEXTP_H
#define _GETTEXTP_H #define _GETTEXTP_H
#include <stddef.h> /* Get size_t. */
#ifdef _LIBC #ifdef _LIBC
# include "../iconv/gconv_int.h" # include "../iconv/gconv_int.h"
#else #else
@ -30,6 +32,8 @@
#include "loadinfo.h" #include "loadinfo.h"
#include "gettext.h" /* Get nls_uint32. */
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
#ifndef PARAMS #ifndef PARAMS
@ -74,35 +78,35 @@ SWAP (i)
plural form. */ plural form. */
struct expression struct expression
{ {
int nargs; /* Number of arguments. */
enum operator enum operator
{ {
/* Without arguments: */
var, /* The variable "n". */ var, /* The variable "n". */
num, /* Decimal number. */ num, /* Decimal number. */
/* Unary operators: */
lnot, /* Logical NOT. */
/* Binary operators: */
mult, /* Multiplication. */ mult, /* Multiplication. */
divide, /* Division. */ divide, /* Division. */
module, /* Module operation. */ module, /* Module operation. */
plus, /* Addition. */ plus, /* Addition. */
minus, /* Subtraction. */ minus, /* Subtraction. */
less_than, /* Comparison. */
greater_than, /* Comparison. */
less_or_equal, /* Comparison. */
greater_or_equal, /* Comparison. */
equal, /* Comparision for equality. */ equal, /* Comparision for equality. */
not_equal, /* Comparision for inequality. */ not_equal, /* Comparision for inequality. */
land, /* Logical AND. */ land, /* Logical AND. */
lor, /* Logical OR. */ lor, /* Logical OR. */
/* Ternary operators: */
qmop /* Question mark operator. */ qmop /* Question mark operator. */
} operation; } operation;
union union
{ {
unsigned long int num; /* Number value for `num'. */ unsigned long int num; /* Number value for `num'. */
struct struct expression *args[3]; /* Up to three arguments. */
{
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;
} val; } val;
}; };
@ -115,6 +119,7 @@ struct parse_args
}; };
/* The representation of an opened message catalog. */
struct loaded_domain struct loaded_domain
{ {
const char *data; const char *data;
@ -139,18 +144,27 @@ struct loaded_domain
unsigned long int nplurals; 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
{ {
struct binding *next; struct binding *next;
char *dirname; char *dirname;
char *codeset; char *codeset;
#ifdef __GNUC__ char domainname[ZERO];
char domainname[0];
#else
char domainname[1];
#endif
}; };
/* 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; extern int _nl_msg_cat_cntr;
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, 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; internal_function;
#ifdef _LIBC #ifdef _LIBC
extern char *__ngettext PARAMS ((const char *msgid1, const char *msgid2, extern char *__gettext PARAMS ((const char *__msgid));
unsigned long int n)); extern char *__dgettext PARAMS ((const char *__domainname,
extern char *__dngettext PARAMS ((const char *domainname, const char *msgid1, const char *__msgid));
const char *msgid2, unsigned long int n)); extern char *__dcgettext PARAMS ((const char *__domainname,
extern char *__dcngettext PARAMS ((const char *domainname, const char *msgid1, const char *__msgid, int __category));
const char *msgid2, unsigned long int n, extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2,
int category)); unsigned long int __n));
extern char *__dcigettext PARAMS ((const char *domainname, const char *msgid1, extern char *__dngettext PARAMS ((const char *__domainname,
const char *msgid2, int plural, const char *__msgid1, const char *__msgid2,
unsigned long int n, int category)); 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 #else
extern char *ngettext__ PARAMS ((const char *msgid1, const char *msgid2, extern char *gettext__ PARAMS ((const char *__msgid));
unsigned long int n)); extern char *dgettext__ PARAMS ((const char *__domainname,
extern char *dngettext__ PARAMS ((const char *domainname, const char *msgid1, const char *__msgid));
const char *msgid2, unsigned long int n)); extern char *dcgettext__ PARAMS ((const char *__domainname,
extern char *dcngettext__ PARAMS ((const char *domainname, const char *msgid1, const char *__msgid, int __category));
const char *msgid2, unsigned long int n, extern char *ngettext__ PARAMS ((const char *__msgid1, const char *__msgid2,
int category)); unsigned long int __n));
extern char *dcigettext__ PARAMS ((const char *domainname, const char *msgid1, extern char *dngettext__ PARAMS ((const char *__domainname,
const char *msgid2, int plural, const char *__msgid1, const char *__msgid2,
unsigned long int n, int category)); 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 #endif
extern int __gettextdebug; #ifdef _LIBC
extern void __gettext_free_exp (struct expression *exp) internal_function; extern void __gettext_free_exp PARAMS ((struct expression *exp))
extern int __gettextparse (void *arg); 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 @@ */ /* @@ begin of epilog @@ */

View File

@ -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. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
The GNU C Library is free software; you can redistribute it and/or 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) for (cnt = 0; cnt < name_len; ++cnt)
if (isalpha (codeset[cnt])) if (isalpha (codeset[cnt]))
*wp++ = _tolower (codeset[cnt]); *wp++ = tolower (codeset[cnt]);
else if (isdigit (codeset[cnt])) else if (isdigit (codeset[cnt]))
*wp++ = codeset[cnt]; *wp++ = codeset[cnt];

View File

@ -33,6 +33,23 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.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 #if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h> # include <stdlib.h>
#endif #endif
@ -81,6 +98,25 @@
# define munmap __munmap # define munmap __munmap
#endif #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 /* We need a sign, whether a new catalog was loaded, which can be associated
with all translations. This is important if the translations are with all translations. This is important if the translations are
cached by one of GCC's features. */ cached by one of GCC's features. */
@ -93,10 +129,12 @@ int _nl_msg_cat_cntr;
form determination. It represents the expression "n != 1". */ form determination. It represents the expression "n != 1". */
static const struct expression plvar = static const struct expression plvar =
{ {
.nargs = 0,
.operation = var, .operation = var,
}; };
static const struct expression plone = static const struct expression plone =
{ {
.nargs = 0,
.operation = num, .operation = num,
.val = .val =
{ {
@ -105,13 +143,14 @@ static const struct expression plone =
}; };
static struct expression germanic_plural = static struct expression germanic_plural =
{ {
.nargs = 2,
.operation = not_equal, .operation = not_equal,
.val = .val =
{ {
.args2 = .args =
{ {
.left = (struct expression *) &plvar, [0] = (struct expression *) &plvar,
.right = (struct expression *) &plone [1] = (struct expression *) &plone
} }
} }
}; };
@ -132,14 +171,17 @@ init_germanic_plural ()
{ {
if (plone.val.num == 0) if (plone.val.num == 0)
{ {
plvar.nargs = 0;
plvar.operation = var; plvar.operation = var;
plone.nargs = 0;
plone.operation = num; plone.operation = num;
plone.val.num = 1; plone.val.num = 1;
germanic_plural.nargs = 2;
germanic_plural.operation = not_equal; germanic_plural.operation = not_equal;
germanic_plural.val.args2.left = &plvar; germanic_plural.val.args[0] = &plvar;
germanic_plural.val.args2.right = &plone; germanic_plural.val.args[1] = &plone;
} }
} }
@ -157,7 +199,11 @@ _nl_load_domain (domain_file)
{ {
int fd; int fd;
size_t size; size_t size;
#ifdef _LIBC
struct stat64 st; struct stat64 st;
#else
struct stat st;
#endif
struct mo_file_header *data = (struct mo_file_header *) -1; struct mo_file_header *data = (struct mo_file_header *) -1;
int use_mmap = 0; int use_mmap = 0;
struct loaded_domain *domain; struct loaded_domain *domain;
@ -180,7 +226,12 @@ _nl_load_domain (domain_file)
return; return;
/* We must know about the size of the file. */ /* 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 = (size_t) st.st_size) != st.st_size, 0)
|| __builtin_expect (size < sizeof (struct mo_file_header), 0)) || __builtin_expect (size < sizeof (struct mo_file_header), 0))
{ {
@ -343,8 +394,6 @@ _nl_load_domain (domain_file)
# if HAVE_ICONV # if HAVE_ICONV
extern const char *locale_charset (void); extern const char *locale_charset (void);
outcharset = locale_charset (); outcharset = locale_charset ();
if (outcharset == NULL)
outcharset = "";
# endif # endif
# endif # endif
} }
@ -363,6 +412,8 @@ _nl_load_domain (domain_file)
domain->conv = iconv_open (outcharset, charset); domain->conv = iconv_open (outcharset, charset);
# endif # endif
# endif # endif
freea (charset);
} }
#endif /* _LIBC || HAVE_ICONV */ #endif /* _LIBC || HAVE_ICONV */
} }
@ -381,12 +432,19 @@ _nl_load_domain (domain_file)
{ {
/* First get the number. */ /* First get the number. */
char *endp; char *endp;
unsigned long int n;
struct parse_args args; struct parse_args args;
nplurals += 9; nplurals += 9;
while (*nplurals != '\0' && isspace (*nplurals)) while (*nplurals != '\0' && isspace (*nplurals))
++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) if (nplurals == endp)
goto no_plural; goto no_plural;
@ -396,7 +454,7 @@ _nl_load_domain (domain_file)
is passed down to the parser. */ is passed down to the parser. */
plural += 7; plural += 7;
args.cp = plural; args.cp = plural;
if (__gettextparse (&args) != 0) if (PLURAL_PARSE (&args) != 0)
goto no_plural; goto no_plural;
domain->plural = args.res; domain->plural = args.res;
} }

View File

@ -1,5 +1,5 @@
/* Handle aliases for locale names. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -73,7 +73,6 @@ void free ();
# endif # endif
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
/* @@ end of prolog @@ */ /* @@ end of prolog @@ */
@ -99,40 +98,14 @@ __libc_lock_define_initialized (static, lock);
# define internal_function # define internal_function
#endif #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. */ some additional code emulating it. */
#ifdef HAVE_ALLOCA #ifdef HAVE_ALLOCA
/* Nothing has to be done. */ # define freea(p) /* nothing */
# define ADD_BLOCK(list, address) /* nothing */
# define FREE_BLOCKS(list) /* nothing */
#else #else
struct block_list # define alloca(n) malloc (n)
{ # define freea(p) free (p)
void *address; #endif
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 */
#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED #if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
# undef fgets # undef fgets
@ -235,16 +208,12 @@ read_alias_file (fname, fname_len)
const char *fname; const char *fname;
int fname_len; int fname_len;
{ {
#ifndef HAVE_ALLOCA
struct block_list *block_list = NULL;
#endif
FILE *fp; FILE *fp;
char *full_fname; char *full_fname;
size_t added; size_t added;
static const char aliasfile[] = "/locale.alias"; static const char aliasfile[] = "/locale.alias";
full_fname = (char *) alloca (fname_len + sizeof aliasfile); full_fname = (char *) alloca (fname_len + sizeof aliasfile);
ADD_BLOCK (block_list, full_fname);
#ifdef HAVE_MEMPCPY #ifdef HAVE_MEMPCPY
mempcpy (mempcpy (full_fname, fname, fname_len), mempcpy (mempcpy (full_fname, fname, fname_len),
aliasfile, sizeof aliasfile); aliasfile, sizeof aliasfile);
@ -254,11 +223,9 @@ read_alias_file (fname, fname_len)
#endif #endif
fp = fopen (full_fname, "r"); fp = fopen (full_fname, "r");
freea (full_fname);
if (fp == NULL) if (fp == NULL)
{ return 0;
FREE_BLOCKS (block_list);
return 0;
}
added = 0; added = 0;
while (!feof (fp)) while (!feof (fp))
@ -331,10 +298,7 @@ read_alias_file (fname, fname_len)
if (nmap >= maxmap) if (nmap >= maxmap)
if (__builtin_expect (extend_alias_table (), 0)) if (__builtin_expect (extend_alias_table (), 0))
{ return added;
FREE_BLOCKS (block_list);
return added;
}
alias_len = strlen (alias) + 1; alias_len = strlen (alias) + 1;
value_len = strlen (value) + 1; value_len = strlen (value) + 1;
@ -347,10 +311,7 @@ read_alias_file (fname, fname_len)
? alias_len + value_len : 1024)); ? alias_len + value_len : 1024));
char *new_pool = (char *) realloc (string_space, new_size); char *new_pool = (char *) realloc (string_space, new_size);
if (new_pool == NULL) if (new_pool == NULL)
{ return added;
FREE_BLOCKS (block_list);
return added;
}
if (__builtin_expect (string_space != new_pool, 0)) 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), qsort (map, nmap, sizeof (struct alias_map),
(int (*) PARAMS ((const void *, const void *))) alias_compare); (int (*) PARAMS ((const void *, const void *))) alias_compare);
FREE_BLOCKS (block_list);
return added; return added;
} }

View File

@ -1,5 +1,5 @@
/* Implementation of ngettext(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -35,12 +35,11 @@
# endif # endif
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
#include <locale.h> #include <locale.h>

View File

@ -11,7 +11,11 @@
#define yychar __gettextchar #define yychar __gettextchar
#define yydebug __gettextdebug #define yydebug __gettextdebug
#define yynerrs __gettextnerrs #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" #line 1 "plural.y"
@ -38,25 +42,127 @@
# include <config.h> # include <config.h>
#endif #endif
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include "gettext.h"
#include "gettextP.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 YYLEX_PARAM &((struct parse_args *) arg)->cp
#define YYPARSE_PARAM arg #define YYPARSE_PARAM arg
#line 36 "plural.y" #line 45 "plural.y"
typedef union { typedef union {
unsigned long int num; unsigned long int num;
enum operator op;
struct expression *exp; struct expression *exp;
} YYSTYPE; } YYSTYPE;
#line 41 "plural.y" #line 51 "plural.y"
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static struct expression *new_exp (enum operator op, int n, ...); static struct expression *new_exp PARAMS ((int nargs, enum operator op,
static int yylex (YYSTYPE *lval, const char **pexp); struct expression * const *args));
static void yyerror (const char *str); 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> #include <stdio.h>
#ifndef __cplusplus #ifndef __cplusplus
@ -67,24 +173,24 @@ static void yyerror (const char *str);
#define YYFINAL 31 #define YYFINAL 27
#define YYFLAG -32768 #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, 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, 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, 2, 2, 10, 2, 2, 2, 2, 5, 2, 14,
17, 10, 8, 2, 9, 2, 11, 2, 2, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, 2,
6, 2, 3, 2, 2, 2, 2, 2, 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, 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, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 4, 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, 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, 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 #if YYDEBUG != 0
static const short yyprhs[] = { 0, static const short yyprhs[] = { 0,
0, 2, 8, 12, 16, 20, 24, 28, 32, 36, 0, 2, 8, 12, 16, 20, 24, 28, 32, 35,
40, 44, 46, 48 37, 39
}; };
static const short yyrhs[] = { 19, static const short yyrhs[] = { 17,
0, 19, 3, 19, 14, 19, 0, 19, 4, 19, 0, 17, 3, 17, 12, 17, 0, 17, 4, 17,
0, 19, 5, 19, 0, 19, 6, 19, 0, 19, 0, 17, 5, 17, 0, 17, 6, 17, 0, 17,
7, 19, 0, 19, 8, 19, 0, 19, 9, 19, 7, 17, 0, 17, 8, 17, 0, 17, 9, 17,
0, 19, 10, 19, 0, 19, 11, 19, 0, 19, 0, 10, 17, 0, 13, 0, 11, 0, 14, 17,
12, 19, 0, 15, 0, 13, 0, 16, 19, 17, 15, 0
0
}; };
#endif #endif
#if YYDEBUG != 0 #if YYDEBUG != 0
static const short yyrline[] = { 0, static const short yyrline[] = { 0,
59, 65, 70, 75, 80, 85, 90, 95, 100, 105, 170, 178, 182, 186, 190, 194, 198, 202, 206, 210,
110, 115, 120, 126 214, 219
}; };
#endif #endif
@ -130,67 +236,61 @@ static const short yyrline[] = { 0,
#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static const char * const yytname[] = { "$","error","$undefined.","'?'","'|'", static const char * const yytname[] = { "$","error","$undefined.","'?'","'|'",
"'&'","'='","'!'","'+'","'-'","'*'","'/'","'%'","NUMBER","':'","'n'","'('","')'", "'&'","EQUOP2","CMPOP2","ADDOP2","MULOP2","'!'","NUMBER","':'","'n'","'('","')'",
"start","exp", NULL "start","exp", NULL
}; };
#endif #endif
static const short yyr1[] = { 0, static const short yyr1[] = { 0,
18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17,
19, 19, 19, 19 17, 17
}; };
static const short yyr2[] = { 0, static const short yyr2[] = { 0,
1, 5, 3, 3, 3, 3, 3, 3, 3, 3, 1, 5, 3, 3, 3, 3, 3, 3, 2, 1,
3, 1, 1, 3 1, 3
}; };
static const short yydefact[] = { 0, static const short yydefact[] = { 0,
13, 12, 0, 1, 0, 0, 0, 0, 0, 0, 0, 11, 10, 0, 1, 9, 0, 0, 0, 0,
0, 0, 0, 0, 0, 14, 0, 3, 4, 5, 0, 0, 0, 0, 12, 0, 3, 4, 5, 6,
6, 7, 8, 9, 10, 11, 0, 2, 0, 0, 7, 8, 0, 2, 0, 0, 0
0
}; };
static const short yydefgoto[] = { 29, static const short yydefgoto[] = { 25,
4 5
}; };
static const short yypact[] = { 58, static const short yypact[] = { -9,
-32768,-32768, 58, 37, 10, 58, 58, 58, 58, 58, -9,-32768,-32768, -9, 34,-32768, 11, -9, -9, -9,
58, 58, 58, 58, 58,-32768, 25, 45, 52, 57, -9, -9, -9, -9,-32768, 24, 39, 43, 16, 26,
57, 65, 65,-32768,-32768,-32768, 58, 37, 1, 2, -3,-32768, -9, 34, 21, 53,-32768
-32768
}; };
static const short yypgoto[] = {-32768, static const short yypgoto[] = {-32768,
-3 -1
}; };
#define YYLAST 77 #define YYLAST 53
static const short yytable[] = { 5, static const short yytable[] = { 6,
30, 31, 17, 18, 19, 20, 21, 22, 23, 24, 1, 2, 7, 3, 4, 14, 16, 17, 18, 19,
25, 26, 6, 7, 8, 9, 10, 11, 12, 13, 20, 21, 22, 8, 9, 10, 11, 12, 13, 14,
14, 15, 0, 28, 0, 0, 16, 6, 7, 8, 26, 24, 12, 13, 14, 15, 8, 9, 10, 11,
9, 10, 11, 12, 13, 14, 15, 0, 27, 6, 12, 13, 14, 13, 14, 23, 8, 9, 10, 11,
7, 8, 9, 10, 11, 12, 13, 14, 15, 8, 12, 13, 14, 10, 11, 12, 13, 14, 11, 12,
9, 10, 11, 12, 13, 14, 15, 9, 10, 11, 13, 14, 27
12, 13, 14, 15, 11, 12, 13, 14, 15, 0,
1, 0, 2, 3, 13, 14, 15
}; };
static const short yycheck[] = { 3, static const short yycheck[] = { 1,
0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 10, 11, 4, 13, 14, 9, 8, 9, 10, 11,
14, 15, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 3, 4, 5, 6, 7, 8, 9,
11, 12, -1, 27, -1, -1, 17, 3, 4, 5, 0, 23, 7, 8, 9, 15, 3, 4, 5, 6,
6, 7, 8, 9, 10, 11, 12, -1, 14, 3, 7, 8, 9, 8, 9, 12, 3, 4, 5, 6,
4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 7, 8, 9, 5, 6, 7, 8, 9, 6, 7,
6, 7, 8, 9, 10, 11, 12, 6, 7, 8, 8, 9, 0
9, 10, 11, 12, 8, 9, 10, 11, 12, -1,
13, -1, 15, 16, 10, 11, 12
}; };
#define YYPURE 1 #define YYPURE 1
@ -738,100 +838,78 @@ yyreduce:
switch (yyn) { switch (yyn) {
case 1: case 1:
#line 60 "plural.y" #line 171 "plural.y"
{ {
if (yyvsp[0].exp == NULL)
YYABORT;
((struct parse_args *) arg)->res = yyvsp[0].exp; ((struct parse_args *) arg)->res = yyvsp[0].exp;
; ;
break;} break;}
case 2: 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) yyval.exp = new_exp_3 (qmop, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 3: case 3:
#line 71 "plural.y" #line 183 "plural.y"
{ {
if ((yyval.exp = new_exp (lor, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_2 (lor, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 4: case 4:
#line 76 "plural.y" #line 187 "plural.y"
{ {
if ((yyval.exp = new_exp (land, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_2 (land, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 5: case 5:
#line 81 "plural.y" #line 191 "plural.y"
{ {
if ((yyval.exp = new_exp (equal, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 6: 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) yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 7: case 7:
#line 91 "plural.y" #line 199 "plural.y"
{ {
if ((yyval.exp = new_exp (plus, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 8: case 8:
#line 96 "plural.y" #line 203 "plural.y"
{ {
if ((yyval.exp = new_exp (minus, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 9: case 9:
#line 101 "plural.y" #line 207 "plural.y"
{ {
if ((yyval.exp = new_exp (mult, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_1 (lnot, yyvsp[0].exp);
YYABORT
; ;
break;} break;}
case 10: case 10:
#line 106 "plural.y" #line 211 "plural.y"
{ {
if ((yyval.exp = new_exp (divide, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) yyval.exp = new_exp_0 (var);
YYABORT
; ;
break;} break;}
case 11: case 11:
#line 111 "plural.y" #line 215 "plural.y"
{ {
if ((yyval.exp = new_exp (module, 2, yyvsp[-2].exp, yyvsp[0].exp)) == NULL) if ((yyval.exp = new_exp_0 (num)) != NULL)
YYABORT yyval.exp->val.num = yyvsp[0].num;
; ;
break;} break;}
case 12: case 12:
#line 116 "plural.y" #line 220 "plural.y"
{ {
if ((yyval.exp = new_exp (var, 0)) == NULL) yyval.exp = yyvsp[-1].exp;
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
; ;
break;} break;}
} }
@ -1056,73 +1134,29 @@ yyerrhandle:
} }
return 1; return 1;
} }
#line 132 "plural.y" #line 225 "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);
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 void
internal_function internal_function
__gettext_free_exp (struct expression *exp) FREE_EXPRESSION (exp)
struct expression *exp;
{ {
if (exp == NULL) if (exp == NULL)
return; return;
/* Handle the recursive case. */ /* Handle the recursive case. */
switch (exp->operation) switch (exp->nargs)
{ {
case qmop: case 3:
__gettext_free_exp (exp->val.args3.fbranch); 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 */ /* 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: default:
break; break;
} }
@ -1132,19 +1166,15 @@ __gettext_free_exp (struct expression *exp)
static int static int
yylex (YYSTYPE *lval, const char **pexp) yylex (lval, pexp)
YYSTYPE *lval;
const char **pexp;
{ {
const char *exp = *pexp; const char *exp = *pexp;
int result; int result;
while (1) while (1)
{ {
if (exp[0] == '\\' && exp[1] == '\n')
{
exp += 2;
continue;
}
if (exp[0] == '\0') if (exp[0] == '\0')
{ {
*pexp = exp; *pexp = exp;
@ -1176,13 +1206,25 @@ yylex (YYSTYPE *lval, const char **pexp)
break; break;
case '=': case '=':
case '!':
if (exp[0] == '=') if (exp[0] == '=')
++exp; {
++exp;
lval->op = equal;
result = EQUOP2;
}
else else
result = YYERRCODE; result = YYERRCODE;
break; break;
case '!':
if (exp[0] == '=')
{
++exp;
lval->op = not_equal;
result = EQUOP2;
}
break;
case '&': case '&':
case '|': case '|':
if (exp[0] == result) if (exp[0] == result)
@ -1191,12 +1233,54 @@ yylex (YYSTYPE *lval, const char **pexp)
result = YYERRCODE; result = YYERRCODE;
break; 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 '*': case '*':
lval->op = mult;
result = MULOP2;
break;
case '/': case '/':
lval->op = divide;
result = MULOP2;
break;
case '%': case '%':
lval->op = module;
result = MULOP2;
break;
case '+': case '+':
lval->op = plus;
result = ADDOP2;
break;
case '-': case '-':
lval->op = minus;
result = ADDOP2;
break;
case 'n':
case '?': case '?':
case ':': case ':':
case '(': case '(':
@ -1227,7 +1311,8 @@ yylex (YYSTYPE *lval, const char **pexp)
static void static void
yyerror (const char *str) yyerror (str)
const char *str;
{ {
/* Do nothing. We don't print error messages here. */ /* Do nothing. We don't print error messages here. */
} }

View File

@ -22,11 +22,20 @@
# include <config.h> # include <config.h>
#endif #endif
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include "gettext.h"
#include "gettextP.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 YYLEX_PARAM &((struct parse_args *) arg)->cp
#define YYPARSE_PARAM arg #define YYPARSE_PARAM arg
%} %}
@ -35,22 +44,124 @@
%union { %union {
unsigned long int num; unsigned long int num;
enum operator op;
struct expression *exp; struct expression *exp;
} }
%{ %{
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static struct expression *new_exp (enum operator op, int n, ...); static struct expression *new_exp PARAMS ((int nargs, enum operator op,
static int yylex (YYSTYPE *lval, const char **pexp); struct expression * const *args));
static void yyerror (const char *str); 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 '?' /* This declares that all operators have the same associativity and the
%left '|' precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
%left '&' There is no unary minus and no bitwise operators.
%left '=', '!' Operators with the same syntactic behaviour have been merged into a single
%left '+', '-' token, to save space in the array generated by bison. */
%left '*', '/', '%' %right '?' /* ? */
%left '|' /* || */
%left '&' /* && */
%left EQUOP2 /* == != */
%left CMPOP2 /* < > <= >= */
%left ADDOP2 /* + - */
%left MULOP2 /* * / % */
%right '!' /* ! */
%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
%token <num> NUMBER %token <num> NUMBER
%type <exp> exp %type <exp> exp
@ -58,143 +169,81 @@ static void yyerror (const char *str);
start: exp start: exp
{ {
if ($1 == NULL)
YYABORT;
((struct parse_args *) arg)->res = $1; ((struct parse_args *) arg)->res = $1;
} }
; ;
exp: exp '?' exp ':' exp exp: exp '?' exp ':' exp
{ {
if (($$ = new_exp (qmop, 3, $1, $3, $5)) == NULL) $$ = new_exp_3 (qmop, $1, $3, $5);
YYABORT
} }
| exp '|' exp | exp '|' exp
{ {
if (($$ = new_exp (lor, 2, $1, $3)) == NULL) $$ = new_exp_2 (lor, $1, $3);
YYABORT
} }
| exp '&' exp | exp '&' exp
{ {
if (($$ = new_exp (land, 2, $1, $3)) == NULL) $$ = new_exp_2 (land, $1, $3);
YYABORT
} }
| exp '=' exp | exp EQUOP2 exp
{ {
if (($$ = new_exp (equal, 2, $1, $3)) == NULL) $$ = new_exp_2 ($2, $1, $3);
YYABORT
} }
| exp '!' exp | exp CMPOP2 exp
{ {
if (($$ = new_exp (not_equal, 2, $1, $3)) == NULL) $$ = new_exp_2 ($2, $1, $3);
YYABORT
} }
| exp '+' exp | exp ADDOP2 exp
{ {
if (($$ = new_exp (plus, 2, $1, $3)) == NULL) $$ = new_exp_2 ($2, $1, $3);
YYABORT
} }
| exp '-' exp | exp MULOP2 exp
{ {
if (($$ = new_exp (minus, 2, $1, $3)) == NULL) $$ = new_exp_2 ($2, $1, $3);
YYABORT
} }
| exp '*' exp | '!' exp
{ {
if (($$ = new_exp (mult, 2, $1, $3)) == NULL) $$ = new_exp_1 (lnot, $2);
YYABORT
}
| exp '/' exp
{
if (($$ = new_exp (divide, 2, $1, $3)) == NULL)
YYABORT
}
| exp '%' exp
{
if (($$ = new_exp (module, 2, $1, $3)) == NULL)
YYABORT
} }
| 'n' | 'n'
{ {
if (($$ = new_exp (var, 0)) == NULL) $$ = new_exp_0 (var);
YYABORT
} }
| NUMBER | NUMBER
{ {
if (($$ = new_exp (num, 0)) == NULL) if (($$ = new_exp_0 (num)) != NULL)
YYABORT; $$->val.num = $1;
$$->val.num = $1
} }
| '(' exp ')' | '(' 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 void
internal_function internal_function
__gettext_free_exp (struct expression *exp) FREE_EXPRESSION (exp)
struct expression *exp;
{ {
if (exp == NULL) if (exp == NULL)
return; return;
/* Handle the recursive case. */ /* Handle the recursive case. */
switch (exp->operation) switch (exp->nargs)
{ {
case qmop: case 3:
__gettext_free_exp (exp->val.args3.fbranch); 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 */ /* 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: default:
break; break;
} }
@ -204,19 +253,15 @@ __gettext_free_exp (struct expression *exp)
static int static int
yylex (YYSTYPE *lval, const char **pexp) yylex (lval, pexp)
YYSTYPE *lval;
const char **pexp;
{ {
const char *exp = *pexp; const char *exp = *pexp;
int result; int result;
while (1) while (1)
{ {
if (exp[0] == '\\' && exp[1] == '\n')
{
exp += 2;
continue;
}
if (exp[0] == '\0') if (exp[0] == '\0')
{ {
*pexp = exp; *pexp = exp;
@ -248,13 +293,25 @@ yylex (YYSTYPE *lval, const char **pexp)
break; break;
case '=': case '=':
case '!':
if (exp[0] == '=') if (exp[0] == '=')
++exp; {
++exp;
lval->op = equal;
result = EQUOP2;
}
else else
result = YYERRCODE; result = YYERRCODE;
break; break;
case '!':
if (exp[0] == '=')
{
++exp;
lval->op = not_equal;
result = EQUOP2;
}
break;
case '&': case '&':
case '|': case '|':
if (exp[0] == result) if (exp[0] == result)
@ -263,12 +320,54 @@ yylex (YYSTYPE *lval, const char **pexp)
result = YYERRCODE; result = YYERRCODE;
break; 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 '*': case '*':
lval->op = mult;
result = MULOP2;
break;
case '/': case '/':
lval->op = divide;
result = MULOP2;
break;
case '%': case '%':
lval->op = module;
result = MULOP2;
break;
case '+': case '+':
lval->op = plus;
result = ADDOP2;
break;
case '-': case '-':
lval->op = minus;
result = ADDOP2;
break;
case 'n':
case '?': case '?':
case ':': case ':':
case '(': case '(':
@ -299,7 +398,8 @@ yylex (YYSTYPE *lval, const char **pexp)
static void static void
yyerror (const char *str) yyerror (str)
const char *str;
{ {
/* Do nothing. We don't print error messages here. */ /* Do nothing. We don't print error messages here. */
} }

View File

@ -1,5 +1,5 @@
/* Implementation of the textdomain(3) function. /* 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 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 modify it under the terms of the GNU Library General Public License as
@ -36,9 +36,8 @@
#ifdef _LIBC #ifdef _LIBC
# include <libintl.h> # include <libintl.h>
#else #else
# include "libgettext.h" # include "libgnuintl.h"
#endif #endif
#include "gettext.h"
#include "gettextP.h" #include "gettextP.h"
#ifdef _LIBC #ifdef _LIBC