]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 4 Apr 1998 07:25:25 +0000 (07:25 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 4 Apr 1998 07:25:25 +0000 (07:25 +0000)
1998-04-03 23:17  Ulrich Drepper  <drepper@cygnus.com>

* iconv/gconv.c: Rewrite of the low-level of gconv.
* iconv/gconv.h: Likewise.
* iconv/gconv_builtin.h: Likewise.
* iconv/gconv_close.c: Likewise.
* iconv/gconv_db.: Likewise.
* iconv/gconv_dl.c: Likewise.
* iconv/gconv_int.h: Likewise.
* iconv/gconv_open.c: Likewise.
* iconv/gconv_simple.c: Likewise.
* iconvdata/8bit-gap.c: Adapt for rewrite.
* iconvdata/8bit-generic.c: Likewise.
* iconvdata/euckr.c: Likewise.
* iconvdata/iso646.c: Likewise.
* iconvdata/iso6937.c: Likewise.
* iconvdata/iso8859-1.c: Likewise.
* iconvdata/johab.c: Likewise.
* iconvdata/sjis.c: Likewise.
* iconvdata/t61.c: Likewise.
* iconvdata/uhc.c: Likewise.

20 files changed:
ChangeLog
iconv/gconv.c
iconv/gconv.h
iconv/gconv_builtin.h
iconv/gconv_close.c
iconv/gconv_db.c
iconv/gconv_dl.c
iconv/gconv_int.h
iconv/gconv_open.c
iconv/gconv_simple.c
iconvdata/8bit-gap.c
iconvdata/8bit-generic.c
iconvdata/euckr.c
iconvdata/iso646.c
iconvdata/iso6937.c
iconvdata/iso8859-1.c
iconvdata/johab.c
iconvdata/sjis.c
iconvdata/t61.c
iconvdata/uhc.c

index 98ead1266f7278803c978fd1e1616504ef6959d1..3a2eed77f8ed5901c3cfaf648f62188e1a5276fe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+1998-04-03 23:17  Ulrich Drepper  <drepper@cygnus.com>
+
+       * iconv/gconv.c: Rewrite of the low-level of gconv.
+       * iconv/gconv.h: Likewise.
+       * iconv/gconv_builtin.h: Likewise.
+       * iconv/gconv_close.c: Likewise.
+       * iconv/gconv_db.: Likewise.
+       * iconv/gconv_dl.c: Likewise.
+       * iconv/gconv_int.h: Likewise.
+       * iconv/gconv_open.c: Likewise.
+       * iconv/gconv_simple.c: Likewise.
+       * iconvdata/8bit-gap.c: Adapt for rewrite.
+       * iconvdata/8bit-generic.c: Likewise.
+       * iconvdata/euckr.c: Likewise.
+       * iconvdata/iso646.c: Likewise.
+       * iconvdata/iso6937.c: Likewise.
+       * iconvdata/iso8859-1.c: Likewise.
+       * iconvdata/johab.c: Likewise.
+       * iconvdata/sjis.c: Likewise.
+       * iconvdata/t61.c: Likewise.
+       * iconvdata/uhc.c: Likewise.
+
 1998-04-03 15:34  Ulrich Drepper  <drepper@cygnus.com>
 
        * iconv/gconv_int.h: New file.  Internal header.
index 5df16354b6a5a12ded9ecf488950ef6a9a3e2aca..71d87ae1f679242faf71976e79a1d7839c115ec7 100644 (file)
@@ -23,6 +23,7 @@
 
 
 int
+internal_function
 __gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
         size_t *outbytesleft, size_t *converted)
 {
index 76a719785e050927d5afe2051bcf4e6dd91cb256..f3f80f4c147b7d7a6262b8558150fa1b9d2c41fd 100644 (file)
@@ -24,6 +24,7 @@
 #define _GCONV_H       1
 
 #include <features.h>
+#include <wchar.h>
 #define __need_size_t
 #include <stddef.h>
 
@@ -51,6 +52,7 @@ enum
 /* Forward declarations.  */
 struct gconv_step;
 struct gconv_step_data;
+struct gconv_loaded_object;
 
 
 /* Type of a conversion function.  */
@@ -59,15 +61,17 @@ typedef int (*gconv_fct) __P ((struct gconv_step *,
                               __const char *, size_t *, size_t *, int));
 
 /* Constructor and destructor for local data for conversion step.  */
-typedef int (*gconv_init_fct) __P ((struct gconv_step *,
-                                   struct gconv_step_data *));
-typedef void (*gconv_end_fct) __P ((struct gconv_step_data *));
+typedef int (*gconv_init_fct) __P ((struct gconv_step *));
+typedef void (*gconv_end_fct) __P ((struct gconv_step *));
 
 
 /* Description of a conversion step.  */
 struct gconv_step
 {
-  void *shlib_handle;
+  struct gconv_loaded_object *shlib_handle;
+  const char *modname;
+
+  int counter;
 
   __const char *from_name;
   __const char *to_name;
@@ -75,6 +79,8 @@ struct gconv_step
   gconv_fct fct;
   gconv_init_fct init_fct;
   gconv_end_fct end_fct;
+
+  void *data;          /* Pointer to step-local data.  */
 };
 
 /* Additional data for steps in use of conversion descriptor.  This is
@@ -87,7 +93,9 @@ struct gconv_step_data
 
   int is_last;
 
-  void *data;          /* Pointer to step-local data.  */
+  mbstate_t *statep;
+  mbstate_t __state;   /* This element should not be used directly by
+                          any module; always use STATEP!  */
 };
 
 
