+2000-10-30 Ulrich Drepper <drepper@redhat.com>
+
+ * dcigettext.c (guess_category_value): For libc always use the
+ setlocale() method.
+
+2000-10-20 Ulrich Drepper <drepper@redhat.com>
+
+ * libintl.glibc (ngettext macro): Add missing parameter.
+ (dngettext macro): Likewise.
+
+2000-10-14 Ulrich Drepper <drepper@redhat.com>
+
+ * localealias.c (read_alias_file): Update string pointers in map[]
+ if realloc() changed the values.
+ Patch by Jakub Jelinek <jakub@redhat.com>.
+
+2000-08-31 Ulrich Drepper <drepper@redhat.com>
+
+ * loadmsgcat.c: Use *stat64 instead of *stat internally.
+
+ * dcigettext.c (free_mem): Correct freeing of _nl_domain_bindings
+ list.
+
+2000-08-27 Ulrich Drepper <drepper@redhat.com>
+
+ * dcigettext.c (DCIGETTEXT): Remove _nl_find_language in code to
+ determine invalid locale name.
+
+2000-08-20 Ulrich Drepper <drepper@redhat.com>
+
+ * 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 <haible@clisp.cons.org>
+
+ * dcigettext.c (dcigettext): Call plural_eval on all platforms, not
+ only those having tsearch.
+
+2000-06-30 Ulrich Drepper <drepper@redhat.com>
+
+ * 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 <drepper@redhat.com>
+
+ * loadmsgcat.c (_nl_load_domain): Call norm_add_slashes with new
+ parameter to always enable transliteration.
+
1998-10-20 Paul Eggert <eggert@twinsun.com>
* po2tbl.sin: Escape trigraphs.
#endif
#if defined STDC_HEADERS || defined _LIBC
+# include <stddef.h>
# include <stdlib.h>
#else
char *getenv ();
# ifndef stpcpy
# define stpcpy __stpcpy
# endif
+# define tfind __tfind
#else
# if !defined HAVE_GETCWD
char *getwd ();
#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 __
/* 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;
}
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,
__libc_rwlock_unlock (_nl_state_lock);
return (char *) (*foundp)->translation;
}
- }
#endif
+ }
retval = _nl_find_msg (domain, msgid1, 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. */
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,
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))
{
# 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);
}
/* `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. */
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)
/* 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);
# 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. */
{
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;
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))
{
}
# 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)
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);
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;
}
%{
/* 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);
%}
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
}
%%
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;
}
}
}
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;
/* Nothing, just return the character. */
break;
+ case ';':
case '\n':
case '\0':
/* Be safe and let the user call this function again. */