* 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> 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. * sysdeps/i386/i686/strcmp.S: Little optimization in non-BP case.
2000-06-30 Greg McGary <greg@mcgary.org> 2000-06-30 Greg McGary <greg@mcgary.org>

View File

@ -55,6 +55,7 @@ extern int errno;
#endif #endif
#if defined STDC_HEADERS || defined _LIBC #if defined STDC_HEADERS || defined _LIBC
# include <stddef.h>
# include <stdlib.h> # include <stdlib.h>
#else #else
char *getenv (); char *getenv ();
@ -313,6 +314,14 @@ struct block_list
#endif /* have alloca */ #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 /* Names for the libintl functions are a problem. They must not clash
with existing names and they should follow ANSI C. But this source 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 __ 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 We allocate always larger blocks which get used over
time. This is faster than many small allocations. */ time. This is faster than many small allocations. */
__libc_lock_define_initialized (static, lock) __libc_lock_define_initialized (static, lock)
#define INITIAL_BLOCK_SIZE 4080
static unsigned char *freemem; static unsigned char *freemem;
static size_t freemem_size; static size_t freemem_size;
size_t resultlen; size_t resultlen;
const unsigned char *inbuf; const unsigned char *inbuf;
unsigned char *outbuf; unsigned char *outbuf;
int malloc_count;
/* Note that we translate (index + 1) consecutive strings at /* Note that we translate (index + 1) consecutive strings at
once, including the final NUL byte. */ once, including the final NUL byte. */
@ -798,9 +809,11 @@ _nl_find_msg (domain_file, msgid, index)
inbuf = result; inbuf = result;
outbuf = freemem + sizeof (nls_uint32); outbuf = freemem + sizeof (nls_uint32);
malloc_count = 0;
while (1) while (1)
{ {
# ifdef _LIBC # ifdef _LIBC
struct transmem_list *newmem;
size_t non_reversible; size_t non_reversible;
int res; int res;
@ -825,6 +838,7 @@ _nl_find_msg (domain_file, msgid, index)
inbuf = result; inbuf = result;
# else # else
# if HAVE_ICONV # if HAVE_ICONV
# define transmem freemem
const char *inptr = (const char *) inbuf; const char *inptr = (const char *) inbuf;
size_t inleft = resultlen; size_t inleft = resultlen;
char *outptr = (char *) outbuf; char *outptr = (char *) outbuf;
@ -845,22 +859,49 @@ _nl_find_msg (domain_file, msgid, index)
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
goto converted; goto converted;
} }
# else
# define transmem freemem
# endif # endif
# endif # endif
resize_freemem: resize_freemem:
/* We must resize the buffer. */ /* We must allocate a new buffer of resize the old one. */
freemem_size = 2 * freemem_size; if (malloc_count > 0)
if (freemem_size < 4064)
freemem_size = 4064;
freemem = (char *) malloc (freemem_size);
if (__builtin_expect (freemem == NULL, 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; freemem_size = 0;
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
goto converted; 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); outbuf = freemem + sizeof (nls_uint32);
} }
@ -1090,6 +1131,7 @@ static void __attribute__ ((unused))
free_mem (void) free_mem (void)
{ {
struct binding *runp; struct binding *runp;
void *old;
for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next) 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. */ /* Remove the search tree with the known translations. */
__tdestroy (root, free); __tdestroy (root, free);
while (transmem_list != NULL)
{
old = transmem_list;
transmem_list = transmem_list->next;
free (old);
}
} }
text_set_element (__libc_subfreeres, free_mem); 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_MESSAGES", "non-existing-locale", 1);
setenv ("LC_CTYPE", "non-existing-locale", 1); setenv ("LC_CTYPE", "non-existing-locale", 1);
setenv ("LANG", "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"); unsetenv ("OUTPUT_CHARSET");
/* This is the name of the existing domain with a catalog for the /* This is the name of the existing domain with a catalog for the
LC_MESSAGES category. */ LC_MESSAGES category. */
@ -225,8 +225,9 @@ positive_gettext_test (void)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0) if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{ {
/* Oops, shouldn't happen. */ /* Oops, shouldn't happen. */
printf (" gettext (\"%s\") failed, returned \"%s\"\n", printf ("\
msgs[cnt].msgid, found); gettext (\"%s\") failed, returned \"%s\", expected \"%s\"\n",
msgs[cnt].msgid, found, msgs[cnt].msgstr);
result = 1; result = 1;
} }
} }
@ -270,8 +271,9 @@ positive_dgettext_test (const char *domain)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0) if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{ {
/* Oops, shouldn't happen. */ /* Oops, shouldn't happen. */
printf (" dgettext (\"%s\", \"%s\") failed, returned \"%s\"\n", printf ("\
domain, msgs[cnt].msgid, found); dgettext (\"%s\", \"%s\") failed, returned \"%s\", expected \"%s\"\n",
domain, msgs[cnt].msgid, found, msgs[cnt].msgstr);
result = 1; result = 1;
} }
} }
@ -293,8 +295,10 @@ positive_dcgettext_test (const char *domain, int category)
if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0) if (found == NULL || strcmp (found, msgs[cnt].msgstr) != 0)
{ {
/* Oops, shouldn't happen. */ /* Oops, shouldn't happen. */
printf (" dcgettext (\"%s\", \"%s\", %s) failed, returned \"%s\"\n", printf ("\
domain, msgs[cnt].msgid, catname[category], found); dcgettext (\"%s\", \"%s\", %s) failed, returned \"%s\", expected \"%s\"\n",
domain, msgs[cnt].msgid, catname[category], found,
msgs[cnt].msgstr);
result = 1; 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): case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN):
default_missing_len = (ctype->default_missing default_missing_len = (ctype->default_missing
? wcslen ((wchar_t *)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_base = &default_missing_len;
iov[2 + elem + offset].iov_len = sizeof (uint32_t); iov[2 + elem + offset].iov_len = sizeof (uint32_t);
idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;