From 0b19481ea2d0828fa43e0c26784937c72cd56c19 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 10 Nov 2000 23:27:45 +0000 Subject: [PATCH] Upgrade to glibc-2.2. --- intl/ChangeLog | 57 +++++++++++++++++++++ intl/dcigettext.c | 124 ++++++++++++++++++++++++++++++++++----------- intl/libintl.glibc | 8 +-- intl/loadmsgcat.c | 30 ++++++----- intl/localealias.c | 12 +++++ intl/plural.y | 68 ++++++++++++++----------- 6 files changed, 224 insertions(+), 75 deletions(-) diff --git a/intl/ChangeLog b/intl/ChangeLog index 49963f2e0..6c96eb870 100644 --- a/intl/ChangeLog +++ b/intl/ChangeLog @@ -1,3 +1,60 @@ +2000-10-30 Ulrich Drepper + + * dcigettext.c (guess_category_value): For libc always use the + setlocale() method. + +2000-10-20 Ulrich Drepper + + * libintl.glibc (ngettext macro): Add missing parameter. + (dngettext macro): Likewise. + +2000-10-14 Ulrich Drepper + + * localealias.c (read_alias_file): Update string pointers in map[] + if realloc() changed the values. + Patch by Jakub Jelinek . + +2000-08-31 Ulrich Drepper + + * loadmsgcat.c: Use *stat64 instead of *stat internally. + + * dcigettext.c (free_mem): Correct freeing of _nl_domain_bindings + list. + +2000-08-27 Ulrich Drepper + + * dcigettext.c (DCIGETTEXT): Remove _nl_find_language in code to + determine invalid locale name. + +2000-08-20 Ulrich Drepper + + * dcigettext.c: Unify use of function aliases to make more compact + PLT. + + * loadmsgcat.c (_nl_unload_domain): Also free conv_tab element. + Pretty printing. + * plural.y (new_exp): Take number of optional parameters in second + parameter. Test for correct number of parameters and free correctly + in case of failure. Adjust all callers. + (yylex): Fix handling of '\0'. Allow ';' as terminator character. + +2000-07-14 Bruno Haible + + * dcigettext.c (dcigettext): Call plural_eval on all platforms, not + only those having tsearch. + +2000-06-30 Ulrich Drepper + + * dcigettext.c (_nl_find_msg): Correct reallocation of buffers in + case the translation is too large. Remember allocated memory blocks + in a list. + (free_mem): Free memory for translations. + +2000-06-16 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Call norm_add_slashes with new + parameter to always enable transliteration. + 1998-10-20 Paul Eggert * po2tbl.sin: Escape trigraphs. diff --git a/intl/dcigettext.c b/intl/dcigettext.c index d6092461c..1ecc857f1 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -54,6 +54,7 @@ extern int errno; #endif #if defined STDC_HEADERS || defined _LIBC +# include # include #else char *getenv (); @@ -137,6 +138,7 @@ void free (); # ifndef stpcpy # define stpcpy __stpcpy # endif +# define tfind __tfind #else # if !defined HAVE_GETCWD char *getwd (); @@ -322,6 +324,19 @@ struct block_list #endif /* have alloca */ +#ifdef _LIBC +/* List of blocks allocated for translations. */ +typedef struct transmem_list +{ + struct transmem_list *next; + char data[0]; +} transmem_block_t; +static struct transmem_list *transmem_list; +#else +typedef char transmem_block_t; +#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 __ @@ -523,10 +538,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) /* When this is a SUID binary we must not allow accessing files outside the dedicated directories. */ - if (ENABLE_SECURE - && (memchr (single_locale, '/', - _nl_find_language (single_locale) - single_locale) - != NULL)) + if (ENABLE_SECURE && strchr (single_locale, '/') != NULL) /* Ingore this entry. */ continue; } @@ -553,24 +565,25 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) if (domain != NULL) { unsigned long int index = 0; -#if defined HAVE_TSEARCH || defined _LIBC - struct loaded_domain *domaindata = - (struct loaded_domain *) domain->data; if (plural != 0) { + struct loaded_domain *domaindata = + (struct loaded_domain *) domain->data; + index = plural_eval (domaindata->plural, n); + if (index >= domaindata->nplurals) + /* This should never happen. It means the plural expression + and the given maximum value do not match. */ + index = 0; + +#if defined HAVE_TSEARCH || defined _LIBC /* Try to find the translation among those which we found at some time. */ search = (struct known_translation_t *) alloca (sizeof (*search) + msgid_len); memcpy (search->msgid, msgid1, msgid_len); search->domain = (char *) domainname; - search->plindex = plural_eval (domaindata->plural, n); - if (search->plindex >= domaindata->nplurals) - /* This should never happen. It means the plural expression - and the given maximum value do not match. */ - search->plindex = 0; - index = search->plindex; + search->plindex = index; search->category = category; foundp = (struct known_translation_t **) tfind (search, &root, @@ -580,8 +593,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) __libc_rwlock_unlock (_nl_state_lock); return (char *) (*foundp)->translation; } - } #endif + } retval = _nl_find_msg (domain, msgid1, index); @@ -784,12 +797,17 @@ _nl_find_msg (domain_file, msgid, index) We allocate always larger blocks which get used over time. This is faster than many small allocations. */ __libc_lock_define_initialized (static, lock) +# define INITIAL_BLOCK_SIZE 4080 static unsigned char *freemem; static size_t freemem_size; size_t resultlen; const unsigned char *inbuf; unsigned char *outbuf; + int malloc_count; +# ifndef _LIBC + transmem_block_t *transmem_list = NULL; +# endif /* Note that we translate (index + 1) consecutive strings at once, including the final NUL byte. */ @@ -807,13 +825,15 @@ _nl_find_msg (domain_file, msgid, index) inbuf = result; outbuf = freemem + sizeof (nls_uint32); + malloc_count = 0; while (1) { + transmem_block_t *newmem; # ifdef _LIBC size_t non_reversible; int res; - if (freemem_size < 4) + if (freemem_size < sizeof (nls_uint32)) goto resize_freemem; res = __gconv (domain->conv, @@ -839,10 +859,10 @@ _nl_find_msg (domain_file, msgid, index) char *outptr = (char *) outbuf; size_t outleft; - if (freemem_size < 4) + if (freemem_size < sizeof (nls_uint32)) goto resize_freemem; - outleft = freemem_size - 4; + outleft = freemem_size - sizeof (nls_uint32); if (iconv (domain->conv, &inptr, &inleft, &outptr, &outleft) != (size_t) (-1)) { @@ -858,18 +878,52 @@ _nl_find_msg (domain_file, msgid, index) # endif resize_freemem: - /* We must resize the buffer. */ - freemem_size = 2 * freemem_size; - if (freemem_size < 4064) - freemem_size = 4064; - freemem = (char *) malloc (freemem_size); - if (__builtin_expect (freemem == NULL, 0)) + /* We must allocate a new buffer or resize the old one. */ + if (malloc_count > 0) + { + ++malloc_count; + freemem_size = malloc_count * INITIAL_BLOCK_SIZE; + newmem = (transmem_block_t *) realloc (transmem_list, + freemem_size); +# ifdef _LIBC + if (newmem != NULL) + transmem_list = transmem_list->next; + else + { + struct transmem_list *old = transmem_list; + + transmem_list = transmem_list->next; + free (old); + } +# endif + } + else + { + malloc_count = 1; + freemem_size = INITIAL_BLOCK_SIZE; + newmem = (transmem_block_t *) malloc (freemem_size); + } + if (__builtin_expect (newmem == NULL, 0)) { + freemem = NULL; freemem_size = 0; __libc_lock_unlock (lock); goto converted; } +# ifdef _LIBC + /* Add the block to the list of blocks we have to free + at some point. */ + newmem->next = transmem_list; + transmem_list = newmem; + + freemem = newmem->data; + freemem_size -= offsetof (struct transmem_list, data); +# else + transmem_list = newmem; + freemem = newmem; +# endif + outbuf = freemem + sizeof (nls_uint32); } @@ -1038,7 +1092,7 @@ guess_category_value (category, categoryname) /* `LANGUAGE' is not set. So we have to proceed with the POSIX methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some systems this can be done by the `setlocale' function itself. */ -#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL +#if defined _LIBC || (defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL) return setlocale (category, NULL); #else /* Setting of LC_ALL overwrites all other. */ @@ -1098,15 +1152,17 @@ mempcpy (dest, src, n) static void __attribute__ ((unused)) free_mem (void) { - struct binding *runp; + void *old; - for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next) + while (_nl_domain_bindings != NULL) { - if (runp->dirname != _nl_default_dirname) + struct binding *oldp = _nl_domain_bindings; + _nl_domain_bindings = _nl_domain_bindings->next; + if (oldp->dirname != _nl_default_dirname) /* Yes, this is a pointer comparison. */ - free (runp->dirname); - if (runp->codeset != NULL) - free (runp->codeset); + free (oldp->dirname); + free (oldp->codeset); + free (oldp); } if (_nl_current_default_domain != _nl_default_default_domain) @@ -1115,6 +1171,14 @@ free_mem (void) /* Remove the search tree with the known translations. */ __tdestroy (root, free); + root = NULL; + + while (transmem_list != NULL) + { + old = transmem_list; + transmem_list = transmem_list->next; + free (old); + } } text_set_element (__libc_subfreeres, free_mem); diff --git a/intl/libintl.glibc b/intl/libintl.glibc index eb81d7cd3..7298852f7 100644 --- a/intl/libintl.glibc +++ b/intl/libintl.glibc @@ -101,13 +101,13 @@ extern char *bind_textdomain_codeset (__const char *__domainname, # define gettext(msgid) dgettext (NULL, msgid) -# define dgettext(domainname, msgid) \ +# define dgettext(domainname, msgid) \ dcgettext (domainname, msgid, LC_MESSAGES) -# define ngettext(msgid, n) dngettext (NULL, msgid, n) +# define ngettext(msgid1, msgid2, n) dngettext (NULL, msgid1, msgid2, n) -# define dngettext(domainname, msgid, n) \ - dcngettext (domainname, msgid, n, LC_MESSAGES) +# define dngettext(domainname, msgid1, msgid2, n) \ + dcngettext (domainname, msgid1, msgid2, n, LC_MESSAGES) #endif /* Optimizing. */ diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index 37af2d3a6..a679de48c 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -154,7 +154,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; @@ -176,7 +180,12 @@ _nl_load_domain (domain_file) return; /* We must know about the size of the file. */ - if (__builtin_expect (fstat (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)) { @@ -348,8 +357,9 @@ _nl_load_domain (domain_file) } # ifdef _LIBC - outcharset = norm_add_slashes (outcharset); - charset = norm_add_slashes (charset); + /* We always want to use transliteration. */ + outcharset = norm_add_slashes (outcharset, "TRANSLIT"); + charset = norm_add_slashes (charset, NULL); if (__gconv_open (outcharset, charset, &domain->conv, GCONV_AVOID_NOCONV) != __GCONV_OK) @@ -419,21 +429,17 @@ _nl_unload_domain (domain) if (domain->plural != &germanic_plural) __gettext_free_exp (domain->plural); -#ifdef _LIBC + if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1) + free (domain->conv_tab); + if (domain->conv != (__gconv_t) -1) __gconv_close (domain->conv); -#else -# if HAVE_ICONV - if (domain->conv != (iconv_t) -1) - iconv_close (domain->conv); -# endif -#endif -#ifdef _POSIX_MAPPED_FILES +# ifdef _POSIX_MAPPED_FILES if (domain->use_mmap) munmap ((caddr_t) domain->data, domain->mmap_size); else -#endif /* _POSIX_MAPPED_FILES */ +# endif /* _POSIX_MAPPED_FILES */ free ((void *) domain->data); free (domain); diff --git a/intl/localealias.c b/intl/localealias.c index c103a048d..2227d9bff 100644 --- a/intl/localealias.c +++ b/intl/localealias.c @@ -350,6 +350,18 @@ read_alias_file (fname, fname_len) FREE_BLOCKS (block_list); return added; } + + if (__builtin_expect (string_space != new_pool, 0)) + { + size_t i; + + for (i = 0; i < nmap; i++) + { + map[i].alias += new_pool - string_space; + map[i].value += new_pool - string_space; + } + } + string_space = new_pool; string_space_max = new_size; } diff --git a/intl/plural.y b/intl/plural.y index 42aac280e..d33bb9644 100644 --- a/intl/plural.y +++ b/intl/plural.y @@ -39,7 +39,7 @@ %{ /* Prototypes for local functions. */ -static struct expression *new_exp (enum operator op, ...); +static struct expression *new_exp (enum operator op, int n, ...); static int yylex (YYSTYPE *lval, const char **pexp); static void yyerror (const char *str); %} @@ -63,62 +63,62 @@ start: exp exp: exp '?' exp ':' exp { - if (($$ = new_exp (qmop, $1, $3, $5, NULL)) == NULL) + if (($$ = new_exp (qmop, 3, $1, $3, $5)) == NULL) YYABORT } | exp '|' exp { - if (($$ = new_exp (lor, $1, $3, NULL)) == NULL) + if (($$ = new_exp (lor, 2, $1, $3)) == NULL) YYABORT } | exp '&' exp { - if (($$ = new_exp (land, $1, $3, NULL)) == NULL) + if (($$ = new_exp (land, 2, $1, $3)) == NULL) YYABORT } | exp '=' exp { - if (($$ = new_exp (equal, $1, $3, NULL)) == NULL) + if (($$ = new_exp (equal, 2, $1, $3)) == NULL) YYABORT } | exp '!' exp { - if (($$ = new_exp (not_equal, $1, $3, NULL)) == NULL) + if (($$ = new_exp (not_equal, 2, $1, $3)) == NULL) YYABORT } | exp '+' exp { - if (($$ = new_exp (plus, $1, $3, NULL)) == NULL) + if (($$ = new_exp (plus, 2, $1, $3)) == NULL) YYABORT } | exp '-' exp { - if (($$ = new_exp (minus, $1, $3, NULL)) == NULL) + if (($$ = new_exp (minus, 2, $1, $3)) == NULL) YYABORT } | exp '*' exp { - if (($$ = new_exp (mult, $1, $3, NULL)) == NULL) + if (($$ = new_exp (mult, 2, $1, $3)) == NULL) YYABORT } | exp '/' exp { - if (($$ = new_exp (divide, $1, $3, NULL)) == NULL) + if (($$ = new_exp (divide, 2, $1, $3)) == NULL) YYABORT } | exp '%' exp { - if (($$ = new_exp (module, $1, $3, NULL)) == NULL) + if (($$ = new_exp (module, 2, $1, $3)) == NULL) YYABORT } | 'n' { - if (($$ = new_exp (var, NULL)) == NULL) + if (($$ = new_exp (var, 0)) == NULL) YYABORT } | NUMBER { - if (($$ = new_exp (num, NULL)) == NULL) + if (($$ = new_exp (num, 0)) == NULL) YYABORT; $$->val.num = $1 } @@ -131,31 +131,33 @@ exp: exp '?' exp ':' exp %% static struct expression * -new_exp (enum operator op, ...) +new_exp (enum operator op, int n, ...) { - struct expression *newp = (struct expression *) malloc (sizeof (*newp)); + struct expression *newp = (struct expression *) calloc (1, sizeof (*newp)); va_list va; - struct expression *next; - va_start (va, op); + va_start (va, n); if (newp == NULL) - while ((next = va_arg (va, struct expression *)) != NULL) - __gettext_free_exp (next); + while (n-- > 0) + __gettext_free_exp (va_arg (va, struct expression *)); else { newp->operation = op; - next = va_arg (va, struct expression *); - if (next != NULL) + if (n > 0) { - newp->val.args3.bexp = next; - next = va_arg (va, struct expression *); - if (next != NULL) + 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)) { - newp->val.args3.tbranch = next; - next = va_arg (va, struct expression *); - if (next != NULL) - newp->val.args3.fbranch = next; + __gettext_free_exp (newp); + newp = NULL; } } } @@ -213,7 +215,14 @@ yylex (YYSTYPE *lval, const char **pexp) exp += 2; continue; } - if (exp[0] != '\0' && exp[0] != ' ' && exp[0] != '\t') + + if (exp[0] == '\0') + { + *pexp = exp; + return YYEOF; + } + + if (exp[0] != ' ' && exp[0] != '\t') break; ++exp; @@ -266,6 +275,7 @@ yylex (YYSTYPE *lval, const char **pexp) /* Nothing, just return the character. */ break; + case ';': case '\n': case '\0': /* Be safe and let the user call this function again. */ -- 2.47.3