index 8e5d692946b98f31ae04899ee41f2b2dece54fe0..9c98c3513dc1027e36eb8cfa57b2470bf4ae5907 100644 (file)
@@ -23,30 +23,22 @@ BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
 
 BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
                        "ISO-10646/UTF8/", 1, "=ucs4->utf8",
-                       __gconv_transform_ucs4_utf8,
-                       __gconv_transform_init_rstate,
-                       __gconv_transform_end_rstate)
+                       __gconv_transform_ucs4_utf8, NULL, NULL)
 
 BUILTIN_TRANSFORMATION ("ISO-10646/UTF-?8/", "ISO-10646/UTF", 13,
                        "ISO-10646/UCS4/", 1, "=utf8->ucs4",
-                       __gconv_transform_utf8_ucs4,
-                       __gconv_transform_init_rstate,
-                       __gconv_transform_end_rstate)
+                       __gconv_transform_utf8_ucs4, NULL, NULL)
 
 BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
 BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
 
 BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "ISO-10646/UCS4/",
                        1, "=ucs2->ucs4",
-                       __gconv_transform_ucs2_ucs4,
-                       __gconv_transform_init_rstate,
-                       __gconv_transform_end_rstate)
+                       __gconv_transform_ucs2_ucs4, NULL, NULL)
 
 BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15, "ISO-10646/UCS2/",
                        1, "=ucs4->ucs2",
-                       __gconv_transform_ucs4_ucs2,
-                       __gconv_transform_init_rstate,
-                       __gconv_transform_end_rstate)
+                       __gconv_transform_ucs4_ucs2, NULL, NULL)
 
 BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
                        __gconv_transform_dummy, NULL, NULL)
index b6d5fbcd9d7d77774a42e5bf46c83d0679399dad..de0937d6104b9cb947abc9a5df3c1b170e04f0cd 100644 (file)
@@ -38,24 +38,11 @@ __gconv_close (gconv_t cd)
   drunp = cd->data;
   do
     {
-      /* Call destructor.  */
-      if (srunp->end_fct != NULL)
-       (*srunp->end_fct) (drunp);
-      else
-       if (drunp->data != NULL)
-         free (drunp->data);
-
       if (!drunp->is_last && drunp->outbuf != NULL)
        free (drunp->outbuf);
-
-      /* Next step.  */
-      ++srunp;
     }
   while (!(drunp++)->is_last);
 
-  /* Save the pointer, we need it below.  */
-  srunp = cd->steps;
-
   /* Free the data allocated for the descriptor.  */
   free (cd->data);
   free (cd);
index 5a3932c60180564dbdd66caa97ee7dc2ec4d7604..e0a94e41c32cd5bd3bfac227632fb9097d824eb6 100644 (file)
@@ -34,6 +34,9 @@ void *__gconv_alias_db;
 size_t __gconv_nmodules;
 struct gconv_module **__gconv_modules_db;
 
+/* We modify global data.   */
+__libc_lock_define_initialized (static, lock)
+
 
 /* Function for searching alias.  */
 int
