about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--iconv/gconv_int.h11
-rw-r--r--iconv/gconv_open.c25
-rw-r--r--iconvdata/8bit-gap.c6
-rw-r--r--iconvdata/8bit-generic.c2
-rw-r--r--iconvdata/ansi_x3.110.c6
-rw-r--r--iconvdata/big5.c2
-rw-r--r--iconvdata/big5hkscs.c2
-rw-r--r--iconvdata/euc-cn.c2
-rw-r--r--iconvdata/euc-jp.c2
-rw-r--r--iconvdata/euc-kr.c2
-rw-r--r--iconvdata/euc-tw.c2
-rw-r--r--iconvdata/gbgbk.c2
-rw-r--r--iconvdata/gbk.c2
-rw-r--r--iconvdata/iso-2022-cn.c2
-rw-r--r--iconvdata/iso-2022-jp.c4
-rw-r--r--iconvdata/iso-2022-kr.c2
-rw-r--r--iconvdata/iso646.c2
-rw-r--r--iconvdata/iso8859-1.c2
-rw-r--r--iconvdata/iso_6937-2.c4
-rw-r--r--iconvdata/iso_6937.c4
-rw-r--r--iconvdata/johab.c4
-rw-r--r--iconvdata/sjis.c4
-rw-r--r--iconvdata/t.61.c4
-rw-r--r--iconvdata/uhc.c4
-rw-r--r--iconvdata/unicode.c2
-rw-r--r--iconvdata/utf-16.c4
-rw-r--r--intl/loadmsgcat.c5
-rw-r--r--locale/C-address.c4
-rw-r--r--locale/C-collate.c2
-rw-r--r--locale/C-ctype.c2
-rw-r--r--locale/C-identification.c4
-rw-r--r--locale/C-measurement.c4
-rw-r--r--locale/C-messages.c4
-rw-r--r--locale/C-monetary.c2
-rw-r--r--locale/C-name.c4
-rw-r--r--locale/C-numeric.c2
-rw-r--r--locale/C-paper.c4
-rw-r--r--locale/C-telephone.c4
-rw-r--r--locale/C-time.c4
-rw-r--r--locale/findlocale.c5
-rw-r--r--locale/loadlocale.c5
-rw-r--r--locale/localeinfo.h9
-rw-r--r--locale/setlocale.c5
-rw-r--r--wcsmbs/wcsmbsload.c12
45 files changed, 161 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 72e3748674..fd3bb20c20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2000-06-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* iconv/gconv_int.h (norm_add_slashes): Optionally add given suffix.
+	* iconv/gconv_open.c: Remove error handling specification from `from'
+	character set name.
+	* intl/loadmsgcat.c (_nl_load_domain): Call norm_add_slashes with
+	new parameter to always enable transliteration.
+	* locale/localeinfo.h (LIMAGIC): Bump number because of incompatible
+	change.
+	(struct locale_data): Add new members use_translit and options.
+	* locale/findlocale.c (_nl_find_locale): Set use_translit flag is
+	character set name contained modifier TRANSLIT.
+	* locale/loadlocale.c (_nl_load_locale): Initialize new use_translit
+	and options fields.
+	(_nl_unload_locale): Free options string if necessary.
+	* wcsmbs/wcsmbsload.c (__wcsmbs_load_conv): Enable translation if
+	the locale names suggested this.
+	* locale/C-address.c: Add two new initialilzers to adjust data
+	structure for new format.
+	* locale/C-collate.c: Likewise.
+	* locale/C-ctype.c: Likewise.
+	* locale/C-identification.c: Likewise.
+	* locale/C-measurement.c: Likewise.
+	* locale/C-messages.c: Likewise.
+	* locale/C-monetary.c: Likewise.
+	* locale/C-name.c: Likewise.
+	* locale/C-numeric.c: Likewise.
+	* locale/C-paper.c: Likewise.
+	* locale/C-telephone.c: Likewise.
+	* locale/C-time.c: Likewise.
+
+	* locale/setlocale.c: Add some more __builtin_expect.
+
 2000-06-15  Ulrich Drepper  <drepper@redhat.com>
 
 	* iconv/gconv.h (__gconv_fct): Change type of fifth parameter to
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index 34dff7d522..5bdf7143e6 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -102,18 +102,19 @@ extern struct gconv_module *__gconv_modules_db;
 
 /* The gconv functions expects the name to be in upper case and complete,
    including the trailing slashes if necessary.  */
-#define norm_add_slashes(str) \
+#define norm_add_slashes(str,suffix) \
   ({									      \
     const char *cp = (str);						      \
     char *result;							      \
     char *tmp;								      \
     size_t cnt = 0;							      \
+    size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);		      \
 									      \
     while (*cp != '\0')							      \
       if (*cp++ == '/')							      \
 	++cnt;								      \
 									      \
-    tmp = result = alloca (cp - (str) + 3);				      \
+    tmp = result = alloca (cp - (str) + 3 + suffix_len);		      \
     cp = (str);								      \
     while (*cp != '\0')							      \
       *tmp++ = _toupper (*cp++);					      \
@@ -121,7 +122,11 @@ extern struct gconv_module *__gconv_modules_db;
       {									      \
 	*tmp++ = '/';							      \
 	if (cnt < 1)							      \
-	  *tmp++ = '/';							      \
+	  {								      \
+	    *tmp++ = '/';						      \
+	    if (suffix != NULL)						      \
+	      tmp = __mempcpy (tmp, suffix, suffix_len);		      \
+	  }								      \
       }									      \
     *tmp = '\0';							      \
     result;								      \
diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c
index 14f1d5e0f9..d2963fa8ee 100644
--- a/iconv/gconv_open.c
+++ b/iconv/gconv_open.c
@@ -37,6 +37,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
   int res;
   int conv_flags = 0;
   const char *errhand;
+  const char *ignore;
 
   /* Find out whether any error handling method is specified.  */
   errhand = strchr (toset, '/');
@@ -44,7 +45,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
     errhand = strchr (errhand + 1, '/');
   if (__builtin_expect (errhand != NULL, 1))
     {
-      if (errhand[1] == '\0')
+      if (*++errhand == '\0')
 	errhand = NULL;
       else
 	{
@@ -56,7 +57,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 
 	  flags = __GCONV_IGNORE_ERRORS;
 
-	  if (strcasecmp (errhand, "IGNORE") == 0)
+	  if (__strcasecmp (errhand, "IGNORE") == 0)
 	    {
 	      /* Found it.  This means we should ignore conversion errors.  */
 	      flags = __GCONV_IGNORE_ERRORS;
@@ -65,6 +66,18 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	}
     }
 
+  /* For the source character set we ignore the error handler specification.
+     XXX Is this really always the best?  */
+  ignore = strchr (fromset, '/');
+  if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL
+      && *++ignore != '\0')
+    {
+      char *newfromset = (char *) alloca (ignore - fromset + 1);
+
+      newfromset[ignore - fromset] = '\0';
+      fromset = memcpy (newfromset, fromset, ignore - fromset);
+    }
+
   res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
   if (res == __GCONV_OK)
     {
@@ -78,7 +91,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
       if (errhand != NULL)
 	{
 	  /* Find the appropriate transliteration handling.  */
-	  if (strcasecmp (errhand, "TRANSLIT") == 0)
+	  if (__strcasecmp (errhand, "TRANSLIT") == 0)
 	    {
 	      /* It's the builtin transliteration handling.  We only
                  suport for it working on the internal encoding.  */
@@ -89,7 +102,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	      trans_fct = __gconv_transliterate;
 	      /* No context, init, or end function.  */
 	    }
-	  else if (strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0)
+	  else if (__strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0)
 	    {
 	      trans_init_fct = (__gconv_trans_init_fct) 1;
 	    }
@@ -151,7 +164,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	      /* Now see whether we can use the transliteration module
 		 for this step.  */
 	      for (n = 0; n < ncsnames; ++n)
-		if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
+		if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
 		  {
 		    /* Match!  Now try the initializer.  */
 		    if (trans_init_fct == NULL
@@ -182,7 +195,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	  /* Now see whether we can use the transliteration module
 	     for this step.  */
 	  for (n = 0; n < ncsnames; ++n)
-	    if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
+	    if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
 	      {
 		/* Match!  Now try the initializer.  */
 		if (trans_init_fct == NULL
diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c
index 6394065c56..a4a32d3eae 100644
--- a/iconvdata/8bit-gap.c
+++ b/iconvdata/8bit-gap.c
@@ -89,7 +89,7 @@ struct gap
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
@@ -112,7 +112,7 @@ struct gap
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
@@ -137,7 +137,7 @@ struct gap
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c
index 1478c5be59..02d972e21c 100644
--- a/iconvdata/8bit-generic.c
+++ b/iconvdata/8bit-generic.c
@@ -72,7 +72,7 @@
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c
index f338055f39..6ec09c3c5c 100644
--- a/iconvdata/ansi_x3.110.c
+++ b/iconvdata/ansi_x3.110.c
@@ -501,7 +501,7 @@ static const char from_ucs4[][2] =
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
@@ -559,7 +559,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -587,7 +587,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
diff --git a/iconvdata/big5.c b/iconvdata/big5.c
index 8cad304c7a..947a92a341 100644
--- a/iconvdata/big5.c
+++ b/iconvdata/big5.c
@@ -8589,7 +8589,7 @@ static const char from_ucs4_tab13[][2] =
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c
index 0859dd8f09..64923d42af 100644
--- a/iconvdata/big5hkscs.c
+++ b/iconvdata/big5hkscs.c
@@ -12746,7 +12746,7 @@ static const char from_ucs4_tab14[][2] =
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c
index 075970ce96..18e73fda6c 100644
--- a/iconvdata/euc-cn.c
+++ b/iconvdata/euc-cn.c
@@ -145,7 +145,7 @@
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c
index 771dc069e8..3e21d55f12 100644
--- a/iconvdata/euc-jp.c
+++ b/iconvdata/euc-jp.c
@@ -222,7 +222,7 @@
 		      {							      \
 			result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
 					      (step, step_data, *inptrp,      \
-					       &inptr, inend, &outbuf,	      \
+					       &inptr, inend, &outptr,	      \
 					       irreversible));		      \
 			if (result != __GCONV_OK)			      \
 			  break;					      \
diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c
index e953df5dc9..c32b9b3537 100644
--- a/iconvdata/euc-kr.c
+++ b/iconvdata/euc-kr.c
@@ -150,7 +150,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c
index f3152478e2..b4cf21ba97 100644
--- a/iconvdata/euc-tw.c
+++ b/iconvdata/euc-tw.c
@@ -197,7 +197,7 @@
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
diff --git a/iconvdata/gbgbk.c b/iconvdata/gbgbk.c
index 15e72d9cfb..0afcd72311 100644
--- a/iconvdata/gbgbk.c
+++ b/iconvdata/gbgbk.c
@@ -106,7 +106,7 @@
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c
index 669e4a9c9f..4505b65c1a 100644
--- a/iconvdata/gbk.c
+++ b/iconvdata/gbk.c
@@ -13456,7 +13456,7 @@ static const char __gbk_from_ucs4_tab12[][2] =
 	    {								      \
 	      result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				    (step, step_data, *inptrp, &inptr, inend, \
-				     &outbuf, irreversible));		      \
+				     &outptr, irreversible));		      \
 	      if (result != __GCONV_OK)					      \
 		break;							      \
 	    }								      \
diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c
index 818f2a773c..f2170698dd 100644
--- a/iconvdata/iso-2022-cn.c
+++ b/iconvdata/iso-2022-cn.c
@@ -328,7 +328,7 @@ enum
 		      {							      \
 			result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
 					      (step, step_data, *inptrp,      \
-					       &inptr, inend, &outbuf,	      \
+					       &inptr, inend, &outptr,	      \
 					       irreversible));		      \
 			if (result != __GCONV_OK)			      \
 			  break;					      \
diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c
index b66c9503b5..ab42bcc75c 100644
--- a/iconvdata/iso-2022-jp.c
+++ b/iconvdata/iso-2022-jp.c
@@ -707,7 +707,7 @@ gconv_end (struct __gconv_step *data)
 		      {							      \
 			result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
 					      (step, step_data, *inptrp,      \
-					       &inptr, inend, &outbuf,	      \
+					       &inptr, inend, &outptr,	      \
 					       irreversible));		      \
 			if (result != __GCONV_OK)			      \
 			  break;					      \
@@ -894,7 +894,7 @@ gconv_end (struct __gconv_step *data)
 					    result = DL_CALL_FCT	      \
   					      (step_data->__trans.__trans_fct,\
 					       (step, step_data, *inptrp,     \
-						&inptr, inend, &outbuf,	      \
+						&inptr, inend, &outptr,	      \
 						irreversible));		      \
 					    if (result != __GCONV_OK)	      \
 					      break;			      \
diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c
index d3cca52d05..52031ca177 100644
--- a/iconvdata/iso-2022-kr.c
+++ b/iconvdata/iso-2022-kr.c
@@ -259,7 +259,7 @@ enum
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
index df81ee2be6..66f89589cc 100644
--- a/iconvdata/iso646.c
+++ b/iconvdata/iso646.c
@@ -889,7 +889,7 @@ gconv_end (struct __gconv_step *data)
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c
index d69a201fed..a6134816db 100644
--- a/iconvdata/iso8859-1.c
+++ b/iconvdata/iso8859-1.c
@@ -53,7 +53,7 @@
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c
index 536d8965fa..cde210844d 100644
--- a/iconvdata/iso_6937-2.c
+++ b/iconvdata/iso_6937-2.c
@@ -569,7 +569,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -594,7 +594,7 @@ static const char from_ucs4[][2] =
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c
index f812ce2c93..e767291adf 100644
--- a/iconvdata/iso_6937.c
+++ b/iconvdata/iso_6937.c
@@ -546,7 +546,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -571,7 +571,7 @@ static const char from_ucs4[][2] =
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/johab.c b/iconvdata/johab.c
index ac3bf82b27..d2947dcd89 100644
--- a/iconvdata/johab.c
+++ b/iconvdata/johab.c
@@ -400,7 +400,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
- 					   inend, &outbuf, irreversible));    \
+ 					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
@@ -445,7 +445,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c
index 806579b283..aa51259355 100644
--- a/iconvdata/sjis.c
+++ b/iconvdata/sjis.c
@@ -4472,7 +4472,7 @@ static const char from_ucs4_extra[0x100][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -4500,7 +4500,7 @@ static const char from_ucs4_extra[0x100][2] =
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c
index a7d42277c9..3c1a69e4ab 100644
--- a/iconvdata/t.61.c
+++ b/iconvdata/t.61.c
@@ -473,7 +473,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
- 				       inend, &outbuf, irreversible));	      \
+ 				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -510,7 +510,7 @@ static const char from_ucs4[][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c
index 9c494ff705..5526e9b5ba 100644
--- a/iconvdata/uhc.c
+++ b/iconvdata/uhc.c
@@ -3225,7 +3225,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
@@ -3265,7 +3265,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
 	      {								      \
 		result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				      (step, step_data, *inptrp, &inptr,      \
-				       inend, &outbuf, irreversible));	      \
+				       inend, &outptr, irreversible));	      \
 		if (result != __GCONV_OK)				      \
 		  break;						      \
 	      }								      \
diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c
index e818c54c31..9caa95df0f 100644
--- a/iconvdata/unicode.c
+++ b/iconvdata/unicode.c
@@ -156,7 +156,7 @@ gconv_end (struct __gconv_step *data)
 	  {								      \
 	    result = DL_CALL_FCT (step_data->__trans.__trans_fct,	      \
 				  (step, step_data, *inptrp, &inptr, inend,   \
-				   &outbuf, irreversible));		      \
+				   &outptr, irreversible));		      \
 	    if (result != __GCONV_OK)					      \
 	      break;							      \
 	  }								      \
diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c
index 44911feb42..fd7bba72bf 100644
--- a/iconvdata/utf-16.c
+++ b/iconvdata/utf-16.c
@@ -206,7 +206,7 @@ gconv_end (struct __gconv_step *data)
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
@@ -249,7 +249,7 @@ gconv_end (struct __gconv_step *data)
 		  {							      \
 		    result = DL_CALL_FCT (step_data->__trans.__trans_fct,     \
 					  (step, step_data, *inptrp, &inptr,  \
-					   inend, &outbuf, irreversible));    \
+					   inend, &outptr, irreversible));    \
 		    if (result != __GCONV_OK)				      \
 		      break;						      \
 		  }							      \
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 4009525fe8..398d7518d9 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -315,8 +315,9 @@ _nl_load_domain (domain_file)
 	    }
 
 # ifdef _LIBC
-	  outcharset = norm_add_slashes (outcharset);
-	  charset = norm_add_slashes (charset);
+	  /* We always want to use transliteration.  */
+	  outcharset = norm_add_slashes (outcharset, "TRANSLIT");
+	  charset = norm_add_slashes (charset, NULL);
 	  if (__gconv_open (outcharset, charset, &domain->conv,
 			    GCONV_AVOID_NOCONV)
 	      != __GCONV_OK)
diff --git a/locale/C-address.c b/locale/C-address.c
index 8b37639d89..75a51d276b 100644
--- a/locale/C-address.c
+++ b/locale/C-address.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_ADDRESS =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   12,
   {
     { string: "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" },
diff --git a/locale/C-collate.c b/locale/C-collate.c
index 0ad0efe271..f8d1430755 100644
--- a/locale/C-collate.c
+++ b/locale/C-collate.c
@@ -97,6 +97,8 @@ const struct locale_data _nl_C_LC_COLLATE =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   18,
   {
     { word: 0 },
diff --git a/locale/C-ctype.c b/locale/C-ctype.c
index 8c85d6ec8b..4ab3f0171e 100644
--- a/locale/C-ctype.c
+++ b/locale/C-ctype.c
@@ -343,6 +343,8 @@ const struct locale_data _nl_C_LC_CTYPE =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   62,
   {
     { string: _nl_C_LC_CTYPE_class },
diff --git a/locale/C-identification.c b/locale/C-identification.c
index 10d9ae9b8d..89ebf3149e 100644
--- a/locale/C-identification.c
+++ b/locale/C-identification.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_IDENTIFICATION =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   15,
   {
     { string: "ISO/IEC 14652 i18n FDCC-set" },
diff --git a/locale/C-measurement.c b/locale/C-measurement.c
index 37db30d939..92de2a9eb5 100644
--- a/locale/C-measurement.c
+++ b/locale/C-measurement.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_MEASUREMENT =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   1,
   {
     { string: "\1" }
diff --git a/locale/C-messages.c b/locale/C-messages.c
index 0363020476..3f96bb0f2f 100644
--- a/locale/C-messages.c
+++ b/locale/C-messages.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_MESSAGES =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   4,
   {
     { string: "^[yY]" },
diff --git a/locale/C-monetary.c b/locale/C-monetary.c
index 96a1e52f25..39d061da55 100644
--- a/locale/C-monetary.c
+++ b/locale/C-monetary.c
@@ -33,6 +33,8 @@ const struct locale_data _nl_C_LC_MONETARY =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   45,
   {
     { string: "" },
diff --git a/locale/C-name.c b/locale/C-name.c
index 4b31370a8c..fdce4cb3cc 100644
--- a/locale/C-name.c
+++ b/locale/C-name.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_NAME =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   6,
   {
     { string: "%p%t%g%t%m%t%f" },
diff --git a/locale/C-numeric.c b/locale/C-numeric.c
index fc2e104304..65fc2734ba 100644
--- a/locale/C-numeric.c
+++ b/locale/C-numeric.c
@@ -32,6 +32,8 @@ const struct locale_data _nl_C_LC_NUMERIC =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   5,
   {
     { string: "." },
diff --git a/locale/C-paper.c b/locale/C-paper.c
index fa3e8557d7..19f847c22f 100644
--- a/locale/C-paper.c
+++ b/locale/C-paper.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_PAPER =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   2,
   {
     { word: 297 },
diff --git a/locale/C-telephone.c b/locale/C-telephone.c
index 9647ac0da4..adf407db2c 100644
--- a/locale/C-telephone.c
+++ b/locale/C-telephone.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -29,6 +29,8 @@ const struct locale_data _nl_C_LC_TELEPHONE =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   4,
   {
     { string: "+%c %a %l" },
diff --git a/locale/C-time.c b/locale/C-time.c
index 9be32c06b3..18bd645ed0 100644
--- a/locale/C-time.c
+++ b/locale/C-time.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
 
@@ -28,6 +28,8 @@ const struct locale_data _nl_C_LC_TIME =
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
   UNDELETABLE,
+  0,
+  NULL,
   62,
   {
     { string: "Sun" },
diff --git a/locale/findlocale.c b/locale/findlocale.c
index f0c911d29f..7567744432 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -181,6 +181,11 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
     }
   *name = (char *) ((struct locale_data *) locale_file->data)->name;
 
+  /* Determine whether the user wants transliteration or not.  */
+  if ((modifier != NULL && __strcasecmp (modifier, "TRANSLIT") == 0)
+      || (special != NULL && __strcasecmp (special, "TRANSLIT") == 0))
+    ((struct locale_data *) locale_file->data)->use_translit = 1;
+
   /* Increment the usage count.  */
   if (((struct locale_data *) locale_file->data)->usage_count
       < MAX_USAGE_COUNT)
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
index cc454abae4..36ce5f4076 100644
--- a/locale/loadlocale.c
+++ b/locale/loadlocale.c
@@ -202,6 +202,8 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
   newdata->filesize = st.st_size;
   newdata->mmaped = mmaped;
   newdata->usage_count = 0;
+  newdata->use_translit = 0;
+  newdata->options = NULL;
   newdata->nstrings = filedata->nstrings;
   for (cnt = 0; cnt < newdata->nstrings; ++cnt)
     {
@@ -232,5 +234,8 @@ _nl_unload_locale (struct locale_data *locale)
 #endif
     free ((void *) locale->filedata);
 
+  if (locale->options != NULL)
+    free (locale->options);
+
   free (locale);
 }
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index ced96ac4a9..b5dfcd92d8 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -1,5 +1,5 @@
 /* Declarations for internal libc locale interfaces
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -33,7 +33,7 @@
 #include <intl/loadinfo.h>	/* For loaded_l10nfile definition.  */
 
 /* Magic number at the beginning of a locale data file for CATEGORY.  */
-#define	LIMAGIC(category)	(0x980505 ^ (category))
+#define	LIMAGIC(category)	(0x20000616 ^ (category))
 
 /* Two special weight constants for the collation data.  */
 #define IGNORE_CHAR	2
@@ -53,6 +53,11 @@ struct locale_data
 
   unsigned int usage_count;	/* Counter for users.  */
 
+  int use_translit;		/* Nonzero if the mb*towv*() and wc*tomb()
+				   functions should use transliteration.  */
+  const char *options;		/* Extra options from the locale name,
+				   not used in the path to the locale data.  */
+
   unsigned int nstrings;	/* Number of strings below.  */
   union locale_data_value
   {
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 0bf9eeef7b..03456fba71 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -220,7 +220,8 @@ setlocale (int category, const char *locale)
   char *composite;
 
   /* Sanity check for CATEGORY argument.  */
-  if (category < 0 || category >= __LC_LAST)
+  if (__builtin_expect (category, 0) < 0
+      || __builtin_expect (category, 0) >= __LC_LAST)
     ERROR_RETURN;
 
   /* Does user want name of current locale?  */
@@ -261,7 +262,7 @@ setlocale (int category, const char *locale)
 	if (category != LC_ALL)
 	  newnames[category] = (char *) locale;
 
-      if (strchr (locale, ';') != NULL)
+      if (__builtin_expect (strchr (locale, ';') != NULL, 0))
 	{
 	  /* This is a composite name.  Make a copy and split it up.  */
 	  char *np = strdupa (locale);
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index 55d19ff0cf..b152b3541c 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -146,7 +146,7 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
 
   /* We should repeat the test since while we waited some other thread
      might have run this function.  */
-  if (__wcsmbs_last_locale != new_category)
+  if (__builtin_expect (__wcsmbs_last_locale != new_category, 1))
     {
       if (new_category->name == _nl_C_name)	/* Yes, pointer comparison.  */
 	{
@@ -161,6 +161,7 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
 	  const char *complete_name;
 	  struct __gconv_step *new_towc;
 	  struct __gconv_step *new_tomb;
+	  int use_translit;
 
 	  /* Free the old conversions.  */
 	  __gconv_close_transform (__wcsmbs_gconv_fcts.tomb, 1);
@@ -169,10 +170,17 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
 	  /* Get name of charset of the locale.  */
 	  charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
 
+	  /* Does the user want transliteration?  */
+	  use_translit = new_category->use_translit;
+
 	  /* Normalize the name and add the slashes necessary for a
              complete lookup.  */
-	  complete_name = norm_add_slashes (charset_name);
+	  complete_name = norm_add_slashes (charset_name,
+					    use_translit ? "TRANSLIT" : NULL);
 
+	  /* It is not necessary to use transliteration in this direction
+	     since the internal character set is supposed to be able to
+	     represent all others.  */
 	  new_towc = getfct ("INTERNAL", complete_name);
 	  if (new_towc != NULL)
 	    new_tomb = getfct (complete_name, "INTERNAL");