From 7f4553513cc2e247fa40ba80485f41e942ba6c9b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 1 Jul 2000 00:04:28 +0000 Subject: Update. * 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. --- ChangeLog | 13 ++++++++++ intl/dcigettext.c | 61 +++++++++++++++++++++++++++++++++++++++++----- intl/tst-gettext.c | 18 ++++++++------ locale/programs/ld-ctype.c | 2 +- 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97f5709ebb..1ff84dfe42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2000-06-30 Ulrich Drepper + * 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 diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 27398c1ca7..ed470b4ee6 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -55,6 +55,7 @@ extern int errno; #endif #if defined STDC_HEADERS || defined _LIBC +# include # include #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); diff --git a/intl/tst-gettext.c b/intl/tst-gettext.c index d9f97187f7..688acbf85a 100644 --- a/intl/tst-gettext.c +++ b/intl/tst-gettext.c @@ -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; } } diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index d3e3d7c30a..156bd101e2 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -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; -- cgit v1.2.3