about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog69
-rw-r--r--NEWS5
-rw-r--r--iconv/gconv_builtin.c9
-rw-r--r--iconv/gconv_builtin.h36
-rw-r--r--iconv/gconv_cache.c4
-rw-r--r--iconv/gconv_conf.c13
-rw-r--r--iconv/gconv_db.c7
-rw-r--r--iconv/gconv_int.h36
-rw-r--r--iconv/gconv_simple.c17
-rw-r--r--iconv/iconvconfig.c10
-rw-r--r--iconv/loop.c13
-rw-r--r--iconv/skeleton.c28
-rw-r--r--iconvdata/8bit-gap.c15
-rw-r--r--iconvdata/8bit-generic.c9
-rw-r--r--iconvdata/ansi_x3.110.c11
-rw-r--r--iconvdata/armscii-8.c11
-rw-r--r--iconvdata/big5.c9
-rw-r--r--iconvdata/big5hkscs.c9
-rw-r--r--iconvdata/cp1255.c9
-rw-r--r--iconvdata/cp1258.c16
-rw-r--r--iconvdata/euc-cn.c9
-rw-r--r--iconvdata/euc-jisx0213.c7
-rw-r--r--iconvdata/euc-jp.c7
-rw-r--r--iconvdata/euc-kr.c9
-rw-r--r--iconvdata/euc-tw.c7
-rw-r--r--iconvdata/gb18030.c7
-rw-r--r--iconvdata/gbbig5.c4
-rw-r--r--iconvdata/gbk.c9
-rw-r--r--iconvdata/ibm932.c59
-rw-r--r--iconvdata/ibm932.h8
-rw-r--r--iconvdata/ibm943.c60
-rw-r--r--iconvdata/ibm943.h8
-rw-r--r--iconvdata/isiri-3342.c7
-rw-r--r--iconvdata/iso8859-1.c4
-rw-r--r--iconvdata/iso_6937-2.c9
-rw-r--r--iconvdata/iso_6937.c9
-rw-r--r--iconvdata/johab.c7
-rw-r--r--iconvdata/shift_jisx0213.c14
-rw-r--r--iconvdata/sjis.c14
-rw-r--r--iconvdata/t.61.c9
-rw-r--r--iconvdata/tcvn5712-1.c14
-rw-r--r--iconvdata/uhc.c9
-rw-r--r--linuxthreads/ChangeLog6
-rw-r--r--wcsmbs/btowc.c69
-rw-r--r--wcsmbs/wcsmbsload.c5
45 files changed, 543 insertions, 163 deletions
diff --git a/ChangeLog b/ChangeLog
index 05a5faed05..bbdfda3972 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,72 @@
+2002-11-30  Bruno Haible  <bruno@clisp.org>
+
+	* iconv/gconv.h (__gconv_btowc_fct): New typedef.
+	(struct __gconv_step): New field __btowc_fct.
+	* wcsmbs/btowc.c (__btowc): Use the __btowc_fct shortcut if possible.
+	* iconv/gconv_int.h (__BUILTIN_TRANSFORM): Renamed from
+	__BUILTIN_TRANS.
+	(__gconv_btwoc_ascii): New declaration.
+	* iconv/gconv_simple.c (BUILTIN_TRANSFORMATION): Add BtowcFct argument.
+	(__gconv_btwoc_ascii): New function.
+	* iconv/gconv_builtin.h: Add BtowcFct argument to all
+	BUILTIN_TRANSFORMATION invocations.
+	* iconv/gconv_conf.c (BUILTIN_TRANSFORMATION): Add BtowcFct argument.
+	* iconv/iconvconfig.c (BUILTIN_TRANSFORMATION): Likewise.
+	* iconv/gconv_builtin.c (map): New field btowc_fct.
+	(BUILTIN_TRANSFORMATION): Add BtowcFct argument. Use it to initialize
+	btowc_fct field.
+	(__gconv_get_builtin_trans): Initialize __btowc_fct field.
+	* iconv/gconv_cache.c (find_module): Initialize __btowc_fct field.
+	* iconv/gconv_db.c (gen_steps, increment_counter): Likewise.
+	* wcsmbs/wcsmbsload.c (to_wc, to_mb): Likewise.
+	* iconv/skeleton.c: Document STORE_REST and FROM_ONEBYTE.
+	(gconv_init): Initialize __btowc_fct field.
+	Undefine EXTRA_LOOP_ARGS and FROM_ONEBYTE at the end.
+	* iconv/loop.c: Document ONEBYTE_BODY.
+	(gconv_btowc, FROM_ONEBYTE): Define if ONEBYTE_BODY is defined.
+	Undefine ONEBYTE_BODY at the end.
+	* iconvdata/8bit-generic.c (ONEBYTE_BODY): New macro.
+	* iconvdata/8bit-gap.c (NONNUL): New macro.
+	(BODY for FROM_LOOP): Use it.
+	(ONEBYTE_BODY): New macro.
+	* iconvdata/isiri-3342.c (HAS_HOLES): Set to 1.
+	(NONNUL): New macro.
+	* iconvdata/ansi_x3.110.c (ONEBYTE_BODY): New macro.
+	* iconvdata/armscii-8.c (ONEBYTE_BODY): New macro.
+	* iconvdata/cp1255.c (ONEBYTE_BODY): New macro.
+	* iconvdata/cp1258.c (ONEBYTE_BODY): New macro.
+	* iconvdata/tcvn5712-1.c (ONEBYTE_BODY): New macro.
+	* iconvdata/big5.c (ONEBYTE_BODY): New macro.
+	* iconvdata/big5hkscs.c (ONEBYTE_BODY): New macro.
+	* iconvdata/euc-cn.c (ONEBYTE_BODY): New macro.
+	* iconvdata/euc-jp.c (ONEBYTE_BODY): New macro.
+	* iconvdata/euc-jisx0213.c (ONEBYTE_BODY): New macro.
+	* iconvdata/euc-kr.c (ONEBYTE_BODY): New macro.
+	* iconvdata/euc-tw.c (ONEBYTE_BODY): New macro.
+	* iconvdata/gbk.c (ONEBYTE_BODY): New macro.
+	* iconvdata/gb18030.c (ONEBYTE_BODY): New macro.
+	* iconvdata/ibm932.c: Include <stdbool.h>.
+	(TRUE, FALSE): Remove macros.
+	(BODY for FROM_LOOP): Remove unused variable rp1.
+	(ONEBYTE_BODY): New macro.
+	(BODY for TO_LOOP): Use bool.
+	* iconvdata/ibm932.h (__ibm932sb_to_ucs4_idx): Remove array.
+	* iconvdata/ibm943.c: Include <stdbool.h>.
+	(TRUE, FALSE): Remove macros.
+	(BODY for FROM_LOOP): Remove unused variable rp1.
+	(ONEBYTE_BODY): New macro.
+	(BODY for TO_LOOP): Use bool.
+	* iconvdata/ibm943.h (__ibm943sb_to_ucs4_idx): Remove array.
+	* iconvdata/iso8859-1.c (ONEBYTE_BODY): New macro.
+	* iconvdata/iso_6937-2.c (ONEBYTE_BODY): New macro.
+	* iconvdata/iso_6937.c (ONEBYTE_BODY): New macro.
+	* iconvdata/johab.c (ONEBYTE_BODY): New macro.
+	* iconvdata/sjis.c (ONEBYTE_BODY): New macro.
+	* iconvdata/shift_jisx0213.c (ONEBYTE_BODY): New macro.
+	* iconvdata/t.61.c (ONEBYTE_BODY): New macro.
+	* iconvdata/uhc.c (ONEBYTE_BODY): New macro.
+	* iconvdata/gbbig5.c: Tweak comment.
+
 2002-12-02  Ulrich Drepper  <drepper@redhat.com>
 
 	* po/fi.po: Update from translation team.
