Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 22 Aug 1999 22:39:16 +0000 (22:39 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 22 Aug 1999 22:39:16 +0000 (22:39 +0000)
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.

ChangeLog
iconv/gconv_int.h
iconv/gconv_open.c
iconv/iconv_open.c
intl/dcgettext.c
intl/gettextP.h
intl/loadmsgcat.c
posix/Makefile
posix/regexbug1.c [new file with mode: 0644]
wcsmbs/wcsmbsload.c

index cee4d64..f6ebb8e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index 6048319..794f41f 100644 (file)
@@ -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.  */
index cf36999..44cb5cc 100644 (file)
@@ -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.  */
index e566c6a..96b910e 100644 (file)
@@ -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)
     {
index 0429cc9..d482da3 100644 (file)
@@ -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);
index bea4404..1b4dcb3 100644 (file)
 #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;
 };
index 23d7388..ba818ce 100644 (file)
@@ -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
        }
     }
index 2790534..f8e72b6 100644 (file)
@@ -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 (file)
index 0000000..6f7f995
--- /dev/null
@@ -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;
+}
index 19ce7e7..bbac794 100644 (file)
@@ -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;