about summary refs log tree commit diff
path: root/iconv
diff options
context:
space:
mode:
Diffstat (limited to 'iconv')
-rw-r--r--iconv/dummy-repertoire.c22
-rw-r--r--iconv/gconv.c19
-rw-r--r--iconv/gconv_builtin.c13
-rw-r--r--iconv/gconv_builtin.h5
-rw-r--r--iconv/gconv_cache.c17
-rw-r--r--iconv/gconv_charset.h10
-rw-r--r--iconv/gconv_conf.c101
-rw-r--r--iconv/gconv_db.c71
-rw-r--r--iconv/gconv_dl.c11
-rw-r--r--iconv/gconv_int.h8
-rw-r--r--iconv/gconv_open.c18
-rw-r--r--iconv/gconv_simple.c4
-rw-r--r--iconv/gconv_trans.c10
-rw-r--r--iconv/iconv_charmap.c48
-rw-r--r--iconv/iconv_open.c4
-rw-r--r--iconv/iconv_prog.c42
-rw-r--r--iconv/iconvconfig.c94
-rw-r--r--iconv/loop.c6
-rw-r--r--iconv/skeleton.c45
-rw-r--r--iconv/strtab.c4
20 files changed, 328 insertions, 224 deletions
diff --git a/iconv/dummy-repertoire.c b/iconv/dummy-repertoire.c
index a195460f9a..a87685c505 100644
--- a/iconv/dummy-repertoire.c
+++ b/iconv/dummy-repertoire.c
@@ -1,21 +1,19 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation.
 
-   The GNU C Library is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* For iconv we don't have to handle repertoire maps.  Provide dummy
    definitions to allow the use of linereader.c unchanged.  */
diff --git a/iconv/gconv.c b/iconv/gconv.c
index f3f49b7db3..cd43d3d6fb 100644
--- a/iconv/gconv.c
+++ b/iconv/gconv.c
@@ -1,6 +1,6 @@
 /* Convert characters in input buffer using conversion descriptor to
    output buffer.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997-2001, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,10 +20,13 @@
    02111-1307 USA.  */
 
 #include <assert.h>
-#include <gconv_int.h>
-#include <sys/param.h>
 #include <dlfcn.h>
 #include <stddef.h>
+#include <sys/param.h>
+
+#include <gconv_int.h>
+#include <sysdep.h>
+
 
 int
 internal_function