diff --git a/NEWS b/NEWS
index 249b69fb5d..f310b2c050 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2002-11-5
+GNU C Library NEWS -- history of user-visible changes.  2002-12-2
 Copyright (C) 1992-2001, 2002 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -17,6 +17,9 @@ Version 2.3.2
   This normally expands to lib, but on some 64-bit platforms to lib64 instead.
 
 * fexecve is implemented on Linux.
+
+* the btowc() function should work 2+ times faster due to specialized
+  callbacks in the iconv modules.  Implemented by Bruno Haible.
 
 Version 2.3
 
diff --git a/iconv/gconv_builtin.c b/iconv/gconv_builtin.c
index 45bd4e7e00..f653d6c7f3 100644
--- a/iconv/gconv_builtin.c
+++ b/iconv/gconv_builtin.c
@@ -1,5 +1,5 @@
 /* Table for builtin transformation mapping.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997-1999, 2000-2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -31,6 +31,7 @@ static struct builtin_map
 {
   const char *name;
   __gconv_fct fct;
+  __gconv_btowc_fct btowc_fct;
 
   int min_needed_from;
   int max_needed_from;
@@ -39,11 +40,12 @@ static struct builtin_map
 
 } map[] =
 {
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT) \
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT) \
   {									      \
     .name = Name,							      \
     .fct = Fct,								      \
+    .btowc_fct = BtowcFct,						      \
 									      \
     .min_needed_from = MinF,						      \
     .max_needed_from = MaxF,						      \
@@ -69,6 +71,7 @@ __gconv_get_builtin_trans (const char *name, struct __gconv_step *step)
   assert (cnt < sizeof (map) / sizeof (map[0]));
 
   step->__fct = map[cnt].fct;
+  step->__btowc_fct = map[cnt].btowc_fct;
   step->__init_fct = NULL;
   step->__end_fct = NULL;
   step->__shlib_handle = NULL;
diff --git a/iconv/gconv_builtin.h b/iconv/gconv_builtin.h
index 1a9d8a80f1..bd34c256dc 100644
--- a/iconv/gconv_builtin.h
+++ b/iconv/gconv_builtin.h
@@ -1,5 +1,5 @@
 /* Builtin transformations.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997-1999, 2000-2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -30,14 +30,14 @@ BUILTIN_ALIAS ("OSF00010105//", "ISO-10646/UCS4/") /* level 2 */
 BUILTIN_ALIAS ("OSF00010106//", "ISO-10646/UCS4/") /* level 3 */
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS4/", 1, "=INTERNAL->ucs4",
-			__gconv_transform_internal_ucs4, 4, 4, 4, 4)
+			__gconv_transform_internal_ucs4, NULL, 4, 4, 4, 4)
 BUILTIN_TRANSFORMATION ("ISO-10646/UCS4/", "INTERNAL", 1, "=ucs4->INTERNAL",
-			__gconv_transform_ucs4_internal, 4, 4, 4, 4)
+			__gconv_transform_ucs4_internal, NULL, 4, 4, 4, 4)
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "UCS-4LE//", 1, "=INTERNAL->ucs4le",
-			__gconv_transform_internal_ucs4le, 4, 4, 4, 4)
+			__gconv_transform_internal_ucs4le, NULL, 4, 4, 4, 4)
 BUILTIN_TRANSFORMATION ("UCS-4LE//", "INTERNAL", 1, "=ucs4le->INTERNAL",
-			__gconv_transform_ucs4le_internal, 4, 4, 4, 4)
+			__gconv_transform_ucs4le_internal, NULL, 4, 4, 4, 4)
 
 BUILTIN_ALIAS ("WCHAR_T//", "INTERNAL")
 
@@ -48,10 +48,11 @@ BUILTIN_ALIAS ("OSF05010001//", "ISO-10646/UTF8/")
 BUILTIN_ALIAS ("ISO-10646/UTF-8/", "ISO-10646/UTF8/")
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UTF8/", 1, "=INTERNAL->utf8",
-			__gconv_transform_internal_utf8, 4, 4, 1, 6)
+			__gconv_transform_internal_utf8, NULL, 4, 4, 1, 6)
 
 BUILTIN_TRANSFORMATION ("ISO-10646/UTF8/", "INTERNAL", 1, "=utf8->INTERNAL",
-			__gconv_transform_utf8_internal, 1, 6, 4, 4)
+			__gconv_transform_utf8_internal, __gconv_btwoc_ascii,
+			1, 6, 4, 4)
 
 BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
 BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
@@ -60,10 +61,10 @@ BUILTIN_ALIAS ("OSF00010101//", "ISO-10646/UCS2/") /* level 2 */
 BUILTIN_ALIAS ("OSF00010102//", "ISO-10646/UCS2/") /* level 3 */
 
 BUILTIN_TRANSFORMATION ("ISO-10646/UCS2/", "INTERNAL", 1, "=ucs2->INTERNAL",
-			__gconv_transform_ucs2_internal, 2, 2, 4, 4)
+			__gconv_transform_ucs2_internal, NULL, 2, 2, 4, 4)
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS2/", 1, "=INTERNAL->ucs2",
-			__gconv_transform_internal_ucs2, 4, 4, 2, 2)
+			__gconv_transform_internal_ucs2, NULL, 4, 4, 2, 2)
 
 
 BUILTIN_ALIAS ("ANSI_X3.4//", "ANSI_X3.4-1968//")
@@ -80,10 +81,11 @@ BUILTIN_ALIAS ("CSASCII//", "ANSI_X3.4-1968//")
 BUILTIN_ALIAS ("OSF00010020//", "ANSI_X3.4-1968//")
 
 BUILTIN_TRANSFORMATION ("ANSI_X3.4-1968//", "INTERNAL", 1, "=ascii->INTERNAL",
-			__gconv_transform_ascii_internal, 4, 4, 1, 1)
+			__gconv_transform_ascii_internal, __gconv_btwoc_ascii,
+			4, 4, 1, 1)
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "ANSI_X3.4-1968//", 1, "=INTERNAL->ascii",
-			__gconv_transform_internal_ascii, 4, 4, 1, 1)
+			__gconv_transform_internal_ascii, NULL, 4, 4, 1, 1)
 
 
 #if BYTE_ORDER == BIG_ENDIAN
