Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 19 Jun 2000 21:12:06 +0000 (21:12 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 19 Jun 2000 21:12:06 +0000 (21:12 +0000)
2000-06-19  Ulrich Drepper  <drepper@redhat.com>

* iconv/gconv.h (__gconv_trans_fct): Add new parameter.
General namespace cleanup.
(struct __gconv_trans_data): Add next field.
(struct __gconv_step_data): Make __trans a pointer.
* iconv/gconv_conf.c: Split out code to find gconv directories from
__gconv_read_conf in new functions.
* iconv/gconv_int.h: Define new data structure and declare new
functions for handling of gconv directory list.
* iconv/gconv_open.c: Allow more than one error handling step being
used.  Call function to load error handling module if it is none
of the builtin transformations.
* iconv/gconv_close.c: Add code to free transliteration data.
* iconv/gconv_trans.c: Add functions to load and unload modules
implementing transliteration etc.
* iconv/skeleton.c: Call all context functions now that more than
one module is allowed.
* iconv/loop.c (STANDARD_ERR_HANDLING): New macro.
* iconv/gconv_simple.c: Use STANDARD_ERR_HANDLING macro for places
where the full error handling using transliteration is needed.
* iconvdata/8bit-gap.c: Likewise.
* iconvdata/8bit-generic.c: Likewise.
* iconvdata/ansi_x3.110.c: Likewise.
* iconvdata/big5.c: Likewise.
* iconvdata/big5hkscs.c: Likewise.
* iconvdata/euc-cn.c: Likewise.
* iconvdata/euc-jp.c: Likewise.
* iconvdata/euc-kr.c: Likewise.
* iconvdata/euc-tw.c: Likewise.
* iconvdata/gbgbk.c: Likewise.
* iconvdata/gbk.c: Likewise.
* iconvdata/iso-2022-cn.c: Likewise.
* iconvdata/iso-2022-jp.c: Likewise.
* iconvdata/iso-2022-kr.c: Likewise.
* iconvdata/iso646.c: Likewise.
* iconvdata/iso8859-1.c: Likewise.
* iconvdata/iso_6937-2.c: Likewise.
* iconvdata/iso_6937.c: Likewise.
* iconvdata/johab.c: Likewise.
* iconvdata/sjis.c: Likewise.
* iconvdata/t.61.c: Likewise.
* iconvdata/uhc.c: Likewise.
* iconvdata/unicode.c: Likewise.
* iconvdata/utf-16.c: Likewise.
* libio/iofwide.c: Reset __trans member of __gconv_trans_data
structure correctly after last change.
* wcsmbs/btowc.c: Likewise.
* wcsmbs/mbrtowc.c: Likewise.
* wcsmbs/mbsnrtowcs.c: Likewise.
* wcsmbs/mbsrtowcs.c: Likewise.
* wcsmbs/wcrtomb.c: Likewise.
* wcsmbs/wcsnrtombs.c: Likewise.
* wcsmbs/wcsrtombs.c: Likewise.
* wcsmbs/wctob.c: Likewise.

* localedata/Makefile: Set -Wno-format for some files since gcc does
not know all the format specifiers.

2000-06-18  Ulrich Drepper  <drepper@redhat.com>

* locale/loadlocale.c (_nl_unload_locale): Remove a bit of
unneeded code.
* locale/lc-time.c (_nl_init_era_entries): Likewise.

45 files changed:
ChangeLog
iconv/gconv.h
iconv/gconv_close.c
iconv/gconv_conf.c
iconv/gconv_int.h
iconv/gconv_open.c
iconv/gconv_simple.c
iconv/gconv_trans.c
iconv/loop.c
iconv/skeleton.c
iconvdata/8bit-gap.c
iconvdata/8bit-generic.c
iconvdata/ansi_x3.110.c
iconvdata/big5.c
iconvdata/big5hkscs.c
iconvdata/euc-cn.c
iconvdata/euc-jp.c
iconvdata/euc-kr.c
iconvdata/euc-tw.c
iconvdata/gbgbk.c
iconvdata/gbk.c
iconvdata/iso-2022-cn.c
iconvdata/iso-2022-jp.c
iconvdata/iso-2022-kr.c
iconvdata/iso646.c
iconvdata/iso8859-1.c
iconvdata/iso_6937-2.c
iconvdata/iso_6937.c
iconvdata/johab.c
iconvdata/sjis.c
iconvdata/t.61.c
iconvdata/uhc.c
iconvdata/unicode.c
iconvdata/utf-16.c
libio/iofwide.c
locale/loadlocale.c
localedata/Makefile
wcsmbs/btowc.c
wcsmbs/mbrtowc.c
wcsmbs/mbsnrtowcs.c
wcsmbs/mbsrtowcs.c
wcsmbs/wcrtomb.c
wcsmbs/wcsnrtombs.c
wcsmbs/wcsrtombs.c
wcsmbs/wctob.c

index 4141af4..8b8305a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,68 @@
+2000-06-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * iconv/gconv.h (__gconv_trans_fct): Add new parameter.
+       General namespace cleanup.
+       (struct __gconv_trans_data): Add next field.
+       (struct __gconv_step_data): Make __trans a pointer.
+       * iconv/gconv_conf.c: Split out code to find gconv directories from
+       __gconv_read_conf in new functions.
+       * iconv/gconv_int.h: Define new data structure and declare new
+       functions for handling of gconv directory list.
+       * iconv/gconv_open.c: Allow more than one error handling step being
+       used.  Call function to load error handling module if it is none
+       of the builtin transformations.
+       * iconv/gconv_close.c: Add code to free transliteration data.
+       * iconv/gconv_trans.c: Add functions to load and unload modules
+       implementing transliteration etc.
+       * iconv/skeleton.c: Call all context functions now that more than
+       one module is allowed.
+       * iconv/loop.c (STANDARD_ERR_HANDLING): New macro.
+       * iconv/gconv_simple.c: Use STANDARD_ERR_HANDLING macro for places
+       where the full error handling using transliteration is needed.
+       * iconvdata/8bit-gap.c: Likewise.
+       * iconvdata/8bit-generic.c: Likewise.
+       * iconvdata/ansi_x3.110.c: Likewise.
+       * iconvdata/big5.c: Likewise.
+       * iconvdata/big5hkscs.c: Likewise.
+       * iconvdata/euc-cn.c: Likewise.
+       * iconvdata/euc-jp.c: Likewise.
+       * iconvdata/euc-kr.c: Likewise.
+       * iconvdata/euc-tw.c: Likewise.
+       * iconvdata/gbgbk.c: Likewise.
+       * iconvdata/gbk.c: Likewise.
+       * iconvdata/iso-2022-cn.c: Likewise.
+       * iconvdata/iso-2022-jp.c: Likewise.
+       * iconvdata/iso-2022-kr.c: Likewise.
+       * iconvdata/iso646.c: Likewise.
+       * iconvdata/iso8859-1.c: Likewise.
+       * iconvdata/iso_6937-2.c: Likewise.
+       * iconvdata/iso_6937.c: Likewise.
+       * iconvdata/johab.c: Likewise.
+       * iconvdata/sjis.c: Likewise.
+       * iconvdata/t.61.c: Likewise.
+       * iconvdata/uhc.c: Likewise.
+       * iconvdata/unicode.c: Likewise.
+       * iconvdata/utf-16.c: Likewise.
+       * libio/iofwide.c: Reset __trans member of __gconv_trans_data
+       structure correctly after last change.
+       * wcsmbs/btowc.c: Likewise.
+       * wcsmbs/mbrtowc.c: Likewise.
+       * wcsmbs/mbsnrtowcs.c: Likewise.
+       * wcsmbs/mbsrtowcs.c: Likewise.
+       * wcsmbs/wcrtomb.c: Likewise.
+       * wcsmbs/wcsnrtombs.c: Likewise.
+       * wcsmbs/wcsrtombs.c: Likewise.
+       * wcsmbs/wctob.c: Likewise.
+
+       * localedata/Makefile: Set -Wno-format for some files since gcc does
+       not know all the format specifiers.
+
+2000-06-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * locale/loadlocale.c (_nl_unload_locale): Remove a bit of
+       unneeded code.
+       * locale/lc-time.c (_nl_init_era_entries): Likewise.
+
 2000-06-18  Andreas Jaeger  <aj@suse.de>
 
        * sysdeps/mips/dl-machine.h: Always use $25 as jump register.
index 0164b62..50458e2 100644 (file)
@@ -76,21 +76,22 @@ typedef void (*__gconv_end_fct) (struct __gconv_step *);
 
 
 /* Type of a transliteration/transscription function.  */
-typedef int (*__gconv_trans_fct) (struct __gconv_step *step,
-                                 struct __gconv_step_data *step_data,
+typedef int (*__gconv_trans_fct) (struct __gconv_step *,
+                                 struct __gconv_step_data *, void *,
                                  __const unsigned char *,
                                  __const unsigned char **,
                                  __const unsigned char *, unsigned char **,
                                  size_t *);
 
 /* Function to call to provide transliteration module with context.  */
-typedef int (*__gconv_trans_context_fct) (struct __gconv_trans_data *data,
+typedef int (*__gconv_trans_context_fct) (struct __gconv_trans_data *,
                                          __const unsigned char *,
                                          __const unsigned char *,
                                          unsigned char *, unsigned char *);
 
 /* Function to query module about supported encoded character sets.  */
-typedef int (*__gconv_trans_query_fct) (__const char **, size_t *);
+typedef int (*__gconv_trans_query_fct) (__const char *, __const char ***,
+                                       size_t *);
 
 /* Constructor and destructor for local data for transliteration.  */
 typedef int (*__gconv_trans_init_fct) (void **, const char *);
@@ -103,6 +104,7 @@ struct __gconv_trans_data
   __gconv_trans_context_fct __trans_context_fct;
   __gconv_trans_end_fct __trans_end_fct;
   void *__data;
+  struct __gconv_trans_data *__next;
 };
 
 
@@ -158,7 +160,7 @@ struct __gconv_step_data
                           any module; always use STATEP!  */
 
   /* Transliteration information.  */
-  struct __gconv_trans_data __trans;
+  struct __gconv_trans_data *__trans;
 };
 
 
index 79dcb0b..002e2c4 100644 (file)
@@ -38,6 +38,20 @@ __gconv_close (__gconv_t cd)
   drunp = cd->__data;
   do
     {
+      struct __gconv_trans_data *transp;
+
+      transp = drunp->__trans;
+      while (transp != NULL)
+       {
+         struct __gconv_trans_data *curp = transp;
+         transp = transp->__next;
+
+         if (__builtin_expect (curp->__trans_end_fct != NULL, 0))
+           curp->__trans_end_fct (curp->__data);
+
+         free (curp);
+       }
+
       if (!(drunp->__flags & __GCONV_IS_LAST) && drunp->__outbuf != NULL)
        free (drunp->__outbuf);
     }
index 0d25c22..480b459 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle configuration data.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -18,6 +18,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 /* This is the default path where we look for module lists.  */
 static const char default_gconv_path[] = GCONV_PATH;
 
+/* The path element in use.   */
+const struct path_elem *__gconv_path_elem;
+/* Maximum length of a single path element.  */
+size_t __gconv_max_path_elem_len;
+
+/* We use the following struct if we couldn't allocate memory.  */
+static const struct path_elem empty_path_elem;
+
 /* Name of the file containing the module information in the directories
    along the path.  */
 static const char gconv_conf_filename[] = "gconv-modules";
@@ -497,48 +506,125 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
        /* Otherwise ignore the line.  */
     }
 