@@ -45,9 +48,15 @@ __gconv (__gconv_t cd, const unsigned char **inbuf,
   cd->__data[last_step].__outbuf = outbuf != NULL ? *outbuf : NULL;
   cd->__data[last_step].__outbufend = outbufend;
 
+  __gconv_fct fct = cd->__steps->__fct;
+#ifdef PTR_DEMANGLE
+  if (cd->__steps->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
   if (inbuf == NULL || *inbuf == NULL)
     /* We just flush.  */
-    result = DL_CALL_FCT (cd->__steps->__fct,
+    result = DL_CALL_FCT (fct,
 			  (cd->__steps, cd->__data, NULL, NULL, NULL,
 			   irreversible,
 			   cd->__data[last_step].__outbuf == NULL ? 2 : 1, 0));
@@ -60,7 +69,7 @@ __gconv (__gconv_t cd, const unsigned char **inbuf,
       do
 	{
 	  last_start = *inbuf;
-	  result = DL_CALL_FCT (cd->__steps->__fct,
+	  result = DL_CALL_FCT (fct,
 				(cd->__steps, cd->__data, inbuf, inbufend,
 				 NULL, irreversible, 0, 0));
 	}
diff --git a/iconv/gconv_builtin.c b/iconv/gconv_builtin.c
index f653d6c7f3..d8beabd416 100644
--- a/iconv/gconv_builtin.c
+++ b/iconv/gconv_builtin.c
@@ -1,5 +1,5 @@
 /* Table for builtin transformation mapping.
-   Copyright (C) 1997-1999, 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 1997-1999, 2000-2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,6 +20,7 @@
 
 #include <endian.h>
 #include <limits.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <gconv_int.h>
@@ -27,16 +28,16 @@
 #include <assert.h>
 
 
-static struct builtin_map
+static const struct builtin_map
 {
   const char *name;
   __gconv_fct fct;
   __gconv_btowc_fct btowc_fct;
 
-  int min_needed_from;
-  int max_needed_from;
-  int min_needed_to;
-  int max_needed_to;
+  int8_t min_needed_from;
+  int8_t max_needed_from;
+  int8_t min_needed_to;
+  int8_t max_needed_to;
 
 } map[] =
 {
diff --git a/iconv/gconv_builtin.h b/iconv/gconv_builtin.h
index bd34c256dc..ef9ab8d7cf 100644
--- a/iconv/gconv_builtin.h
+++ b/iconv/gconv_builtin.h
@@ -1,5 +1,5 @@
 /* Builtin transformations.
-   Copyright (C) 1997-1999, 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 1997-1999, 2000-2002, 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,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+/* All encoding named must be in upper case.  There must be no extra
+   spaces.  */
+
 BUILTIN_ALIAS ("UCS4//", "ISO-10646/UCS4/")
 BUILTIN_ALIAS ("UCS-4//", "ISO-10646/UCS4/")
 BUILTIN_ALIAS ("UCS-4BE//", "ISO-10646/UCS4/")
diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c
index 9b695c377d..716c384de2 100644
--- a/iconv/gconv_cache.c
+++ b/iconv/gconv_cache.c
@@ -1,5 +1,5 @@
 /* Cache handling for iconv modules.
-   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001.
 
@@ -209,7 +209,18 @@ find_module (const char *directory, const char *filename,
 
       /* Call the init function.  */
       if (result->__init_fct != NULL)
-	status = DL_CALL_FCT (result->__init_fct, (result));
+	{
+	  __gconv_init_fct init_fct = result->__init_fct;
+#ifdef PTR_DEMANGLE
+	  PTR_DEMANGLE (init_fct);
+#endif
+	  status = DL_CALL_FCT (init_fct, (result));
+
+#ifdef PTR_MANGLE
+	  if (result->__btowc_fct != NULL)
+	    PTR_MANGLE (result->__btowc_fct);
+#endif
+	}
     }
 
   return status;
@@ -456,7 +467,7 @@ libc_freeres_fn (free_mem)
   if (cache_malloced)
     free (gconv_cache);
 #ifdef _POSIX_MAPPED_FILES
-  else
+  else if (gconv_cache != NULL)
     __munmap (gconv_cache, cache_size);
 #endif
 }
diff --git a/iconv/gconv_charset.h b/iconv/gconv_charset.h
index 4a3db73118..8882f4319f 100644
--- a/iconv/gconv_charset.h
+++ b/iconv/gconv_charset.h
@@ -1,5 +1,5 @@
 /* Charset name normalization.
-   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001,2002,2003,2004,2005,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001.
 
@@ -29,9 +29,9 @@ strip (char *wp, const char *s)
 
   while (*s != '\0')
     {
-      if (__isalnum_l (*s, &_nl_C_locobj)
-	  || *s == '_' || *s == '-' || *s == '.' || *s == ',')
-	*wp++ = __toupper_l (*s, &_nl_C_locobj);
+      if (__isalnum_l (*s, _nl_C_locobj_ptr)
+	  || *s == '_' || *s == '-' || *s == '.' || *s == ',' || *s == ':')
+	*wp++ = __toupper_l (*s, _nl_C_locobj_ptr);
       else if (*s == '/')
 	{
 	  if (++slash_count == 3)
@@ -52,7 +52,7 @@ static inline char * __attribute__ ((unused, always_inline))
 upstr (char *dst, const char *str)
 {
   char *cp = dst;
-  while ((*cp++ = __toupper_l (*str++, &_nl_C_locobj)) != '\0')
+  while ((*cp++ = __toupper_l (*str++, _nl_C_locobj_ptr)) != '\0')
     /* nothing */;
   return dst;
 }
diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
index 858d40998b..22ffa4f41c 100644
--- a/iconv/gconv_conf.c
+++ b/iconv/gconv_conf.c
@@ -1,5 +1,5 @@
 /* Handle configuration data.
-   Copyright (C) 1997,98,99,2000,2001,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997-2003, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -46,7 +46,7 @@ struct path_elem *__gconv_path_elem;
 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;
+static const struct path_elem empty_path_elem = { NULL, 0 };
 
 /* Name of the file containing the module information in the directories
    along the path.  */
@@ -78,11 +78,11 @@ static struct gconv_module builtin_modules[] =
 #undef BUILTIN_ALIAS
 };
 
-static const char *builtin_aliases[] =
+static const char builtin_aliases[] =
 {
 #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
 			       MinF, MaxF, MinT, MaxT)
-#define BUILTIN_ALIAS(From, To) From " " To,
+#define BUILTIN_ALIAS(From, To) From "\0" To "\0"
 
 #include "gconv_builtin.h"
 
@@ -124,40 +124,16 @@ detect_conflict (const char *alias)
 }
 
 
