(insert-char-data): Fix format of `iso-10646-comment'; swap order of
[chise/xemacs-chise.git] / src / file-coding.c
index b310424..3068c89 100644 (file)
@@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
+
 #include "buffer.h"
 #include "elhash.h"
 #include "insdel.h"
@@ -244,10 +245,46 @@ static Lisp_Object mark_coding_system (Lisp_Object, void (*) (Lisp_Object));
 static void print_coding_system (Lisp_Object, Lisp_Object, int);
 static void finalize_coding_system (void *header, int for_disksave);
 
+#ifdef MULE
+static const struct lrecord_description ccs_description_1[] = {
+  { XD_LISP_OBJECT, offsetof(charset_conversion_spec, from_charset), 2 },
+  { XD_END }
+};
+
+static const struct struct_description ccs_description = {
+  sizeof(charset_conversion_spec),
+  ccs_description_1
+};
+  
+static const struct lrecord_description ccsd_description_1[] = {
+  XD_DYNARR_DESC(charset_conversion_spec_dynarr, &ccs_description),
+  { XD_END }
+};
+
+static const struct struct_description ccsd_description = {
+  sizeof(charset_conversion_spec_dynarr),
+  ccsd_description_1
+};
+#endif
+
+static const struct lrecord_description coding_system_description[] = {
+  { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, name), 2 },
+  { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, mnemonic), 3 },
+  { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, eol_lf), 3 },
+#ifdef MULE
+  { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, iso2022.initial_charset), 4 },
+  { XD_STRUCT_PTR,  offsetof(struct Lisp_Coding_System, iso2022.input_conv),  1, &ccsd_description },
+  { XD_STRUCT_PTR,  offsetof(struct Lisp_Coding_System, iso2022.output_conv), 1, &ccsd_description },
+  { XD_LISP_OBJECT, offsetof(struct Lisp_Coding_System, ccl.decode), 2 },
+#endif
+  { XD_END }
+};
+
 DEFINE_LRECORD_IMPLEMENTATION ("coding-system", coding_system,
                               mark_coding_system, print_coding_system,
                               finalize_coding_system,
-                              0, 0, struct Lisp_Coding_System);
+                              0, 0, coding_system_description,
+                              struct Lisp_Coding_System);
 
 static Lisp_Object
 mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object))
@@ -1583,26 +1620,65 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
   if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT ||
       *eol_type_in_out == EOL_AUTODETECT)
     {
+      unsigned char random_buffer[4096];
+      int nread;
+      Lisp_Object coding_system = Qnil;
 
-      while (1)
+      nread = Lstream_read (stream, random_buffer, sizeof (random_buffer));
+      if (nread)
        {
-         unsigned char random_buffer[4096];
-         int nread;
+         unsigned char *cp = random_buffer;
 
-         nread = Lstream_read (stream, random_buffer, sizeof (random_buffer));
-         if (!nread)
-           break;
-         if (detect_coding_type (&decst, random_buffer, nread,
-                                 XCODING_SYSTEM_TYPE (*codesys_in_out) !=
-                                 CODESYS_AUTODETECT))
-           break;
-       }
+         while (cp < random_buffer + nread)
+           {
+             if ((*cp++ == 'c') && (cp < random_buffer + nread) &&
+                 (*cp++ == 'o') && (cp < random_buffer + nread) &&
+                 (*cp++ == 'd') && (cp < random_buffer + nread) &&
+                 (*cp++ == 'i') && (cp < random_buffer + nread) &&
+                 (*cp++ == 'n') && (cp < random_buffer + nread) &&
+                 (*cp++ == 'g') && (cp < random_buffer + nread) &&
+                 (*cp++ == ':') && (cp < random_buffer + nread))
+               {
+                 unsigned char coding_system_name[4096 - 6];
+                 unsigned char *np = coding_system_name;
 
+                 while ( (cp < random_buffer + nread)
+                         && ((*cp == ' ') || (*cp == '\t')) )
+                   {
+                     cp++;
+                   }
+                 while ( (cp < random_buffer + nread) &&
+                         (*cp != ' ') && (*cp != '\t') && (*cp != ';') )
+                   {
+                     *np++ = *cp++;
+                   }
+                 *np = 0;
+                 coding_system
+                   = Ffind_coding_system (intern (coding_system_name));
+                 break;
+               }
+           }
+         if (EQ(coding_system, Qnil))
+           do{
+             if (detect_coding_type (&decst, random_buffer, nread,
+                                     XCODING_SYSTEM_TYPE (*codesys_in_out)
+                                     != CODESYS_AUTODETECT))
+               break;
+             nread = Lstream_read (stream,
+                                   random_buffer, sizeof (random_buffer));
+             if (!nread)
+               break;
+           } while(1);
+       }
       *eol_type_in_out = decst.eol_type;
       if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT)
-       *codesys_in_out = coding_system_from_mask (decst.mask);
+       {
+         if (EQ(coding_system, Qnil))
+           *codesys_in_out = coding_system_from_mask (decst.mask);
+         else
+           *codesys_in_out = coding_system;
+       }
     }
-
   /* If we absolutely can't determine the EOL type, just assume LF. */
   if (*eol_type_in_out == EOL_AUTODETECT)
     *eol_type_in_out = EOL_LF;
@@ -1856,6 +1932,9 @@ struct decoding_stream
   /* Additional information (the state of the running CCL program)
      used by the CCL decoder. */
   struct ccl_program ccl;
+
+  /* counter for UTF-8 or UCS-4 */
+  unsigned char counter;
 #endif
   struct detection_state decst;
 };
@@ -1990,6 +2069,7 @@ reset_decoding_stream (struct decoding_stream *str)
     {
       setup_ccl_program (&str->ccl, CODING_SYSTEM_CCL_DECODE (str->codesys));
     }
+  str->counter = 0;
 #endif /* MULE */
   str->flags = str->ch = 0;
 }
@@ -2173,7 +2253,8 @@ mule_decode (Lstream *decoding, CONST unsigned char *src,
       decode_coding_utf8 (decoding, src, dst, n);
       break;
     case CODESYS_CCL:
-      ccl_driver (&str->ccl, src, dst, n, 0);
+      str->ccl.last_block = str->flags & CODING_STATE_END;
+      ccl_driver (&str->ccl, src, dst, n, 0, CCL_MODE_DECODING);
       break;
     case CODESYS_ISO2022:
       decode_coding_iso2022 (decoding, src, dst, n);
@@ -2589,7 +2670,8 @@ mule_encode (Lstream *encoding, CONST unsigned char *src,
       encode_coding_utf8 (encoding, src, dst, n);
       break;
     case CODESYS_CCL:
-      ccl_driver (&str->ccl, src, dst, n, 0);
+      str->ccl.last_block = str->flags & CODING_STATE_END;
+      ccl_driver (&str->ccl, src, dst, n, 0, CCL_MODE_ENCODING);
       break;
     case CODESYS_ISO2022:
       encode_coding_iso2022 (encoding, src, dst, n);
@@ -2748,10 +2830,16 @@ decode_coding_sjis (Lstream *decoding, CONST unsigned char *src,
            {
              unsigned char e1, e2;
 
-             Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208);
              DECODE_SJIS (ch, c, e1, e2);
+#ifdef UTF2000
+             DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_japanese_jisx0208,
+                                           e1 & 0x7F,
+                                           e2 & 0x7F), dst);
+#else
+             Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208);
              Dynarr_add (dst, e1);
              Dynarr_add (dst, e2);
+#endif
            }
          else
            {
@@ -2767,8 +2855,13 @@ decode_coding_sjis (Lstream *decoding, CONST unsigned char *src,
            ch = c;
          else if (BYTE_SJIS_KATAKANA_P (c))
            {
+#ifdef UTF2000
+             DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_katakana_jisx0201,
+                                           c & 0x7F, 0), dst);
+#else
              Dynarr_add (dst, LEADING_BYTE_KATAKANA_JISX0201);
              Dynarr_add (dst, c);
+#endif
            }
          else
            DECODE_ADD_BINARY_CHAR (c, dst);
@@ -2793,10 +2886,82 @@ encode_coding_sjis (Lstream *encoding, CONST unsigned char *src,
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys);
+#ifdef UTF2000
+  unsigned char char_boundary = str->iso2022.current_char_boundary;
+#endif
 
   while (n--)
     {
       c = *src++;
+#ifdef UTF2000
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               Dynarr_add (dst, c);
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         {
+           Lisp_Object charset;
+           unsigned int c1, c2, s1, s2;
+           
+           BREAKUP_CHAR (ch, charset, c1, c2);
+           if (EQ(charset, Vcharset_katakana_jisx0201))
+             {
+               Dynarr_add (dst, c1 | 0x80);
+             }
+           else if (EQ(charset, Vcharset_japanese_jisx0208))
+             {
+               ENCODE_SJIS (c1 | 0x80, c2 | 0x80, s1, s2);
+               Dynarr_add (dst, s1);
+               Dynarr_add (dst, s2);
+             }
+         }
+         char_boundary = 0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+#else
       if (c == '\n')
        {
          if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
@@ -2833,10 +2998,14 @@ encode_coding_sjis (Lstream *encoding, CONST unsigned char *src,
              ch = 0;
            }
        }
+#endif
     }
 
   str->flags = flags;
   str->ch    = ch;
+#ifdef UTF2000
+  str->iso2022.current_char_boundary = char_boundary;
+#endif
 }
 
 DEFUN ("decode-shift-jis-char", Fdecode_shift_jis_char, 1, 1, 0, /*
@@ -3068,6 +3237,7 @@ static void
 encode_coding_big5 (Lstream *encoding, CONST unsigned char *src,
                    unsigned_char_dynarr *dst, unsigned int n)
 {
+#ifndef UTF2000
   unsigned char c;
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags  = str->flags;
@@ -3122,6 +3292,7 @@ encode_coding_big5 (Lstream *encoding, CONST unsigned char *src,
 
   str->flags = flags;
   str->ch    = ch;
+#endif
 }
 
 
@@ -3142,7 +3313,7 @@ Return the corresponding character.
   if (BYTE_BIG5_TWO_BYTE_1_P (b1) &&
       BYTE_BIG5_TWO_BYTE_2_P (b2))
     {
-      int leading_byte;
+      Charset_ID leading_byte;
       Lisp_Object charset;
       DECODE_BIG5 (b1, b2, leading_byte, c1, c2);
       charset = CHARSET_BY_LEADING_BYTE (leading_byte);
@@ -3369,37 +3540,40 @@ decode_coding_ucs4 (Lstream *decoding, CONST unsigned char *src,
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags = str->flags;
   unsigned int ch    = str->ch;
+  unsigned char counter = str->counter;
 
   while (n--)
     {
       unsigned char c = *src++;
-      switch (flags)
+      switch (counter)
        {
        case 0:
          ch = c;
-         flags = 3;
+         counter = 3;
          break;
        case 1:
          decode_ucs4 ( ( ch << 8 ) | c, dst);
          ch = 0;
-         flags = 0;
+         counter = 0;
          break;
        default:
          ch = ( ch << 8 ) | c;
-         flags--;
+         counter--;
        }
     }
-  if (flags & CODING_STATE_END)
+  if (counter & CODING_STATE_END)
     DECODE_OUTPUT_PARTIAL_CHAR (ch);
 
   str->flags = flags;
   str->ch    = ch;
+  str->counter = counter;
 }
 
 static void
 encode_coding_ucs4 (Lstream *encoding, CONST unsigned char *src,
                    unsigned_char_dynarr *dst, unsigned int n)
 {
+#ifndef UTF2000
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags = str->flags;
   unsigned int ch = str->ch;
@@ -3528,6 +3702,7 @@ encode_coding_ucs4 (Lstream *encoding, CONST unsigned char *src,
   str->iso2022.current_charset = charset;
 
   /* Verbum caro factum est! */
+#endif
 }
 
 \f
@@ -3578,37 +3753,38 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src,
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = str->eol_type;
+  unsigned char counter = str->counter;
 
   while (n--)
     {
       unsigned char c = *src++;
-      switch (flags)
+      switch (counter)
        {
        case 0:
          if ( c >= 0xfc )
            {
              ch = c & 0x01;
-             flags = 5;
+             counter = 5;
            }
          else if ( c >= 0xf8 )
            {
              ch = c & 0x03;
-             flags = 4;
+             counter = 4;
            }
          else if ( c >= 0xf0 )
            {
              ch = c & 0x07;
-             flags = 3;
+             counter = 3;
            }
          else if ( c >= 0xe0 )
            {
              ch = c & 0x0f;
-             flags = 2;
+             counter = 2;
            }
          else if ( c >= 0xc0 )
            {
              ch = c & 0x1f;
-             flags = 1;
+             counter = 1;
            }
          else
            {
@@ -3620,11 +3796,11 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src,
          ch = ( ch << 6 ) | ( c & 0x3f );
          decode_ucs4 (ch, dst);
          ch = 0;
-         flags = 0;
+         counter = 0;
          break;
        default:
          ch = ( ch << 6 ) | ( c & 0x3f );
-         flags--;
+         counter--;
        }
     label_continue_loop:;
     }
@@ -3634,6 +3810,7 @@ decode_coding_utf8 (Lstream *decoding, CONST unsigned char *src,
 
   str->flags = flags;
   str->ch    = ch;
+  str->counter = counter;
 }
 
 #ifndef UTF2000
@@ -4780,7 +4957,7 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src,
        {                       /* Graphic characters */
          Lisp_Object charset;
 #ifndef UTF2000
-         int lb;
+         Charset_ID lb;
 #endif
          int reg;
 
@@ -4824,9 +5001,23 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src,
                    charset = new_charset;
                }
 
-#ifndef UTF2000
+#ifdef UTF2000
+             if (XCHARSET_DIMENSION (charset) == 1)
+               {
+                 DECODE_OUTPUT_PARTIAL_CHAR (ch);
+                 DECODE_ADD_UCS_CHAR
+                   (MAKE_CHAR (charset, c & 0x7F, 0), dst);
+               }
+             else if (ch)
+               {
+                 DECODE_ADD_UCS_CHAR
+                   (MAKE_CHAR (charset, ch & 0x7F, c & 0x7F), dst);
+                 ch = 0;
+               }
+             else
+               ch = c;
+#else
              lb = XCHARSET_LEADING_BYTE (charset);
-#endif
              switch (XCHARSET_REP_BYTES (charset))
                {
                case 1: /* ASCII */
@@ -4836,37 +5027,25 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src,
 
                case 2: /* one-byte official */
                  DECODE_OUTPUT_PARTIAL_CHAR (ch);
-#ifdef UTF2000
-                 DECODE_ADD_UCS_CHAR(MAKE_CHAR(charset, c, 0), dst);
-#else
                  Dynarr_add (dst, lb);
                  Dynarr_add (dst, c | 0x80);
-#endif
                  break;
 
                case 3: /* one-byte private or two-byte official */
                  if (XCHARSET_PRIVATE_P (charset))
                    {
                      DECODE_OUTPUT_PARTIAL_CHAR (ch);
-#ifdef UTF2000
-                     DECODE_ADD_UCS_CHAR(MAKE_CHAR(charset, c, 0), dst);
-#else
                      Dynarr_add (dst, PRE_LEADING_BYTE_PRIVATE_1);
                      Dynarr_add (dst, lb);
                      Dynarr_add (dst, c | 0x80);
-#endif
                    }
                  else
                    {
                      if (ch)
                        {
-#ifdef UTF2000
-                         DECODE_ADD_UCS_CHAR(MAKE_CHAR(charset, ch, c), dst);
-#else
                          Dynarr_add (dst, lb);
                          Dynarr_add (dst, ch | 0x80);
                          Dynarr_add (dst, c | 0x80);
-#endif
                          ch = 0;
                        }
                      else
@@ -4877,19 +5056,16 @@ decode_coding_iso2022 (Lstream *decoding, CONST unsigned char *src,
                default:        /* two-byte private */
                  if (ch)
                    {
-#ifdef UTF2000
-                     DECODE_ADD_UCS_CHAR(MAKE_CHAR(charset, ch, c), dst);
-#else
                      Dynarr_add (dst, PRE_LEADING_BYTE_PRIVATE_2);
                      Dynarr_add (dst, lb);
                      Dynarr_add (dst, ch | 0x80);
                      Dynarr_add (dst, c | 0x80);
-#endif
                      ch = 0;
                    }
                  else
                    ch = c;
                }
+#endif
            }
 
          if (!ch)
@@ -5007,12 +5183,15 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
   unsigned char char_boundary;
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags          = str->flags;
-  unsigned int ch             = str->ch;
+  Emchar ch                   = str->ch;
   Lisp_Coding_System *codesys = str->codesys;
   eol_type_t eol_type         = CODING_SYSTEM_EOL_TYPE (str->codesys);
   int i;
   Lisp_Object charset;
   int half;
+#ifdef UTF2000
+  unsigned int byte1, byte2;
+#endif
 
 #ifdef ENABLE_COMPOSITE_CHARS
   /* flags for handling composite chars.  We do a little switcharoo
@@ -5029,6 +5208,216 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
 #ifdef ENABLE_COMPOSITE_CHARS
  back_to_square_n:
 #endif
+#ifdef UTF2000
+  while (n--)
+    {
+      c = *src++;
+
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+
+             restore_left_to_right_direction (codesys, dst, &flags, 0);
+             
+             /* Make sure G0 contains ASCII */
+             if ((c > ' ' && c < ISO_CODE_DEL) ||
+                 !CODING_SYSTEM_ISO2022_NO_ASCII_CNTL (codesys))
+               {
+                 ensure_normal_shift (str, dst);
+                 iso2022_designate (Vcharset_ascii, 0, str, dst);
+               }
+             
+             /* If necessary, restore everything to the default state
+                at end-of-line */
+             if (c == '\n' &&
+                 !(CODING_SYSTEM_ISO2022_NO_ASCII_EOL (codesys)))
+               {
+                 restore_left_to_right_direction (codesys, dst, &flags, 0);
+
+                 ensure_normal_shift (str, dst);
+
+                 for (i = 0; i < 4; i++)
+                   {
+                     Lisp_Object initial_charset =
+                       CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i);
+                     iso2022_designate (initial_charset, i, str, dst);
+                   }
+               }
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               {
+                 if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys)
+                     && fit_to_be_escape_quoted (c))
+                   Dynarr_add (dst, ISO_CODE_ESC);
+                 Dynarr_add (dst, c);
+               }
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         
+         char_boundary = 0;
+         if ( (0x80 <= ch) && (ch <= 0x9f) )
+           {
+             charmask = (half == 0 ? 0x00 : 0x80);
+         
+             if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys)
+                 && fit_to_be_escape_quoted (ch))
+               Dynarr_add (dst, ISO_CODE_ESC);
+             /* you asked for it ... */
+             Dynarr_add (dst, ch);
+           }
+         else
+           {
+             int reg;
+
+             BREAKUP_CHAR (ch, charset, byte1, byte2);
+             ensure_correct_direction (XCHARSET_DIRECTION (charset),
+                                       codesys, dst, &flags, 0);
+
+             /* Now determine which register to use. */
+             reg = -1;
+             for (i = 0; i < 4; i++)
+               {
+                 if (EQ (charset, str->iso2022.charset[i]) ||
+                     EQ (charset,
+                         CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i)))
+                   {
+                     reg = i;
+                     break;
+                   }
+               }
+             
+             if (reg == -1)
+               {
+                 if (XCHARSET_GRAPHIC (charset) != 0)
+                   {
+                     if (!NILP (str->iso2022.charset[1]) &&
+                         (!CODING_SYSTEM_ISO2022_SEVEN (codesys) ||
+                          CODING_SYSTEM_ISO2022_LOCK_SHIFT (codesys)))
+                       reg = 1;
+                     else if (!NILP (str->iso2022.charset[2]))
+                       reg = 2;
+                     else if (!NILP (str->iso2022.charset[3]))
+                       reg = 3;
+                     else
+                       reg = 0;
+                   }
+                 else
+                   reg = 0;
+               }
+             
+             iso2022_designate (charset, reg, str, dst);
+             
+             /* Now invoke that register. */
+             switch (reg)
+               {
+               case 0:
+                 ensure_normal_shift (str, dst);
+                 half = 0;
+                 break;
+                 
+               case 1:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (codesys))
+                   {
+                     ensure_shift_out (str, dst);
+                     half = 0;
+                   }
+                 else
+                   half = 1;
+                 break;
+                 
+               case 2:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys))
+                   {
+                     Dynarr_add (dst, ISO_CODE_ESC);
+                     Dynarr_add (dst, 'N');
+                     half = 0;
+                   }
+                 else
+                   {
+                     Dynarr_add (dst, ISO_CODE_SS2);
+                     half = 1;
+                   }
+                 break;
+                 
+               case 3:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys))
+                   {
+                     Dynarr_add (dst, ISO_CODE_ESC);
+                     Dynarr_add (dst, 'O');
+                     half = 0;
+                   }
+                 else
+                   {
+                     Dynarr_add (dst, ISO_CODE_SS3);
+                     half = 1;
+                   }
+                 break;
+                 
+               default:
+                 abort ();
+               }
+             
+             charmask = (half == 0 ? 0x00 : 0x80);
+             
+             switch (XCHARSET_DIMENSION (charset))
+               {
+               case 1:
+                 Dynarr_add (dst, byte1 | charmask);
+                 break;
+               case 2:
+                 Dynarr_add (dst, byte1 | charmask);
+                 Dynarr_add (dst, byte2 | charmask);
+                 break;
+               default:
+                 abort ();
+               }
+           }
+         ch =0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+    }
+#else /* not UTF2000 */
+
   while (n--)
     {
       c = *src++;
@@ -5080,11 +5469,6 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
          char_boundary = 1;
        }
 
-#ifdef UTF2000
-      else if (BUFBYTE_FIRST_BYTE_P (c))
-       {
-       }
-#else
       else if (BUFBYTE_LEADING_BYTE_P (c) || BUFBYTE_LEADING_BYTE_P (ch))
        { /* Processing Leading Byte */
          ch = 0;
@@ -5188,7 +5572,6 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
            }
          char_boundary = 0;
        }
-#endif /* not UTF2000 */
       else
        {                       /* Processing Non-ASCII character */
          charmask = (half == 0 ? 0x7F : 0xFF);
@@ -5272,6 +5655,7 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
            }
        }
     }
+#endif /* not UTF2000 */
 
 #ifdef ENABLE_COMPOSITE_CHARS
   if (in_composite)
@@ -5285,7 +5669,11 @@ encode_coding_iso2022 (Lstream *encoding, CONST unsigned char *src,
     }
 #endif /* ENABLE_COMPOSITE_CHARS */
 
+#ifdef UTF2000
+  if ( (char_boundary == 0) && flags & CODING_STATE_END)
+#else
   if (char_boundary && flags & CODING_STATE_END)
+#endif
     {
       restore_left_to_right_direction (codesys, dst, &flags, 0);
       ensure_normal_shift (str, dst);
@@ -5348,10 +5736,68 @@ encode_coding_no_conversion (Lstream *encoding, CONST unsigned char *src,
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys);
+#ifdef UTF2000
+  unsigned char char_boundary = str->iso2022.current_char_boundary;
+#endif
 
   while (n--)
     {
-      c = *src++;
+      c = *src++;        
+#ifdef UTF2000
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               Dynarr_add (dst, c);
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         Dynarr_add (dst, ch & 0xff);
+         char_boundary = 0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+#else /* not UTF2000 */
       if (c == '\n')
        {
          if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
@@ -5387,10 +5833,14 @@ encode_coding_no_conversion (Lstream *encoding, CONST unsigned char *src,
             untranslatable character, so ignore it */
          ch = 0;
        }
+#endif /* not UTF2000 */
     }
 
   str->flags = flags;
   str->ch    = ch;
+#ifdef UTF2000
+  str->iso2022.current_char_boundary = char_boundary;
+#endif
 }
 
 \f