@@ -128,9 +131,7 @@ add_derivation (const char *fromset, const char *toset,
     malloc (sizeof (struct known_derivation) + fromset_len + toset_len);
   if (new_deriv != NULL)
     {
-      new_deriv->from = memcpy ((char *) new_deriv
-                               + sizeof (struct known_derivation),
-                               fromset, fromset_len);
+      new_deriv->from = memcpy (new_deriv + 1, fromset, fromset_len);
       new_deriv->to = memcpy ((char *) new_deriv->from + fromset_len,
                              toset, toset_len);
 
@@ -149,6 +150,11 @@ internal_function
 free_derivation (void *p)
 {
   struct known_derivation *deriv = (struct known_derivation *) p;
+  size_t cnt;
+
+  for (cnt = 0; cnt < deriv->nsteps; ++cnt)
+    if (deriv->steps[cnt].end_fct)
+      (*deriv->steps[cnt].end_fct) (&deriv->steps[cnt]);
 
   free ((struct gconv_step *) deriv->steps);
   free (deriv);
@@ -189,7 +195,7 @@ gen_steps (struct derivation_step *best, const char *toset,
          if (current->code->module_name[0] == '/')
            {
              /* Load the module, return handle for it.  */
-             void *shlib_handle =
+             struct gconv_loaded_object *shlib_handle =
                __gconv_find_shlib (current->code->module_name);
 
              if (shlib_handle == NULL)
@@ -199,27 +205,21 @@ gen_steps (struct derivation_step *best, const char *toset,
                }
 
              result[step_cnt].shlib_handle = shlib_handle;
-
-             result[step_cnt].fct = __gconv_find_func (shlib_handle, "gconv");
-             if (result[step_cnt].fct == NULL)
-               {
-                 /* Argh, no conversion function.  There is something
-                    wrong here.  */
-                 __gconv_release_shlib (result[step_cnt].shlib_handle);
-                 failed = 1;
-                 break;
-               }
-
-             result[step_cnt].init_fct = __gconv_find_func (shlib_handle,
-                                                            "gconv_init");
-             result[step_cnt].end_fct = __gconv_find_func (shlib_handle,
-                                                           "gconv_end");
+             result[step_cnt].modname = shlib_handle->name;
+             result[step_cnt].counter = 0;
+             result[step_cnt].fct = shlib_handle->fct;
+             result[step_cnt].init_fct = shlib_handle->init_fct;
+             result[step_cnt].end_fct = shlib_handle->end_fct;
            }
          else
            /* It's a builtin transformation.  */
            __gconv_get_builtin_trans (current->code->module_name,
                                       &result[step_cnt]);
 
+         /* Call the init function.  */
+         if (result[step_cnt].init_fct != NULL)
+           (*result[step_cnt].init_fct) (&result[step_cnt]);
+
          current = current->last;
        }
 
@@ -227,7 +227,11 @@ gen_steps (struct derivation_step *best, const char *toset,
        {
          /* Something went wrong while initializing the modules.  */
          while (++step_cnt < *nsteps)
-           __gconv_release_shlib (result[step_cnt].shlib_handle);
+           {
+             if (result[step_cnt].end_fct != NULL)
+               (*result[step_cnt].end_fct) (&result[step_cnt]);
+             __gconv_release_shlib (result[step_cnt].shlib_handle);
+           }
          free (result);
          *nsteps = 0;
          status = GCONV_NOCONV;
@@ -273,7 +277,8 @@ find_derivation (const char *toset, const char *toset_expand,
 
   /* ### TODO
      For now we use a simple algorithm with quadratic runtime behaviour.
-     The task is to match the `toset' with any of the available.  */
+     The task is to match the `toset' with any of the available rules,
+     starting from FROMSET.  */
   if (fromset_expand != NULL)
     {
       first = NEW_STEP (fromset_expand, NULL, NULL);
@@ -495,6 +500,9 @@ __gconv_find_transform (const char *toset, const char *fromset,
   /* Ensure that the configuration data is read.  */
   __libc_once (once, __gconv_read_conf);
 
+  /* Acquire the lock.  */
+  __libc_lock_lock (lock);
+
   /* If we don't have a module database return with an error.  */
   if (__gconv_modules_db == NULL)
     return GCONV_NOCONV;
@@ -517,6 +525,33 @@ __gconv_find_transform (const char *toset, const char *fromset,
   result = find_derivation (toset, toset_expand, fromset, fromset_expand,
                            handle, nsteps);
 
+  /* Increment the user counter.  */
+  if (result == GCONV_OK)
+    {
+      size_t cnt = *nsteps;
+      struct gconv_step *steps = *handle;
+
+      do
+       if (steps[--cnt].counter++ == 0)
+         {
+           steps[--cnt].shlib_handle =
+             __gconv_find_shlib (steps[--cnt].modname);
+           if (steps[--cnt].shlib_handle == NULL)
+             {
+               /* Oops, this is the second time we use this module (after
+                  unloading) and this time loading failed!?  */
+               while (++cnt < *nsteps)
+                 __gconv_release_shlib (steps[cnt].shlib_handle);
+               result = GCONV_NOCONV;
+               break;
+             }
+         }
+      while (cnt > 0);
+    }
+
+  /* Release the lock.  */
+  __libc_lock_unlock (lock);
+
   /* The following code is necessary since `find_derivation' will return
      GCONV_OK even when no derivation was found but the same request
      was processed before.  I.e., negative results will also be cached.  */
@@ -533,14 +568,22 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
 {
   int result = GCONV_OK;
 
+  /* Acquire the lock.  */
+  __libc_lock_lock (lock);
+
   while (nsteps-- > 0)
-    if (steps[nsteps].shlib_handle != NULL)
+    if (steps[nsteps].shlib_handle != NULL
+       && --steps[nsteps].counter == 0)
       {
        result = __gconv_release_shlib (steps[nsteps].shlib_handle);
        if (result != GCONV_OK)
          break;
+       steps[nsteps].shlib_handle = NULL;
       }
 
+  /* Release the lock.  */
+  __libc_lock_unlock (lock);
+
   return result;
 }
 
index 2a7cc92a3df824be406e5660a8b0e02803823780..b11e156a037ad2e06c955c4a536b16e5c380fea3 100644 (file)
 #define TRIES_BEFORE_UNLOAD    2
 
 
-/* Structure describing one loaded shared object.  This normally are
-   objects to perform conversation but as a special case the db shared
-   object is also handled.  */
-struct loaded_object
-{
-  /* Name of the object.  */
-  const char *name;
-
-  /* Reference counter for the db functionality.  If no conversion is
-     needed we unload the db library.  */
-  int counter;
-
-  /* The handle for the shared object.  */
-  void *handle;
-};
-
-
 /* Array of loaded objects.  This is shared by all threads so we have
    to use semaphores to access it.  */
 static void *loaded;
-__libc_lock_define_initialized (static, lock)
 
 
 
@@ -68,8 +50,10 @@ __libc_lock_define_initialized (static, lock)
 static int
 known_compare (const void *p1, const void *p2)
 {
-  const struct loaded_object *s1 = (const struct loaded_object *) p1;
-  const struct loaded_object *s2 = (const struct loaded_object *) p2;
+  const struct gconv_loaded_object *s1 =
+    (const struct gconv_loaded_object *) p1;
+  const struct gconv_loaded_object *s2 =
+    (const struct gconv_loaded_object *) p2;
 
   return (intptr_t) s1->handle - (intptr_t) s2->handle;
 }
@@ -78,7 +62,7 @@ known_compare (const void *p1, const void *p2)
 static void
 do_open (void *a)
 {
-  struct loaded_object *args = (struct loaded_object *) a;
+  struct gconv_loaded_object *args = (struct gconv_loaded_object *) a;
   /* Open and relocate the shared object.  */
   args->handle = _dl_open (args->name, RTLD_LAZY);
 }
@@ -124,9 +108,9 @@ get_sym (void *a)
 }
 
 
-void *
+static void *
 internal_function
-__gconv_find_func (void *handle, const char *name)
+find_func (void *handle, const char *name)
 {
   struct get_sym_args args;
 
@@ -141,15 +125,11 @@ __gconv_find_func (void *handle, const char *name)
 
 /* Open the gconv database if necessary.  A non-negative return value
    means success.  */
-void *
+struct gconv_loaded_object *
 internal_function
 __gconv_find_shlib (const char *name)
 {
-  void *result = NULL;
-  struct loaded_object *found;
-
-  /* Acquire the lock.  */
-  __libc_lock_lock (lock);
+  struct gconv_loaded_object *found;
 
   /* Search the tree of shared objects previously requested.  Data in
      the tree are `loaded_object' structures, whose first member is a
@@ -164,7 +144,7 @@ __gconv_find_shlib (const char *name)
   if (found == NULL)
     {
       /* This name was not known before.  */
-      found = malloc (sizeof (struct loaded_object));
+      found = malloc (sizeof (struct gconv_loaded_object));
       if (found != NULL)
        {
          /* Point the tree node at this new structure.  */
@@ -189,35 +169,50 @@ __gconv_find_shlib (const char *name)
       if (found->counter < -TRIES_BEFORE_UNLOAD)
        {
          if (dlerror_run (do_open, found) == 0)
-           found->counter = 1;
+           {
+             found->fct = find_func (found->handle, "gconv");
+             if (found->fct == NULL)
+               {
+                 /* Argh, no conversion function.  There is something
+                     wrong here.  */
+                 __gconv_release_shlib (found);
+                 found = NULL;
+               }
+             else
+               {
+                 found->init_fct = find_func (found->handle, "gconv_init");
+                 found->end_fct = find_func (found->handle, "gconv_end");
+
+                 /* We have succeeded in loading the shared object.  */
+                 found->counter = 1;
+               }
+           }
+         else
+           /* Error while loading the shared object.  */
+           found = NULL;
        }
       else if (found->handle != NULL)
        found->counter = MAX (found->counter + 1, 1);
-
-      result = found->handle;
     }
 
-  /* Release the lock.  */
-  __libc_lock_unlock (lock);
-
-  return result;
+  return found;
 }
 
 
 /* This is very ugly but the tsearch functions provide no way to pass
    information to the walker function.  So we use a global variable.
    It is MT safe since we use a lock.  */
-static void *release_handle;
+static struct gconv_loaded_object *release_handle;
 
 static void
 do_release_shlib (const void *nodep, VISIT value, int level)
 {
-  struct loaded_object *obj = *(struct loaded_object **) nodep;
+  struct gconv_loaded_object *obj = *(struct gconv_loaded_object **) nodep;
 
   if (value != preorder && value != leaf)
     return;
 
-  if (obj->handle == release_handle)
+  if (obj == release_handle)
     /* This is the object we want to unload.  Now set the release
        counter to zero.  */
     obj->counter = 0;
@@ -228,7 +223,7 @@ do_release_shlib (const void *nodep, VISIT value, int level)
          /* Unload the shared object.  We don't use the trick to
             catch errors since in the case an error is signalled
             something is really wrong.  */
-         _dl_close ((struct link_map *) obj->handle);
+         _dl_close (obj->handle);
 
          obj->handle = NULL;
        }
@@ -239,11 +234,8 @@ do_release_shlib (const void *nodep, VISIT value, int level)
 /* Notify system that a shared object is not longer needed.  */
 int
 internal_function
-__gconv_release_shlib (void *handle)
+__gconv_release_shlib (struct gconv_loaded_object *handle)
 {
-  /* Acquire the lock.  */
-  __libc_lock_lock (lock);
-
   /* Urgh, this is ugly but we have no other possibility.  */
   release_handle = handle;
 
@@ -252,8 +244,5 @@ __gconv_release_shlib (void *handle)
      if necessary.  */
   __twalk (loaded, do_release_shlib);
 
-  /* Release the lock.  */
-  __libc_lock_unlock (lock);
-
   return GCONV_OK;
 }
index 5261284d7ff17a73b29ec0cc2bc4a9a066e8f901..5e0723ed3492f125c982adf1d7fc8ca36c01c0df 100644 (file)
@@ -29,8 +29,8 @@ __BEGIN_DECLS
 /* Structure for alias definition.  Simply to strings.  */
 struct gconv_alias
 {
-  __const char *fromname;
-  __const char *toname;
+  const char *fromname;
+  const char *toname;
 };
 
 
@@ -38,19 +38,41 @@ struct gconv_alias
 #define GCONV_DEFAULT_BUFSIZE  8160
 
 
+/* Structure describing one loaded shared object.  This normally are
+   objects to perform conversation but as a special case the db shared
+   object is also handled.  */
+struct gconv_loaded_object
+{
+  /* Name of the object.  */
+  const char *name;
+
+  /* Reference counter for the db functionality.  If no conversion is
+     needed we unload the db library.  */
+  int counter;
+
+  /* The handle for the shared object.  */
+  struct link_map *handle;
+
+  /* Pointer to the functions the module defines.  */
+  gconv_fct fct;
+  gconv_init_fct init_fct;
+  gconv_end_fct end_fct;
+};
+
+
 /* Description for an available conversion module.  */
 struct gconv_module
 {
-  __const char *from_pattern;
-  __const char *from_constpfx;
+  const char *from_pattern;
+  const char *from_constpfx;
   size_t from_constpfx_len;
-  __const regex_t *from_regex;
+  const regex_t *from_regex;
 
-  __const char *to_string;
+  const char *to_string;
 
   int cost;
 
-  __const char *module_name;
+  const char *module_name;
 };
 
 
@@ -65,65 +87,56 @@ extern struct gconv_module **__gconv_modules_db;
 
 
 /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET.  */
-extern int __gconv_open __P ((__const char *__toset, __const char *__fromset,
-                             gconv_t *__handle))
+extern int __gconv_open (const char *__toset, const char *__fromset,
+                        gconv_t *__handle)
      internal_function;
 
 /* Free resources associated with transformation descriptor CD.  */
-extern int __gconv_close __P ((gconv_t cd))
+extern int __gconv_close (gconv_t cd)
      internal_function;
 
 /* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF
    according to rules described by CD and place up to *OUTBYTESLEFT
    bytes in buffer starting at *OUTBUF.  Return number of written
    characters in *CONVERTED if this pointer is not null.  */
-extern int __gconv __P ((gconv_t __cd,
-                        __const char **__inbuf, size_t *__inbytesleft,
-                        char **__outbuf, size_t *__outbytesleft,
-                        size_t *__converted))
+extern int __gconv (gconv_t __cd, const char **__inbuf, size_t *__inbytesleft,
+                   char **__outbuf, size_t *__outbytesleft,
+                   size_t *__converted)
      internal_function;
 
 /* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
    the single steps necessary for transformation from FROMSET to TOSET.  */
-extern int __gconv_find_transform __P ((__const char *__toset,
-                                       __const char *__fromset,
-                                       struct gconv_step **__handle,
-                                       size_t *__nsteps))
+extern int __gconv_find_transform (const char *__toset, const char *__fromset,
+                                  struct gconv_step **__handle,
+                                  size_t *__nsteps)
      internal_function;
 
 /* Read all the configuration data and cache it.  */
-extern void __gconv_read_conf __P ((void))
+extern void __gconv_read_conf (void)
      internal_function;
 
 /* Comparison function to search alias.  */
-extern int __gconv_alias_compare __P ((__const void *__p1,
-                                      __const void *__p2));
+extern int __gconv_alias_compare (const void *__p1, const void *__p2);
 
 /* Clear reference to transformation step implementations which might
    cause the code to be unloaded.  */
-extern int __gconv_close_transform __P ((struct gconv_step *__steps,
-                                        size_t __nsteps))
-     internal_function;
-
-
-/* Find in the shared object associated with HANDLE for a function with
-   name NAME.  Return function pointer or NULL.  */
-extern void *__gconv_find_func __P ((void *__handle, __const char *__name))
+extern int __gconv_close_transform (struct gconv_step *__steps,
+                                   size_t __nsteps)
      internal_function;
 
 /* Load shared object named by NAME.  If already loaded increment reference
    count.  */
-extern void *__gconv_find_shlib __P ((__const char *__name))
+extern struct gconv_loaded_object *__gconv_find_shlib (const char *__name)
      internal_function;
 
 /* Release shared object.  If no further reference is available unload
    the object.  */
-extern int __gconv_release_shlib __P ((void *__handle))
+extern int __gconv_release_shlib (struct gconv_loaded_object *__handle)
      internal_function;
 
 /* Fill STEP with information about builtin module with NAME.  */
-extern void __gconv_get_builtin_trans __P ((__const char *__name,
-                                           struct gconv_step *__step))
+extern void __gconv_get_builtin_trans (const char *__name,
+                                      struct gconv_step *__step)
      internal_function;
 
 
@@ -131,9 +144,9 @@ extern void __gconv_get_builtin_trans __P ((__const char *__name,
 /* Builtin transformations.  */
 #ifdef _LIBC
 # define __BUILTIN_TRANS(Name) \
-  extern int Name __P ((struct gconv_step *__step,                           \
-                       struct gconv_step_data *__data, __const char *__inbuf,\
-                       size_t *__inlen, size_t *__written, int __do_flush))
+  extern int Name (struct gconv_step *__step, struct gconv_step_data *__data, \
+                  const char *__inbuf, size_t *__inlen, size_t *__written,   \
+                  int __do_flush)
 
 __BUILTIN_TRANS (__gconv_transform_dummy);
 __BUILTIN_TRANS (__gconv_transform_ucs4_utf8);
@@ -142,10 +155,6 @@ __BUILTIN_TRANS (__gconv_transform_ucs2_ucs4);
 __BUILTIN_TRANS (__gconv_transform_ucs4_ucs2);
 # undef __BUITLIN_TRANS
 
-extern int __gconv_transform_init_rstate __P ((struct gconv_step *__step,
-                                             struct gconv_step_data *__data));
-extern void __gconv_transform_end_rstate __P ((struct gconv_step_data *__data));
-
 #endif
 
 __END_DECLS
index ea7b3653af8802152d657967a84c59777c444b2e..d82dcfee483922e6e3931fc50f3a30e645dc18fe 100644 (file)
@@ -65,25 +65,18 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
                     buffer.  Signal this to the initializer.  */
                  data[cnt].is_last = cnt == nsteps - 1;
 
-                 if (steps[cnt].init_fct != NULL)
-                   {
-                     res = (steps[cnt].init_fct) (&steps[cnt], &data[cnt]);
-                     if (res != GCONV_OK)
-                       break;
-                   }
+                 /* We use the `mbstate_t' member in DATA.  */
+                 data[cnt].statep = &data[cnt].__state;
 
-                 if (!data[cnt].is_last && data[cnt].outbuf == NULL)
+                 /* Allocate the buffer.  */
+                 data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
+                 data[cnt].outbuf = (char *) malloc (data[cnt].outbufsize);
+                 if (data[cnt].outbuf == NULL)
                    {
-                     data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
-                     data[cnt].outbuf =
-                       (char *) malloc (data[cnt].outbufsize);
-                     if (data[cnt].outbuf == NULL)
-                       {
-                         res = GCONV_NOMEM;
-                         break;
-                       }
-                     data[cnt].outbufavail = 0;
+                     res = GCONV_NOMEM;
+                     break;
                    }
+                 data[cnt].outbufavail = 0;
                }
            }
        }
@@ -99,14 +92,7 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
          if (result->data != NULL)
            {
              while (cnt-- > 0)
-               if (steps[cnt].end_fct != NULL)
-                 (*steps[cnt].end_fct) (&result->data[cnt]);
-               else
-                 {
-                   free (result->data[cnt].outbuf);
-                   if (result->data[cnt].data != NULL)
-                     free (result->data[cnt].data);
-                 }
+               free (result->data[cnt].outbuf);
 
              free (result->data);
            }
index 280ecf57b51f182c7153bea5b2485b6143ac9595..7fbdfbacf30342fa46d3b7d06883bb7b1ba278e5 100644 (file)
@@ -58,26 +58,6 @@ __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
 }
 
 
-int
-__gconv_transform_init_rstate (struct gconv_step *step,
-                              struct gconv_step_data *data)
-{
-  /* We have to provide the transformation function an correctly initialized
-     object of type `mbstate_t'.  This must be dynamically allocated.  */
-  data->data = calloc (1, sizeof (mbstate_t));
-
-  return data->data == NULL ? GCONV_NOMEM : GCONV_OK;
-}
-
-
-void
-__gconv_transform_end_rstate (struct gconv_step_data *data)
-{
-  if (data->data != NULL)
-    free (data->data);
-}
-
-
 int
 __gconv_transform_ucs4_utf8 (struct gconv_step *step,
                             struct gconv_step_data *data, const char *inbuf,
@@ -95,7 +75,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
   if (do_flush)
     {
       /* Clear the state.  */
-      memset (data->data, '\0', sizeof (mbstate_t));
+      memset (data->statep, '\0', sizeof (mbstate_t));
       do_write = 0;
 
       /* Call the steps down the chain if there are any.  */
@@ -127,7 +107,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
                                   (const wchar_t **) &newinbuf,
                                   *inlen / sizeof (wchar_t),
                                   data->outbufsize - data->outbufavail,
-                                  (mbstate_t *) data->data);
+                                  data->statep);
 
          /* Remember how much we converted.  */
          do_write += newinbuf - inbuf;
@@ -200,7 +180,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
   if (do_flush)
     {
       /* Clear the state.  */
-      memset (data->data, '\0', sizeof (mbstate_t));
+      memset (data->statep, '\0', sizeof (mbstate_t));
       do_write = 0;
 
       /* Call the steps down the chain if there are any.  */
@@ -229,7 +209,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
                                   &newinbuf, *inlen,
                                   ((data->outbufsize
                                     - data->outbufavail) / sizeof (wchar_t)),
-                                  (mbstate_t *) data->data);
+                                  data->statep);
 
          /* Remember how much we converted.  */
          do_write += actually;
@@ -244,7 +224,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
              break;
            }
 
-         if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+         if (*inlen == 0 && !mbsinit (data->statep))
            {
              /* We have an incomplete character at the end.  */
              result = GCONV_INCOMPLETE_INPUT;
@@ -309,7 +289,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
   if (do_flush)
     {
       /* Clear the state.  */
-      memset (data->data, '\0', sizeof (mbstate_t));
+      memset (data->statep, '\0', sizeof (mbstate_t));
       do_write = 0;
 
       /* Call the steps down the chain if there are any.  */
@@ -347,7 +327,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
          if (*inlen != 1)
            {
              /* We have an incomplete input character.  */
-             mbstate_t *state = (mbstate_t *) data->data;
+             mbstate_t *state = data->statep;
              state->count = 1;
              state->value = *(uint8_t *) newinbuf;
              --*inlen;
@@ -363,7 +343,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
              break;
            }
 
-         if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+         if (*inlen == 0 && !mbsinit (data->statep))
            {
              /* We have an incomplete character at the end.  */
              result = GCONV_INCOMPLETE_INPUT;
@@ -428,7 +408,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
   if (do_flush)
     {
       /* Clear the state.  */
-      memset (data->data, '\0', sizeof (mbstate_t));
+      memset (data->statep, '\0', sizeof (mbstate_t));
       do_write = 0;
 
       /* Call the steps down the chain if there are any.  */
@@ -474,7 +454,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
          if (*inlen < 4)
            {
              /* We have an incomplete input character.  */
-             mbstate_t *state = (mbstate_t *) data->data;
+             mbstate_t *state = data->statep;
              state->count = *inlen;
              state->value = 0;
              while (*inlen > 0)
@@ -495,7 +475,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
              break;
            }
 
-         if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+         if (*inlen == 0 && !mbsinit (data->statep))
            {
              /* We have an incomplete character at the end.  */
              result = GCONV_INCOMPLETE_INPUT;
index 301bd6b810aeca603f2055e5c8296d950447e881..1528cb6bf7cee19abf1b9cda93dc0e5955c2c127 100644 (file)
@@ -50,7 +50,7 @@ struct s_8bit_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct s_8bit_data *new_data;
@@ -71,7 +71,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -80,7 +80,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -119,7 +119,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct s_8bit_data *) data->data)->dir;
+      enum direction dir = ((struct s_8bit_data *) step->data)->dir;
 
       do_write = 0;
 
index e8493fc445eef977926a37c58b031362b078d7e2..7f0bbae6b0a0114b7e08b4f88a3657cbd746df6e 100644 (file)
@@ -37,7 +37,7 @@ struct s_8bit_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct s_8bit_data *new_data;
@@ -58,7 +58,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -67,7 +67,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -106,7 +106,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct s_8bit_data *) data->data)->dir;
+      enum direction dir = ((struct s_8bit_data *) step->data)->dir;
 
       do_write = 0;
 
index ba58034b855ebd3348f3c8bc8856e7f064b7668f..9789e883e9206ffc6dc8b2267b878dc157515667 100644 (file)
@@ -63,7 +63,7 @@ euckr_from_ucs4(wchar_t ch, unsigned char *cp)
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct euckr_data *new_data;
@@ -84,7 +84,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -93,7 +93,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -132,7 +132,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct euckr_data *) data->data)->dir;
+      enum direction dir = ((struct euckr_data *) step->data)->dir;
 
       do_write = 0;
 
index 3b4864ef11c9fbfccebf8c7e1361efc7f4bb5b4d..a9705f063699850a90325e97214217396f9cc82e 100644 (file)
@@ -58,7 +58,7 @@ struct iso646_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct iso646_data *new_data;
@@ -100,7 +100,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
     {
       new_data->dir = dir;
       new_data->var = var;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -109,7 +109,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -148,8 +148,8 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct iso646_data *) data->data)->dir;