-  if (line != NULL)
-    free (line);
+  free (line);
+
   fclose (fp);
 }
 
 
+/* Determine the directories we are looking for data in.  */
+void
+__gconv_get_path (void)
+{
+  struct path_elem *result;
+  __libc_lock_define_initialized (static, lock);
+
+  __libc_lock_lock (lock);
+
+  /* Make sure there wasn't a second thread doing it already.  */
+  result = (struct path_elem *) __gconv_path_elem;
+  if (result == NULL)
+    {
+      /* Determine the complete path first.  */
+      const char *user_path;
+      char *gconv_path;
+      size_t gconv_path_len;
+      char *elem;
+      char *oldp;
+      char *cp;
+      int nelems;
+
+      user_path = __secure_getenv ("GCONV_PATH");
+      if (user_path == NULL)
+       {
+         /* No user-defined path.  Make a modifiable copy of the
+            default path.  */
+         gconv_path = strdupa (default_gconv_path);
+         gconv_path_len = sizeof (default_gconv_path);
+       }
+      else
+       {
+         /* Append the default path to the user-defined path.  */
+         size_t user_len = strlen (user_path);
+
+         gconv_path_len = user_len + 1 + sizeof (default_gconv_path);
+         gconv_path = alloca (gconv_path_len);
+         __mempcpy (__mempcpy (__mempcpy (gconv_path, user_path, user_len),
+                               ":", 1),
+                    default_gconv_path, sizeof (default_gconv_path));
+       }
+
+      /* In a first pass we calculate the number of elements.  */
+      oldp = NULL;
+      cp = strchr (gconv_path, ':');
+      nelems = 1;
+      while (cp != NULL)
+       {
+         if (cp != oldp + 1)
+           ++nelems;
+         oldp = cp;
+         cp =  strchr (cp + 1, ':');
+       }
+
+      /* Allocate the memory for the result.  */
+      result = (struct path_elem *) malloc ((nelems + 1)
+                                           * sizeof (struct path_elem)
+                                           + gconv_path_len + nelems);
+      if (result != NULL)
+       {
+         char *strspace = (char *) &result[nelems + 1];
+         int n = 0;
+
+         /* Separate the individual parts.  */
+         __gconv_max_path_elem_len = 0;
+         elem = __strtok_r (gconv_path, ":", &gconv_path);
+         assert (elem != NULL);
+         do
+           {
+             result[n].name = strspace;
+             strspace = __stpcpy (strspace, elem);
+             if (strspace[-1] != '/')
+               *strspace++ = '/';
+
+             result[n].len = strspace - result[n].name;
+             if (result[n].len > __gconv_max_path_elem_len)
+               __gconv_max_path_elem_len = result[n].len;
+
+             *strspace++ = '\0';
+             ++n;
+           }
+         while ((elem = __strtok_r (NULL, ":", &gconv_path)) != NULL);
+
+         result[n].name = NULL;
+         result[n].len = 0;
+       }
+
+      __gconv_path_elem = result ?: &empty_path_elem;
+    }
+
+  __libc_lock_unlock (lock);
+}
+
+
 /* Read all configuration files found in the user-specified and the default
    path.  */
 void
 __gconv_read_conf (void)
 {
-  const char *user_path = __secure_getenv ("GCONV_PATH");
-  char *gconv_path, *elem;
   void *modules = NULL;
   size_t nmodules = 0;
   int save_errno = errno;
   size_t cnt;
 
-  if (user_path == NULL)
-    /* No user-defined path.  Make a modifiable copy of the default path.  */
-    gconv_path = strdupa (default_gconv_path);
-  else
-    {
-      /* Append the default path to the user-defined path.  */
-      size_t user_len = strlen (user_path);
-
-      gconv_path = alloca (user_len + 1 + sizeof (default_gconv_path));
-      __mempcpy (__mempcpy (__mempcpy (gconv_path, user_path, user_len),
-                           ":", 1),
-                default_gconv_path, sizeof (default_gconv_path));
-    }
+  /* Find out where we have to look.  */
+  if (__gconv_path_elem == NULL)
+    __gconv_get_path ();
 
-  elem = __strtok_r (gconv_path, ":", &gconv_path);
-  while (elem != NULL)
+  for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
     {
-#ifndef MAXPATHLEN
-      /* We define a reasonable limit.  */
-# define MAXPATHLEN 4096
-#endif
-      char real_elem[MAXPATHLEN];
+      char real_elem[__gconv_max_path_elem_len + sizeof (gconv_conf_filename)];
 
-      if (__realpath (elem, real_elem) != NULL)
+      if (__realpath (__gconv_path_elem[cnt].name, real_elem) != NULL)
        {
          size_t elem_len = strlen (real_elem);
          char *filename;
@@ -551,9 +637,6 @@ __gconv_read_conf (void)
          /* Read the next configuration file.  */
          read_conf_file (filename, real_elem, elem_len, &modules, &nmodules);
        }
-
-      /* Get next element in the path.  */
-      elem = __strtok_r (NULL, ":", &gconv_path);
     }
 
   /* Add the internal modules.  */
@@ -586,3 +669,15 @@ __gconv_read_conf (void)
   /* Restore the error number.  */
   __set_errno (save_errno);
 }
