summaryrefslogtreecommitdiff
path: root/iconv/gconv_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconv/gconv_db.c')
-rw-r--r--iconv/gconv_db.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
index 8dc6b14d25..6540cc393c 100644
--- a/iconv/gconv_db.c
+++ b/iconv/gconv_db.c
@@ -1,5 +1,5 @@
/* Provide access to the collection of available transformation modules.
- Copyright (C) 1997-2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1997-2003, 2004, 2005, 2006 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 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <assert.h>
#include <limits.h>
#include <search.h>
#include <stdlib.h>
@@ -28,6 +29,7 @@
#include <dlfcn.h>
#include <gconv_int.h>
+#include <sysdep.h>
/* Simple data structure for alias mapping. We have two names, `from'
@@ -180,7 +182,15 @@ free_derivation (void *p)
for (cnt = 0; cnt < deriv->nsteps; ++cnt)
if (deriv->steps[cnt].__counter > 0
&& deriv->steps[cnt].__end_fct != NULL)
- DL_CALL_FCT (deriv->steps[cnt].__end_fct, (&deriv->steps[cnt]));
+ {
+ assert (deriv->steps[cnt].__shlib_handle != NULL);
+
+ __gconv_end_fct end_fct = deriv->steps[cnt].__end_fct;
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (end_fct);
+#endif
+ DL_CALL_FCT (end_fct, (&deriv->steps[cnt]));
+ }
/* Free the name strings. */
free ((char *) deriv->steps[0].__from_name);
@@ -196,22 +206,30 @@ void
internal_function
__gconv_release_step (struct __gconv_step *step)
{
- if (--step->__counter == 0)
+ /* Skip builtin modules; they are not reference counted. */
+ if (step->__shlib_handle != NULL && --step->__counter == 0)
{
/* Call the destructor. */
if (step->__end_fct != NULL)
- DL_CALL_FCT (step->__end_fct, (step));
-
-#ifndef STATIC_GCONV
- /* Skip builtin modules; they are not reference counted. */
- if (step->__shlib_handle != NULL)
{
- /* Release the loaded module. */
- __gconv_release_shlib (step->__shlib_handle);
- step->__shlib_handle = NULL;
+ assert (step->__shlib_handle != NULL);
+
+ __gconv_end_fct end_fct = step->__end_fct;
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (end_fct);
+#endif
+ DL_CALL_FCT (end_fct, (step));
}
+
+#ifndef STATIC_GCONV
+ /* Release the loaded module. */
+ __gconv_release_shlib (step->__shlib_handle);
+ step->__shlib_handle = NULL;
#endif
}
+ else if (step->__shlib_handle == NULL)
+ /* Builtin modules should not have end functions. */
+ assert (step->__end_fct == NULL);
}
static int
@@ -272,10 +290,15 @@ gen_steps (struct derivation_step *best, const char *toset,
result[step_cnt].__btowc_fct = NULL;
/* Call the init function. */
- if (result[step_cnt].__init_fct != NULL)
+ __gconv_init_fct init_fct = result[step_cnt].__init_fct;
+ if (init_fct != NULL)
{
- status = DL_CALL_FCT (result[step_cnt].__init_fct,
- (&result[step_cnt]));
+ assert (result[step_cnt].__shlib_handle != NULL);
+
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (init_fct);
+# endif
+ status = DL_CALL_FCT (init_fct, (&result[step_cnt]));
if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
{
@@ -285,6 +308,11 @@ gen_steps (struct derivation_step *best, const char *toset,
result[step_cnt].__end_fct = NULL;
break;
}
+
+# ifdef PTR_MANGLE
+ if (result[step_cnt].__btowc_fct != NULL)
+ PTR_MANGLE (result[step_cnt].__btowc_fct);
+# endif
}
}
else
@@ -362,8 +390,19 @@ increment_counter (struct __gconv_step *steps, size_t nsteps)
}
/* Call the init function. */
- if (step->__init_fct != NULL)
- DL_CALL_FCT (step->__init_fct, (step));
+ __gconv_init_fct init_fct = step->__init_fct;
+ if (init_fct != NULL)
+ {
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (init_fct);
+#endif
+ DL_CALL_FCT (init_fct, (step));
+
+#ifdef PTR_MANGLE
+ if (step->__btowc_fct != NULL)
+ PTR_MANGLE (step->__btowc_fct);
+#endif
+ }
}
}
return result;