Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 6 Jan 2001 20:21:33 +0000 (20:21 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 6 Jan 2001 20:21:33 +0000 (20:21 +0000)
2001-01-06  Ulrich Drepper  <drepper@redhat.com>

* iconv/skeleton.c: Reset outbuf for next round of the loop.
Reported by Owen Taylor <otaylor@redhat.com>.
* iconv/Makefile (tests): Add tst-iconv3.
* iconv/tst-iconv3.c: New file.

* iconvdata/ibm930.c: Fix handling of state.  Optimize a bit.
* iconvdata/ibm933.c: Likewise.
* iconvdata/ibm935.c: Likewise.
* iconvdata/ibm937.c: Likewise.
* iconvdata/ibm939.c: Likewise.
* iconvdata/ibm930.h: Adjust single byte table for optimization.
* iconvdata/ibm933.h: Likewise.
* iconvdata/ibm935.h: Likewise.
* iconvdata/ibm939.h: Likewise.

* iconvdata/testdata/IBM930: Add misssing SI.
* iconvdata/testdata/IBM933: Likewise.
* iconvdata/testdata/IBM935: Likewise.
* iconvdata/testdata/IBM937: Likewise.
* iconvdata/testdata/IBM939: Likewise.

* configure.in: Check for old add-ons that shouldn't be used with
current glibc anymore.

17 files changed:
ChangeLog
iconv/Makefile
iconv/skeleton.c
iconvdata/ibm930.c
iconvdata/ibm930.h
iconvdata/ibm933.c
iconvdata/ibm933.h
iconvdata/ibm935.c
iconvdata/ibm935.h
iconvdata/ibm937.c
iconvdata/ibm939.c
iconvdata/ibm939.h
iconvdata/testdata/IBM930
iconvdata/testdata/IBM933
iconvdata/testdata/IBM935
iconvdata/testdata/IBM937
iconvdata/testdata/IBM939

index e65260a..1152287 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,30 @@
+2001-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+       * iconv/skeleton.c: Reset outbuf for next round of the loop.
+       Reported by Owen Taylor <otaylor@redhat.com>.
+       * iconv/Makefile (tests): Add tst-iconv3.
+       * iconv/tst-iconv3.c: New file.
+
+       * iconvdata/ibm930.c: Fix handling of state.  Optimize a bit.
+       * iconvdata/ibm933.c: Likewise.
+       * iconvdata/ibm935.c: Likewise.
+       * iconvdata/ibm937.c: Likewise.
+       * iconvdata/ibm939.c: Likewise.
+       * iconvdata/ibm930.h: Adjust single byte table for optimization.
+       * iconvdata/ibm933.h: Likewise.
+       * iconvdata/ibm935.h: Likewise.
+       * iconvdata/ibm939.h: Likewise.
+
+       * iconvdata/testdata/IBM930: Add misssing SI.
+       * iconvdata/testdata/IBM933: Likewise.
+       * iconvdata/testdata/IBM935: Likewise.
+       * iconvdata/testdata/IBM937: Likewise.
+       * iconvdata/testdata/IBM939: Likewise.
+
 2001-01-06  Andreas Jaeger  <aj@suse.de>
 
-        * configure.in: Check for old add-ons that shouldn't be used with
-        current glibc anymore.
+       * configure.in: Check for old add-ons that shouldn't be used with
+       current glibc anymore.
 
 2001-01-06  Mark Kettenis  <kettenis@gnu.org>
 
index 46ce05b..b6c4f23 100644 (file)
@@ -34,7 +34,7 @@ CFLAGS-gconv_db.c = -DSTATIC_GCONV
 CFLAGS-gconv_simple.c = -DSTATIC_GCONV
 endif
 
-tests  = tst-iconv1 tst-iconv2
+tests  = tst-iconv1 tst-iconv2 tst-iconv3
 
 distribute     = gconv_builtin.h gconv_int.h loop.c skeleton.c
 
index 2b080ba..98abc33 100644 (file)
@@ -1,5 +1,5 @@
 /* Skeleton for a conversion module.
-   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -398,7 +398,7 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
                           || (uintptr_t) inptr % MIN_NEEDED_TO != 0)));
 #endif
 
-      do
+      while (1)
        {
          struct __gconv_trans_data *trans;
 
@@ -561,10 +561,18 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
                /* All the output is consumed, we can make another run
                   if everything was ok.  */
                if (status == __GCONV_FULL_OUTPUT)
-                 status = __GCONV_OK;
+                 {
+                   status = __GCONV_OK;
+                   outbuf = data->__outbuf;
+                 }
            }
+
+         if (status != __GCONV_OK)
+           break;
+
+         /* Reset the output buffer pointer for the next round.  */
+         outbuf = data->__outbuf;
        }
-      while (status == __GCONV_OK);
 
 #ifdef END_LOOP
       END_LOOP
index 11270ff..1a78b90 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM930.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
 #define CHARSET_NAME   "IBM930//"
 #define FROM_LOOP      from_ibm930
 #define TO_LOOP                to_ibm930
+#define MIN_NEEDED_FROM        1
+#define MAX_NEEDED_FROM        2
+#define MIN_NEEDED_TO  4
+#define MAX_NEEDED_TO  4
+#define PREPARE_LOOP \
+  int save_curcs;                                                            \
+  int *curcsp = &data->__statep->__count;
+#define EXTRA_LOOP_ARGS                , curcsp
 
 /* Definitions of initialization and destructor function.  */
 #define DEFINE_INIT    1
 #define DEFINE_FINI    1
 
-#define MIN_NEEDED_FROM        1
-#define MIN_NEEDED_TO  4
+
+/* Since this is a stateful encoding we have to provide code which resets
+   the output state to the initial state.  This has to be done during the
+   flushing.  */
+#define EMIT_SHIFT_TO_INIT \
+  if ((data->__statep->__count & ~7) != sb)                                  \
+    {                                                                        \
+      if (FROM_DIRECTION)                                                    \
+       data->__statep->__count &= 7;                                         \
+      else                                                                   \
+       {                                                                     \
+         unsigned char *outbuf = data->__outbuf;                             \
+                                                                             \
+         /* We are not in the initial state.  To switch back we have         \
+            to emit `SI'.  */                                                \
+         if (__builtin_expect (outbuf >= data->__outbufend, 0))              \
+           /* We don't have enough room in the output buffer.  */            \
+           status = __GCONV_FULL_OUTPUT;                                     \
+         else                                                                \
+           {                                                                 \
+             /* Write out the shift sequence.  */                            \
+             *outbuf++ = SI;                                                 \
+             data->__outbuf = outbuf;                                        \
+             data->__statep->__count &= 7;                                   \
+           }                                                                 \
+       }                                                                     \
+    }
+
+
+/* Since we might have to reset input pointer we must be able to save
+   and retore the state.  */
+#define SAVE_RESET_STATE(Save) \
+  if (Save)                                                                  \
+    save_curcs = *curcsp;                                                    \
+  else                                                                       \
+    *curcsp = save_curcs
+
 
 /* Current codeset type.  */
 enum
 {
-  init = 0,
-  sb,
-  db
+  sb = 0,
+  db = 64
 };
 