@@ -94,11 +96,13 @@ BUILTIN_ALIAS ("UCS-2LE//", "UNICODELITTLE//")
 
 BUILTIN_TRANSFORMATION ("UNICODELITTLE//", "INTERNAL", 1,
 			"=ucs2reverse->INTERNAL",
-			__gconv_transform_ucs2reverse_internal, 2, 2, 4, 4)
+			__gconv_transform_ucs2reverse_internal, NULL,
+			2, 2, 4, 4)
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODELITTLE//", 1,
 			"=INTERNAL->ucs2reverse",
-			__gconv_transform_internal_ucs2reverse, 4, 4, 2, 2)
+			__gconv_transform_internal_ucs2reverse, NULL,
+			4, 4, 2, 2)
 #else
 BUILTIN_ALIAS ("UNICODELITTLE//", "ISO-10646/UCS2/")
 BUILTIN_ALIAS ("UCS-2LE//", "ISO-10646/UCS2/")
@@ -107,9 +111,11 @@ BUILTIN_ALIAS ("UCS-2BE//", "UNICODEBIG//")
 
 BUILTIN_TRANSFORMATION ("UNICODEBIG//", "INTERNAL", 1,
 			"=ucs2reverse->INTERNAL",
-			__gconv_transform_ucs2reverse_internal, 2, 2, 4, 4)
+			__gconv_transform_ucs2reverse_internal, NULL,
+			2, 2, 4, 4)
 
 BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODEBIG//", 1,
 			"=INTERNAL->ucs2reverse",
-			__gconv_transform_internal_ucs2reverse, 4, 4, 2, 2)
+			__gconv_transform_internal_ucs2reverse, NULL,
+			4, 4, 2, 2)
 #endif
diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c
index 8f92cbaf67..882acc6fa4 100644
--- a/iconv/gconv_cache.c
+++ b/iconv/gconv_cache.c
@@ -201,7 +201,11 @@ find_module (const char *directory, const char *filename,
       result->__init_fct = result->__shlib_handle->init_fct;
       result->__end_fct = result->__shlib_handle->end_fct;
 
+      /* These settings can be overridden by the init function.  */
+      result->__btowc_fct = NULL;
       result->__data = NULL;
+
+      /* Call the init function.  */
       if (result->__init_fct != NULL)
 	status = DL_CALL_FCT (result->__init_fct, (result));
     }
diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
index cd5055c303..1262e76618 100644
--- a/iconv/gconv_conf.c
+++ b/iconv/gconv_conf.c
@@ -61,8 +61,8 @@ static const char gconv_module_ext[] = MODULE_EXT;
 /* We have a few builtin transformations.  */
 static struct gconv_module builtin_modules[] =
 {
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT) \
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT) \
   {									      \
     from_string: From,							      \
     to_string: To,							      \
@@ -73,18 +73,21 @@ static struct gconv_module builtin_modules[] =
 #define BUILTIN_ALIAS(From, To)
 
 #include "gconv_builtin.h"
-};
 
 #undef BUILTIN_TRANSFORMATION
 #undef BUILTIN_ALIAS
+};
 
 static const char *builtin_aliases[] =
 {
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT)
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT)
 #define BUILTIN_ALIAS(From, To) From " " To,
 
 #include "gconv_builtin.h"
+
+#undef BUILTIN_TRANSFORMATION
+#undef BUILTIN_ALIAS
 };
 
 #ifdef USE_IN_LIBIO
diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
index 70c33df16d..020b556d5e 100644
--- a/iconv/gconv_db.c
+++ b/iconv/gconv_db.c
@@ -268,6 +268,9 @@ gen_steps (struct derivation_step *best, const char *toset,
 	      result[step_cnt].__init_fct = shlib_handle->init_fct;
 	      result[step_cnt].__end_fct = shlib_handle->end_fct;
 
+	      /* These settings can be overridden by the init function.  */
+	      result[step_cnt].__btowc_fct = NULL;
+
 	      /* Call the init function.  */
 	      if (result[step_cnt].__init_fct != NULL)
 		{
@@ -353,8 +356,12 @@ increment_counter (struct __gconv_step *steps, size_t nsteps)
 	      step->__fct = step->__shlib_handle->fct;
 	      step->__init_fct = step->__shlib_handle->init_fct;
 	      step->__end_fct = step->__shlib_handle->end_fct;
+
+	      /* These settings can be overridden by the init function.  */
+	      step->__btowc_fct = NULL;
 	    }
 
+	  /* Call the init function.  */
 	  if (step->__init_fct != NULL)
 	    DL_CALL_FCT (step->__init_fct, (step));
 	}
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index 1ac878d900..dec29d9c14 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -264,7 +264,7 @@ extern int __gconv_transliterate (struct __gconv_step *step,
 
 /* Builtin transformations.  */
 #ifdef _LIBC
-# define __BUILTIN_TRANS(Name) \
+# define __BUILTIN_TRANSFORM(Name) \
   extern int Name (struct __gconv_step *step,				      \
 		   struct __gconv_step_data *data,			      \
 		   const unsigned char **inbuf,				      \
@@ -272,21 +272,25 @@ extern int __gconv_transliterate (struct __gconv_step *step,
 		   unsigned char **outbufstart, size_t *irreversible,	      \
 		   int do_flush, int consume_incomplete)
 
-__BUILTIN_TRANS (__gconv_transform_ascii_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_ascii);
-__BUILTIN_TRANS (__gconv_transform_utf8_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_utf8);
-__BUILTIN_TRANS (__gconv_transform_ucs2_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_ucs2);
-__BUILTIN_TRANS (__gconv_transform_ucs2reverse_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_ucs2reverse);
-__BUILTIN_TRANS (__gconv_transform_internal_ucs4);
-__BUILTIN_TRANS (__gconv_transform_ucs4_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_ucs4le);
-__BUILTIN_TRANS (__gconv_transform_ucs4le_internal);
-__BUILTIN_TRANS (__gconv_transform_internal_utf16);
-__BUILTIN_TRANS (__gconv_transform_utf16_internal);
-# undef __BUITLIN_TRANS
+__BUILTIN_TRANSFORM (__gconv_transform_ascii_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_ascii);
+__BUILTIN_TRANSFORM (__gconv_transform_utf8_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_utf8);
+__BUILTIN_TRANSFORM (__gconv_transform_ucs2_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2);
+__BUILTIN_TRANSFORM (__gconv_transform_ucs2reverse_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2reverse);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4);
+__BUILTIN_TRANSFORM (__gconv_transform_ucs4_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4le);
+__BUILTIN_TRANSFORM (__gconv_transform_ucs4le_internal);
+__BUILTIN_TRANSFORM (__gconv_transform_internal_utf16);
+__BUILTIN_TRANSFORM (__gconv_transform_utf16_internal);
+# undef __BUITLIN_TRANSFORM
+
+/* Specialized conversion function for a single byte to INTERNAL, recognizing
+   only ASCII characters.  */
+extern wint_t __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c);
 
 #endif
 
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index 35346aa498..3937b95c92 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -28,10 +28,11 @@
 #include <string.h>
 #include <wchar.h>
 #include <sys/param.h>
