+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.
};
+/* Flags for `gconv_open'. */
+enum
+{
+ GCONV_AVOID_NOCONV = 1 << 0
+};
+
+
/* Global variables. */
/* Database of alias names. */
/* 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. */
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. */
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;
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. */
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)
{
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
)
{
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. */
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);
#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"
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;
};
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)
{
size_t len;
char *charset;
+ const char *outcharset;
charsetstr += strlen ("charset=");
len = strcspn (charsetstr, " \t\n");
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
}
}
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
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)
--- /dev/null
+#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;
+}
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;