+
+
+
+/* Free all resources if necessary.  */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  if (__gconv_path_elem != NULL && __gconv_path_elem != &empty_path_elem)
+    free ((void *) __gconv_path_elem);
+}
+
+text_set_element (__libc_subfreeres, free_mem);
index 5bdf714..6d19971 100644 (file)
 __BEGIN_DECLS
 
 
+/* Type to represent search path.  */
+struct path_elem
+{
+  const char *name;
+  size_t len;
+};
+
+/* Variable with search path for `gconv' implementation.  */
+extern const struct path_elem *__gconv_path_elem;
+/* Maximum length of a single path element.  */
+extern size_t __gconv_max_path_elem_len;
+
+
 /* Structure for alias definition.  Simply to strings.  */
 struct gconv_alias
 {
@@ -83,6 +96,21 @@ struct gconv_module
 };
 
 
+/* Internal data structure to represent transliteration module.  */
+struct trans_struct
+{
+  const char *name;
+  struct trans_struct *next;
+
+  const char **csnames;
+  size_t ncsnames;
+  __gconv_trans_fct trans_fct;
+  __gconv_trans_context_fct trans_context_fct;
+  __gconv_trans_init_fct trans_init_fct;
+  __gconv_trans_end_fct trans_end_fct;
+};
+
+
 /* Flags for `gconv_open'.  */
 enum
 {
@@ -161,6 +189,9 @@ extern int __gconv_find_transform (const char *toset, const char *fromset,
 /* Read all the configuration data and cache it.  */
 extern void __gconv_read_conf (void);
 
+/* Determine the directories we are looking in.  */
+extern void __gconv_get_path (void);
+
 /* Comparison function to search alias.  */
 extern int __gconv_alias_compare (const void *p1, const void *p2);
 
@@ -185,9 +216,14 @@ extern void __gconv_get_builtin_trans (const char *name,
                                       struct __gconv_step *step)
      internal_function;
 
+/* Try to load transliteration step module.  */
+extern int __gconv_translit_find (struct trans_struct *trans)
+     internal_function;
+
 /* Transliteration using the locale's data.  */
 extern int __gconv_transliterate (struct __gconv_step *step,
                                  struct __gconv_step_data *step_data,
+                                 void *trans_data,
                                  __const unsigned char *inbufstart,
                                  __const unsigned char **inbufp,
                                  __const unsigned char *inbufend,
index d2963fa..2374703 100644 (file)
@@ -38,6 +38,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
   int conv_flags = 0;
   const char *errhand;
   const char *ignore;
+  struct trans_struct *trans = NULL;
 
   /* Find out whether any error handling method is specified.  */
   errhand = strchr (toset, '/');
@@ -51,17 +52,85 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
        {
          /* Make copy without the error handling description.  */
          char *newtoset = (char *) alloca (errhand - toset + 1);
+         char *tok;
+         char *ptr;
 
          newtoset[errhand - toset] = '\0';
          toset = memcpy (newtoset, toset, errhand - toset);
 
-         flags = __GCONV_IGNORE_ERRORS;
+         /* Find the appropriate transliteration handlers.  */
+         tok = strdupa (errhand);
 
-         if (__strcasecmp (errhand, "IGNORE") == 0)
+         tok = __strtok_r (tok, ",", &ptr);
+         while (tok != NULL)
            {
-             /* Found it.  This means we should ignore conversion errors.  */
-             flags = __GCONV_IGNORE_ERRORS;
-             errhand = NULL;
+             if (__strcasecmp (tok, "TRANSLIT") == 0)
+               {
+                 /* It's the builtin transliteration handling.  We only
+                    support it for working on the internal encoding.  */
+                 static const char *internal_trans_names[1] = { "INTERNAL" };
+                 struct trans_struct *lastp = NULL;
+                 struct trans_struct *runp;
+
+                 for (runp = trans; runp != NULL; runp = runp->next)
+                   if (runp->trans_fct == __gconv_transliterate)
+                     break;
+                   else
+                     lastp = runp;
+
+                 if (runp == NULL)
+                   {
+                     struct trans_struct *newp;
+
+                     newp = (struct trans_struct *) alloca (sizeof (*newp));
+                     memset (newp, '\0', sizeof (*newp));
+
+                     /* We leave the `name' field zero to signal that
+                        this is an internal transliteration step.  */
+                     newp->csnames = internal_trans_names;
+                     newp->ncsnames = 1;
+                     newp->trans_fct = __gconv_transliterate;
+
+                     if (lastp == NULL)
+                       trans = newp;
+                     else
+                       lastp->next = newp;
+                   }
+               }
+             else if (__strcasecmp (tok, "IGNORE") == 0)
+               /* Set the flag to ignore all errors.  */
+               flags = __GCONV_IGNORE_ERRORS;
+             else
+               {
+                 /* `tok' is possibly a module name.  We'll see later
+                    whether we can find it.  But first see that we do
+                    not already a module of this name.  */
+                 struct trans_struct *lastp = NULL;
+                 struct trans_struct *runp;
+
+                 for (runp = trans; runp != NULL; runp = runp->next)
+                   if (runp->name != NULL
+                       && __strcasecmp (tok, runp->name) == 0)
+                     break;
+                   else
+                     lastp = runp;
+
+                 if (runp == NULL)
+                   {
+                     struct trans_struct *newp;
+
+                     newp = (struct trans_struct *) alloca (sizeof (*newp));
+                     memset (newp, '\0', sizeof (*newp));
+                     newp->name = tok;
+
+                     if (lastp == NULL)
+                       trans = newp;
+                     else
+                       lastp->next = newp;
+                   }
+               }
+
+             tok = __strtok_r (NULL, ",", &ptr);
            }
        }
     }
@@ -81,31 +150,18 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
   res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
   if (res == __GCONV_OK)
     {
-      const char **csnames = NULL;
-      size_t ncsnames = 0;
-      __gconv_trans_fct trans_fct = NULL;
-      __gconv_trans_context_fct trans_context_fct = NULL;
-      __gconv_trans_init_fct trans_init_fct = NULL;
-      __gconv_trans_end_fct trans_end_fct = NULL;
-
-      if (errhand != NULL)
+      /* Find the modules.  */
+      struct trans_struct *lastp = NULL;
+      struct trans_struct *runp;
+
+      for (runp = trans; runp != NULL; runp = runp->next)
        {
-         /* Find the appropriate transliteration handling.  */
-         if (__strcasecmp (errhand, "TRANSLIT") == 0)
-           {
-             /* It's the builtin transliteration handling.  We only
-                 suport for it working on the internal encoding.  */
-             static const char *internal_trans_names[1] = { "INTERNAL" };
-
-             csnames = internal_trans_names;
-             ncsnames = 1;
-             trans_fct = __gconv_transliterate;
-             /* No context, init, or end function.  */
-           }
-         else if (__strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0)
-           {
-             trans_init_fct = (__gconv_trans_init_fct) 1;
-           }
+         if (runp->name == NULL
+             || __builtin_expect (__gconv_translit_find (runp), 0) == 0)
+           lastp = runp;
+         else
+           /* This means we haven't found the module.  Remove it.  */
+           (lastp == NULL ? trans : lastp->next) = runp->next;
        }
 
       /* Allocate room for handle.  */
@@ -154,32 +210,51 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 
              result->__data[cnt].__outbuf = (char *) malloc (size);
              if (result->__data[cnt].__outbuf == NULL)
-               {
-                 res = __GCONV_NOMEM;
-                 break;
-               }
+               goto bail;
+
              result->__data[cnt].__outbufend =
                result->__data[cnt].__outbuf + size;
 
-             /* Now see whether we can use the transliteration module
-                for this step.  */
-             for (n = 0; n < ncsnames; ++n)
-               if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
-                 {
-                   /* Match!  Now try the initializer.  */
-                   if (trans_init_fct == NULL
-                       || (trans_init_fct (&result->__data[cnt].__trans.__data,
-                                           steps[cnt].__to_name)
-                           == __GCONV_OK))
-                     {
-                       result->__data[cnt].__trans.__trans_fct = trans_fct;
-                       result->__data[cnt].__trans.__trans_context_fct =
-                         trans_context_fct;
-                       result->__data[cnt].__trans.__trans_end_fct =
-                         trans_end_fct;
-                     }
-                   break;
-                 }
+             /* Now see whether we can use any of the transliteration
+                modules for this step.  */
+             for (runp = trans; runp != NULL; runp = runp->next)
+               for (n = 0; n < runp->ncsnames; ++n)
+                 if (__strcasecmp (steps[cnt].__from_name,
+                                   runp->csnames[n]) == 0)
+                   {
+                     void *data = NULL;
+
+                     /* Match!  Now try the initializer.  */
+                     if (runp->trans_init_fct == NULL
+                         || (runp->trans_init_fct (data, steps[cnt].__to_name)
+                             == __GCONV_OK))
+                       {
+                         /* Append at the end of the list.  */
+                         struct __gconv_trans_data *newp;
+                         struct __gconv_trans_data *endp;
+                         struct __gconv_trans_data *lastp;
+
+                         newp = (struct __gconv_trans_data *)
+                           malloc (sizeof (struct __gconv_trans_data));
+                         if (newp == NULL)
+                           goto bail;
+
+                         newp->__trans_fct = runp->trans_fct;
+                         newp->__trans_context_fct = runp->trans_context_fct;
+                         newp->__trans_end_fct = runp->trans_end_fct;
+
+                         lastp = NULL;
+                         for (endp = result->__data[cnt].__trans;
+                              endp != NULL; endp = endp->__next)
+                           lastp = endp;
+
+                         if (lastp == NULL)
+                           result->__data[cnt].__trans = newp;
+                         else
+                           lastp->__next = newp;
+                       }
+                     break;
+                   }
            }
 
          /* Now handle the last entry.  */
@@ -194,34 +269,72 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 
          /* Now see whether we can use the transliteration module
             for this step.  */
-         for (n = 0; n < ncsnames; ++n)
-           if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
-             {
-               /* Match!  Now try the initializer.  */
-               if (trans_init_fct == NULL
-                   || trans_init_fct (&result->__data[cnt].__trans.__data,
-                                      steps[cnt].__to_name)
-                   == __GCONV_OK)
-                 {
-                   result->__data[cnt].__trans.__trans_fct = trans_fct;
-                   result->__data[cnt].__trans.__trans_context_fct =
-                     trans_context_fct;
-                   result->__data[cnt].__trans.__trans_end_fct =
-                     trans_end_fct;
-                 }
-               break;
-             }
+         for (runp = trans; runp != NULL; runp = runp->next)
+           for (n = 0; n < runp->ncsnames; ++n)
+             if (__strcasecmp (steps[cnt].__from_name, runp->csnames[n]) == 0)
+               {
+                 void *data = NULL;
+
+                 /* Match!  Now try the initializer.  */
+                 if (runp->trans_init_fct == NULL
+                     || (runp->trans_init_fct (data, steps[cnt].__to_name)
+                         == __GCONV_OK))
+                   {
+                     /* Append at the end of the list.  */
+                     struct __gconv_trans_data *newp;
+                     struct __gconv_trans_data *endp;
+                     struct __gconv_trans_data *lastp;
+
+                     newp = (struct __gconv_trans_data *)
+                       malloc (sizeof (struct __gconv_trans_data));
+                     if (newp == NULL)
+                       goto bail;
+
+                     newp->__trans_fct = runp->trans_fct;
+                     newp->__trans_context_fct = runp->trans_context_fct;
+                     newp->__trans_end_fct = runp->trans_end_fct;
+
+                     lastp = NULL;
+                     for (endp = result->__data[cnt].__trans;
+                          endp != NULL; endp = endp->__next)
+                       lastp = endp;
+
+                     if (lastp == NULL)
+                       result->__data[cnt].__trans = newp;
+                     else
+                       lastp->__next = newp;
+                   }
+                 break;
+               }
        }
 
       if (res != __GCONV_OK)
        {
          /* Something went wrong.  Free all the resources.  */
-         int serrno = errno;
+         int serrno;
+       bail:
+         serrno = errno;
 
          if (result != NULL)
            {
              while (cnt-- > 0)
-               free (result->__data[cnt].__outbuf);
+               {
+                 struct __gconv_trans_data *transp;
+
+                 transp = result->__data[cnt].__trans;
+                 while (transp != NULL)
+                   {
+                     struct __gconv_trans_data *curp = transp;
+                     transp = transp->__next;
+
+                     if (__builtin_expect (curp->__trans_end_fct != NULL, 0))
+                       curp->__trans_end_fct (curp->__data);
+
+                     free (curp);
+                   }
+
+                 free (result->__data[cnt].__outbuf);
+               }
 
              free (result);
              result = NULL;
index 3905745..019aac2 100644 (file)
@@ -797,25 +797,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
     /* XXX unaligned.  */                                                    \
     if (__builtin_expect (*((uint32_t *) inptr), 0) > 0x7f)                  \
       {                                                                              \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           /* This is no correct ANSI_X3.4-1968 character.  */               \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       /* It's an one byte sequence.  */                                              \
@@ -1186,24 +1168,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
   {                                                                          \
     if (__builtin_expect (*((uint32_t *) inptr), 0) >= 0x10000)                      \
       {                                                                              \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++;                    \
@@ -1253,25 +1218,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
     uint32_t val = *((uint32_t *) inptr);                                    \
     if (__builtin_expect (val, 0) >= 0x10000)                                \
       {                                                                              \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     *((uint16_t *) outptr)++ = bswap_16 (val);                               \
     inptr += 4;                                                                      \
index 269917b..4d6e776 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
 #include <dlfcn.h>
+#include <search.h>
 #include <stdint.h>
+#include <string.h>
 
+#include <bits/libc-lock.h>
 #include "gconv_int.h"
 #include "../locale/localeinfo.h"
 
@@ -28,6 +32,7 @@
 int
 __gconv_transliterate (struct __gconv_step *step,
                       struct __gconv_step_data *step_data,
+                      void *trans_data __attribute__ ((unused)),
                       const unsigned char *inbufstart,
                       const unsigned char **inbufp,
                       const unsigned char *inbufend,
@@ -218,3 +223,178 @@ __gconv_transliterate (struct __gconv_step *step,
   /* Haven't found a match.  */
   return __GCONV_ILLEGAL_INPUT;
 }
+
+
+/* Structure to represent results of found (or not) transliteration
+   modules.  */
+struct known_trans
+{
+  /* This structure must remain the first member.  */
+  struct trans_struct info;
+
+  const char *fname;
+  void *handle;
+  int open_count;
+};
+
+
+/* Tree with results of previous calls to __gconv_translit_find.  */
+static void *search_tree;
+
+/* We modify global data.   */
+__libc_lock_define_initialized (static, lock);
+
+
+/* Compare two transliteration entries.  */
+static int
+trans_compare (const void *p1, const void *p2)
+{
+  struct known_trans *s1 = (struct known_trans *) p1;
+  struct known_trans *s2 = (struct known_trans *) p2;
+
+  return strcmp (s1->info.name, s2->info.name);
+}
+
+
+/* Open (maybe reopen) the module named in the struct.  Get the function
+   and data structure pointers we need.  */
+static int
+open_translit (struct known_trans *trans)
+{
+  __gconv_trans_query_fct queryfct;
+
+  trans->handle = __libc_dlopen (trans->fname);
+  if (trans->handle == NULL)
+    /* Not available.  */
+    return 1;
+
+  /* Find the required symbol.  */
+  queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");
+  if (queryfct == NULL)
+    {
+      /* We cannot live with that.  */
+    close_and_out:
+      __libc_dlclose (trans->handle);
+      trans->handle = NULL;
+      return 1;
+    }
+
+  /* Get the context.  */
+  if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)
+      != 0)
+    goto close_and_out;
+
+  /* Of course we also have to have the actual function.  */
+  trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");
+  if (trans->info.trans_fct == NULL)
+    goto close_and_out;
+
+  /* Now the optional functions.  */
+  trans->info.trans_init_fct =
+    __libc_dlsym (trans->handle, "gconv_trans_init");
+  trans->info.trans_context_fct =
+    __libc_dlsym (trans->handle, "gconv_trans_context");
+  trans->info.trans_end_fct =
+    __libc_dlsym (trans->handle, "gconv_trans_end");
+
+  trans->open_count = 1;
+
+  return 0;
+}
+
+
+int
+internal_function
+__gconv_translit_find (struct trans_struct *trans)
+{
+  struct known_trans **found;
+  const struct path_elem *runp;
+  int res = 1;
+
+  /* We have to have a name.  */
+  assert (trans->name != NULL);
+
+  /* Acquire the lock.  */
+  __libc_lock_lock (lock);
+
+  /* See whether we know this module already.  */
+  found = __tfind (trans, &search_tree, trans_compare);
+  if (found != NULL)
+    {
+      /* Is this module available?  */
+      if ((*found)->handle != NULL)
+       {
+         /* Maybe we have to reopen the file.  */
+         if ((*found)->handle != (void *) -1)
+           /* The object is not unloaded.  */
+           res = 0;
+         else if (open_translit (*found) == 0)
+           {
+             /* Copy the data.  */
+             *trans = (*found)->info;
+             res = 0;
+           }
+       }
+    }
+  else
+    {
+      size_t name_len = strlen (trans->name) + 1;
+      int need_so = 0;
+      struct known_trans *newp;
+
+      /* We have to continue looking for the module.  */
+      if (__gconv_path_elem == NULL)
+       __gconv_get_path ();
+
+      /* See whether we have to append .so.  */
+      if (name_len <= 3 || memcmp (&trans->name[name_len - 3], ".so", 3) != 0)
+       need_so = 1;
+
+      /* Create a new entry.  */
+      newp = (struct known_trans *) malloc (sizeof (struct known_trans)
+                                           + (__gconv_max_path_elem_len
+                                              + name_len + 3)
+                                           + name_len);
+      if (newp != NULL)
+       {
+         char *cp;
+
+         /* Clear the struct.  */
+         memset (newp, '\0', sizeof (struct known_trans));
+
+         /* Store a copy of the module name.  */
+         newp->info.name = (char *) (newp + 1);
+         cp = __mempcpy ((char *) newp->info.name, trans->name, name_len);
+
+         newp->fname = cp;
+
+         /* Seach in all the directories.  */
+         for (runp = __gconv_path_elem; runp->name != NULL; ++runp)
+           {
+             cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name),
+                             trans->name, name_len);
+             if (need_so)
+               memcpy (cp, ".so", sizeof (".so"));
+
+             if (open_translit (newp) == 0)
+               {
+                 /* We found a module.  */
+                 res = 0;
+                 break;
+               }
+           }
+
+         /* In any case we'll add the entry to our search tree.  */
+         if (__tsearch (newp, &search_tree, trans_compare) == NULL)
+           {
+             /* Yickes, this should not happen.  Unload the object.  */
+             res = 1;
+             /* XXX unload here.  */
+           }
+       }
+    }
+
+  __libc_lock_unlock (lock);
+
+  return res;
+}
index ebbc136..04ae50b 100644 (file)
 #define ignore_errors_p() (flags & __GCONV_IGNORE_ERRORS)
 
 
+/* Error handling with transliteration/transcription function use and
+   ignoring of errors.  Note that we cannot use the do while (0) trick
+   since `break' and `continue' must reach certain points.  */
+#define STANDARD_ERR_HANDLER(Incr) \
+  {                                                                          \
+    struct __gconv_trans_data *trans;                                        \
+                                                                             \
+    result = __GCONV_ILLEGAL_INPUT;                                          \
+    /* First try the transliteration methods.  */                            \
+    for (trans = step_data->__trans; trans != NULL; trans = trans->__next)    \
+      {                                                                              \
+       result = DL_CALL_FCT (trans->__trans_fct,                             \
+                             (step, step_data, trans->__data, *inptrp,       \
+                              &inptr, inend, &outptr, irreversible));        \
+       if (result != __GCONV_ILLEGAL_INPUT)                                  \
+         break;                                                              \
+      }                                                                              \
+    /* If any of them recognized the input stop.  */                         \
+    if (result != __GCONV_ILLEGAL_INPUT)                                     \
+      break;                                                                 \
+                                                                             \
+    /* Next see whether we have to ignore the error.  If not, stop.  */              \
+    if (! ignore_errors_p ())                                                \
+      break;                                                                 \
+                                                                             \
+    /* When we come here it means we ignore the character.  */               \
+    ++*irreversible;                                                         \
+    inptr += Incr;                                                           \
+    continue;                                                                \
+  }
+
+
 /* The function returns the status, as defined in gconv.h.  */
 static inline int
 FCTNAME (LOOPFCT) (struct __gconv_step *step,
index 8dbebb8..854cc70 100644 (file)
@@ -379,6 +379,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 
       do
        {
+         struct __gconv_trans_data *trans;
+
          /* Remember the start value for this round.  */
          inptr = *inptrp;
          /* The outbuf buffer is empty.  */
@@ -429,10 +431,10 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 
          /* Give the transliteration module the chance to store the
             original text and the result in case it needs a context.  */
-         if (data->__trans.__trans_context_fct != NULL)
-           DL_CALL_FCT (data->__trans.__trans_context_fct,
-                        (data->__trans.__data, inptr, *inptrp,
-                         outstart, outbuf));
+         for (trans = data->__trans; trans != NULL; trans = trans->__next)
+           if (trans->__trans_context_fct != NULL)
+             DL_CALL_FCT (trans->__trans_context_fct,
+                          (trans->__data, inptr, *inptrp, outstart, outbuf));
 
          /* We finished one use of the loops.  */
          ++data->__invocation_counter;
index a4a32d3..7caa542 100644 (file)
@@ -83,75 +83,17 @@ struct gap
     unsigned char res;                                                       \
                                                                              \
     if (__builtin_expect (ch, 0) >= 0xffff)                                  \
+      rp = NULL;                                                             \
+    else                                                                     \
+      while (ch > rp->end)                                                   \
+       ++rp;                                                                 \
+    if (__builtin_expect (rp == NULL, 0)                                     \
+       || __builtin_expect (ch < rp->start, 0)                               \
+       || (res = from_ucs4[ch + rp->idx],                                    \
+           __builtin_expect (res, '\1') == '\0' && ch != 0))                 \
       {                                                                              \
        /* This is an illegal character.  */                                  \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
-       ++*irreversible;                                                      \
-       inptr += 4;                                                           \
-       continue;                                                             \
-      }                                                                              \
-    while (ch > rp->end)                                                     \
-      ++rp;                                                                  \
-    if (__builtin_expect (ch < rp->start, 0))                                \
-      {                                                                              \
-       /* This is an illegal character.  */                                  \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
-      }                                                                              \
-                                                                             \
-    res = from_ucs4[ch + rp->idx];                                           \
-    if (__builtin_expect (res, '\1') == '\0' && ch != 0)                     \
-      {                                                                              \
-       /* This is an illegal character.  */                                  \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
                                                                              \
     *outptr++ = res;                                                         \
index 02d972e..bc05ccd 100644 (file)
        || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0))       \
       {                                                                              \
        /* This is an illegal character.  */                                  \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-      }                                                                              \
-    else                                                                     \
-      {                                                                              \
-       *outptr++ = from_ucs4[ch];                                            \
-       inptr += 4;                                                           \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
+                                                                             \
+    *outptr++ = from_ucs4[ch];                                               \
+    inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
 #include <iconv/loop.c>
index 6ec09c3..d55af6f 100644 (file)
@@ -497,25 +497,7 @@ static const char from_ucs4[][2] =
            if (tmp[0] == '\0')                                               \
              {                                                               \
                /* Illegal characters.  */                                    \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   ++*irreversible;                                          \
-                   inptr += 4;                                               \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
            tmp[1] = '\0';                                                    \
            cp = tmp;                                                         \
@@ -555,25 +537,7 @@ static const char from_ucs4[][2] =
        else                                                                  \
          {                                                                   \
            /* Illegal characters.  */                                        \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               ++*irreversible;                                              \
-               inptr += 4;                                                   \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
       }                                                                              \
     else                                                                     \
@@ -583,25 +547,7 @@ static const char from_ucs4[][2] =
        if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                \
          {                                                                   \
            /* Illegal characters.  */                                        \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               ++*irreversible;                                              \
-               inptr += 4;                                                   \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
       }                                                                              \
                                                                              \
index 947a92a..1ba1b3f 100644 (file)
@@ -8585,25 +8585,7 @@ static const char from_ucs4_tab13[][2] =
     if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                   \
       {                                                                              \
        /* Illegal character.  */                                             \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       {                                                                              \
index 64923d4..bf38e15 100644 (file)
@@ -12742,25 +12742,7 @@ static const char from_ucs4_tab14[][2] =
     if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                   \
       {                                                                              \
        /* Illegal character.  */                                             \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       {                                                                              \
index 18e73fd..58f47ed 100644 (file)
            if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR)          \
              {                                                               \
                /* Illegal character.  */                                     \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   inptr += 4;                                               \
-                   ++*irreversible;                                          \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            /* It's a GB 2312 character, adjust it for EUC-CN.  */            \
index 3e21d55..fc0794d 100644 (file)
                else                                                          \
                  {                                                           \
                    /* Illegal character.  */                                 \
-                   if (step_data->__trans.__trans_fct != NULL)               \
-                     {                                                       \
-                       result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
-                                             (step, step_data, *inptrp,      \
-                                              &inptr, inend, &outptr,        \
-                                              irreversible));                \
-                       if (result != __GCONV_OK)                             \
-                         break;                                              \
-                     }                                                       \
-                   else if (! ignore_errors_p ())                            \
-                     {                                                       \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                   else                                                      \
-                     {                                                       \
-                       inptr += 4;                                           \
-                       ++*irreversible;                                      \
-                     }                                                       \
-                   continue;                                                 \
+                   STANDARD_ERR_HANDLER (4);                                 \
                  }                                                           \
              }                                                               \
          }                                                                   \
index c32b9b3..abb40c8 100644 (file)
@@ -146,25 +146,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
     if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                   \
       {                                                                              \
        /* Illegal character.  */                                             \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
                                                                              \
     *outptr++ = cp[0];                                                       \
index b4cf21b..ed7a197 100644 (file)
            if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR)          \
              {                                                               \
                /* Illegal character.  */                                     \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   inptr += 4;                                               \
-                   ++*irreversible;                                          \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            /* It's a CNS 11643 character, adjust it for EUC-TW.  */          \
index 0afcd72..02e25f3 100644 (file)
                && __builtin_expect (ch, 0xa1a1) <= 0xa8c0))                  \
          {                                                                   \
            /* One of the characters we cannot map.  */                       \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 2;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           /* Copy the two bytes.  */                                        \
-           *outptr++ = *inptr++;                                             \
-           *outptr++ = *inptr++;                                             \
+           STANDARD_ERR_HANDLER (2);                                         \
          }                                                                   \
+                                                                             \
+       /* Copy the two bytes.  */                                            \
+       *outptr++ = *inptr++;                                                 \
+       *outptr++ = *inptr++;                                                 \
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
index 4505b65..c3010f3 100644 (file)
@@ -13452,25 +13452,7 @@ static const char __gbk_from_ucs4_tab12[][2] =
       if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                 \
        {                                                                     \
          /* Illegal character.  */                                           \
-         if (step_data->__trans.__trans_fct != NULL)                         \
-           {                                                                 \
-             result = DL_CALL_FCT (step_data->__trans.__trans_fct,           \
-                                   (step, step_data, *inptrp, &inptr, inend, \
-                                    &outptr, irreversible));                 \
-             if (result != __GCONV_OK)                                       \
-               break;                                                        \
-           }                                                                 \
-         else if (! ignore_errors_p ())                                      \
-           {                                                                 \
-             result = __GCONV_ILLEGAL_INPUT;                                 \
-             break;                                                          \
-           }                                                                 \
-         else                                                                \
-           {                                                                 \
-             inptr += 4;                                                     \
-             ++*irreversible;                                                \
-           }                                                                 \
-         continue;                                                           \
+         STANDARD_ERR_HANDLER (4);                                           \
        }                                                                     \
       /* See whether there is enough room for the second byte we write.  */   \
       else if (cp[1] != '\0' && __builtin_expect (outptr + 1 >= outend, 0))   \
index f217069..6ffa18d 100644 (file)
@@ -324,26 +324,7 @@ enum
                else                                                          \
                  {                                                           \
                    /* Even this does not work.  Error.  */                   \
-                   if (step_data->__trans.__trans_fct != NULL)               \
-                     {                                                       \
-                       result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
-                                             (step, step_data, *inptrp,      \
-                                              &inptr, inend, &outptr,        \
-                                              irreversible));                \
-                       if (result != __GCONV_OK)                             \
-                         break;                                              \
-                     }                                                       \
-                   else if (! ignore_errors_p ())                            \
-                     {                                                       \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                   else                                                      \
-                     {                                                       \
-                       inptr += 4;                                           \
-                       ++*irreversible;                                      \
-                     }                                                       \
-                   continue;                                                 \
+                   STANDARD_ERR_HANDLER (4);                                 \
                  }                                                           \
              }                                                               \
          }                                                                   \
index ab42bcc..ecfdae4 100644 (file)
@@ -703,26 +703,7 @@ gconv_end (struct __gconv_step *data)
                else if (__builtin_expect (var, iso2022jp2) == iso2022jp)     \
                  {                                                           \
                    /* We have no other choice.  */                           \
-                   if (step_data->__trans.__trans_fct != NULL)               \
-                     {                                                       \
-                       result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
-                                             (step, step_data, *inptrp,      \
-                                              &inptr, inend, &outptr,        \
-                                              irreversible));                \
-                       if (result != __GCONV_OK)                             \
-                         break;                                              \
-                     }                                                       \
-                   else if (! ignore_errors_p ())                            \
-                     {                                                       \
-                       result = __GCONV_ILLEGAL_INPUT;                       \
-                       break;                                                \
-                     }                                                       \
-                   else                                                      \
-                     {                                                       \
-                       inptr += 4;                                           \
-                       ++*irreversible;                                      \
-                     }                                                       \
-                   continue;                                                 \
+                   STANDARD_ERR_HANDLER (4);                                 \
                  }                                                           \
                else                                                          \
                  {                                                           \
@@ -888,28 +869,7 @@ gconv_end (struct __gconv_step *data)
                                      }                                       \
                                    else                                      \
                                      {                                       \
-                                       if (step_data->__trans.__trans_fct    \
-                                           != NULL)                          \
-                                         {                                   \
-                                           result = DL_CALL_FCT              \
-                                             (step_data->__trans.__trans_fct,\
-                                              (step, step_data, *inptrp,     \
-                                               &inptr, inend, &outptr,       \
-                                               irreversible));               \
-                                           if (result != __GCONV_OK)         \
-                                             break;                          \
-                                         }                                   \
-                                       else if (! ignore_errors_p ())        \
-                                         {                                   \
-                                            result = __GCONV_ILLEGAL_INPUT;  \
-                                            break;                           \
-                                         }                                   \
-                                       else                                  \
-                                         {                                   \
-                                           ++*irreversible;                  \
-                                           inptr += 4;                       \
-                                         }                                   \
-                                       continue;                             \
+                                       STANDARD_ERR_HANDLER (4);             \
                                      }                                       \
                                  }                                           \
                              }                                               \
index 52031ca..56e17a2 100644 (file)
@@ -255,25 +255,7 @@ enum
        if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR)            \
          {                                                                   \
            /* Illegal character.  */                                         \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               ++*irreversible;                                              \
-               inptr += 4;                                                   \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
index 66f8958..99dc025 100644 (file)
@@ -885,29 +885,10 @@ gconv_end (struct __gconv_step *data)
                                                                              \
     if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT)      \
       {                                                                              \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           /* Exit the loop with an error.  */                               \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
-    else                                                                     \
-      *outptr++ = (unsigned char) ch;                                        \
+                                                                             \
+    *outptr++ = (unsigned char) ch;                                          \
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
index a613481..bedc425 100644 (file)
     if (__builtin_expect (ch, 0) > 0xff)                                     \
       {                                                                              \
        /* We have an illegal character.  */                                  \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       *outptr++ = (unsigned char) ch;                                        \
index cde2108..dda8acd 100644 (file)
@@ -565,50 +565,17 @@ static const char from_ucs4[][2] =
          default:                                                            \
            /* Illegal characters.  */                                        \
            cp = NULL;                                                        \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           break;                                                            \
+         }                                                                   \
+       if (cp == NULL)                                                       \
+         {                                                                   \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
       }                                                                              \
     else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0)    \
       {                                                                              \
        /* Illegal characters.  */                                            \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       cp = from_ucs4[ch];                                                    \
index e767291..d51f321 100644 (file)
@@ -542,50 +542,13 @@ static const char from_ucs4[][2] =
        if (__builtin_expect (fail, 0))                                       \
          {                                                                   \
            /* Illegal characters.  */                                        \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
       }                                                                              \
     else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0)    \
       {                                                                              \
        /* Illegal characters.  */                                            \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       cp = from_ucs4[ch];                                                    \
index d2947dc..46649c5 100644 (file)
@@ -396,26 +396,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
              }                                                               \
            if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR)        \
              {                                                               \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   inptr += 4;                                               \
-                   ++*irreversible;                                          \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            outptr[0] -= 0x4a;                                                \
@@ -441,26 +422,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
              }                                                               \
            if (__builtin_expect (written, 1) == __UNKNOWN_10646_CHAR)        \
              {                                                               \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   inptr += 4;                                               \
-                   ++*irreversible;                                          \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            outptr[0] -= 0x4a;                                                \
index aa51259..08dce1c 100644 (file)
@@ -4466,29 +4466,8 @@ static const char from_ucs4_extra[0x100][2] =
                 && __builtin_expect (ch, 0xff01) <= 0xffef)                  \
          cp = from_ucs4_extra[ch - 0xff00];                                  \
        else                                                                  \
-         {                                                                   \
-           /* Illegal character.  */                                         \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
-         }                                                                   \
+         /* Illegal character.  */                                           \
+         cp = "";                                                            \
       }                                                                              \
     else                                                                     \
       cp = from_ucs4_lat1[ch];                                               \