+#include <gconv_int.h>
 
 #define BUILTIN_ALIAS(s1, s2) /* nothing */
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT) \
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT) \
   extern int Fct (struct __gconv_step *, struct __gconv_step_data *,	      \
 		  __const unsigned char **, __const unsigned char *,	      \
 		  unsigned char **, size_t *, int, int);
@@ -43,6 +44,18 @@
 #endif
 
 
+/* Specialized conversion function for a single byte to INTERNAL, recognizing
+   only ASCII characters.  */
+wint_t
+__gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
+{
+  if (c < 0x80)
+    return c;
+  else
+    return WEOF;
+}
+
+
 /* Transform from the internal, UCS4-like format, to UCS4.  The
    difference between the internal ucs4 format and the real UCS4
    format is, if any, the endianess.  The Unicode/ISO 10646 says that
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
index 62e3e4e413..a3c0a4b01f 100644
--- a/iconv/iconvconfig.c
+++ b/iconv/iconvconfig.c
@@ -201,8 +201,8 @@ static struct
   {
 #define BUILTIN_ALIAS(alias, real) \
     { .from = alias, .to = real },
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT)
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT)
 #include <gconv_builtin.h>
   };
 #undef BUILTIN_ALIAS
@@ -218,11 +218,13 @@ static struct
 } builtin_trans[] =
   {
 #define BUILTIN_ALIAS(alias, real)
-#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \
-			       MinT, MaxT) \
+#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
+			       MinF, MaxF, MinT, MaxT) \
     { .from = From, .to = To, .module = Name, .cost = Cost },
 #include <gconv_builtin.h>
   };
+#undef BUILTIN_ALIAS
+#undef BUILTIN_TRANSFORMATION
 #define nbuiltin_trans (sizeof (builtin_trans) / sizeof (builtin_trans[0]))
 
 
diff --git a/iconv/loop.c b/iconv/loop.c
index deb0173930..b0b76f32e8 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -43,6 +43,9 @@
 
      INIT_PARAMS	code to define and initialize variables from params.
      UPDATE_PARAMS	code to store result in params.
+
+     ONEBYTE_BODY	body of the specialized conversion function for a
+			single byte from the current character set to INTERNAL.
 */
 
 #include <assert.h>
@@ -453,6 +456,15 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
 #endif
 
 
+#ifdef ONEBYTE_BODY
+/* Define the shortcut function for btowc.  */
+static wint_t
+gconv_btowc (struct __gconv_step *step, unsigned char c)
+  ONEBYTE_BODY
+# define FROM_ONEBYTE gconv_btowc
+#endif
+
+
 /* We remove the macro definitions so that we can include this file again
    for the definition of another function.  */
 #undef MIN_NEEDED_INPUT
@@ -465,6 +477,7 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
 #undef EXTRA_LOOP_DECLS
 #undef INIT_PARAMS
 #undef UPDATE_PARAMS
+#undef ONEBYTE_BODY
 #undef UNPACK_BYTES
 #undef LOOP_NEED_STATE
 #undef LOOP_NEED_FLAGS
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index edcd92eb87..579426c7e5 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -101,6 +101,26 @@
      EXTRA_LOOP_ARGS	optional macro specifying extra arguments passed
 			to loop function.
 
+     STORE_REST		optional, needed only when MAX_NEEDED_FROM > 4.
+			This macro stores the seen but unconverted input bytes
+			in the state.
+
+     FROM_ONEBYTE	optional.  If defined, should be the name of a
+			specialized conversion function for a single byte
+			from the current character set to INTERNAL.  This
+			function has prototype
+			   wint_t
+			   FROM_ONEBYTE (struct __gconv_step *, unsigned char);
+			and does a special conversion:
+			- The input is a single byte.
+			- The output is a single uint32_t.
+			- The state before the conversion is the initial state;
+			  the state after the conversion is irrelevant.
+			- No transliteration.
+			- __invocation_counter = 0.
+			- __internal_use = 1.
+			- do_flush = 0.
+
    Modules can use mbstate_t to store conversion state as follows:
 
    * Bits 2..0 of '__count' contain the number of lookahead input bytes
@@ -315,6 +335,10 @@ gconv_init (struct __gconv_step *step)
       step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM;
       step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO;
       step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO;