-      enum variant var = ((struct iso646_data *) data->data)->var;
+      enum direction dir = ((struct iso646_data *) step->data)->dir;
+      enum variant var = ((struct iso646_data *) step->data)->var;
 
       do_write = 0;
 
index 01080360bbfdedba4ef9fb289a6eb84215083d9d..377eef5afc27af2a2feb86af723abc3be6f38309 100644 (file)
@@ -387,7 +387,7 @@ struct iso6937_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct iso6937_data *new_data;
@@ -408,7 +408,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -417,7 +417,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -456,7 +456,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct iso6937_data *) data->data)->dir;
+      enum direction dir = ((struct iso6937_data *) step->data)->dir;
 
       do_write = 0;
 
index 5f98adcfee67e0c02e034eb46eb385b4dab053e7..cdeb526d7a3d34ef6dd6b66325718faef3751620 100644 (file)
@@ -37,7 +37,7 @@ struct iso88591_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct iso88591_data *new_data;
@@ -58,7 +58,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -67,7 +67,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -106,7 +106,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct iso88591_data *) data->data)->dir;
+      enum direction dir = ((struct iso88591_data *) step->data)->dir;
 
       do_write = 0;
 
index 3acd5fcad789790ee58ae926c8bc8a3b94f2f346..bde56ce1d33f35235a99cc2a9482970815512141 100644 (file)
@@ -239,7 +239,7 @@ johab_from_ucs4 (wchar_t ch, unsigned char *cp)
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct johab_data *new_data;
@@ -260,7 +260,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -269,7 +269,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -308,7 +308,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct johab_data *) data->data)->dir;
+      enum direction dir = ((struct johab_data *) step->data)->dir;
 
       do_write = 0;
 