-/* Add new alias.  */
+/* The actual code to add aliases.  */
 static void
-add_alias (char *rp, void *modules)
+add_alias2 (const char *from, const char *to, const char *wp, void *modules)
 {
-  /* We now expect two more string.  The strings are normalized
-     (converted to UPPER case) and strored in the alias database.  */
-  struct gconv_alias *new_alias;
-  char *from, *to, *wp;
-
-  while (__isspace_l (*rp, &_nl_C_locobj))
-    ++rp;
-  from = wp = rp;
-  while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
-    *wp++ = __toupper_l (*rp++, &_nl_C_locobj);
-  if (*rp == '\0')
-    /* There is no `to' string on the line.  Ignore it.  */
-    return;
-  *wp++ = '\0';
-  to = ++rp;
-  while (__isspace_l (*rp, &_nl_C_locobj))
-    ++rp;
-  while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
-    *wp++ = __toupper_l (*rp++, &_nl_C_locobj);
-  if (to == wp)
-    /* No `to' string, ignore the line.  */
-    return;
-  *wp++ = '\0';
-
   /* Test whether this alias conflicts with any available module.  */
   if (detect_conflict (from))
     /* It does conflict, don't add the alias.  */
     return;
 
-  new_alias = (struct gconv_alias *)
+  struct gconv_alias *new_alias = (struct gconv_alias *)
     malloc (sizeof (struct gconv_alias) + (wp - from));
   if (new_alias != NULL)
     {
@@ -177,6 +153,37 @@ add_alias (char *rp, void *modules)
 }
 
 
+/* Add new alias.  */
+static void
+add_alias (char *rp, void *modules)
+{
+  /* We now expect two more string.  The strings are normalized
+     (converted to UPPER case) and strored in the alias database.  */
+  char *from, *to, *wp;
+
+  while (__isspace_l (*rp, _nl_C_locobj_ptr))
+    ++rp;
+  from = wp = rp;
+  while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
+    *wp++ = __toupper_l (*rp++, _nl_C_locobj_ptr);
+  if (*rp == '\0')
+    /* There is no `to' string on the line.  Ignore it.  */
+    return;
+  *wp++ = '\0';
+  to = ++rp;
+  while (__isspace_l (*rp, _nl_C_locobj_ptr))
+    ++rp;
+  while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
+    *wp++ = __toupper_l (*rp++, _nl_C_locobj_ptr);
+  if (to == wp)
+    /* No `to' string, ignore the line.  */
+    return;
+  *wp++ = '\0';
+
+  add_alias2 (from, to, wp, modules);
+}
+
+
 /* Insert a data structure for a new module in the search tree.  */
 static void
 internal_function
@@ -254,30 +261,30 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
   int need_ext;
   int cost_hi;
 
-  while (__isspace_l (*rp, &_nl_C_locobj))
+  while (__isspace_l (*rp, _nl_C_locobj_ptr))
     ++rp;
   from = rp;
-  while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
+  while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
     {
-      *rp = __toupper_l (*rp, &_nl_C_locobj);
+      *rp = __toupper_l (*rp, _nl_C_locobj_ptr);
       ++rp;
     }
   if (*rp == '\0')
     return;
   *rp++ = '\0';
   to = wp = rp;
-  while (__isspace_l (*rp, &_nl_C_locobj))
+  while (__isspace_l (*rp, _nl_C_locobj_ptr))
     ++rp;
-  while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
-    *wp++ = __toupper_l (*rp++, &_nl_C_locobj);
+  while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
+    *wp++ = __toupper_l (*rp++, _nl_C_locobj_ptr);
   if (*rp == '\0')
     return;
   *wp++ = '\0';
   do
     ++rp;
-  while (__isspace_l (*rp, &_nl_C_locobj));
+  while (__isspace_l (*rp, _nl_C_locobj_ptr));
   module = wp;
-  while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
+  while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
     *wp++ = *rp++;
   if (*rp == '\0')
     {
@@ -392,7 +399,7 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
 	if (rp[n - 1] == '\n')
 	  rp[n - 1] = '\0';
 
-      while (__isspace_l (*rp, &_nl_C_locobj))
+      while (__isspace_l (*rp, _nl_C_locobj_ptr))
 	++rp;
 
       /* If this is an empty line go on with the next one.  */
@@ -400,7 +407,7 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
 	continue;
 
       word = rp;
-      while (*rp != '\0' && !__isspace_l (*rp, &_nl_C_locobj))
+      while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
 	++rp;
 
       if (rp - word == sizeof ("alias") - 1
@@ -588,12 +595,16 @@ __gconv_read_conf (void)
     }
 
   /* Add aliases for builtin conversions.  */
-  cnt = sizeof (builtin_aliases) / sizeof (builtin_aliases[0]);
-  while (cnt > 0)
+  const char *cp = builtin_aliases;
+  do
     {
-      char *copy = strdupa (builtin_aliases[--cnt]);
-      add_alias (copy, modules);
+      const char *from = cp;
+      const char *to = __rawmemchr (from, '\0') + 1;
+      cp = __rawmemchr (to, '\0') + 1;
+
+      add_alias2 (from, to, cp, modules);
     }
+  while (*cp != '\0');
 
   /* Restore the error number.  */
   __set_errno (save_errno);
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;
diff --git a/iconv/gconv_dl.c b/iconv/gconv_dl.c
index 9504017210..8217b7e553 100644
--- a/iconv/gconv_dl.c
+++ b/iconv/gconv_dl.c
@@ -1,5 +1,5 @@
 /* Handle loading/unloading of shared object for transformation.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -29,6 +29,7 @@
 #include <sys/param.h>
 
 #include <gconv_int.h>
+#include <sysdep.h>
 
 
 #ifdef DEBUG
@@ -130,6 +131,14 @@ __gconv_find_shlib (const char *name)
 		  found->init_fct = __libc_dlsym (found->handle, "gconv_init");
 		  found->end_fct = __libc_dlsym (found->handle, "gconv_end");
 
+#ifdef PTR_MANGLE
+		  PTR_MANGLE (found->fct);
+		  if (found->init_fct != NULL)
+		    PTR_MANGLE (found->init_fct);
+		  if (found->end_fct !=  NULL)
+		    PTR_MANGLE (found->end_fct);
+#endif
+
 		  /* We have succeeded in loading the shared object.  */
 		  found->counter = 1;
 		}
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index 36d4ae2d44..8d9cdaefc2 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -22,6 +22,8 @@
 
 #include "gconv.h"
 #include <stdlib.h>		/* For alloca used in macro below.  */
+#include <ctype.h>		/* For __toupper_l used in macro below.  */
+#include <string.h>		/* For strlen et al used in macro below.  */
 #include <bits/libc-lock.h>
 
 __BEGIN_DECLS
@@ -126,7 +128,7 @@ extern struct gconv_module *__gconv_modules_db attribute_hidden;
 extern const char *__gconv_path_envvar attribute_hidden;
 
 /* Lock for the conversion database content.  */
-__libc_lock_define (extern, __gconv_lock);
+__libc_lock_define (extern, __gconv_lock attribute_hidden)
 
 
 /* The gconv functions expects the name to be in upper case and complete,
@@ -146,7 +148,7 @@ __libc_lock_define (extern, __gconv_lock);
     tmp = result = __alloca (cp - (str) + 3 + suffix_len);		      \
     cp = (str);								      \
     while (*cp != '\0')							      \
-      *tmp++ = __toupper_l (*cp++, &_nl_C_locobj);			      \
+      *tmp++ = __toupper_l (*cp++, _nl_C_locobj_ptr);			      \
     if (cnt < 2)							      \
       {									      \
 	*tmp++ = '/';							      \
diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c
index 90da784f78..bbf27b3dc5 100644
--- a/iconv/gconv_open.c
+++ b/iconv/gconv_open.c
@@ -1,5 +1,6 @@
 /* Find matching transformation algorithms and initialize steps.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,1999,2000,2001,2004,2005
+	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -66,11 +67,12 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	  tok = __strtok_r (tok, ",", &ptr);
 	  while (tok != NULL)
 	    {
-	      if (__strcasecmp_l (tok, "TRANSLIT", &_nl_C_locobj) == 0)
+	      if (__strcasecmp_l (tok, "TRANSLIT", _nl_C_locobj_ptr) == 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" };
+		  static const char *const internal_trans_names[1]
+		    = { "INTERNAL" };
 		  struct trans_struct *lastp = NULL;
 		  struct trans_struct *runp;
 
@@ -89,7 +91,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 
 		      /* We leave the `name' field zero to signal that
 			 this is an internal transliteration step.  */
-		      newp->csnames = internal_trans_names;
+		      newp->csnames = (const char **) internal_trans_names;
 		      newp->ncsnames = 1;
 		      newp->trans_fct = __gconv_transliterate;
 
@@ -99,7 +101,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 			lastp->next = newp;
 		    }
 		}
