* iconv/gconv_trans.c: Test with _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN
	whether this information is available.

	* intl/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.

	* intl/tst-gettext.c: Use correct locale.  Improve error messages.

	* locale/programs/ld-ctype.c (ctype_output): If no default_missing
	information is available set the string length to zero.
This commit is contained in:
Ulrich Drepper 2000-07-01 00:04:28 +00:00
parent fb46e8d284
commit 7f4553513c
4 changed files with 80 additions and 14 deletions

View file

@ -1,5 +1,18 @@
2000-06-30 Ulrich Drepper <drepper@redhat.com>
* iconv/gconv_trans.c: Test with _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN
whether this information is available.
* intl/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.
* intl/tst-gettext.c: Use correct locale. Improve error messages.
* locale/programs/ld-ctype.c (ctype_output): If no default_missing
information is available set the string length to zero.
* sysdeps/i386/i686/strcmp.S: Little optimization in non-BP case.
2000-06-30 Greg McGary <greg@mcgary.org>

View file

@ -55,6 +55,7 @@ extern int errno;
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stddef.h>
# include <stdlib.h>
#else
char *getenv ();
@ -313,6 +314,14 @@ struct block_list
#endif /* have alloca */
/* List of blocks allocated for translations. */
static struct transmem_list
{
struct transmem_list *next;
char data[0];
} *transmem_list;
/* 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 __
@ -775,12 +784,14 @@ _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;
/* Note that we translate (index + 1) consecutive strings at
once, including the final NUL byte. */
@ -798,9 +809,11 @@ _nl_find_msg (domain_file, msgid, index)
inbuf = result;
outbuf = freemem + sizeof (nls_uint32);
malloc_count = 0;
while (1)
{
# ifdef _LIBC
struct transmem_list *newmem;
size_t non_reversible;
int res;
@ -825,6 +838,7 @@ _nl_find_msg (domain_file, msgid, index)
inbuf = result;
# else
# if HAVE_ICONV
# define transmem freemem
const char *inptr = (const char *) inbuf;
size_t inleft = resultlen;
char *outptr = (char *) outbuf;
@ -845,22 +859,49 @@ _nl_find_msg (domain_file, msgid, index)
__libc_lock_unlock (lock);
goto converted;
}
# else
# define transmem freemem
# endif
# 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 of resize the old one. */
if (malloc_count > 0)
{
struct transmem_list *next = transmem_list->next;
++malloc_count;
freemem_size = malloc_count * INITIAL_BLOCK_SIZE;
newmem = (struct transmem_list *) realloc (transmem_list,
freemem_size);
if (newmem != NULL)
transmem_list = next;
}
else
{
malloc_count = 1;
freemem_size = INITIAL_BLOCK_SIZE;
newmem = (struct transmem_list *) 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);
# endif
outbuf = freemem + sizeof (nls_uint32);
}
@ -1090,6 +1131,7 @@ static void __attribute__ ((unused))
free_mem (void)
{
struct binding *runp;
void *old;
for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
{
@ -1106,6 +1148,13 @@ free_mem (void)
/* Remove the search tree with the known translations. */
__tdestroy (root, free);
while (transmem_list != NULL)
{
old = transmem_list;
transmem_list = transmem_list->next;
free (old);
}
}
text_set_element (__libc_subfreeres, free_mem);

View file

@ -71,7 +71,7 @@ main (int argc, char *argv[])
setenv ("LC_MESSAGES", "non-existing-locale", 1);
setenv ("LC_CTYPE", "non-existing-locale", 1);
setenv ("LANG", "non-existing-locale", 1);
setlocale (LC_CTYPE, "de_DE");
setlocale (LC_CTYPE, "de_DE.ISO-8859-1");
unsetenv ("OUTPUT_CHARSET");
/* This is the name of the existing domain with a catalog for the
LC_MESSAGES category. */
@ -225,8 +225,9 @@ positive_gettext_test (void)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{
/* Oops, shouldn't happen. */
printf (" gettext (\"%s\") failed, returned \"%s\"\n",
msgs[cnt].msgid, found);
printf ("\
gettext (\"%s\") failed, returned \"%s\", expected \"%s\"\n",
msgs[cnt].msgid, found, msgs[cnt].msgstr);
result = 1;
}
}
@ -270,8 +271,9 @@ positive_dgettext_test (const char *domain)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{
/* Oops, shouldn't happen. */
printf (" dgettext (\"%s\", \"%s\") failed, returned \"%s\"\n",
domain, msgs[cnt].msgid, found);
printf ("\
dgettext (\"%s\", \"%s\") failed, returned \"%s\", expected \"%s\"\n",
domain, msgs[cnt].msgid, found, msgs[cnt].msgstr);
result = 1;
}
}
@ -293,8 +295,10 @@ positive_dcgettext_test (const char *domain, int category)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{
/* Oops, shouldn't happen. */
printf (" dcgettext (\"%s\", \"%s\", %s) failed, returned \"%s\"\n",
domain, msgs[cnt].msgid, catname[category], found);
printf ("\
dcgettext (\"%s\", \"%s\", %s) failed, returned \"%s\", expected \"%s\"\n",
domain, msgs[cnt].msgid, catname[category], found,
msgs[cnt].msgstr);
result = 1;
}
}

View file

@ -1078,7 +1078,7 @@ ctype_output (struct localedef_t *locale, struct charmap_t *charmap,
case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN):
default_missing_len = (ctype->default_missing
? wcslen ((wchar_t *)ctype->default_missing)
: 1);
: 0);
iov[2 + elem + offset].iov_base = &default_missing_len;
iov[2 + elem + offset].iov_len = sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;