+
 /* First, define the conversion function from IBM-930 to UCS4.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT       MAX_NEEDED_FROM
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_TO
-#define INIT_PARAMS            int curcs = init;
 #define LOOPFCT                FROM_LOOP
 #define BODY \
   {                                                                          \
     uint32_t ch = *inptr;                                                    \
     uint32_t res;                                                            \
-    const struct gap *rp1 = __ibm930sb_to_ucs4_idx;                          \
-    const struct gap *rp2 = __ibm930db_to_ucs4_idx;                          \
                                                                              \
     if (__builtin_expect (ch, 0) == SO)                                              \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift OUT, change to DBCS converter.  */                           \
        if (curcs == db)                                                      \
          {                                                                   \
@@ -76,16 +111,10 @@ enum
          }                                                                   \
        curcs = db;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
     else if (__builtin_expect (ch, 0) == SI)                                 \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift IN, change to SBCS converter */                              \
        if (curcs == sb)                                                      \
          {                                                                   \
@@ -94,19 +123,14 @@ enum
          }                                                                   \
        curcs = sb;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
                                                                              \
-    if (curcs == sb || curcs == init)                                        \
+    if (curcs == sb)                                                         \
       {                                                                              \
        /* Use the IBM930 table for single byte.  */                          \
-       while (ch > rp1->end)                                                 \
-         ++rp1;                                                              \
-                                                                             \
-       if (__builtin_expect (rp1 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp1->start, 0)                          \
-           || (res = __ibm930sb_to_ucs4[ch + rp1->idx],                      \
-               __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
+       res = __ibm930sb_to_ucs4[ch];                                         \
+       if (__builtin_expect (res, L'\1') == L'\0' && ch != '\0')             \
          {                                                                   \
            /* This is an illegal character.  */                              \
            if (! ignore_errors_p ())                                         \
@@ -115,21 +139,21 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           ++inptr;                                                          \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (res == 0xa5)                                                  \
-             res = 0x5c;                                                     \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           ++inptr;                                                          \
          }                                                                   \
+       ++inptr;                                                              \
       }                                                                              \
-    else if (curcs == db)                                                    \
+    else                                                                     \
       {                                                                              \
        /* Use the IBM930 table for double byte. */                           \
+       const struct gap *rp2 = __ibm930db_to_ucs4_idx;                       \
+                                                                             \
+       assert (curcs == db);                                                 \
+                                                                             \
        if (__builtin_expect (inptr + 1 >= inend, 0))                         \
          {                                                                   \
            /* The second character is not available.  Store the              \
@@ -142,8 +166,7 @@ enum
        while (ch > rp2->end)                                                 \
          ++rp2;                                                              \
                                                                              \
-       if (__builtin_expect (rp2 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp2->start, 0)                          \
+       if (__builtin_expect (ch < rp2->start, 0)                             \
            || (res = __ibm930db_to_ucs4[ch + rp2->idx],                      \
                __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
          {                                                                   \
@@ -154,24 +177,25 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           inptr += 2;                                                       \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           inptr += 2;                                                       \
          }                                                                   \
+       inptr += 2;                                                           \
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_TO
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_FROM
-#define INIT_PARAMS            int curcs = init;
+#define MAX_NEEDED_OUTPUT      MAX_NEEDED_FROM
 #define LOOPFCT                        TO_LOOP
 #define BODY \
   {                                                                          \
@@ -182,16 +206,21 @@ enum
                                                                              \
     if (__builtin_expect (ch, 0) >= 0xffff)                                  \
       {                                                                              \
-       rp1 = NULL;                                                           \
-       rp2 = NULL;                                                           \
+       if (! ignore_errors_p ())                                             \
+         {                                                                   \
+           result = __GCONV_ILLEGAL_INPUT;                                   \
+           break;                                                            \
+         }                                                                   \
+       ++*irreversible;                                                      \
+       inptr += 4;                                                           \
+       continue;                                                             \
       }                                                                              \
-    else                                                                     \
-      while (ch > rp1->end)                                                  \
-       ++rp1;                                                                \
+                                                                             \
+    while (ch > rp1->end)                                                    \
+      ++rp1;                                                                 \
                                                                              \
     /* Use the UCS4 table for single byte.  */                               \
-    if (__builtin_expect (rp1 == NULL, 0)                                    \
-       || __builtin_expect (ch < rp1->start, 0)                              \
+    if (__builtin_expect (ch < rp1->start, 0)                        \
        || (cp = __ucs4_to_ibm930sb[ch + rp1->idx],                           \
            __builtin_expect (cp[0], L'\1') == L'\0' && ch != '\0'))          \
       {                                                                              \
@@ -199,8 +228,7 @@ enum
        while (ch > rp2->end)                                                 \
          ++rp2;                                                              \
                                                                              \
-       if (__builtin_expect (rp2 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp2->start, 0)                          \
+       if (__builtin_expect (ch < rp2->start, 0)                             \
            || (cp = __ucs4_to_ibm930db[ch + rp2->idx],                       \
                __builtin_expect (cp[0], L'\1')==L'\0' && ch != '\0'))        \
          {                                                                   \
@@ -214,7 +242,7 @@ enum
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (curcs == init || curcs == sb)                                 \
+           if (curcs == sb)                                                  \
              {                                                               \
                if (__builtin_expect (outptr+1 > outend, 0))                  \
                  {                                                           \
@@ -264,6 +292,9 @@ enum
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Now define the toplevel functions.  */
index 4ad6bb8..d7cca13 100644 (file)
@@ -1,5 +1,5 @@
 /* Tables for conversion from and to IBM930.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -32,49 +32,40 @@ struct gap
 };
 
 
-static const struct gap __ibm930sb_to_ucs4_idx[] =
+static const uint16_t __ibm930sb_to_ucs4[256] =
 {
-  { start: 0x0000, end: 0x0056, idx:     0 },
-  { start: 0x0058, end: 0x0058, idx:    -1 },
-  { start: 0x005a, end: 0x0069, idx:    -2 },
-  { start: 0x006b, end: 0x009b, idx:    -3 },
-  { start: 0x009d, end: 0x00c9, idx:    -4 },
-  { start: 0x00d0, end: 0x00d9, idx:   -10 },
-  { start: 0x00e0, end: 0x00e0, idx:   -16 },
-  { start: 0x00e2, end: 0x00e9, idx:   -17 },
-  { start: 0x00f0, end: 0x00f9, idx:   -23 },
-  { start: 0x00ff, end: 0x00ff, idx:   -28 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
-static const uint16_t __ibm930sb_to_ucs4[] =
-{
-  0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097,
-  0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
-  0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092,
-  0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083,
-  0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C,
-  0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095,
-  0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E,
-  0x001A, 0x0020, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
-  0xFF68, 0xFF69, 0x00A3, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, 0x0026,
-  0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70, 0x0021, 0x00A5,
-  0x002A, 0x0029, 0x003B, 0x00AC, 0x002D, 0x002F, 0x0061, 0x0062, 0x0063,
-  0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x002C, 0x0025, 0x005F, 0x003E,
-  0x003F, 0x005B, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
-  0x0070, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, 0x005D,
-  0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79,
-  0xFF7A, 0x0071, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81,
-  0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0x0072,
-  0xFF8A, 0xFF8B, 0xFF8C, 0x007E, 0x203E, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90,
-  0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0x0073, 0xFF96, 0xFF97, 0xFF98,
-  0xFF99, 0x005E, 0x00A2, 0x005C, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
-  0x0079, 0x007A, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, 0x007B,
-  0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049,
-  0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051,
-  0x0052, 0x0024, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
-  0x005A, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-  0x0038, 0x0039, 0x009F
+  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
+  /* 0x08 */ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
+  /* 0x18 */ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+  /* 0x20 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
+  /* 0x28 */ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+  /* 0x30 */ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
+  /* 0x38 */ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+  /* 0x40 */ 0x0020, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
+  /* 0x48 */ 0xFF68, 0xFF69, 0x00A3, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+  /* 0x50 */ 0x0026, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0x0000,
+  /* 0x58 */ 0xFF70, 0x0000, 0x0021, 0x005C, 0x002A, 0x0029, 0x003B, 0x00AC,
+  /* 0x60 */ 0x002D, 0x002F, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066,
+  /* 0x68 */ 0x0067, 0x0068, 0x0000, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+  /* 0x70 */ 0x005B, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+  /* 0x78 */ 0x0070, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+  /* 0x80 */ 0x005D, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
+  /* 0x88 */ 0xFF78, 0xFF79, 0xFF7A, 0x0071, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E,
+  /* 0x90 */ 0xFF7F, 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86,
+  /* 0x98 */ 0xFF87, 0xFF88, 0xFF89, 0x0072, 0x0000, 0xFF8A, 0xFF8B, 0xFF8C,
+  /* 0xa0 */ 0x007E, 0x203E, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, 0xFF92,
+  /* 0xa8 */ 0xFF93, 0xFF94, 0xFF95, 0x0073, 0xFF96, 0xFF97, 0xFF98, 0xFF99,
+  /* 0xb0 */ 0x005E, 0x00A2, 0x005C, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+  /* 0xb8 */ 0x0079, 0x007A, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
+  /* 0xc0 */ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+  /* 0xc8 */ 0x0048, 0x0049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xd0 */ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+  /* 0xd8 */ 0x0051, 0x0052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xe0 */ 0x0024, 0x0000, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+  /* 0xe8 */ 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xf0 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+  /* 0xf8 */ 0x0038, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009F
 };
 
 static const struct gap __ibm930db_to_ucs4_idx[] =
index be7fc0c..9a9b053 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM933.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
 #define CHARSET_NAME   "IBM933//"
 #define FROM_LOOP      from_ibm933
 #define TO_LOOP                to_ibm933
+#define MIN_NEEDED_FROM        1
+#define MAX_NEEDED_FROM        2
+#define MIN_NEEDED_TO  4
+#define MAX_NEEDED_TO  4
+#define PREPARE_LOOP \
+  int save_curcs;                                                            \
+  int *curcsp = &data->__statep->__count;
+#define EXTRA_LOOP_ARGS                , curcsp
 
 /* Definitions of initialization and destructor function.  */
 #define DEFINE_INIT    1
 #define DEFINE_FINI    1
 
-#define MIN_NEEDED_FROM        1
-#define MIN_NEEDED_TO  4
+
+/* Since this is a stateful encoding we have to provide code which resets
+   the output state to the initial state.  This has to be done during the
+   flushing.  */
+#define EMIT_SHIFT_TO_INIT \
+  if ((data->__statep->__count & ~7) != sb)                                  \
+    {                                                                        \
+      if (FROM_DIRECTION)                                                    \
+       data->__statep->__count &= 7;                                         \
+      else                                                                   \
+       {                                                                     \
+         unsigned char *outbuf = data->__outbuf;                             \
+                                                                             \
+         /* We are not in the initial state.  To switch back we have         \
+            to emit `SI'.  */                                                \
+         if (__builtin_expect (outbuf >= data->__outbufend, 0))              \
+           /* We don't have enough room in the output buffer.  */            \
+           status = __GCONV_FULL_OUTPUT;                                     \
+         else                                                                \
+           {                                                                 \
+             /* Write out the shift sequence.  */                            \
+             *outbuf++ = SI;                                                 \
+             data->__outbuf = outbuf;                                        \
+             data->__statep->__count &= 7;                                   \
+           }                                                                 \
+       }                                                                     \
+    }
+
+
+/* Since we might have to reset input pointer we must be able to save
+   and retore the state.  */
+#define SAVE_RESET_STATE(Save) \
+  if (Save)                                                                  \
+    save_curcs = *curcsp;                                                    \
+  else                                                                       \
+    *curcsp = save_curcs
+
 
 /* Current codeset type.  */
 enum
 {
-  init = 0,
-  sb,
-  db
+  sb = 0,
+  db = 64
 };
 
 /* First, define the conversion function from IBM-933 to UCS4.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT       MAX_NEEDED_FROM
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_TO
-#define INIT_PARAMS            int curcs = init;
 #define LOOPFCT                FROM_LOOP
 #define BODY \
   {                                                                          \
     uint32_t ch = *inptr;                                                    \
     uint32_t res;                                                            \
-    const struct gap *rp1 = __ibm933sb_to_ucs4_idx;                          \
-    const struct gap *rp2 = __ibm933db_to_ucs4_idx;                          \
                                                                              \
     if (__builtin_expect (ch, 0) == SO)                                              \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift OUT, change to DBCS converter.  */                           \
        if (curcs == db)                                                      \
          {                                                                   \
@@ -76,16 +110,10 @@ enum
          }                                                                   \
        curcs = db;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
     else if (__builtin_expect (ch, 0) == SI)                                 \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift IN, change to SBCS converter.  */                            \
        if (curcs == sb)                                                      \
          {                                                                   \
@@ -94,19 +122,14 @@ enum
          }                                                                   \
        curcs = sb;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
                                                                              \
-    if (curcs == sb || curcs == init)                                        \
+    if (curcs == sb)                                                         \
       {                                                                              \
        /* Use the IBM933 table for single byte.  */                          \
-       while (ch > rp1->end)                                                 \
-         ++rp1;                                                              \
-                                                                             \
-       if (__builtin_expect (rp1 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp1->start, 0)                          \
-           || (res = __ibm933sb_to_ucs4[ch + rp1->idx],                      \
-               __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
+       res = __ibm933sb_to_ucs4[ch];                                         \
+       if (__builtin_expect (res, L'\1') == L'\0' && ch != '\0')             \
          {                                                                   \
            /* This is an illegal character.  */                              \
            if (! ignore_errors_p ())                                         \
@@ -115,18 +138,20 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           ++inptr;                                                          \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           ++inptr;                                                          \
          }                                                                   \
+       ++inptr;                                                              \
       }                                                                              \
-    else if (curcs == db)                                                    \
+    else                                                                     \
       {                                                                              \
+       const struct gap *rp2 = __ibm933db_to_ucs4_idx;                       \
+                                                                             \
+       assert (curcs == db);                                                 \
+                                                                             \
        /* Use the IBM933 table for double byte.  */                          \
        if (__builtin_expect (inptr + 1 >= inend, 0))                         \
          {                                                                   \
@@ -164,12 +189,15 @@ enum
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_TO
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_FROM
-#define INIT_PARAMS            int curcs = init;
+#define MAX_NEEDED_OUTPUT      MAX_NEEDED_FROM
 #define LOOPFCT                        TO_LOOP
 #define BODY \
   {                                                                          \
@@ -180,16 +208,21 @@ enum
                                                                              \
     if (__builtin_expect (ch, 0) >= 0xffff)                                  \
       {                                                                              \
-       rp1 = NULL;                                                           \
-       rp2 = NULL;                                                           \
+       if (! ignore_errors_p ())                                             \
+         {                                                                   \
+           result = __GCONV_ILLEGAL_INPUT;                                   \
+           break;                                                            \
+         }                                                                   \
+       ++*irreversible;                                                      \
+       inptr += 4;                                                           \
+       continue;                                                             \
       }                                                                              \
-    else                                                                     \
-      while (ch > rp1->end)                                                  \
-       ++rp1;                                                                \
+                                                                             \
+    while (ch > rp1->end)                                                    \
+      ++rp1;                                                                 \
                                                                              \
     /* Use the UCS4 table for single byte.  */                               \
-    if (__builtin_expect (rp1 == NULL, 0)                                    \
-       || __builtin_expect (ch < rp1->start, 0)                              \
+    if (__builtin_expect (ch < rp1->start, 0)                        \
        || (cp = __ucs4_to_ibm933sb[ch + rp1->idx],                           \
            __builtin_expect (cp[0], L'\1') == L'\0' && ch != '\0'))          \
       {                                                                              \
@@ -197,8 +230,7 @@ enum
        while (ch > rp2->end)                                                 \
          ++rp2;                                                              \
                                                                              \
-       if (__builtin_expect (rp2 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp2->start, 0)                          \
+       if (__builtin_expect (ch < rp2->start, 0)                             \
            || (cp = __ucs4_to_ibm933db[ch + rp2->idx],                       \
                __builtin_expect (cp[0], L'\1')==L'\0' && ch != '\0'))        \
          {                                                                   \
@@ -212,7 +244,7 @@ enum
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (curcs == init || curcs == sb)                                 \
+           if (curcs == sb)                                                  \
              {                                                               \
                if (__builtin_expect (outptr+1 > outend, 0))                  \
                  {                                                           \
@@ -257,6 +289,9 @@ enum
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Now define the toplevel functions.  */
index 09daf88..20f25cc 100644 (file)
@@ -1,5 +1,5 @@
 /* Tables for conversion from and to IBM933.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -32,51 +32,40 @@ struct gap
 };
 
 
-static const struct gap __ibm933sb_to_ucs4_idx[] =
+static const uint16_t __ibm933sb_to_ucs4[256] =
 {
-  { start: 0x0000, end: 0x0040, idx:     0 },
-  { start: 0x0042, end: 0x0050, idx:    -1 },
-  { start: 0x0052, end: 0x0070, idx:    -2 },
-  { start: 0x0072, end: 0x008f, idx:    -3 },
-  { start: 0x0091, end: 0x00b0, idx:    -4 },
-  { start: 0x00b2, end: 0x00b2, idx:    -5 },
-  { start: 0x00ba, end: 0x00bc, idx:   -12 },
-  { start: 0x00c0, end: 0x00c9, idx:   -15 },
-  { start: 0x00d0, end: 0x00d9, idx:   -21 },
-  { start: 0x00e0, end: 0x00e0, idx:   -27 },
-  { start: 0x00e2, end: 0x00e9, idx:   -28 },
-  { start: 0x00f0, end: 0x00f9, idx:   -34 },
-  { start: 0x00ff, end: 0x00ff, idx:   -39 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
-static const uint16_t __ibm933sb_to_ucs4[] =
-{
-  0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097,
-  0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
-  0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092,
-  0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083,
-  0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C,
-  0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095,
-  0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E,
-  0x001A, 0x0020, 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6,
-  0xFFA7, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, 0x0026, 0xFFA8,
-  0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF, 0x0021, 0x0024,
-  0x002A, 0x0029, 0x003B, 0x00AC, 0x002D, 0x002F, 0xFFB0, 0xFFB1, 0xFFB2,
-  0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0x00A6, 0x002C, 0x0025, 0x005F,
-  0x003E, 0x003F, 0x005B, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD,
-  0xFFBE, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, 0x005D,
-  0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
-  0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, 0x006A, 0x006B, 0x006C,
-  0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0xFFCA, 0xFFCB, 0xFFCC,
-  0xFFCD, 0xFFCE, 0xFFCF, 0x203E, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076,
-  0x0077, 0x0078, 0x0079, 0x007A, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6,
-  0xFFD7, 0x005E, 0x005C, 0xFFDA, 0xFFDB, 0xFFDC, 0x007B, 0x0041, 0x0042,
-  0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x007D, 0x004A,
-  0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x20A9,
-  0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x0030,
-  0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
-  0x009F
+  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
+  /* 0x08 */ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
+  /* 0x18 */ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+  /* 0x20 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
+  /* 0x28 */ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+  /* 0x30 */ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
+  /* 0x38 */ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+  /* 0x40 */ 0x0020, 0x0000, 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5,
+  /* 0x48 */ 0xFFA6, 0xFFA7, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+  /* 0x50 */ 0x0026, 0x0000, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD,
+  /* 0x58 */ 0xFFAE, 0xFFAF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
+  /* 0x60 */ 0x002D, 0x002F, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5,
+  /* 0x68 */ 0xFFB6, 0xFFB7, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+  /* 0x70 */ 0x005B, 0x0000, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD,
+  /* 0x78 */ 0xFFBE, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+  /* 0x80 */ 0x005D, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+  /* 0x88 */ 0x0068, 0x0069, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
+  /* 0x90 */ 0x0000, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
+  /* 0x98 */ 0x0071, 0x0072, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
+  /* 0xa0 */ 0x203E, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+  /* 0xa8 */ 0x0079, 0x007A, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7,
+  /* 0xb0 */ 0x005E, 0x0000, 0x005C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xb8 */ 0x0000, 0x0000, 0xFFDA, 0xFFDB, 0xFFDC, 0x0000, 0x0000, 0x0000,
+  /* 0xc0 */ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+  /* 0xc8 */ 0x0048, 0x0049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xd0 */ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+  /* 0xd8 */ 0x0051, 0x0052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xe0 */ 0x20A9, 0x0000, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+  /* 0xe8 */ 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xf0 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+  /* 0xf8 */ 0x0038, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009F
 };
 
 static const struct gap __ibm933db_to_ucs4_idx[] =
index f63398d..04b8e9d 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM935
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
 #define CHARSET_NAME   "IBM935//"
 #define FROM_LOOP      from_ibm935
 #define TO_LOOP                to_ibm935
+#define MIN_NEEDED_FROM        1
+#define MAX_NEEDED_FROM        2
+#define MIN_NEEDED_TO  4
+#define MAX_NEEDED_TO  4
+#define PREPARE_LOOP \
+  int save_curcs;                                                            \
+  int *curcsp = &data->__statep->__count;
+#define EXTRA_LOOP_ARGS                , curcsp
 
 /* Definitions of initialization and destructor function.  */
 #define DEFINE_INIT    1
 #define DEFINE_FINI    1
 
-#define MIN_NEEDED_FROM        1
-#define MIN_NEEDED_TO  4
+
+/* Since this is a stateful encoding we have to provide code which resets
+   the output state to the initial state.  This has to be done during the
+   flushing.  */
+#define EMIT_SHIFT_TO_INIT \
+  if ((data->__statep->__count & ~7) != sb)                                  \
+    {                                                                        \
+      if (FROM_DIRECTION)                                                    \
+       data->__statep->__count &= 7;                                         \
+      else                                                                   \
+       {                                                                     \
+         unsigned char *outbuf = data->__outbuf;                             \
+                                                                             \
+         /* We are not in the initial state.  To switch back we have         \
+            to emit `SI'.  */                                                \
+         if (__builtin_expect (outbuf >= data->__outbufend, 0))              \
+           /* We don't have enough room in the output buffer.  */            \
+           status = __GCONV_FULL_OUTPUT;                                     \
+         else                                                                \
+           {                                                                 \
+             /* Write out the shift sequence.  */                            \
+             *outbuf++ = SI;                                                 \
+             data->__outbuf = outbuf;                                        \
+             data->__statep->__count &= 7;                                   \
+           }                                                                 \
+       }                                                                     \
+    }
+
+
+/* Since we might have to reset input pointer we must be able to save
+   and retore the state.  */
+#define SAVE_RESET_STATE(Save) \
+  if (Save)                                                                  \
+    save_curcs = *curcsp;                                                    \
+  else                                                                       \
+    *curcsp = save_curcs
+
 
 /* Current codeset type.  */
 enum
 {
-  init = 0,
-  sb,
-  db
+  sb = 0,
+  db = 64
 };
 
 /* First, define the conversion function from IBM-935 to UCS4.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT       MAX_NEEDED_FROM
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_TO
-#define INIT_PARAMS            int curcs = init;
 #define LOOPFCT                FROM_LOOP
 #define BODY \
   {                                                                          \
     uint32_t ch = *inptr;                                                    \
     uint32_t res;                                                            \
-    const struct gap *rp1 = __ibm935sb_to_ucs4_idx;                          \
-    const struct gap *rp2 = __ibm935db_to_ucs4_idx;                          \
                                                                              \
     if (__builtin_expect(ch, 0) == SO)                                       \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift OUT, change to DBCS converter.  */                           \
        if (curcs == db)                                                      \
          {                                                                   \
@@ -76,16 +110,10 @@ enum
          }                                                                   \
        curcs = db;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
     else if (__builtin_expect (ch, 0) == SI)                                 \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift IN, change to SBCS converter.  */                            \
        if (curcs == sb)                                                      \
          {                                                                   \
@@ -94,19 +122,14 @@ enum
          }                                                                   \
        curcs = sb;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
                                                                              \
-    if (curcs == sb || curcs == init)                                        \
+    if (curcs == sb)                                                         \
       {                                                                              \
        /* Use the IBM935 table for single byte.  */                          \
-       while (ch > rp1->end)                                                 \
-         ++rp1;                                                              \
-                                                                             \
-       if (__builtin_expect (rp1 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp1->start, 0)                          \
-           || (res = __ibm935sb_to_ucs4[ch + rp1->idx],                      \
-               __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
+       res = __ibm935sb_to_ucs4[ch];                                         \
+       if (__builtin_expect (res, L'\1') == L'\0' && ch != '\0')             \
          {                                                                   \
            /* This is an illegal character.  */                              \
            if (! ignore_errors_p ())                                         \
@@ -115,18 +138,20 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           ++inptr;                                                          \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           inptr++;                                                          \
          }                                                                   \
+       ++inptr;                                                              \
       }                                                                              \
-    else if (curcs == db)                                                    \
+    else                                                                     \
       {                                                                              \
+       const struct gap *rp2 = __ibm935db_to_ucs4_idx;                       \
+                                                                             \
+       assert (curcs == db);                                                 \
+                                                                             \
        /* Use the IBM935 table for double byte.  */                          \
        if (__builtin_expect (inptr + 1 >= inend, 0))                         \
          {                                                                   \
@@ -152,24 +177,25 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           inptr += 2;                                                       \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           inptr += 2;                                                       \
          }                                                                   \
+       inptr += 2;                                                           \
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_TO
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_FROM
-#define INIT_PARAMS            int curcs = init;
+#define MAX_NEEDED_OUTPUT      MAX_NEEDED_FROM
 #define LOOPFCT                        TO_LOOP
 #define BODY \
   {                                                                          \
@@ -180,16 +206,21 @@ enum
                                                                              \
     if (__builtin_expect (ch, 0) >= 0xffff)                                  \
       {                                                                              \
-       rp1 = NULL;                                                           \
-       rp2 = NULL;                                                           \
+       if (! ignore_errors_p ())                                             \
+         {                                                                   \
+           result = __GCONV_ILLEGAL_INPUT;                                   \
+           break;                                                            \
+         }                                                                   \
+       ++*irreversible;                                                      \
+       inptr += 4;                                                           \
+       continue;                                                             \
       }                                                                              \
-    else                                                                     \
-      while (ch > rp1->end)                                                  \
-       ++rp1;                                                                \
+                                                                             \
+    while (ch > rp1->end)                                                    \
+      ++rp1;                                                                 \
                                                                              \
     /* Use the UCS4 table for single byte.  */                               \
-    if (__builtin_expect (rp1 == NULL, 0)                                    \
-       || __builtin_expect (ch < rp1->start, 0)                              \
+    if (__builtin_expect (ch < rp1->start, 0)                                \
        || (cp = __ucs4_to_ibm935sb[ch + rp1->idx],                           \
            __builtin_expect (cp[0], L'\1') == L'\0' && ch != '\0'))          \
       {                                                                              \
@@ -197,8 +228,7 @@ enum
        while (ch > rp2->end)                                                 \
          ++rp2;                                                              \
                                                                              \
-       if (__builtin_expect (rp2 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp2->start, 0)                          \
+       if (__builtin_expect (ch < rp2->start, 0)                             \
            || (cp = __ucs4_to_ibm935db[ch + rp2->idx],                       \
                __builtin_expect (cp[0], L'\1')==L'\0' && ch != '\0'))        \
          {                                                                   \
@@ -212,7 +242,7 @@ enum
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (curcs == init || curcs == sb)                                 \
+           if (curcs == sb)                                                  \
              {                                                               \
                if (__builtin_expect (outptr+1 > outend, 0))                  \
                  {                                                           \
@@ -257,6 +287,9 @@ enum
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Now define the toplevel functions.  */
index 1e5613b..cfaf96f 100644 (file)
@@ -1,5 +1,5 @@
 /* Tables for conversion from and to IBM935
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -32,49 +32,40 @@ struct gap
 };
 
 
-static const struct gap __ibm935sb_to_ucs4_idx[] =
+static const uint16_t __ibm935sb_to_ucs4[256] =
 {
-  { start: 0x0000, end: 0x0040, idx:     0 },
-  { start: 0x004a, end: 0x0050, idx:    -9 },
-  { start: 0x005a, end: 0x0061, idx:   -18 },
-  { start: 0x006a, end: 0x006f, idx:   -26 },
-  { start: 0x0079, end: 0x007f, idx:   -35 },
-  { start: 0x0081, end: 0x0089, idx:   -36 },
-  { start: 0x0091, end: 0x0099, idx:   -43 },
-  { start: 0x00a0, end: 0x00a9, idx:   -49 },
-  { start: 0x00b0, end: 0x00b0, idx:   -55 },
-  { start: 0x00b2, end: 0x00b2, idx:   -56 },
-  { start: 0x00ba, end: 0x00bb, idx:   -63 },
-  { start: 0x00c0, end: 0x00c9, idx:   -67 },
-  { start: 0x00d0, end: 0x00d9, idx:   -73 },
-  { start: 0x00e0, end: 0x00e0, idx:   -79 },
-  { start: 0x00e2, end: 0x00e9, idx:   -80 },
-  { start: 0x00f0, end: 0x00f9, idx:   -86 },
-  { start: 0x00ff, end: 0x00ff, idx:   -91 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
-static const uint16_t __ibm935sb_to_ucs4[] =
-{
-  0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097,
-  0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
-  0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092,
-  0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083,
-  0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C,
-  0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095,
-  0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E,
-  0x001A, 0x0020, 0x00A3, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, 0x0026,
-  0x0021, 0x00A5, 0x002A, 0x0029, 0x003B, 0x00AC, 0x002D, 0x002F, 0x00A6,
-  0x002C, 0x0025, 0x005F, 0x003E, 0x003F, 0x0060, 0x003A, 0x0023, 0x0040,
-  0x0027, 0x003D, 0x0022, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066,
-  0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
-  0x0070, 0x0071, 0x0072, 0x007E, 0x203E, 0x0073, 0x0074, 0x0075, 0x0076,
-  0x0077, 0x0078, 0x0079, 0x007A, 0x005E, 0x005C, 0x005B, 0x005D, 0x007B,
-  0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049,
-  0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051,
-  0x0052, 0x0024, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
-  0x005A, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-  0x0038, 0x0039, 0x009F
+  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
+  /* 0x08 */ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
+  /* 0x18 */ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+  /* 0x20 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
+  /* 0x28 */ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+  /* 0x30 */ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
+  /* 0x38 */ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+  /* 0x40 */ 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0x48 */ 0x0000, 0x0000, 0x00A3, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+  /* 0x50 */ 0x0026, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0x58 */ 0x0000, 0x0000, 0x0021, 0x00A5, 0x002A, 0x0029, 0x003B, 0x00AC,
+  /* 0x60 */ 0x002D, 0x002F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0x68 */ 0x0000, 0x0000, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+  /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0x78 */ 0x0000, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+  /* 0x80 */ 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+  /* 0x88 */ 0x0068, 0x0069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0x90 */ 0x0000, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
+  /* 0x98 */ 0x0071, 0x0072, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xa0 */ 0x007E, 0x203E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+  /* 0xa8 */ 0x0079, 0x007A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xb0 */ 0x005E, 0x0000, 0x005C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xb8 */ 0x0000, 0x0000, 0x005B, 0x005D, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xc0 */ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+  /* 0xc8 */ 0x0048, 0x0049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xd0 */ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+  /* 0xd8 */ 0x0051, 0x0052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xe0 */ 0x0024, 0x0000, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+  /* 0xe8 */ 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xf0 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+  /* 0xf8 */ 0x0038, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009F
 };
 
 static const struct gap __ibm935db_to_ucs4_idx[] =
index 98e9683..6da55ae 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion to and from IBM937.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
 #define CHARSET_NAME   "IBM937//"
 #define FROM_LOOP      from_ibm937
 #define TO_LOOP                to_ibm937
+#define MIN_NEEDED_FROM        1
+#define MAX_NEEDED_FROM        2
+#define MIN_NEEDED_TO  4
+#define MAX_NEEDED_TO  4
+#define PREPARE_LOOP \
+  int save_curcs;                                                            \
+  int *curcsp = &data->__statep->__count;
+#define EXTRA_LOOP_ARGS                , curcsp
 
 /* Definitions of initialization and destructor function.  */
 #define DEFINE_INIT    1
 #define DEFINE_FINI    1
 
-#define MIN_NEEDED_FROM        1
-#define MIN_NEEDED_TO  4
+
+/* Since this is a stateful encoding we have to provide code which resets
+   the output state to the initial state.  This has to be done during the
+   flushing.  */
+#define EMIT_SHIFT_TO_INIT \
+  if ((data->__statep->__count & ~7) != sb)                                  \
+    {                                                                        \
+      if (FROM_DIRECTION)                                                    \
+       data->__statep->__count &= 7;                                         \
+      else                                                                   \
+       {                                                                     \
+         unsigned char *outbuf = data->__outbuf;                             \
+                                                                             \
+         /* We are not in the initial state.  To switch back we have         \
+            to emit `SI'.  */                                                \
+         if (__builtin_expect (outbuf >= data->__outbufend, 0))              \
+           /* We don't have enough room in the output buffer.  */            \
+           status = __GCONV_FULL_OUTPUT;                                     \
+         else                                                                \
+           {                                                                 \
+             /* Write out the shift sequence.  */                            \
+             *outbuf++ = SI;                                                 \
+             data->__outbuf = outbuf;                                        \
+             data->__statep->__count &= 7;                                   \
+           }                                                                 \
+       }                                                                     \
+    }
+
+
+/* Since we might have to reset input pointer we must be able to save
+   and retore the state.  */
+#define SAVE_RESET_STATE(Save) \
+  if (Save)                                                                  \
+    save_curcs = *curcsp;                                                    \
+  else                                                                       \
+    *curcsp = save_curcs
+
 
 /* Current codeset type.  */
 enum
 {
-  init = 0,
-  sb,
-  db
+  sb = 0,
+  db = 64
 };
 
 /* First, define the conversion function from IBM-937 to UCS4.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT       MAX_NEEDED_FROM
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_TO
-#define INIT_PARAMS            int curcs = init;
 #define LOOPFCT                FROM_LOOP
 #define BODY \
   {                                                                          \
@@ -59,12 +101,6 @@ enum
                                                                              \
     if (__builtin_expect (ch, 0) == SO)                                              \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift OUT, change to DBCS converter.  */                           \
        if (curcs == db)                                                      \
          {                                                                   \
@@ -73,16 +109,10 @@ enum
          }                                                                   \
        curcs = db;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
     else if (__builtin_expect (ch, 0) == SI)                                 \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift IN, change to SBCS converter.  */                            \
        if (curcs == sb)                                                      \
          {                                                                   \
@@ -91,10 +121,10 @@ enum
          }                                                                   \
        curcs = sb;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
                                                                              \
-    if (curcs == sb || curcs == init)                                        \
+    if (curcs == sb)                                                         \
       {                                                                              \
        /* Use the UCS4 table for single byte.  */                            \
        ch = __ibm937sb_to_ucs4[ch];                                          \
@@ -107,19 +137,20 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           ++inptr;                                                          \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, ch);                                               \
            outptr += 4;                                                      \
-           inptr++;                                                          \
          }                                                                   \
+       ++inptr;                                                              \
       }                                                                              \
-    else if (curcs == db)                                                    \
+    else                                                                     \
       {                                                                              \
        /* Use the IBM937 table for double byte.  */                          \
+                                                                             \
+       assert (curcs == db);                                                 \
+                                                                             \
        ch = ibm937db_to_ucs4(inptr[0], inptr[1]);                            \
        if (__builtin_expect (ch, L'\1') == L'\0' && *inptr != '\0')          \
          {                                                                   \
@@ -130,24 +161,25 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           inptr += 2;                                                       \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, ch);                                               \
            outptr += 4;                                                      \
-           inptr += 2;                                                       \
          }                                                                   \
+       inptr += 2;                                                           \
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Next, define the other direction.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_TO
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_FROM
-#define INIT_PARAMS            int curcs = init;
+#define MAX_NEEDED_OUTPUT      MAX_NEEDED_FROM
 #define LOOPFCT                        TO_LOOP
 #define BODY \
   {                                                                          \
@@ -174,7 +206,7 @@ enum
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (curcs == init || curcs == sb)                                 \
+           if (curcs == sb)                                                  \
              {                                                               \
                *outptr++ = SO;                                               \
                if (__builtin_expect (outptr == outend, 0))                   \
@@ -207,6 +239,9 @@ enum
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Now define the toplevel functions.  */
index 7dd7284..d50d880 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion to and from IBM939.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
 #define CHARSET_NAME   "IBM939//"
 #define FROM_LOOP      from_ibm939
 #define TO_LOOP                to_ibm939
+#define MIN_NEEDED_FROM        1
+#define MAX_NEEDED_FROM        2
+#define MIN_NEEDED_TO  4
+#define MAX_NEEDED_TO  4
+#define PREPARE_LOOP \
+  int save_curcs;                                                            \
+  int *curcsp = &data->__statep->__count;
+#define EXTRA_LOOP_ARGS                , curcsp
 
 /* Definitions of initialization and destructor function.  */
 #define DEFINE_INIT    1
 #define DEFINE_FINI    1
 
-#define MIN_NEEDED_FROM        1
-#define MIN_NEEDED_TO  4
+
+/* Since this is a stateful encoding we have to provide code which resets
+   the output state to the initial state.  This has to be done during the
+   flushing.  */
+#define EMIT_SHIFT_TO_INIT \
+  if ((data->__statep->__count & ~7) != sb)                                  \
+    {                                                                        \
+      if (FROM_DIRECTION)                                                    \
+       data->__statep->__count &= 7;                                         \
+      else                                                                   \
+       {                                                                     \
+         unsigned char *outbuf = data->__outbuf;                             \
+                                                                             \
+         /* We are not in the initial state.  To switch back we have         \
+            to emit `SI'.  */                                                \
+         if (__builtin_expect (outbuf >= data->__outbufend, 0))              \
+           /* We don't have enough room in the output buffer.  */            \
+           status = __GCONV_FULL_OUTPUT;                                     \
+         else                                                                \
+           {                                                                 \
+             /* Write out the shift sequence.  */                            \
+             *outbuf++ = SI;                                                 \
+             data->__outbuf = outbuf;                                        \
+             data->__statep->__count &= 7;                                   \
+           }                                                                 \
+       }                                                                     \
+    }
+
+
+/* Since we might have to reset input pointer we must be able to save
+   and retore the state.  */
+#define SAVE_RESET_STATE(Save) \
+  if (Save)                                                                  \
+    save_curcs = *curcsp;                                                    \
+  else                                                                       \
+    *curcsp = save_curcs
+
 
 /* Current codeset type.  */
 enum
 {
-  init = 0,
-  sb,
-  db
+  sb = 0,
+  db = 64
 };
 
 /* First, define the conversion function from IBM-939 to UCS4.  */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT       MAX_NEEDED_FROM
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_TO
-#define INIT_PARAMS            int curcs = init;
 #define LOOPFCT                FROM_LOOP
 #define BODY \
   {                                                                          \
     uint32_t ch = *inptr;                                                    \
     uint32_t res;                                                            \
-    const struct gap *rp1 = __ibm939sb_to_ucs4_idx;                          \
-    const struct gap *rp2 = __ibm939db_to_ucs4_idx;                          \
                                                                              \
     if (__builtin_expect (ch, 0) == SO)                                              \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift OUT, change to DBCS converter.  */                           \
        if (curcs == db)                                                      \
          {                                                                   \
@@ -76,16 +110,10 @@ enum
          }                                                                   \
        curcs = db;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
     else if (__builtin_expect (ch, 0) == SI)                                 \
       {                                                                              \
-       if (__builtin_expect (inptr + 1 >= inend, 0))                         \
-         {                                                                   \
-           result = __GCONV_INCOMPLETE_INPUT;                                \
-           break;                                                            \
-         }                                                                   \
-                                                                             \
        /* Shift IN, change to SBCS converter.  */                            \
        if (curcs == sb)                                                      \
          {                                                                   \
@@ -94,19 +122,14 @@ enum
          }                                                                   \
        curcs = sb;                                                           \
        ++inptr;                                                              \
-       ch = *inptr;                                                          \
+       continue;                                                             \
       }                                                                              \
                                                                              \
-    if (curcs == sb || curcs == init)                                        \
+    if (curcs == sb)                                                         \
       {                                                                              \
        /* Use the IBM939 table for single byte.  */                          \
-       while (ch > rp1->end)                                                 \
-         ++rp1;                                                              \
-                                                                             \
-       if (__builtin_expect (rp1 == NULL, 0)                                 \
-           || __builtin_expect (ch < rp1->start, 0)                          \
-           || (res = __ibm939sb_to_ucs4[ch + rp1->idx],                      \
-               __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
+       res = __ibm939sb_to_ucs4[ch];                                         \
+       if (__builtin_expect (res, L'\1') == L'\0' && ch != '\0')             \
          {                                                                   \
            /* This is an illegal character.  */                              \
            if (! ignore_errors_p ())                                         \
@@ -115,21 +138,21 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           ++inptr;                                                          \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (res == 0xa5)                                                  \
-             res = 0x5c;                                                     \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           ++inptr;                                                          \
          }                                                                   \
+       ++inptr;                                                              \
       }                                                                              \
-    else if (curcs == db)                                                    \
+    else                                                                     \
       {                                                                              \
        /* Use the IBM939 table for double byte.  */                          \
+       const struct gap *rp2 = __ibm939db_to_ucs4_idx;                       \
+                                                                             \
+       assert (curcs == db);                                                 \
+                                                                             \
        if (__builtin_expect (inptr + 1 >= inend, 0))                         \
          {                                                                   \
            /* The second character is not available.  Store the              \
@@ -154,24 +177,25 @@ enum
                break;                                                        \
              }                                                               \
            ++*irreversible;                                                  \
-           inptr += 2;                                                       \
-           continue;                                                         \
          }                                                                   \
        else                                                                  \
          {                                                                   \
            put32 (outptr, res);                                              \
            outptr += 4;                                                      \
-           inptr += 2;                                                       \
          }                                                                   \
+       inptr += 2;                                                           \
       }                                                                              \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Next, define the other direction */
 #define MIN_NEEDED_INPUT       MIN_NEEDED_TO
 #define MIN_NEEDED_OUTPUT      MIN_NEEDED_FROM
-#define INIT_PARAMS            int curcs = init;
+#define MAX_NEEDED_OUTPUT      MAX_NEEDED_FROM
 #define LOOPFCT                        TO_LOOP
 #define BODY \
   {                                                                          \
@@ -214,7 +238,7 @@ enum
          }                                                                   \
        else                                                                  \
          {                                                                   \
-           if (curcs == init || curcs == sb)                                 \
+           if (curcs == sb)                                                  \
              {                                                               \
                if (__builtin_expect (outptr+1 > outend, 0))                  \
                  {                                                           \
@@ -264,6 +288,9 @@ enum
     inptr += 4;                                                                      \
   }
 #define LOOP_NEED_FLAGS
+#define EXTRA_LOOP_DECLS       , int *curcsp
+#define INIT_PARAMS            int curcs = *curcsp & ~7
+#define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
 /* Now define the toplevel functions. */
index 57e0b6f..d5b0639 100644 (file)
@@ -1,5 +1,5 @@
 /* Tables for conversion to and from IBM939.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -32,49 +32,40 @@ struct gap
 };
 
 
-static const struct gap __ibm939sb_to_ucs4_idx[] =
+static const uint16_t __ibm939sb_to_ucs4[256] =
 {
-  { start: 0x0000, end: 0x0040, idx:     0 },
-  { start: 0x0042, end: 0x0069, idx:    -1 },
-  { start: 0x006b, end: 0x007f, idx:    -2 },
-  { start: 0x0081, end: 0x008f, idx:    -3 },
-  { start: 0x0091, end: 0x00c9, idx:    -4 },
-  { start: 0x00d0, end: 0x00d9, idx:   -10 },
-  { start: 0x00e0, end: 0x00e0, idx:   -16 },
-  { start: 0x00e2, end: 0x00e9, idx:   -17 },
-  { start: 0x00f0, end: 0x00f9, idx:   -23 },
-  { start: 0x00ff, end: 0x00ff, idx:   -28 },
-  { start: 0xffff, end: 0xffff, idx:     0 }
-};
-
-static const uint16_t __ibm939sb_to_ucs4[] =
-{
-  0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097,
-  0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
-  0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092,
-  0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083,
-  0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C,
-  0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095,
-  0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E,
-  0x001A, 0x0020, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
-  0xFF68, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, 0x0026, 0xFF69,
-  0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0x0021,
-  0x0024, 0x002A, 0x0029, 0x003B, 0x00AC, 0x002D, 0x002F, 0xFF72, 0xFF73,
-  0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0x002C, 0x0025, 0x005F,
-  0x003E, 0x003F, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80,
-  0xFF81, 0xFF82, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
-  0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
-  0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0x006A, 0x006B, 0x006C,
-  0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0xFF89, 0xFF8A, 0xFF8B,
-  0xFF8C, 0xFF8D, 0xFF8E, 0x203E, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076,
-  0x0077, 0x0078, 0x0079, 0x007A, 0xFF8F, 0xFF90, 0xFF91, 0x005B, 0xFF92,
-  0xFF93, 0x005E, 0x00A3, 0x00A5, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98,
-  0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0x005D, 0xFF9E, 0xFF9F, 0x007B,
-  0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049,
-  0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051,
-  0x0052, 0x005C, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
-  0x005A, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-  0x0038, 0x0039, 0x009F
+  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
+  /* 0x08 */ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
+  /* 0x18 */ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+  /* 0x20 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
+  /* 0x28 */ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+  /* 0x30 */ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
+  /* 0x38 */ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+  /* 0x40 */ 0x0020, 0x0000, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66,
+  /* 0x48 */ 0xFF67, 0xFF68, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+  /* 0x50 */ 0x0026, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
+  /* 0x58 */ 0xFF70, 0xFF71, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
+  /* 0x60 */ 0x002D, 0x002F, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
+  /* 0x68 */ 0xFF78, 0xFF79, 0x0000, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+  /* 0x70 */ 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81,
+  /* 0x78 */ 0xFF82, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+  /* 0x80 */ 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+  /* 0x88 */ 0x0068, 0x0069, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88,
+  /* 0x90 */ 0x0000, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
+  /* 0x98 */ 0x0071, 0x0072, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E,
+  /* 0xa0 */ 0x203E, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+  /* 0xa8 */ 0x0079, 0x007A, 0xFF8F, 0xFF90, 0xFF91, 0x005B, 0xFF92, 0xFF93,
+  /* 0xb0 */ 0x005E, 0x00A3, 0x005C, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98,
+  /* 0xb8 */ 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0x005D, 0xFF9E, 0xFF9F,
+  /* 0xc0 */ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+  /* 0xc8 */ 0x0048, 0x0049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xd0 */ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+  /* 0xd8 */ 0x0051, 0x0052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xe0 */ 0x005C, 0x0000, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+  /* 0xe8 */ 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  /* 0xf0 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+  /* 0xf8 */ 0x0038, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009F
 };
 
 static const struct gap __ibm939db_to_ucs4_idx[] =
index 551cb60..ab2632e 100644 (file)
Binary files a/iconvdata/testdata/IBM930 and b/iconvdata/testdata/IBM930 differ
index 4da0d68..449ed02 100644 (file)
Binary files a/iconvdata/testdata/IBM933 and b/iconvdata/testdata/IBM933 differ
index 4a905ee..a35941b 100644 (file)
Binary files a/iconvdata/testdata/IBM935 and b/iconvdata/testdata/IBM935 differ
index 58bd263..b448487 100644 (file)
Binary files a/iconvdata/testdata/IBM937 and b/iconvdata/testdata/IBM937 differ
index 9c10f9e..6970f02 100644 (file)
Binary files a/iconvdata/testdata/IBM939 and b/iconvdata/testdata/IBM939 differ