-	      else if (__strcasecmp_l (tok, "IGNORE", &_nl_C_locobj) == 0)
+	      else if (__strcasecmp_l (tok, "IGNORE", _nl_C_locobj_ptr) == 0)
 		/* Set the flag to ignore all errors.  */
 		conv_flags |= __GCONV_IGNORE_ERRORS;
 	      else
@@ -113,7 +115,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 		  for (runp = trans; runp != NULL; runp = runp->next)
 		    if (runp->name != NULL
 			&& __strcasecmp_l (tok, runp->name,
-					   &_nl_C_locobj) == 0)
+					   _nl_C_locobj_ptr) == 0)
 		      break;
 		    else
 		      lastp = runp;
@@ -233,7 +235,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	      for (runp = trans; runp != NULL; runp = runp->next)
 		for (n = 0; n < runp->ncsnames; ++n)
 		  if (__strcasecmp_l (steps[cnt].__from_name,
-				      runp->csnames[n], &_nl_C_locobj) == 0)
+				      runp->csnames[n], _nl_C_locobj_ptr) == 0)
 		    {
 		      void *data = NULL;
 
@@ -279,7 +281,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 		  /* Allocate the buffer.  */
 		  size = (GCONV_NCHAR_GOAL * steps[cnt].__max_needed_to);
 
-		  result->__data[cnt].__outbuf = (char *) malloc (size);
+		  result->__data[cnt].__outbuf = malloc (size);
 		  if (result->__data[cnt].__outbuf == NULL)
 		    {
 		      res = __GCONV_NOMEM;
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index e0d14139ba..343c27521f 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -1,5 +1,5 @@
 /* Simple transformations functions.
-   Copyright (C) 1997-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1997-2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -886,7 +886,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
     else if (__builtin_expect (wc <= 0x7fffffff, 1))			      \
       {									      \
 	size_t step;							      \
-	char *start;							      \
+	unsigned char *start;						      \
 									      \
 	for (step = 2; step < 6; ++step)				      \
 	  if ((wc & (~(uint32_t)0 << (5 * step + 1))) == 0)		      \
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
index e54c18490f..9e04e64ee2 100644
--- a/iconv/gconv_trans.c
+++ b/iconv/gconv_trans.c
@@ -54,6 +54,12 @@ __gconv_transliterate (struct __gconv_step *step,
   winbuf = (const uint32_t *) *inbufp;
   winbufend = (const uint32_t *) inbufend;
 
+  __gconv_fct fct = step->__fct;
+#ifdef PTR_DEMANGLE
+  if (step->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
   /* If there is no transliteration information in the locale don't do
      anything and return the error.  */
   size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
@@ -119,7 +125,7 @@ __gconv_transliterate (struct __gconv_step *step,
 	      /* Try this input text.  */
 	      toinptr = (const unsigned char *) &to_tbl[idx2];
 	      outptr = *outbufstart;
-	      res = DL_CALL_FCT (step->__fct,
+	      res = DL_CALL_FCT (fct,
 				 (step, step_data, &toinptr,
 				  (const unsigned char *) &to_tbl[idx2 + len],
 				  &outptr, NULL, 0, 0));
@@ -204,7 +210,7 @@ __gconv_transliterate (struct __gconv_step *step,
 		? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT);
 
       outptr = *outbufstart;
-      res = DL_CALL_FCT (step->__fct,
+      res = DL_CALL_FCT (fct,
 			 (step, step_data, &toinptr,
 			  (const unsigned char *) (default_missing + len),
 			  &outptr, NULL, 0, 0));
diff --git a/iconv/iconv_charmap.c b/iconv/iconv_charmap.c
index 03a8f5fa23..a54d738120 100644
--- a/iconv/iconv_charmap.c
+++ b/iconv/iconv_charmap.c
@@ -1,22 +1,20 @@
 /* Convert using charmaps and possibly iconv().
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation.
 
-   The GNU C Library is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <assert.h>
 #include <errno.h>
@@ -367,19 +365,27 @@ use_to_charmap (const char *from_code, struct charmap_t *to_charmap)
 	  if (outptr != (char *) outbuf)
 	    {
 	      /* We got some output.  Good, use it.  */
-	      struct charseq *newp;
+	      union
+	      {
+		struct charseq seq;
+		struct
+		{
+		  const char *name;
+		  uint32_t ucs4;
+		  int nbytes;
+		  unsigned char bytes[outlen];
+		} mem;
+	      } new;
 
 	      outlen = sizeof (outbuf) - outlen;
 	      assert ((char *) outbuf + outlen == outptr);
 
-	      newp = (struct charseq *) xmalloc (sizeof (struct charseq)
-						 + outlen);
-	      newp->name = out->name;
-	      newp->ucs4 = out->ucs4;
-	      newp->nbytes = outlen;
-	      memcpy (newp->bytes, outbuf, outlen);
+	      new.mem.name = out->name;
+	      new.mem.ucs4 = out->ucs4;
+	      new.mem.nbytes = outlen;
+	      memcpy (new.mem.bytes, outbuf, outlen);
 
-	      add_bytes (rettbl, newp, out);
+	      add_bytes (rettbl, &new.seq, out);
 	    }
 
 	  /* Clear any possible state left behind.  */
@@ -490,7 +496,7 @@ process_fd (struct convtable *tbl, int fd, FILE *output)
      process it in one step.  */
   static char *inbuf = NULL;
   static size_t maxlen = 0;
-  char *inptr = NULL;
+  char *inptr = inbuf;
   size_t actlen = 0;
 
   while (actlen < maxlen)
diff --git a/iconv/iconv_open.c b/iconv/iconv_open.c
index e0f6135575..fc94fa5fe0 100644
--- a/iconv/iconv_open.c
+++ b/iconv/iconv_open.c
@@ -1,5 +1,5 @@
 /* Get descriptor for character set conversion.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,1999,2000,2001,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -38,7 +38,7 @@ iconv_open (const char *tocode, const char *fromcode)
   int res;
 
   /* Normalize the name.  We remove all characters beside alpha-numeric,
-     '_', '-', '/', and '.'.  */
+     '_', '-', '/', '.', and ':'.  */
   tocode_len = strlen (tocode);
   tocode_conv = (char *) alloca (tocode_len + 3);
   strip (tocode_conv, tocode);
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
index 86852857a3..77829971ad 100644
--- a/iconv/iconv_prog.c
+++ b/iconv/iconv_prog.c
@@ -1,22 +1,20 @@
 /* Convert text in given files from the specified from-set to the to-set.
-   Copyright (C) 1998-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998-2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation.
 
-   The GNU C Library is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <argp.h>
 #include <assert.h>
@@ -185,12 +183,12 @@ main (int argc, char *argv[])
   if (strchr (from_code, '/') != NULL)
     /* The from-name might be a charmap file name.  Try reading the
        file.  */
-    from_charmap = charmap_read (from_code, /*0, 1*/1, 0, 0);
+    from_charmap = charmap_read (from_code, /*0, 1*/1, 0, 0, 0);
 
   if (strchr (orig_to_code, '/') != NULL)
     /* The to-name might be a charmap file name.  Try reading the
        file.  */
-    to_charmap = charmap_read (orig_to_code, /*0, 1,*/1,0, 0);
+    to_charmap = charmap_read (orig_to_code, /*0, 1,*/1, 0, 0, 0);
 
 
   /* Determine output file.  */
@@ -239,26 +237,30 @@ main (int argc, char *argv[])
 	      if (from_wrong)
 		{
 		  if (to_wrong)
-		    error (EXIT_FAILURE, 0,
+		    error (0, 0,
 			   _("\
-conversion from `%s' and to `%s' are not supported"),
+conversions from `%s' and to `%s' are not supported"),
 			   from_pretty, to_pretty);
 		  else
-		    error (EXIT_FAILURE, 0,
+		    error (0, 0,
 			   _("conversion from `%s' is not supported"),
 			   from_pretty);
 		}
 	      else
 		{
 		  if (to_wrong)
-		    error (EXIT_FAILURE, 0,
+		    error (0, 0,
 			   _("conversion to `%s' is not supported"),
 			   to_pretty);
 		  else
-		    error (EXIT_FAILURE, 0,
+		    error (0, 0,
 			   _("conversion from `%s' to `%s' is not supported"),
 			   from_pretty, to_pretty);
 		}
+
+	      argp_help (&argp, stderr, ARGP_HELP_SEE,
+			 program_invocation_short_name);
+	      exit (1);
 	    }
 	  else
 	    error (EXIT_FAILURE, errno,
@@ -424,7 +426,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2006");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
index 74240911a2..59867f9015 100644
--- a/iconv/iconvconfig.c
+++ b/iconv/iconvconfig.c
@@ -1,22 +1,20 @@
 /* Generate fastloading iconv module configuration files.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000-2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation.
 
-   The GNU C Library is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <argp.h>
 #include <assert.h>
@@ -341,7 +339,7 @@ main (int argc, char *argv[])
   if (status == 0)
     status = write_output ();
   else
-    error (1, 0, _("no output file produced because warning were issued"));
+    error (1, 0, _("no output file produced because warnings were issued"));
 
   return status;
 }
@@ -397,7 +395,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2006");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
@@ -985,11 +983,11 @@ next_prime (uint32_t seed)
 
    Offset   Length       Description
    0000     4            Magic header bytes
-   0004     4            Offset of string table (stoff)
-   0008     4            Offset of name hashing table (hoff)
-   000C     4            Hashing table size (hsize)
-   0010     4            Offset of module table (moff)
-   0014     4            Offset of other conversion module table (ooff)
+   0004     2            Offset of string table (stoff)
+   0006     2            Offset of name hashing table (hoff)
+   0008     2            Hashing table size (hsize)
+   000A     2            Offset of module table (moff)
+   000C     2            Offset of other conversion module table (ooff)
 
    stoff    ???          String table
 
@@ -1013,6 +1011,34 @@ next_prime (uint32_t seed)
                               module name offset
                          (following last entry with step count 0)
 */
+
+static struct hash_entry *hash_table;
+static size_t hash_size;
+
+/* Function to insert the names.  */
+static void name_insert (const void *nodep, VISIT value, int level)
+{
+  struct name *name;
+  unsigned int idx;
+  unsigned int hval2;
+
+  if (value != leaf && value != postorder)
+    return;
+
+  name = *(struct name **) nodep;
+  idx = name->hashval % hash_size;
+  hval2 = 1 + name->hashval % (hash_size - 2);
+
+  while (hash_table[idx].string_offset != 0)
+    if ((idx += hval2) >= hash_size)
+      idx -= hash_size;
+
+  hash_table[idx].string_offset = strtaboffset (name->strent);
+
+  assert (name->module_idx != -1);
+  hash_table[idx].module_idx = name->module_idx;
+}
+
 static int
 write_output (void)
 {
@@ -1020,8 +1046,6 @@ write_output (void)
   char *string_table;
   size_t string_table_size;
   struct gconvcache_header header;
-  struct hash_entry *hash_table;
-  size_t hash_size;
   struct module_entry *module_table;
   char *extra_table;
   char *cur_extra_table;
@@ -1034,31 +1058,6 @@ write_output (void)
   char tmpfname[(output_file == NULL ? sizeof finalname : output_file_len + 1)
 		+ strlen (".XXXXXX")];
 
-  /* Function to insert the names.  */
-  auto void
-  name_insert (const void *nodep, VISIT value, int level)
-    {
-      struct name *name;
-      unsigned int idx;
-      unsigned int hval2;
-
-      if (value != leaf && value != postorder)
-	return;
-
-      name = *(struct name **) nodep;
-      idx = name->hashval % hash_size;
-      hval2 = 1 + name->hashval % (hash_size - 2);
-
-      while (hash_table[idx].string_offset != 0)
-	if ((idx += hval2) >= hash_size)
-	  idx -= hash_size;
-
-      hash_table[idx].string_offset = strtaboffset (name->strent);
-
-      assert (name->module_idx != -1);
-      hash_table[idx].module_idx = name->module_idx;
-    }
-
   /* Open the output file.  */
   if (output_file == NULL)
     {
@@ -1178,6 +1177,9 @@ write_output (void)
 	}
     }
 
+  /* Clear padding.  */
+  memset (&header, 0, sizeof (struct gconvcache_header));
+
   header.magic = GCONVCACHE_MAGIC;
 
   iov[0].iov_base = &header;
diff --git a/iconv/loop.c b/iconv/loop.c
index 1918fe5007..9785bf865c 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -1,5 +1,5 @@
 /* Conversion loop frame work.
-   Copyright (C) 1998-2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -450,6 +450,10 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
 #else
       /* We don't have enough input for another complete input
 	 character.  */
+      assert (inend - inptr > (state->__count & ~7));
+      assert (inend - inptr <= 7);
+      state->__count = (state->__count & ~7) | (inend - inptr);
+      inlen = 0;
       while (inptr < inend)
 	state->__value.__wchb[inlen++] = *inptr++;
 #endif
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 579426c7e5..baace6b3fb 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -1,5 +1,5 @@
 /* Skeleton for a conversion module.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -58,13 +58,6 @@
                         of one round through the TO_LOOP.  Defaults
                         to MIN_NEEDED_FROM and MAX_NEEDED_FROM, respectively.
 
-     DEFINE_DIRECTION_OBJECTS
-			two objects will be defined to be used when the
-			`gconv' function must only distinguish two
-			directions.  This is implied by DEFINE_INIT.
-			If this macro is not defined the following
-			macro must be available.
-
      FROM_DIRECTION	this macro is supposed to return a value != 0
 			if we convert from the current character set,
 			otherwise it return 0.
@@ -151,21 +144,22 @@
 # include <dlfcn.h>
 #endif
 
+#include <sysdep.h>
+
 #ifndef DL_CALL_FCT
 # define DL_CALL_FCT(fct, args) fct args
 #endif
 
 /* The direction objects.  */
-#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT
-static int from_object;
-static int to_object;
-
+#if DEFINE_INIT
 # ifndef FROM_DIRECTION
-#  define FROM_DIRECTION (step->__data == &from_object)
+#  define FROM_DIRECTION_VAL NULL
+#  define TO_DIRECTION_VAL ((void *) ~((uintptr_t) 0))
+#  define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL)
 # endif
 #else
 # ifndef FROM_DIRECTION
-#  error "FROM_DIRECTION must be provided if direction objects are not used"
+#  error "FROM_DIRECTION must be provided if non-default init is used"
 # endif
 #endif
 
@@ -329,7 +323,7 @@ gconv_init (struct __gconv_step *step)
   /* Determine which direction.  */
   if (strcmp (step->__from_name, CHARSET_NAME) == 0)
     {
-      step->__data = &from_object;
+      step->__data = FROM_DIRECTION_VAL;
 
       step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM;
       step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM;
@@ -342,7 +336,7 @@ gconv_init (struct __gconv_step *step)
     }
   else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
     {
-      step->__data = &to_object;
+      step->__data = TO_DIRECTION_VAL;
 
       step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM;
       step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM;
@@ -401,10 +395,17 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 {
   struct __gconv_step *next_step = step + 1;
   struct __gconv_step_data *next_data = data + 1;
-  __gconv_fct fct;
+  __gconv_fct fct = NULL;
   int status;
 
-  fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct;
+  if ((data->__flags & __GCONV_IS_LAST) == 0)
+    {
+      fct = next_step->__fct;
+#ifdef PTR_DEMANGLE
+      if (next_step->__shlib_handle != NULL)
+	PTR_DEMANGLE (fct);
+#endif
+    }
 
   /* If the function is called with no input this means we have to reset
      to the initial state.  The possibly partly converted input is
@@ -681,8 +682,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 #ifdef RESET_INPUT_BUFFER
 		      RESET_INPUT_BUFFER;
 #else
-		      /* We have a problem with the in on of the functions
-			 below.  Undo the conversion upto the error point.  */
+		      /* We have a problem in one of the functions below.
+			 Undo the conversion upto the error point.  */
 		      size_t nstatus;
 
 		      /* Reload the pointers.  */
@@ -780,12 +781,11 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 
 	  STORE_REST
 # else
-	  size_t cnt;
-
 	  /* Make sure the remaining bytes fit into the state objects
              buffer.  */
 	  assert (inend - *inptrp < 4);
 
+	  size_t cnt;
 	  for (cnt = 0; *inptrp < inend; ++cnt)
 	    data->__statep->__value.__wchb[cnt] = *(*inptrp)++;
 	  data->__statep->__count &= ~7;
@@ -815,7 +815,6 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 #undef TO_LOOP_MAX_NEEDED_FROM
 #undef TO_LOOP_MIN_NEEDED_TO
 #undef TO_LOOP_MAX_NEEDED_TO
-#undef DEFINE_DIRECTION_OBJECTS
 #undef FROM_DIRECTION
 #undef EMIT_SHIFT_TO_INIT
 #undef FROM_LOOP
diff --git a/iconv/strtab.c b/iconv/strtab.c
index e6feb2cf24..4a8f29a675 100644
--- a/iconv/strtab.c
+++ b/iconv/strtab.c
@@ -1,5 +1,5 @@
 /* C string table handling.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
    This program is free software; you can redistribute it and/or modify
@@ -326,7 +326,7 @@ strtabfinalize (struct Strtab *st, size_t *size)
   copylen = 1;
   copystrings (st->root, &endp, &copylen);
   assert (copylen == st->total + 1);
-  assert (endp = retval + st->total + 1);
+  assert (endp == retval + st->total + 1);
   *size = copylen;
 
   return retval;