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>
* 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
CPPFLAGS += -D'GNULOCALEDIR="$(msgcatdir)"' \
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
BISONFLAGS = --yacc --name-prefix=__gettext --output

View file

@ -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;

View file

@ -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 @@ */

View file

@ -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;

View file

@ -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 @@ */

View file

@ -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 @@ */

View file

@ -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 @@ */

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.
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] != ',')

View file

@ -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 @@ */

View file

@ -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

View file

@ -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

View file

@ -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 @@ */

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.
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];

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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>

View file

@ -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"
#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
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. */
}

View file

@ -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
$$ = new_exp_2 (land, $1, $3);
}
| exp '=' exp
| exp EQUOP2 exp
{
if (($$ = new_exp (equal, 2, $1, $3)) == NULL)
YYABORT
$$ = new_exp_2 ($2, $1, $3);
}
| exp '!' exp
| exp CMPOP2 exp
{
if (($$ = new_exp (not_equal, 2, $1, $3)) == NULL)
YYABORT
$$ = new_exp_2 ($2, $1, $3);
}
| exp '+' exp
| exp ADDOP2 exp
{
if (($$ = new_exp (plus, 2, $1, $3)) == NULL)
YYABORT
$$ = new_exp_2 ($2, $1, $3);
}
| exp '-' exp
| exp MULOP2 exp
{
if (($$ = new_exp (minus, 2, $1, $3)) == NULL)
YYABORT
$$ = new_exp_2 ($2, $1, $3);
}
| exp '*' exp
| '!' exp
{
if (($$ = new_exp (mult, 2, $1, $3)) == NULL)
YYABORT
}
| exp '/' exp
{
if (($$ = new_exp (divide, 2, $1, $3)) == NULL)
YYABORT
}
| 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. */
}

View file

@ -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