This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

btowc() speedup


Hi Ulrich,

Here is a patch that speeds up btowc() by more than a factor of 2. The
timings are:

                        time            time
locale                  before          after

de_DE.UTF-8             0.48            0.21
de_DE.ISO-8859-1        0.43            0.21
ru_RU.KOI8-R            0.48            0.25
zh_CN.GBK               0.54            0.21

All times are given for a single btowc() call in microseconds, averaged
across more than 10 million calls.

The optimization is possible because btowc() calls the conversion function
with very specific arguments (initial state, no flushing, no transliteration,
no alignment problems) and because the big conversion loop's BODY is overkill
for this situation.

A new macro ONEBYTE_BODY is added to those conversion modules that are used
for locales. It is only ca. 5 lines long, compared to the big BODY macro.
This macro is optional - without this macro, the btowc() function falls back
to the generic, slower method.

In passing this patch also makes some trivial improvements to some converters:
  - Clean up a hack in isiri-3342.c.
  - Remove some unused/dead code from two IBM converters.
  - Comment fix: don't confuse "byte" and "character".
  - Rename macro __BUILTIN_TRANS to __BUILTIN_TRANSFORM, because 'trans'
    means 'transliteration' is most other places.


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.

--- glibc-20021126/iconv/gconv.h.bak	2001-08-21 18:49:14.000000000 +0200
+++ glibc-20021126/iconv/gconv.h	2002-11-30 14:52:04.000000000 +0100
@@ -1,4 +1,4 @@
-/* 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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -71,6 +71,9 @@
 			    __const unsigned char **, __const unsigned char *,
 			    unsigned char **, size_t *, int, int);
 
+/* Type of a specialized conversion function for a single byte to INTERNAL.  */
+typedef wint_t (*__gconv_btowc_fct) (struct __gconv_step *, unsigned char);
+
 /* Constructor and destructor for local data for conversion step.  */
 typedef int (*__gconv_init_fct) (struct __gconv_step *);
 typedef void (*__gconv_end_fct) (struct __gconv_step *);
@@ -120,6 +123,7 @@
   char *__to_name;
 
   __gconv_fct __fct;
+  __gconv_btowc_fct __btowc_fct;
   __gconv_init_fct __init_fct;
   __gconv_end_fct __end_fct;
 
--- glibc-20021126/wcsmbs/btowc.c.bak	2002-09-04 21:07:36.000000000 +0200
+++ glibc-20021126/wcsmbs/btowc.c	2002-11-30 15:00:14.000000000 +0100
@@ -30,12 +30,6 @@
 __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 @@
   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;