+
+#ifdef FROM_ONEBYTE
+      step->__btowc_fct = FROM_ONEBYTE;
+#endif
     }
   else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
     {
@@ -796,10 +820,12 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 #undef EMIT_SHIFT_TO_INIT
 #undef FROM_LOOP
 #undef TO_LOOP
+#undef ONE_DIRECTION
 #undef SAVE_RESET_STATE
 #undef RESET_INPUT_BUFFER
 #undef FUNCTION_NAME
 #undef PREPARE_LOOP
 #undef END_LOOP
-#undef ONE_DIRECTION
+#undef EXTRA_LOOP_ARGS
 #undef STORE_REST
+#undef FROM_ONEBYTE
diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c
index 2ddc49eb64..9d48d170ba 100644
--- a/iconvdata/8bit-gap.c
+++ b/iconvdata/8bit-gap.c
@@ -32,6 +32,10 @@ struct gap
 /* Now we can include the tables.  */
 #include TABLES
 
+#ifndef NONNUL
+# define NONNUL(c)	((c) != '\0')
+#endif
+
 
 #define FROM_LOOP		from_gap
 #define TO_LOOP			to_gap
@@ -49,7 +53,7 @@ struct gap
   {									      \
     uint32_t ch = to_ucs4[*inptr];					      \
 									      \
-    if (HAS_HOLES && __builtin_expect (ch, L'\1') == L'\0' && *inptr != '\0') \
+    if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && NONNUL (*inptr))    \
       {									      \
 	/* This is an illegal character.  */				      \
 	STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
@@ -63,6 +67,15 @@ struct gap
     ++inptr;								      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+									      \
+    if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && NONNUL (c))	      \
+      return WEOF;							      \
+    else								      \
+      return ch;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c
index 6ed5532693..373289f84d 100644
--- a/iconvdata/8bit-generic.c
+++ b/iconvdata/8bit-generic.c
@@ -47,6 +47,15 @@
     ++inptr;								      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+									      \
+    if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && c != '\0')	      \
+      return WEOF;							      \
+    else								      \
+      return ch;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c
index 08746cf5f7..b20e12a79c 100644
--- a/iconvdata/ansi_x3.110.c
+++ b/iconvdata/ansi_x3.110.c
@@ -404,7 +404,7 @@ static const char from_ucs4[][2] =
 									      \
     if (__builtin_expect (ch >= 0xc1, 0) && ch <= 0xcf)			      \
       {									      \
-	/* Composed character.  First test whether the next character	      \
+	/* Composed character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	uint32_t ch2;							      \
 									      \
@@ -449,6 +449,15 @@ static const char from_ucs4[][2] =
     inptr += incr;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+									      \
+    if (__builtin_expect (ch == 0, 0) && c != '\0')			      \
+      return WEOF;							      \
+    else								      \
+      return ch;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/armscii-8.c b/iconvdata/armscii-8.c
index b3db9a99a8..dbaf8be2ee 100644
--- a/iconvdata/armscii-8.c
+++ b/iconvdata/armscii-8.c
@@ -71,6 +71,17 @@ static const uint16_t map_from_armscii_8[0xfe - 0xa2 + 1] =
     ++inptr;								      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0xa0)							      \
+      /* Upto and including 0xa0 the ARMSCII-8 corresponds to Unicode.  */    \
+      return c;								      \
+    else if (c >= 0xa2 && c <= 0xfe)					      \
+      /* Use the table.  */						      \
+      return map_from_armscii_8[c - 0xa2];				      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/big5.c b/iconvdata/big5.c
index 22c3ab6ddd..cdf8a76c5d 100644
--- a/iconvdata/big5.c
+++ b/iconvdata/big5.c
@@ -8397,7 +8397,7 @@ static const char from_ucs4_tab15[][2] =
 									      \
     if (ch >= 0xa1 && ch <= 0xf9)					      \
       {									      \
-	/* Two-byte character.  First test whether the next character	      \
+	/* Two-byte character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	uint32_t ch2;							      \
 	int idx;							      \
@@ -8447,6 +8447,13 @@ static const char from_ucs4_tab15[][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c
index 0903968669..b1aedd171b 100644
--- a/iconvdata/big5hkscs.c
+++ b/iconvdata/big5hkscs.c
@@ -16817,7 +16817,7 @@ static struct
 									      \
     if (ch >= 0x81 && ch <= 0xfe)					      \
       {									      \
-	/* Two-byte character.  First test whether the next character	      \
+	/* Two-byte character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	uint32_t ch2;							      \
 	int idx;							      \
@@ -16852,6 +16852,13 @@ static struct
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/cp1255.c b/iconvdata/cp1255.c
index 19edb27a66..6cccf526e6 100644
--- a/iconvdata/cp1255.c
+++ b/iconvdata/cp1255.c
@@ -321,6 +321,15 @@ static const struct { unsigned int idx; unsigned int len; } comp_table[8] = {
   }
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS	, int *statep
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    uint32_t ch = to_ucs4[c - 0x80];					      \
+    if (ch == L'\0' || (ch >= 0x05d0 && ch <= 0x05f2))			      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/cp1258.c b/iconvdata/cp1258.c
index 853ef63531..553d50b443 100644
--- a/iconvdata/cp1258.c
+++ b/iconvdata/cp1258.c
@@ -480,6 +480,22 @@ static const struct
   }
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS	, int *statep
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch;							      \
+									      \
+    if (c < 0x80)							      \
+      ch = c;								      \
+    else								      \
+      {									      \
+	ch = to_ucs4[c - 0x80];						      \
+	if (ch == L'\0')						      \
+	  return WEOF;							      \
+      }									      \
+    if (ch >= 0x0041 && ch <= 0x01b0)					      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c
index c1bcadb35b..f912317876 100644
--- a/iconvdata/euc-cn.c
+++ b/iconvdata/euc-cn.c
@@ -54,7 +54,7 @@
       else								      \
 	{								      \
 	  /* Two or more byte character.  First test whether the	      \
-	     next character is also available.  */			      \
+	     next byte is also available.  */				      \
 	  const unsigned char *endp;					      \
 									      \
 	  if (__builtin_expect (inptr + 1 >= inend, 0))			      \
@@ -88,6 +88,13 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/euc-jisx0213.c b/iconvdata/euc-jisx0213.c
index 733cbc15ee..dc6ccfd0cc 100644
--- a/iconvdata/euc-jisx0213.c
+++ b/iconvdata/euc-jisx0213.c
@@ -230,6 +230,13 @@
   }
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS	, int *statep
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c
index 7faa080322..9cb6a47040 100644
--- a/iconvdata/euc-jp.c
+++ b/iconvdata/euc-jp.c
@@ -117,6 +117,13 @@
     put32 (outptr, ch);							      \
     outptr += 4;							      \
   }
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x8e || (c >= 0x90 && c <= 0x9f))				      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #define LOOP_NEED_FLAGS
 #include <iconv/loop.c>
 
diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c
index 37ed71fd60..7774720bd6 100644
--- a/iconvdata/euc-kr.c
+++ b/iconvdata/euc-kr.c
@@ -90,7 +90,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
       }									      \
     else								      \
       {									      \
-	/* Two-byte character.  First test whether the next character	      \
+	/* Two-byte character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	ch = ksc5601_to_ucs4 (&inptr, inend - inptr, 0x80);		      \
 	if (__builtin_expect (ch == 0, 0))				      \
@@ -108,6 +108,13 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x9f)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c
index 8d3b1aa1b5..6674dad397 100644
--- a/iconvdata/euc-tw.c
+++ b/iconvdata/euc-tw.c
@@ -112,6 +112,13 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/gb18030.c b/iconvdata/gb18030.c
index f6b3576416..31f3c20939 100644
--- a/iconvdata/gb18030.c
+++ b/iconvdata/gb18030.c
@@ -25772,6 +25772,13 @@ static const unsigned char __ucs_to_gb18030_tab2[8192][2] =
     *((uint32_t *) outptr)++ = ch;					      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/gbbig5.c b/iconvdata/gbbig5.c
index 695ffb2c07..b2b4743e24 100644
--- a/iconvdata/gbbig5.c
+++ b/iconvdata/gbbig5.c
@@ -4802,7 +4802,7 @@ const char __from_big5_to_gb2312 [13973][2] =
     else if (ch >= 0xa1 && ch <= 0xf7)					      \
       {									      \
 	/* Two-byte character.  First test whether the		      	      \
-	   next character is also available.  */			      \
+	   next byte is also available.  */				      \
 	const char *cp;							      \
 	int idx;							      \
 									      \
@@ -4891,7 +4891,7 @@ const char __from_big5_to_gb2312 [13973][2] =
     else if (ch >= 0xa1 && ch <= 0xf9)					      \
       {									      \
 	/* Two byte character.  First test whether the			      \
-	   next character is also available.  */			      \
+	   next byte is also available.  */				      \
 	const char *cp;							      \
 	int idx;							      \
 									      \
diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c
index a738a9eb9d..ad8a37412a 100644
--- a/iconvdata/gbk.c
+++ b/iconvdata/gbk.c
@@ -13154,7 +13154,7 @@ static const char __gbk_from_ucs4_tab12[][2] =
       else								      \
 	{								      \
 	  /* Two or more byte character.  First test whether the	      \
-	     next character is also available.  */			      \
+	     next byte is also available.  */				      \
 	  uint32_t ch2;							      \
 	  int idx;							      \
 									      \
@@ -13195,6 +13195,13 @@ static const char __gbk_from_ucs4_tab12[][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/ibm932.c b/iconvdata/ibm932.c
index 1e87067fef..420b19ab80 100644
--- a/iconvdata/ibm932.c
+++ b/iconvdata/ibm932.c
@@ -20,13 +20,9 @@
 
 #include <dlfcn.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include "ibm932.h"
 
-#ifndef TRUE
-#define TRUE  1
-#define FALSE 0
-#endif
-
 #define FROM	0
 #define TO	1
 
@@ -50,38 +46,24 @@
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   {									      \
-    const struct gap *rp1 = __ibm932sb_to_ucs4_idx;			      \
     const struct gap *rp2 = __ibm932db_to_ucs4_idx;			      \
     uint32_t ch = *inptr;						      \
     uint32_t res;							      \
 									      \
-    if (__builtin_expect (ch >= 0xffff, 0))				      \
-      {									      \
-	rp1 = NULL;							      \
-	rp2 = NULL;							      \
-      }									      \
-    else if (__builtin_expect (ch, 0) == 0x80				      \
-	     || __builtin_expect (ch, 0) == 0xa0			      \
-	     || __builtin_expect (ch, 0) == 0xfd			      \
-	     || __builtin_expect (ch, 0) == 0xfe			      \
-	     || __builtin_expect (ch, 0) == 0xff)			      \
+    if (__builtin_expect (ch == 0x80, 0)				      \
+	|| __builtin_expect (ch == 0xa0, 0)				      \
+	|| __builtin_expect (ch == 0xfd, 0)				      \
+	|| __builtin_expect (ch == 0xfe, 0)				      \
+	|| __builtin_expect (ch == 0xff, 0))				      \
       {									      \
 	/* This is an illegal character.  */				      \
 	STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
       }									      \
-    else								      \
-      {									      \
-	while (ch > rp1->end)						      \
-	  ++rp1;							      \
-      }									      \
 									      \
     /* Use the IBM932 table for single byte.  */			      \
-    if (__builtin_expect (rp1 == NULL, 0)				      \
-	|| __builtin_expect (ch < rp1->start, 0)			      \
-	|| (res = __ibm932sb_to_ucs4[ch + rp1->idx],			      \
-	__builtin_expect (res, '\1') == 0 && ch != 0))			      \
+    res = __ibm932sb_to_ucs4[ch];					      \
+    if (__builtin_expect (res == 0, 0) && ch != 0)			      \
       {									      \
-									      \
 	/* Use the IBM932 table for double byte.  */			      \
 	if (__builtin_expect (inptr + 1 >= inend, 0))			      \
 	  {								      \
@@ -128,6 +110,25 @@
       }									      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c == 0x80 || c == 0xa0 || c >= 0xfd)				      \
+      return WEOF;							      \
+    uint32_t res = __ibm932sb_to_ucs4[c];				      \
+    if (res == 0 && c != 0)						      \
+      return WEOF;							      \
+    if (res == 0x1c)							      \
+      res = 0x1a;							      \
+    else if (res == 0x7f)						      \
+      res = 0x1c;							      \
+    else if (res == 0xa5)						      \
+      res = 0x5c;							      \
+    else if (res == 0x203e)						      \
+      res = 0x7e;							      \
+    else if (res == 0x1a)						      \
+      res = 0x7f;							      \
+    return res;								      \
+  }
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
@@ -140,7 +141,7 @@
     const struct gap *rp = __ucs4_to_ibm932sb_idx;			      \
     unsigned char sc;							      \
     uint32_t ch = get32 (inptr);					      \
-    uint16_t found = TRUE;						      \
+    bool found = true;							      \
     uint32_t i;								      \
     uint32_t low;							      \
     uint32_t high;							      \
@@ -163,7 +164,7 @@
       {									      \
 									      \
 	/* Use the UCS4 table for double byte.  */			      \
-	found = FALSE;							      \
+	found = false;							      \
 	low = 0;							      \
 	high = (sizeof (__ucs4_to_ibm932db) >> 1)			      \
 		/ sizeof (__ucs4_to_ibm932db[0][FROM]);			      \
@@ -178,7 +179,7 @@
 	    else 							      \
 	      {								      \
 		pccode = __ucs4_to_ibm932db[i][TO];			      \
-		found = TRUE;						      \
+		found = true;						      \
 		break;							      \
 	      }								      \
 	  }								      \
diff --git a/iconvdata/ibm932.h b/iconvdata/ibm932.h
index 500beb80e6..464d4edcb7 100644
--- a/iconvdata/ibm932.h
+++ b/iconvdata/ibm932.h
@@ -1,5 +1,5 @@
 /* Tables for conversion from and to IBM932.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@jp.ibm.com>, 2000.
 
@@ -31,12 +31,6 @@ struct gap
   int32_t idx;
 };
 
-static const struct gap __ibm932sb_to_ucs4_idx[] =
-{
-  { start: 0x0000, end: 0x00ff, idx:     0 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
 static const uint16_t __ibm932sb_to_ucs4[] =
 {
   0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
diff --git a/iconvdata/ibm943.c b/iconvdata/ibm943.c
index 818f6823c5..bf387bbc3e 100644
--- a/iconvdata/ibm943.c
+++ b/iconvdata/ibm943.c
@@ -20,13 +20,9 @@
 
 #include <dlfcn.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include "ibm943.h"
 
-#ifndef TRUE
-#define TRUE  1
-#define FALSE 0
-#endif
-
 #define FROM	0
 #define TO	1
 
@@ -50,38 +46,25 @@
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   {									      \
-    const struct gap *rp1 = __ibm943sb_to_ucs4_idx;			      \
     const struct gap *rp2 = __ibm943db_to_ucs4_idx;			      \
     uint32_t ch = *inptr;						      \
     uint32_t res;							      \
 									      \
-    if (__builtin_expect (ch >= 0xffff, 0))				      \
-      {									      \
-	rp1 = NULL;							      \
-	rp2 = NULL;							      \
-      }									      \
-    else if (__builtin_expect (ch, 0) == 0x80				      \
-	     || __builtin_expect (ch, 0) == 0xa0			      \
-	     || __builtin_expect (ch, 0) == 0xfd			      \
-	     || __builtin_expect (ch, 0) == 0xfe			      \
-	     || __builtin_expect (ch, 0) == 0xff)			      \
+    if (__builtin_expect (ch == 0x80, 0)				      \
+	|| __builtin_expect (ch == 0xa0, 0)				      \
+	|| __builtin_expect (ch == 0xfd, 0)				      \
+	|| __builtin_expect (ch == 0xfe, 0)				      \
+	|| __builtin_expect (ch == 0xff, 0))				      \
       {									      \
 	/* This is an illegal character.  */				      \
 	STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
       }									      \
-    else								      \
-      {									      \
-	while (ch > rp1->end)						      \
-	  ++rp1;							      \
-      }									      \
 									      \
     /* Use the IBM943 table for single byte.  */			      \
-    if (__builtin_expect (rp1 == NULL, 0)				      \
-	|| __builtin_expect (ch < rp1->start, 0)			      \
-	|| (res = __ibm943sb_to_ucs4[ch + rp1->idx],			      \
-	__builtin_expect (res, '\1') == 0 && ch != 0))			      \
+    if (__builtin_expect (ch > 0xdf, 0)					      \
+	|| (res = __ibm943sb_to_ucs4[ch],				      \
+	    __builtin_expect (res == 0, 0) && ch != 0))			      \
       {									      \
-									      \
 	/* Use the IBM943 table for double byte.  */			      \
 	if (__builtin_expect (inptr + 1 >= inend, 0))			      \
 	  {								      \
@@ -128,6 +111,25 @@
       }									      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c == 0x80 || c == 0xa0 || c >= 0xe0)				      \
+      return WEOF;							      \
+    uint32_t res = __ibm943sb_to_ucs4[c];				      \
+    if (res == 0 && c != 0)						      \
+      return WEOF;							      \
+    if (res == 0x1c)							      \
+      res = 0x1a;							      \
+    else if (res == 0x7f)						      \
+      res = 0x1c;							      \
+    else if (res == 0xa5)						      \
+      res = 0x5c;							      \
+    else if (res == 0x203e)						      \
+      res = 0x7e;							      \
+    else if (res == 0x1a)						      \
+      res = 0x7f;							      \
+    return res;								      \
+  }
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
@@ -140,7 +142,7 @@
     const struct gap *rp = __ucs4_to_ibm943sb_idx;			      \
     unsigned char sc;							      \
     uint32_t ch = get32(inptr);						      \
-    uint16_t found = TRUE;						      \
+    bool found = true;							      \
     uint32_t i;								      \
     uint32_t low;							      \
     uint32_t high;							      \
@@ -163,7 +165,7 @@
       {									      \
 									      \
 	/* Use the UCS4 table for double byte.  */			      \
-	found = FALSE;							      \
+	found = false;							      \
 	low = 0;							      \
 	high = (sizeof (__ucs4_to_ibm943db) >> 1)			      \
 		/ sizeof (__ucs4_to_ibm943db[0][FROM]);			      \
@@ -178,7 +180,7 @@
 	    else 							      \
 	      {								      \
 		pccode = __ucs4_to_ibm943db[i][TO];			      \
-		found = TRUE;						      \
+		found = true;						      \
 		break;							      \
 	      }								      \
 	  }								      \
diff --git a/iconvdata/ibm943.h b/iconvdata/ibm943.h
index 09a3c8d905..b523672dcb 100644
--- a/iconvdata/ibm943.h
+++ b/iconvdata/ibm943.h
@@ -1,5 +1,5 @@
 /* Tables for conversion from and to IBM943.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@jp.ibm.com>, 2000.
 
@@ -31,12 +31,6 @@ struct gap
   int32_t idx;
 };
 
-static const struct gap __ibm943sb_to_ucs4_idx[] =
-{
-  { start: 0x0000, end: 0x00df, idx:     0 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
 static const uint16_t __ibm943sb_to_ucs4[] =
 {
   0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
diff --git a/iconvdata/isiri-3342.c b/iconvdata/isiri-3342.c
index 8b72863cce..6cc5abb458 100644
--- a/iconvdata/isiri-3342.c
+++ b/iconvdata/isiri-3342.c
@@ -1,5 +1,5 @@
 /* Conversion from and to ISIRI-3342.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
 
@@ -24,6 +24,9 @@
 #define TABLES <isiri-3342.h>
 
 #define CHARSET_NAME	"ISIRI-3342//"
-#define HAS_HOLES	(*inptr > 0x80)	/* 0x80 really maps to 0x0000.  */
+#define HAS_HOLES	1
+
+/* 0x80 really maps to 0x0000.  */
+#define NONNUL(c)	((c) != '\0' && (c) != 0x80)
 
 #include <8bit-gap.c>
diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c
index dc394007b8..60ab29d56f 100644
--- a/iconvdata/iso8859-1.c
+++ b/iconvdata/iso8859-1.c
@@ -36,6 +36,10 @@
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   *((uint32_t *) outptr)++ = *inptr++;
+#define ONEBYTE_BODY \
+  {									      \
+    return c;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c
index a2b174ee65..b6bf2c0696 100644
--- a/iconvdata/iso_6937-2.c
+++ b/iconvdata/iso_6937-2.c
@@ -402,7 +402,7 @@ static const char from_ucs4[][2] =
 									      \
     if (__builtin_expect (ch >= 0xc1, 0) && ch <= 0xcf)			      \
       {									      \
-	/* Composed character.  First test whether the next character	      \
+	/* Composed character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	int ch2;							      \
 									      \
@@ -449,6 +449,13 @@ static const char from_ucs4[][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+    if (ch == 0 && c != '\0')						      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c
index b800a4f860..16263ed033 100644
--- a/iconvdata/iso_6937.c
+++ b/iconvdata/iso_6937.c
@@ -394,7 +394,7 @@ static const char from_ucs4[][2] =
 									      \
     if (__builtin_expect (ch >= 0xc1, 0) && ch <= 0xcf)			      \
       {									      \
-	/* Composed character.  First test whether the next character	      \
+	/* Composed character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	int ch2;							      \
 									      \
@@ -441,6 +441,13 @@ static const char from_ucs4[][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+    if (ch == 0 && c != '\0')						      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/johab.c b/iconvdata/johab.c
index a83483e66e..6d6f92235c 100644
--- a/iconvdata/johab.c
+++ b/iconvdata/johab.c
@@ -276,6 +276,13 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x7f)							      \
+      return (c == 0x5c ? 0x20a9 : c);					      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/shift_jisx0213.c b/iconvdata/shift_jisx0213.c
index 119e0017b9..82592ad5dc 100644
--- a/iconvdata/shift_jisx0213.c
+++ b/iconvdata/shift_jisx0213.c
@@ -232,6 +232,20 @@
   }
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS	, int *statep
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      {									      \
+	if (c == 0x5c)							      \
+	  return 0xa5;							      \
+	if (c == 0x7e)							      \
+	  return 0x203e;						      \
+	return c;							      \
+      }									      \
+    if (c >= 0xa1 && c <= 0xdf)						      \
+      return 0xfec0 + c;						      \
+    return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c
index 285f24fdaf..4561779d44 100644
--- a/iconvdata/sjis.c
+++ b/iconvdata/sjis.c
@@ -4409,6 +4409,20 @@ static const char from_ucs4_extra[0x100][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      {									      \
+	if (c == 0x5c)							      \
+	  return 0xa5;							      \
+	if (c == 0x7e)							      \
+	  return 0x203e;						      \
+	return c;							      \
+      }									      \
+    if (c >= 0xa1 && c <= 0xdf)						      \
+      return 0xfec0 + c;						      \
+    return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c
index 5227802b22..1e84fe9226 100644
--- a/iconvdata/t.61.c
+++ b/iconvdata/t.61.c
@@ -387,7 +387,7 @@ static const char from_ucs4[][2] =
 									      \
     if (__builtin_expect (ch >= 0xc1, 0) && ch <= 0xcf)			      \
       {									      \
-	/* Composed character.  First test whether the next character	      \
+	/* Composed character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	uint32_t ch2;							      \
 									      \
@@ -427,6 +427,13 @@ static const char from_ucs4[][2] =
     inptr += increment;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch = to_ucs4[c];						      \
+    if (ch == 0 && c != '\0')						      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/tcvn5712-1.c b/iconvdata/tcvn5712-1.c
index 7cd6f0161e..8194ef030d 100644
--- a/iconvdata/tcvn5712-1.c
+++ b/iconvdata/tcvn5712-1.c
@@ -474,6 +474,20 @@ static const struct
     ++inptr;								      \
   }
 #define EXTRA_LOOP_DECLS	, int *statep
+#define ONEBYTE_BODY \
+  {									      \
+    uint32_t ch;							      \
+									      \
+    if (c < 0x18)							      \
+      ch = map_from_tcvn_low[c];					      \
+    else if (c >= 0x80)							      \
+      ch = map_from_tcvn_high[c - 0x80];				      \
+    else								      \
+      ch = c;								      \
+    if (ch >= 0x0041 && ch <= 0x01b0)					      \
+      return WEOF;							      \
+    return ch;								      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c
index 87247689c9..5d25b863ee 100644
--- a/iconvdata/uhc.c
+++ b/iconvdata/uhc.c
@@ -3073,7 +3073,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
       }									      \
     else								      \
       {									      \
-	/* Two-byte character.  First test whether the next character	      \
+	/* Two-byte character.  First test whether the next byte	      \
 	   is also available.  */					      \
 	uint32_t ch2;							      \
 									      \
@@ -3147,6 +3147,13 @@ static const char uhc_hangul_from_ucs[11172][2] =
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 62dea84e98..53ef5c6694 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,9 @@
+2002-11-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Define macros which
+	require it to 200112L.  Remove _POSIX_POLL and _POSIX_SELECT.
+	* sysdeps/unix/sysv/linux/i386/bits/posix_opt.h: Likewise.
+
 2002-11-19  Ulrich Drepper  <drepper@redhat.com>
 
 	* Versions (libc:GLIBC_2.0): Remove names of functions which are
diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c
index ca75e281e6..1ba0221403 100644
--- a/wcsmbs/btowc.c
+++ b/wcsmbs/btowc.c
@@ -30,12 +30,6 @@ wint_t
 __btowc (c)
      int c;
 {
-  wchar_t result;
-  struct __gconv_step_data data;
-  unsigned char inbuf[1];
-  const unsigned char *inptr = inbuf;
-  size_t dummy;
-  int status;
   const struct gconv_fcts *fcts;
 
   /* If the parameter does not fit into one byte or it is the EOF value
@@ -43,32 +37,51 @@ __btowc (c)
   if (c < SCHAR_MIN || c > UCHAR_MAX || c == EOF)
     return WEOF;
 
-  /* Tell where we want the result.  */
-  data.__outbuf = (unsigned char *) &result;
-  data.__outbufend = data.__outbuf + sizeof (wchar_t);
-  data.__invocation_counter = 0;
-  data.__internal_use = 1;
-  data.__flags = __GCONV_IS_LAST;
-  data.__statep = &data.__state;
-  data.__trans = NULL;
-
-  /* Make sure we start in the initial state.  */
-  memset (&data.__state, '\0', sizeof (mbstate_t));
-
   /* Get the conversion functions.  */
   fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
 
-  /* Create the input string.  */
-  inbuf[0] = c;
+  if (__builtin_expect (fcts->towc_nsteps == 1, 1)
+      && __builtin_expect (fcts->towc->__btowc_fct != NULL, 1))
+    {
+      /* Use the shortcut function.  */
+      return DL_CALL_FCT (fcts->towc->__btowc_fct,
+			  (fcts->towc, (unsigned char) c));
+    }
+  else
+    {
+      /* Fall back to the slow but generic method.  */
+      wchar_t result;
+      struct __gconv_step_data data;
+      unsigned char inbuf[1];
+      const unsigned char *inptr = inbuf;
+      size_t dummy;
+      int status;
+
+      /* Tell where we want the result.  */
+      data.__outbuf = (unsigned char *) &result;
+      data.__outbufend = data.__outbuf + sizeof (wchar_t);
+      data.__invocation_counter = 0;
+      data.__internal_use = 1;
+      data.__flags = __GCONV_IS_LAST;
+      data.__statep = &data.__state;
+      data.__trans = NULL;
+
+      /* Make sure we start in the initial state.  */
+      memset (&data.__state, '\0', sizeof (mbstate_t));
+
+      /* Create the input string.  */
+      inbuf[0] = c;
+
+      status = DL_CALL_FCT (fcts->towc->__fct,
+			    (fcts->towc, &data, &inptr, inptr + 1,
+			     NULL, &dummy, 0, 1));
 
-  status = DL_CALL_FCT (fcts->towc->__fct,
-			(fcts->towc, &data, &inptr, inptr + 1,
-			 NULL, &dummy, 0, 1));
-  /* The conversion failed.  */
-  if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT
-      && status != __GCONV_EMPTY_INPUT)
-    result = WEOF;
+      if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT
+	  && status != __GCONV_EMPTY_INPUT)
+	/* The conversion failed.  */
+	result = WEOF;
 
-  return result;
+      return result;
+    }
 }
 weak_alias (__btowc, btowc)
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index bf23d25cac..2fea6c38b3 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -37,6 +37,7 @@ static struct __gconv_step to_wc =
   .__from_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
   .__to_name = (char *) "INTERNAL",
   .__fct = __gconv_transform_ascii_internal,
+  .__btowc_fct = __gconv_btwoc_ascii,
   .__init_fct = NULL,
   .__end_fct = NULL,
   .__min_needed_from = 1,
@@ -55,6 +56,7 @@ static struct __gconv_step to_mb =
   .__from_name = (char *) "INTERNAL",
   .__to_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
   .__fct = __gconv_transform_internal_ascii,
+  .__btowc_fct = NULL,
   .__init_fct = NULL,
   .__end_fct = NULL,
   .__min_needed_from = 4,
@@ -225,7 +227,8 @@ __wcsmbs_clone_conv (struct gconv_fcts *copy)
   /* Copy the data.  */
   *copy = *orig;
 
-  /* Now increment the usage counters.  */
+  /* Now increment the usage counters.
+     Note: This assumes copy->towc_nsteps == 1 and copy->tomb_nsteps == 1.  */
   if (copy->towc->__shlib_handle != NULL)
     ++copy->towc->__counter;
   if (copy->tomb->__shlib_handle != NULL)