@@ -4496,26 +4475,7 @@ static const char from_ucs4_extra[0x100][2] =
     if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                   \
       {                                                                              \
        /* Illegal character.  */                                             \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           /* This is an illegal character.  */                              \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           inptr += 4;                                                       \
-           ++*irreversible;                                                  \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       {                                                                              \
index 3c1a69e..611eca8 100644 (file)
@@ -469,26 +469,7 @@ static const char from_ucs4[][2] =
                 || __builtin_expect (ch, 0x2d8) == 0x02dc)                   \
          {                                                                   \
            /* Illegal characters.  */                                        \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
@@ -506,26 +487,7 @@ static const char from_ucs4[][2] =
        if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                \
          {                                                                   \
            /* Illegal.  */                                                   \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
       }                                                                              \
                                                                              \
index 5526e9b..38ae65b 100644 (file)
@@ -3221,26 +3221,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
          }                                                                   \
        if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR)            \
          {                                                                   \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
                                                                              \
        *outptr++ |= 0x80;                                                    \
@@ -3261,26 +3242,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
          }                                                                   \
        if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR)            \
          {                                                                   \
-           if (step_data->__trans.__trans_fct != NULL)                       \
-             {                                                               \
-               result = DL_CALL_FCT (step_data->__trans.__trans_fct,         \
-                                     (step, step_data, *inptrp, &inptr,      \
-                                      inend, &outptr, irreversible));        \
-               if (result != __GCONV_OK)                                     \
-                 break;                                                      \
-             }                                                               \
-           else if (! ignore_errors_p ())                                    \
-             {                                                               \
-               /* This is an illegal character.  */                          \
-               result = __GCONV_ILLEGAL_INPUT;                               \
-               break;                                                        \
-             }                                                               \
-           else                                                              \
-             {                                                               \
-               inptr += 4;                                                   \
-               ++*irreversible;                                              \
-             }                                                               \
-           continue;                                                         \
+           STANDARD_ERR_HANDLER (4);                                         \
          }                                                                   \
                                                                              \
        *outptr++ |= 0x80;                                                    \