-
-  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 (__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));
+
+      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)
--- glibc-20021126/iconv/gconv_int.h.bak	2002-09-04 21:07:20.000000000 +0200
+++ glibc-20021126/iconv/gconv_int.h	2002-11-30 18:56:46.000000000 +0100
@@ -264,7 +264,7 @@
 
 /* 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 @@
 		   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
 
--- glibc-20021126/iconv/gconv_simple.c.bak	2002-11-22 14:22:16.000000000 +0100
+++ glibc-20021126/iconv/gconv_simple.c	2002-11-30 19:46:00.000000000 +0100
@@ -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
--- glibc-20021126/iconv/gconv_builtin.h.bak	2001-07-27 18:47:13.000000000 +0200
+++ glibc-20021126/iconv/gconv_builtin.h	2002-11-30 13:23:47.000000000 +0100
@@ -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 ("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 ("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 ("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 ("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_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_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
--- glibc-20021126/iconv/gconv_conf.c.bak	2002-11-04 13:25:24.000000000 +0100
+++ glibc-20021126/iconv/gconv_conf.c	2002-11-30 13:29:45.000000000 +0100
@@ -61,8 +61,8 @@
 /* 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 @@
 #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
--- glibc-20021126/iconv/iconvconfig.c.bak	2002-08-26 15:49:36.000000000 +0200
+++ glibc-20021126/iconv/iconvconfig.c	2002-11-30 13:27:53.000000000 +0100
@@ -201,8 +201,8 @@
   {
 #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 @@
 } 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]))
 
 
--- glibc-20021126/iconv/gconv_builtin.c.bak	2001-07-27 18:47:13.000000000 +0200
+++ glibc-20021126/iconv/gconv_builtin.c	2002-11-30 13:33:58.000000000 +0100
@@ -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 @@
 {
   const char *name;
   __gconv_fct fct;
+  __gconv_btowc_fct btowc_fct;
 
   int min_needed_from;
   int max_needed_from;
@@ -39,11 +40,12 @@
 
 } 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 @@
   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;
--- glibc-20021126/iconv/gconv_cache.c.bak	2002-11-04 13:25:24.000000000 +0100
+++ glibc-20021126/iconv/gconv_cache.c	2002-11-30 14:38:04.000000000 +0100
@@ -201,7 +201,11 @@
       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));
     }
--- glibc-20021126/iconv/gconv_db.c.bak	2002-11-04 13:25:24.000000000 +0100
+++ glibc-20021126/iconv/gconv_db.c	2002-11-30 14:40:43.000000000 +0100
@@ -268,6 +268,9 @@
 	      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 @@
 	      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));
 	}
--- glibc-20021126/wcsmbs/wcsmbsload.c.bak	2002-09-06 16:30:11.000000000 +0200
+++ glibc-20021126/wcsmbs/wcsmbsload.c	2002-11-30 15:05:41.000000000 +0100
@@ -37,6 +37,7 @@
   .__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 @@
   .__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 @@
   /* 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)
--- glibc-20021126/iconv/skeleton.c.bak	2002-05-15 14:29:41.000000000 +0200
+++ glibc-20021126/iconv/skeleton.c	2002-11-30 14:53:30.000000000 +0100
@@ -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 @@
       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 @@
 #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
--- glibc-20021126/iconv/loop.c.bak	2002-11-30 02:41:57.000000000 +0100
+++ glibc-20021126/iconv/loop.c	2002-11-30 20:10:30.000000000 +0100
@@ -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 @@
 #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 @@
 #undef EXTRA_LOOP_DECLS
 #undef INIT_PARAMS
 #undef UPDATE_PARAMS
+#undef ONEBYTE_BODY
 #undef UNPACK_BYTES
 #undef LOOP_NEED_STATE
 #undef LOOP_NEED_FLAGS
--- glibc-20021126/iconvdata/8bit-generic.c.bak	2002-07-01 13:29:10.000000000 +0200
+++ glibc-20021126/iconvdata/8bit-generic.c	2002-11-30 16:48:43.000000000 +0100
@@ -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>
 
 
--- glibc-20021126/iconvdata/8bit-gap.c.bak	2002-07-01 13:29:10.000000000 +0200
+++ glibc-20021126/iconvdata/8bit-gap.c	2002-11-30 20:10:35.000000000 +0100
@@ -32,6 +32,10 @@
 /* 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 @@
   {									      \
     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 @@
     ++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>
 
 
--- glibc-20021126/iconvdata/isiri-3342.c.bak	2001-07-10 22:58:40.000000000 +0200
+++ glibc-20021126/iconvdata/isiri-3342.c	2002-11-30 20:09:23.000000000 +0100
@@ -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>
--- glibc-20021126/iconvdata/ansi_x3.110.c.bak	2002-07-01 13:29:10.000000000 +0200
+++ glibc-20021126/iconvdata/ansi_x3.110.c	2002-11-30 18:51:04.000000000 +0100
@@ -404,7 +404,7 @@
 									      \
     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 @@
     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>
 
 
--- glibc-20021126/iconvdata/armscii-8.c.bak	2002-07-01 13:29:10.000000000 +0200
+++ glibc-20021126/iconvdata/armscii-8.c	2002-11-30 16:48:10.000000000 +0100
@@ -71,6 +71,17 @@
     ++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>
 
 
--- glibc-20021126/iconvdata/cp1255.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/cp1255.c	2002-11-30 17:01:35.000000000 +0100
@@ -321,6 +321,15 @@
   }
 #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>
 
 
--- glibc-20021126/iconvdata/cp1258.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/cp1258.c	2002-11-30 17:06:58.000000000 +0100
@@ -480,6 +480,22 @@
   }
 #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>
 
 
--- glibc-20021126/iconvdata/tcvn5712-1.c.bak	2002-07-01 13:29:15.000000000 +0200
+++ glibc-20021126/iconvdata/tcvn5712-1.c	2002-11-30 20:29:55.000000000 +0100
@@ -474,6 +474,20 @@
     ++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>
 
 
--- glibc-20021126/iconvdata/big5.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/big5.c	2002-11-30 18:51:46.000000000 +0100
@@ -8397,7 +8397,7 @@
 									      \
     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 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/big5hkscs.c.bak	2002-11-30 02:49:40.000000000 +0100
+++ glibc-20021126/iconvdata/big5hkscs.c	2002-11-30 18:51:31.000000000 +0100
@@ -16955,7 +16955,7 @@
 									      \
     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;							      \
@@ -16990,6 +16990,13 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/euc-cn.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/euc-cn.c	2002-11-30 18:58:48.000000000 +0100
@@ -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>
 
 
--- glibc-20021126/iconvdata/euc-jp.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/euc-jp.c	2002-11-30 17:17:50.000000000 +0100
@@ -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>
 
--- glibc-20021126/iconvdata/euc-jisx0213.c.bak	2002-09-24 14:01:20.000000000 +0200
+++ glibc-20021126/iconvdata/euc-jisx0213.c	2002-11-30 18:58:55.000000000 +0100
@@ -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>
 
 
--- glibc-20021126/iconvdata/euc-kr.c.bak	2002-07-01 13:29:11.000000000 +0200
+++ glibc-20021126/iconvdata/euc-kr.c	2002-11-30 18:51:21.000000000 +0100
@@ -90,7 +90,7 @@
       }									      \
     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 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x9f)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/euc-tw.c.bak	2002-07-01 13:29:12.000000000 +0200
+++ glibc-20021126/iconvdata/euc-tw.c	2002-11-30 18:58:57.000000000 +0100
@@ -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>
 
 
--- glibc-20021126/iconvdata/gbk.c.bak	2002-07-01 13:29:13.000000000 +0200
+++ glibc-20021126/iconvdata/gbk.c	2002-11-30 18:59:02.000000000 +0100
@@ -13154,7 +13154,7 @@
       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 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/gb18030.c.bak	2002-07-01 13:29:13.000000000 +0200
+++ glibc-20021126/iconvdata/gb18030.c	2002-11-30 18:59:00.000000000 +0100
@@ -25772,6 +25772,13 @@
     *((uint32_t *) outptr)++ = ch;					      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/ibm932.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/ibm932.c	2002-11-30 18:06:19.000000000 +0100
@@ -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;							      \
 	      }								      \
 	  }								      \
--- glibc-20021126/iconvdata/ibm932.h.bak	2001-12-04 00:03:56.000000000 +0100
+++ glibc-20021126/iconvdata/ibm932.h	2002-11-30 17:57:23.000000000 +0100
@@ -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 @@
   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,
--- glibc-20021126/iconvdata/ibm943.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/ibm943.c	2002-11-30 18:07:10.000000000 +0100
@@ -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;							      \
 	      }								      \
 	  }								      \
--- glibc-20021126/iconvdata/ibm943.h.bak	2001-12-04 00:03:56.000000000 +0100
+++ glibc-20021126/iconvdata/ibm943.h	2002-11-30 18:03:53.000000000 +0100
@@ -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 @@
   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,
--- glibc-20021126/iconvdata/iso8859-1.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/iso8859-1.c	2002-11-30 18:09:30.000000000 +0100
@@ -36,6 +36,10 @@
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   *((uint32_t *) outptr)++ = *inptr++;
+#define ONEBYTE_BODY \
+  {									      \
+    return c;								      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/iso_6937-2.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/iso_6937-2.c	2002-11-30 18:49:19.000000000 +0100
@@ -402,7 +402,7 @@
 									      \
     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 @@
     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>
 
 
--- glibc-20021126/iconvdata/iso_6937.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/iso_6937.c	2002-11-30 18:48:36.000000000 +0100
@@ -394,7 +394,7 @@
 									      \
     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 @@
     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>
 
 
--- glibc-20021126/iconvdata/johab.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/johab.c	2002-11-30 18:17:20.000000000 +0100
@@ -276,6 +276,13 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c <= 0x7f)							      \
+      return (c == 0x5c ? 0x20a9 : c);					      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/sjis.c.bak	2002-07-01 13:29:14.000000000 +0200
+++ glibc-20021126/iconvdata/sjis.c	2002-11-30 18:23:22.000000000 +0100
@@ -4409,6 +4409,20 @@
     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>
 
 
--- glibc-20021126/iconvdata/shift_jisx0213.c.bak	2002-09-24 14:01:20.000000000 +0200
+++ glibc-20021126/iconvdata/shift_jisx0213.c	2002-11-30 18:25:33.000000000 +0100
@@ -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>
 
 
--- glibc-20021126/iconvdata/t.61.c.bak	2002-07-01 13:29:15.000000000 +0200
+++ glibc-20021126/iconvdata/t.61.c	2002-11-30 18:47:52.000000000 +0100
@@ -387,7 +387,7 @@
 									      \
     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 @@
     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>
 
 
--- glibc-20021126/iconvdata/uhc.c.bak	2002-07-01 13:29:15.000000000 +0200
+++ glibc-20021126/iconvdata/uhc.c	2002-11-30 18:59:04.000000000 +0100
@@ -3073,7 +3073,7 @@
       }									      \
     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 @@
     outptr += 4;							      \
   }
 #define LOOP_NEED_FLAGS
+#define ONEBYTE_BODY \
+  {									      \
+    if (c < 0x80)							      \
+      return c;								      \
+    else								      \
+      return WEOF;							      \
+  }
 #include <iconv/loop.c>
 
 
--- glibc-20021126/iconvdata/gbbig5.c.bak	2002-07-01 13:29:13.000000000 +0200
+++ glibc-20021126/iconvdata/gbbig5.c	2002-11-30 18:50:00.000000000 +0100
@@ -4802,7 +4802,7 @@
     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 @@
     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;							      \
 									      \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]