index 492bbd7ade6b56309a37b90ad72a4375bf30fc24..f713db1cc44c26bf51af9765af67f4afa4735387 100644 (file)
@@ -3997,7 +3997,7 @@ struct sjis_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct sjis_data *new_data;
@@ -4018,7 +4018,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -4027,7 +4027,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -4066,7 +4066,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct sjis_data *) data->data)->dir;
+      enum direction dir = ((struct sjis_data *) step->data)->dir;
 
       do_write = 0;
 
index a8de21cc3d092293ba612c1b87d7b63f5d2611ff..7d4314dfd27505223e989185aeaa25bc5af6c70d 100644 (file)
@@ -378,7 +378,7 @@ struct t61_data
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct t61_data *new_data;
@@ -399,7 +399,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
          != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -408,7 +408,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -447,7 +447,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct t61_data *) data->data)->dir;
+      enum direction dir = ((struct t61_data *) step->data)->dir;
 
       do_write = 0;
 
index c64ff1b0af874cbebf711e829b07b2f9dd5fa515..9e5f0092650105d43be85ee0bca48e402ac158d5 100644 (file)
@@ -2623,7 +2623,7 @@ uhc_from_ucs4(wchar_t ch, unsigned char *cp)
 
 
 int
-gconv_init (struct gconv_step *step, struct gconv_step_data *data)
+gconv_init (struct gconv_step *step)
 {
   /* Determine which direction.  */
   struct uhc_data *new_data;
@@ -2643,7 +2643,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
           = (struct uhc_data *) malloc (sizeof (struct uhc_data))) != NULL))
     {
       new_data->dir = dir;
-      data->data = new_data;
+      step->data = new_data;
       result = GCONV_OK;
     }
 
@@ -2652,7 +2652,7 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
 
 
 void
-gconv_end (struct gconv_step_data *data)
+gconv_end (struct gconv_step *data)
 {
   free (data->data);
 }
@@ -2691,7 +2691,7 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
     }
   else
     {
-      enum direction dir = ((struct uhc_data *) data->data)->dir;
+      enum direction dir = ((struct uhc_data *) step->data)->dir;
 
       do_write = 0;