index 9caa95d..d927cdf 100644 (file)
@@ -152,26 +152,7 @@ gconv_end (struct __gconv_step *data)
                                                                              \
     if (__builtin_expect (c, 0) >= 0x10000)                                  \
       {                                                                              \
-       if (step_data->__trans.__trans_fct != NULL)                           \
-         {                                                                   \
-           result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
-                                 (step, step_data, *inptrp, &inptr, inend,   \
-                                  &outptr, irreversible));                   \
-           if (result != __GCONV_OK)                                         \
-             break;                                                          \
-         }                                                                   \
-       else if (! ignore_errors_p ())                                        \
-         {                                                                   \
-           /* This is an illegal character.  */                              \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
-           break;                                                            \
-         }                                                                   \
-       else                                                                  \
-         {                                                                   \
-           ++*irreversible;                                                  \
-           inptr += 4;                                                       \
-         }                                                                   \
-       continue;                                                             \
+       STANDARD_ERR_HANDLER (4);                                             \
       }                                                                              \
     else                                                                     \
       {                                                                              \
index fd7bba7..4b7fefa 100644 (file)
@@ -202,26 +202,7 @@ gconv_end (struct __gconv_step *data)
          {                                                                   \
            if (__builtin_expect (c, 0) >= 0x110000)                          \
              {                                                               \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   ++*irreversible;                                          \
-                   inptr += 4;                                               \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            /* Generate a surrogate character.  */                            \
@@ -245,26 +226,7 @@ gconv_end (struct __gconv_step *data)
          {                                                                   \
            if (__builtin_expect (c, 0) >= 0x110000)                          \
              {                                                               \
-               if (step_data->__trans.__trans_fct != NULL)                   \
-                 {                                                           \
-                   result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
-                                         (step, step_data, *inptrp, &inptr,  \
-                                          inend, &outptr, irreversible));    \
-                   if (result != __GCONV_OK)                                 \
-                     break;                                                  \
-                 }                                                           \
-               else if (! ignore_errors_p ())                                \
-                 {                                                           \
-                   /* This is an illegal character.  */                      \
-                   result = __GCONV_ILLEGAL_INPUT;                           \
-                   break;                                                    \
-                 }                                                           \
-               else                                                          \
-                 {                                                           \
-                   ++*irreversible;                                          \
-                   inptr += 4;                                               \
-                 }                                                           \
-               continue;                                                     \
+               STANDARD_ERR_HANDLER (4);                                     \
              }                                                               \
                                                                              \
            /* Generate a surrogate character.  */                            \
index 8ad2129..12649fd 100644 (file)
@@ -124,9 +124,9 @@ _IO_fwide (fp, mode)
        cc->__cd_in.__cd.__data[0].__internal_use = 1;
        cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
        cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
+
        /* XXX For now no transliteration.  */
-       memset (&cc->__cd_in.__cd.__data[0].__trans, '\0',
-               sizeof (struct __gconv_trans_data));
+       cc->__cd_in.__cd.__data[0].__trans = NULL;
 
        cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed.  */
        cc->__cd_out.__cd.__steps = fcts.tomb;
@@ -135,9 +135,9 @@ _IO_fwide (fp, mode)
        cc->__cd_out.__cd.__data[0].__internal_use = 1;
        cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
        cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
+
        /* XXX For now no transliteration.  */
-       memset (&cc->__cd_out.__cd.__data[0].__trans, '\0',
-               sizeof (struct __gconv_trans_data));
+       cc->__cd_out.__cd.__data[0].__trans = NULL;
       }
 #else
 # error "somehow determine this from LC_CTYPE"
index 36ce5f4..54336c4 100644 (file)
@@ -234,8 +234,6 @@ _nl_unload_locale (struct locale_data *locale)
 #endif
     free ((void *) locale->filedata);
 
-  if (locale->options != NULL)
-    free (locale->options);
-
+  free (locale->options);
   free (locale);
 }
index 6f20ff9..765717e 100644 (file)
@@ -75,6 +75,13 @@ $(inst_i18ndir)/charmaps/%: charmaps/% $(+force); $(do-install)
 $(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install)
 $(inst_i18ndir)/repertoiremaps/%: repertoiremaps/% $(+force); $(do-install)
 
+# gcc does not know all the format specifiers we are using here.
+CFLAGS-tst-mbswcs1.c = -Wno-format
+CFLAGS-tst-mbswcs2.c = -Wno-format
+CFLAGS-tst-mbswcs3.c = -Wno-format
+CFLAGS-tst-mbswcs4.c = -Wno-format
+CFLAGS-tst-mbswcs5.c = -Wno-format
+CFLAGS-tst-trans.c = -Wno-format
 
 ifeq (no,$(cross-compiling))
 ifeq (yes,$(build-shared))
index cf0ec08..14d076c 100644 (file)
@@ -49,7 +49,7 @@ __btowc (c)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = &data.__state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* Make sure we start in the initial state.  */
   memset (&data.__state, '\0', sizeof (mbstate_t));
index 6f54179..d78a38b 100644 (file)
@@ -49,7 +49,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* A first special case is if S is NULL.  This means put PS in the
      initial state.  */
index 0410232..d8c0cdc 100644 (file)
@@ -57,7 +57,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   if (nmc == 0)
     return 0;
index 73a24a7..9f93518 100644 (file)
@@ -53,7 +53,7 @@ __mbsrtowcs (dst, src, len, ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* Make sure we use the correct function.  */
   update_conversion_ptrs ();
index f7100d4..ec75e57 100644 (file)
@@ -49,7 +49,7 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* A first special case is if S is NULL.  This means put PS in the
      initial state.  */
index f7b4363..129d099 100644 (file)
@@ -55,7 +55,7 @@ __wcsnrtombs (dst, src, nwc, len, ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   if (nwc == 0)
     return 0;
index 3c731aa..22dc76c 100644 (file)
@@ -51,7 +51,7 @@ __wcsrtombs (dst, src, len, ps)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = ps ?: &state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* Make sure we use the correct function.  */
   update_conversion_ptrs ();
index cee739c..0ee17ce 100644 (file)
@@ -43,7 +43,7 @@ wctob (c)
   data.__internal_use = 1;
   data.__flags = __GCONV_IS_LAST;
   data.__statep = &data.__state;
-  memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data));
+  data.__trans = NULL;
 
   /* Make sure we start in the initial state.  */
   memset (&data.__state, '\0', sizeof (mbstate_t));