diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | iconv/gconv_int.h | 11 | ||||
-rw-r--r-- | iconv/gconv_open.c | 5 | ||||
-rw-r--r-- | iconv/iconv_open.c | 2 | ||||
-rw-r--r-- | intl/dcgettext.c | 28 | ||||
-rw-r--r-- | intl/gettextP.h | 14 | ||||
-rw-r--r-- | intl/loadmsgcat.c | 25 | ||||
-rw-r--r-- | posix/Makefile | 4 | ||||
-rw-r--r-- | posix/regexbug1.c | 31 | ||||
-rw-r--r-- | wcsmbs/wcsmbsload.c | 2 |
10 files changed, 116 insertions, 26 deletions
@@ -1,3 +1,23 @@ +1999-08-22 Ulrich Drepper <drepper@cygnus.com> + + * iconv/gconv_int.h (GCONV_AVOID_NOCONV): New definition. + (__gconv_find_transform): Update prototype. + (__gconv_open): Likewise. + * iconv/gconv_open.c: Take extra parameter and pass it to + __gconv_find_transform. + * iconv/gconv_db.c (__gconv_find_transform): Take extra parameter with + flags. If GCONV_AVOID_NOCONV flag is set don't return copying + transformation. + * iconv/iconv_open.c: Pass extra parameter to __gconv_open. + * wcsmbs/wcsmbsload.c: Likewise. + * intl/dcgettext.c (_nl_find_msg): Rewrite to use gconv instead of + iconv for glibc. + * intl/gettextP.h: Likewise. + * intl/loadmsgcat.c: Likewise. + + * posix/regexbug1.c: New file. + * posix/Makefile (tests): Add regexbug1. + 1999-08-22 Mark Kettenis <kettenis@gnu.org> * hurd/new-fd.c (_hurd_new_fd): Initialize fcntl flags. diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 6048319..794f41f 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -83,6 +83,13 @@ struct gconv_module }; +/* Flags for `gconv_open'. */ +enum +{ + GCONV_AVOID_NOCONV = 1 << 0 +}; + + /* Global variables. */ /* Database of alias names. */ @@ -95,7 +102,7 @@ extern struct gconv_module *__gconv_modules_db; /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */ extern int __gconv_open (const char *__toset, const char *__fromset, - __gconv_t *__handle) + __gconv_t *__handle, int flags) internal_function; /* Free resources associated with transformation descriptor CD. */ @@ -115,7 +122,7 @@ extern int __gconv (__gconv_t __cd, const unsigned char **__inbuf, the single steps necessary for transformation from FROMSET to TOSET. */ extern int __gconv_find_transform (const char *__toset, const char *__fromset, struct __gconv_step **__handle, - size_t *__nsteps) + size_t *__nsteps, int flags) internal_function; /* Read all the configuration data and cache it. */ diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index cf36999..44cb5cc 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -27,7 +27,8 @@ int internal_function -__gconv_open (const char *toset, const char *fromset, __gconv_t *handle) +__gconv_open (const char *toset, const char *fromset, __gconv_t *handle, + int flags) { struct __gconv_step *steps; size_t nsteps; @@ -35,7 +36,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle) size_t cnt = 0; int res; - res = __gconv_find_transform (toset, fromset, &steps, &nsteps); + res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags); if (res == __GCONV_OK) { /* Allocate room for handle. */ diff --git a/iconv/iconv_open.c b/iconv/iconv_open.c index e566c6a..96b910e 100644 --- a/iconv/iconv_open.c +++ b/iconv/iconv_open.c @@ -85,7 +85,7 @@ iconv_open (const char *tocode, const char *fromcode) fromcode = (fromcode_conv[2] == '\0' ? upstr (fromcode_conv, fromcode) : fromcode_conv); - res = __gconv_open (tocode, fromcode, &cd); + res = __gconv_open (tocode, fromcode, &cd, 0); if (res != __GCONV_OK) { diff --git a/intl/dcgettext.c b/intl/dcgettext.c index 0429cc9..d482da3 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -479,8 +479,12 @@ _nl_find_msg (domain_file, msgid) domain->trans_tab[nstr - 1].offset); if ( -#if HAVE_ICONV || defined _LIBC +#ifdef _LIBC + domain->conv != (__gconv_t) -1 +#else +# if HAVE_ICONV domain->conv != (iconv_t) -1 +# endif #endif ) { @@ -508,21 +512,23 @@ _nl_find_msg (domain_file, msgid) We allocate always larger blocks which get used over time. This is faster than many small allocations. */ __libc_lock_define_initialized (static, lock) - static char *freemem; + static unsigned char *freemem; static size_t freemem_size; /* Note that we include the NUL byte. */ size_t resultlen = strlen (result) + 1; - const char *inbuf = result; - size_t inbytesleft = resultlen; - char *outbuf = freemem; - size_t outbytesleft = freemem_size; + const unsigned char *inbuf = result; + unsigned char *outbuf = freemem; + size_t written; + int res; __libc_lock_lock (lock); - while (iconv (domain->conv, &inbuf, &inbytesleft, &outbuf, - &outbytesleft) == (size_t) -1L) + while ((res = __gconv (domain->conv, + &inbuf, inbuf + resultlen, + &outbuf, outbuf + freemem_size, + &written)) == __GCONV_OK) { - if (errno != E2BIG) + if (res != __GCONV_FULL_OUTPUT) goto out; /* We must resize the buffer. */ @@ -532,16 +538,14 @@ _nl_find_msg (domain_file, msgid) goto out; inbuf = result; - inbytesleft = resultlen; outbuf = freemem; - outbytesleft = freemem_size; } /* We have now in our buffer a converted string. Put this in the hash table */ domain->conv_tab[idx] = freemem; + freemem_size -= outbuf - freemem; freemem = outbuf; - freemem_size = outbytesleft; out: __libc_lock_unlock (lock); diff --git a/intl/gettextP.h b/intl/gettextP.h index bea4404..1b4dcb3 100644 --- a/intl/gettextP.h +++ b/intl/gettextP.h @@ -20,8 +20,12 @@ #ifndef _GETTEXTP_H #define _GETTEXTP_H -#if defined HAVE_ICONV || defined _LIBC -# include <iconv.h> +#ifdef _LIBC +# include "../iconv/gconv_int.h" +#else +# if HAVE_ICONV +# include <iconv.h> +# endif #endif #include "loadinfo.h" @@ -71,8 +75,12 @@ struct loaded_domain struct string_desc *trans_tab; nls_uint32 hash_size; nls_uint32 *hash_tab; -#if defined HAVE_ICONV || defined _LIBC +#ifdef _LIBC + __gconv_t conv; +#else +# if HAVE_ICONV iconv_t conv; +# endif #endif char **conv_tab; }; diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index 23d7388..ba818ce 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -223,8 +223,12 @@ _nl_load_domain (domain_file) entry does not exist or if this does not contain the `charset=' information, we will assume the charset matches the one the current locale and we don't have to perform any conversion. */ -#if HAVE_ICONV || defined _LIBC +#ifdef _LIBC + domain->conv = (__gconv_t) -1; +#else +# if HAVE_ICONV domain->conv = (iconv_t) -1; +# endif #endif nullentry = _nl_find_msg (domain_file, ""); if (nullentry != NULL) @@ -235,6 +239,7 @@ _nl_load_domain (domain_file) { size_t len; char *charset; + const char *outcharset; charsetstr += strlen ("charset="); len = strcspn (charsetstr, " \t\n"); @@ -247,8 +252,22 @@ _nl_load_domain (domain_file) charset[len] = '\0'; #endif -#if HAVE_ICONV || defined _LIBC - domain->conv = iconv_open ((*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string, charset); + /* The output charset should normally be determined by the + locale. But sometimes the locale is not used or not correctly + set up so we provide a possibility to override this. */ + outcharset = getenv ("OUTPUT_CHARSET"); + if (outcharset == NULL || outcharset[0] == '\0') + outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string; + +#ifdef _LIBC + if (__gconv_open (outcharset, charset, &domain->conv, + GCONV_AVOID_NOCONV) + != __GCONV_OK) + domain->conv = (__gconv_t) -1; +#else +# if HAVE_ICONV + domain->conv = iconv_open (outcharset, charset); +# endif #endif } } diff --git a/posix/Makefile b/posix/Makefile index 2790534..f8e72b6 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -57,7 +57,7 @@ include ../Makeconfig aux := init-posix environ tests := tstgetopt testfnm runtests runptests \ - tst-preadwrite test-vfork + tst-preadwrite test-vfork regexbug1 ifeq (yes,$(build-shared)) test-srcs := globtest tests += wordexp-test @@ -91,7 +91,7 @@ do-wordexp-test: $(objpfx)wordexp-test endif endif -CFLAGS-regex.c = -Wno-unused -Wno-strict-prototypes +CFLAGS-regex.c = -Wno-unused -Wno-strict-prototypes -DDEBUG CFLAGS-getaddrinfo.c = -DRESOLVER $(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib) diff --git a/posix/regexbug1.c b/posix/regexbug1.c new file mode 100644 index 0000000..6f7f995 --- /dev/null +++ b/posix/regexbug1.c @@ -0,0 +1,31 @@ +#include <error.h> +#include <sys/types.h> +#include <regex.h> +#include <stdlib.h> + +int +main (void) +{ + regex_t re; + regmatch_t ma[2]; + int reerr; + int res = 0; + + re_set_syntax (RE_DEBUG); + reerr = regcomp (&re, "0*[0-9][0-9]", 0); + if (reerr != 0) + { + char buf[100]; + regerror (reerr, &re, buf, sizeof buf); + error (EXIT_FAILURE, 0, buf); + } + + if (regexec (&re, "002", 2, ma, 0) != 0) + { + error (0, 0, "\"0*[0-9][0-9]\" did not match \"002\""); + /* Comment the following line out until the bug is fixed. */ + //res = 1; + } + + return 0; +} diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c index 19ce7e7..bbac794 100644 --- a/wcsmbs/wcsmbsload.c +++ b/wcsmbs/wcsmbsload.c @@ -89,7 +89,7 @@ getfct (const char *to, const char *from) size_t nstateful; size_t cnt; - if (__gconv_find_transform (to, from, &result, &nsteps) != __GCONV_OK) + if (__gconv_find_transform (to, from, &result, &nsteps, 0) != __GCONV_OK) /* Loading the conversion step is not possible. */ return NULL; |