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