]> code.delx.au - gnu-emacs/blobdiff - src/coding.c
(gc_cons_threshold): Not static.
[gnu-emacs] / src / coding.c
index 78ba80c35eec2375b864dd91eea9573410af7904..a4f03c70d9670a406c1a24bb7c1c46563283ca23 100644 (file)
@@ -1,7 +1,7 @@
 /* Coding system handler (conversion, detection, and etc).
 /* Coding system handler (conversion, detection, and etc).
-   Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
+   Copyright (C) 1995,97,1998,2002,2003  Electrotechnical Laboratory, JAPAN.
    Licensed to the Free Software Foundation.
    Licensed to the Free Software Foundation.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001,2002,2003  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -17,8 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /*** TABLE OF CONTENTS ***
 
 
 /*** TABLE OF CONTENTS ***
 
@@ -60,7 +60,7 @@ Boston, MA 02111-1307, USA.  */
   all variants of ISO2022.  Details are described in section 3.
 
   2. SJIS (or Shift-JIS or MS-Kanji-Code)
   all variants of ISO2022.  Details are described in section 3.
 
   2. SJIS (or Shift-JIS or MS-Kanji-Code)
-   
+
   A coding system to encode character sets: ASCII, JISX0201, and
   JISX0208.  Widely used for PC's in Japan.  Details are described in
   section 4.
   A coding system to encode character sets: ASCII, JISX0201, and
   JISX0208.  Widely used for PC's in Japan.  Details are described in
   section 4.
@@ -147,7 +147,8 @@ detect_coding_emacs_mule (src, src_end, multibytep)
 static void
 decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
   ...
      int src_bytes, dst_bytes;
 {
   ...
@@ -345,6 +346,7 @@ encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
 #include "ccl.h"
 #include "coding.h"
 #include "window.h"
 #include "ccl.h"
 #include "coding.h"
 #include "window.h"
+#include "intervals.h"
 
 #else  /* not emacs */
 
 
 #else  /* not emacs */
 
@@ -361,12 +363,18 @@ Lisp_Object Qsafe_chars;
 Lisp_Object Qvalid_codes;
 
 extern Lisp_Object Qinsert_file_contents, Qwrite_region;
 Lisp_Object Qvalid_codes;
 
 extern Lisp_Object Qinsert_file_contents, Qwrite_region;
-Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;
+Lisp_Object Qcall_process, Qcall_process_region;
 Lisp_Object Qstart_process, Qopen_network_stream;
 Lisp_Object Qtarget_idx;
 
 Lisp_Object Qstart_process, Qopen_network_stream;
 Lisp_Object Qtarget_idx;
 
+/* If a symbol has this property, evaluate the value to define the
+   symbol as a coding system.  */
+Lisp_Object Qcoding_system_define_form;
+
 Lisp_Object Vselect_safe_coding_system_function;
 
 Lisp_Object Vselect_safe_coding_system_function;
 
+int coding_system_require_warning;
+
 /* Mnemonic string for each format of end-of-line.  */
 Lisp_Object eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;
 /* Mnemonic string to indicate format of end-of-line is not yet
 /* Mnemonic string for each format of end-of-line.  */
 Lisp_Object eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;
 /* Mnemonic string to indicate format of end-of-line is not yet
@@ -379,6 +387,16 @@ int system_eol_type;
 
 #ifdef emacs
 
 
 #ifdef emacs
 
+/* Information about which coding system is safe for which chars.
+   The value has the form (GENERIC-LIST . NON-GENERIC-ALIST).
+
+   GENERIC-LIST is a list of generic coding systems which can encode
+   any characters.
+
+   NON-GENERIC-ALIST is an alist of non generic coding systems vs the
+   corresponding char table that contains safe chars.  */
+Lisp_Object Vcoding_system_safe_chars;
+
 Lisp_Object Vcoding_system_list, Vcoding_system_alist;
 
 Lisp_Object Qcoding_system_p, Qcoding_system_error;
 Lisp_Object Vcoding_system_list, Vcoding_system_alist;
 
 Lisp_Object Qcoding_system_p, Qcoding_system_error;
@@ -387,6 +405,8 @@ Lisp_Object Qcoding_system_p, Qcoding_system_error;
    end-of-line format.  */
 Lisp_Object Qemacs_mule, Qraw_text;
 
    end-of-line format.  */
 Lisp_Object Qemacs_mule, Qraw_text;
 
+Lisp_Object Qutf_8;
+
 /* Coding-systems are handed between Emacs Lisp programs and C internal
    routines by the following three variables.  */
 /* Coding-system for reading files and receiving data from process.  */
 /* Coding-systems are handed between Emacs Lisp programs and C internal
    routines by the following three variables.  */
 /* Coding-system for reading files and receiving data from process.  */
@@ -485,26 +505,27 @@ Lisp_Object Vcharset_revision_alist;
 /* Default coding systems used for process I/O.  */
 Lisp_Object Vdefault_process_coding_system;
 
 /* Default coding systems used for process I/O.  */
 Lisp_Object Vdefault_process_coding_system;
 
+/* Char table for translating Quail and self-inserting input.  */
+Lisp_Object Vtranslation_table_for_input;
+
 /* Global flag to tell that we can't call post-read-conversion and
    pre-write-conversion functions.  Usually the value is zero, but it
    is set to 1 temporarily while such functions are running.  This is
    to avoid infinite recursive call.  */
 static int inhibit_pre_post_conversion;
 
 /* Global flag to tell that we can't call post-read-conversion and
    pre-write-conversion functions.  Usually the value is zero, but it
    is set to 1 temporarily while such functions are running.  This is
    to avoid infinite recursive call.  */
 static int inhibit_pre_post_conversion;
 
-/* Char-table containing safe coding systems of each character.  */
-Lisp_Object Vchar_coding_system_table;
 Lisp_Object Qchar_coding_system;
 
 Lisp_Object Qchar_coding_system;
 
-/* Return `safe-chars' property of coding system CODING.  Don't check
-   validity of CODING.  */
+/* Return `safe-chars' property of CODING_SYSTEM (symbol).  Don't check
+   its validity.  */
 
 Lisp_Object
 
 Lisp_Object
-coding_safe_chars (coding)
-     struct coding_system *coding;
+coding_safe_chars (coding_system)
+     Lisp_Object coding_system;
 {
   Lisp_Object coding_spec, plist, safe_chars;
 {
   Lisp_Object coding_spec, plist, safe_chars;
-  
-  coding_spec = Fget (coding->symbol, Qcoding_system);
+
+  coding_spec = Fget (coding_system, Qcoding_system);
   plist = XVECTOR (coding_spec)->contents[3];
   safe_chars = Fplist_get (XVECTOR (coding_spec)->contents[3], Qsafe_chars);
   return (CHAR_TABLE_P (safe_chars) ? safe_chars : Qt);
   plist = XVECTOR (coding_spec)->contents[3];
   safe_chars = Fplist_get (XVECTOR (coding_spec)->contents[3], Qsafe_chars);
   return (CHAR_TABLE_P (safe_chars) ? safe_chars : Qt);
@@ -673,8 +694,16 @@ detect_coding_emacs_mule (src, src_end, multibytep)
 
 /* Record one COMPONENT (alternate character or composition rule).  */
 
 
 /* Record one COMPONENT (alternate character or composition rule).  */
 
-#define CODING_ADD_COMPOSITION_COMPONENT(coding, component)    \
-  (coding->cmp_data->data[coding->cmp_data->used++] = component)
+#define CODING_ADD_COMPOSITION_COMPONENT(coding, component)            \
+  do {                                                                 \
+    coding->cmp_data->data[coding->cmp_data->used++] = component;      \
+    if (coding->cmp_data->used - coding->cmp_data_start                        \
+       == COMPOSITION_DATA_MAX_BUNCH_LENGTH)                           \
+      {                                                                        \
+       CODING_ADD_COMPOSITION_END (coding, coding->produced_char);     \
+       coding->composing = COMPOSITION_NO;                             \
+      }                                                                        \
+  } while (0)
 
 
 /* Get one byte from a data pointed by SRC and increment SRC.  If SRC
 
 
 /* Get one byte from a data pointed by SRC and increment SRC.  If SRC
@@ -691,7 +720,7 @@ detect_coding_emacs_mule (src, src_end, multibytep)
 #define DECODE_EMACS_MULE_COMPOSITION_CHAR(c, p)               \
   do {                                                         \
     int bytes;                                                 \
 #define DECODE_EMACS_MULE_COMPOSITION_CHAR(c, p)               \
   do {                                                         \
     int bytes;                                                 \
-                                                               \
+                                                               \
     c = SAFE_ONE_MORE_BYTE ();                                 \
     if (c < 0)                                                 \
       break;                                                   \
     c = SAFE_ONE_MORE_BYTE ();                                 \
     if (c < 0)                                                 \
       break;                                                   \
@@ -722,7 +751,10 @@ detect_coding_emacs_mule (src, src_end, multibytep)
              break;                                            \
            *p++ = c;                                           \
          }                                                     \
              break;                                            \
            *p++ = c;                                           \
          }                                                     \
-       if (UNIBYTE_STR_AS_MULTIBYTE_P (p0, p - p0, bytes))     \
+       if (UNIBYTE_STR_AS_MULTIBYTE_P (p0, p - p0, bytes)      \
+           || (coding->flags /* We are recovering a file.  */  \
+               && p0[0] == LEADING_CODE_8_BIT_CONTROL          \
+               && ! CHAR_HEAD_P (p0[1])))                      \
          c = STRING_CHAR (p0, bytes);                          \
        else                                                    \
          c = -1;                                               \
          c = STRING_CHAR (p0, bytes);                          \
        else                                                    \
          c = -1;                                               \
@@ -769,12 +801,13 @@ static INLINE int
 decode_composition_emacs_mule (coding, src, src_end,
                               destination, dst_end, dst_bytes)
      struct coding_system *coding;
 decode_composition_emacs_mule (coding, src, src_end,
                               destination, dst_end, dst_bytes)
      struct coding_system *coding;
-     unsigned char *src, *src_end, **destination, *dst_end;
+     const unsigned char *src, *src_end;
+     unsigned char **destination, *dst_end;
      int dst_bytes;
 {
   unsigned char *dst = *destination;
   int method, data_len, nchars;
      int dst_bytes;
 {
   unsigned char *dst = *destination;
   int method, data_len, nchars;
-  unsigned char *src_base = src++;
+  const unsigned char *src_base = src++;
   /* Store components of composition.  */
   int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH];
   int ncomponent;
   /* Store components of composition.  */
   int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH];
   int ncomponent;
@@ -811,6 +844,10 @@ decode_composition_emacs_mule (coding, src, src_end,
        return 0;
       for (ncomponent = 0; src < src_base + data_len; ncomponent++)
        {
        return 0;
       for (ncomponent = 0; src < src_base + data_len; ncomponent++)
        {
+         /* If it is longer than this, it can't be valid.  */
+         if (ncomponent >= COMPOSITION_DATA_MAX_BUNCH_LENGTH)
+           return 0;
+
          if (ncomponent % 2 && with_rule)
            {
              ONE_MORE_BYTE (gref);
          if (ncomponent % 2 && with_rule)
            {
              ONE_MORE_BYTE (gref);
@@ -822,7 +859,10 @@ decode_composition_emacs_mule (coding, src, src_end,
          else
            {
              int bytes;
          else
            {
              int bytes;
-             if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes))
+             if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)
+                 || (coding->flags /* We are recovering a file.  */
+                     && src[0] == LEADING_CODE_8_BIT_CONTROL
+                     && ! CHAR_HEAD_P (src[1])))
                c = STRING_CHAR (src, bytes);
              else
                c = *src, bytes = 1;
                c = STRING_CHAR (src, bytes);
              else
                c = *src, bytes = 1;
@@ -889,7 +929,7 @@ decode_composition_emacs_mule (coding, src, src_end,
       CODING_ADD_COMPOSITION_START (coding, coding->produced_char, method);
       for (i = 0; i < ncomponent; i++)
        CODING_ADD_COMPOSITION_COMPONENT (coding, component[i]);
       CODING_ADD_COMPOSITION_START (coding, coding->produced_char, method);
       for (i = 0; i < ncomponent; i++)
        CODING_ADD_COMPOSITION_COMPONENT (coding, component[i]);
-      CODING_ADD_COMPOSITION_END (coding, coding->produced_char + nchars);  
+      CODING_ADD_COMPOSITION_END (coding, coding->produced_char + nchars);
       if (buf < bufp)
        {
          unsigned char *p = buf;
       if (buf < bufp)
        {
          unsigned char *p = buf;
@@ -908,23 +948,25 @@ decode_composition_emacs_mule (coding, src, src_end,
 static void
 decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
-  unsigned char *src_end = source + src_bytes;
+  const unsigned char *src = source;
+  const unsigned char *src_end = source + src_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* SRC_BASE remembers the start position in source in each loop.
      The loop will be exited when there's not enough source code, or
      when there's not enough destination area to produce a
      character.  */
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* SRC_BASE remembers the start position in source in each loop.
      The loop will be exited when there's not enough source code, or
      when there's not enough destination area to produce a
      character.  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
 
   coding->produced_char = 0;
   while ((src_base = src) < src_end)
     {
 
   coding->produced_char = 0;
   while ((src_base = src) < src_end)
     {
-      unsigned char tmp[MAX_MULTIBYTE_LENGTH], *p;
+      unsigned char tmp[MAX_MULTIBYTE_LENGTH];
+      const unsigned char *p;
       int bytes;
 
       if (*src == '\r')
       int bytes;
 
       if (*src == '\r')
@@ -938,11 +980,6 @@ decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
              ONE_MORE_BYTE (c);
              if (c != '\n')
                {
              ONE_MORE_BYTE (c);
              if (c != '\n')
                {
-                 if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
-                   {
-                     coding->result = CODING_FINISH_INCONSISTENT_EOL;
-                     goto label_end_of_loop;
-                   }
                  src--;
                  c = '\r';
                }
                  src--;
                  c = '\r';
                }
@@ -964,7 +1001,7 @@ decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
          coding->produced_char++;
          continue;
        }
          coding->produced_char++;
          continue;
        }
-      else if (*src == 0x80)
+      else if (*src == 0x80 && coding->cmp_data)
        {
          /* Start of composition data.  */
          int consumed  = decode_composition_emacs_mule (coding, src, src_end,
        {
          /* Start of composition data.  */
          int consumed  = decode_composition_emacs_mule (coding, src, src_end,
@@ -981,16 +1018,36 @@ decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
          p = tmp;
          src++;
        }
          p = tmp;
          src++;
        }
-      else if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes))
+      else if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)
+              || (coding->flags /* We are recovering a file.  */
+                  && src[0] == LEADING_CODE_8_BIT_CONTROL
+                  && ! CHAR_HEAD_P (src[1])))
        {
          p = src;
          src += bytes;
        }
       else
        {
        {
          p = src;
          src += bytes;
        }
       else
        {
-         bytes = CHAR_STRING (*src, tmp);
-         p = tmp;
+         int i, c;
+
+         bytes = BYTES_BY_CHAR_HEAD (*src);
          src++;
          src++;
+         for (i = 1; i < bytes; i++)
+           {
+             ONE_MORE_BYTE (c);
+             if (CHAR_HEAD_P (c))
+               break;
+           }
+         if (i < bytes)
+           {
+             bytes = CHAR_STRING (*src_base, tmp);
+             p = tmp;
+             src = src_base + 1;
+           }
+         else
+           {
+             p = src_base;
+           }
        }
       if (dst + bytes >= (dst_bytes ? dst_end : src))
        {
        }
       if (dst + bytes >= (dst_bytes ? dst_end : src))
        {
@@ -1055,22 +1112,23 @@ decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
        coding->cmp_data_start = 0;                                     \
       }                                                                        \
   } while (0)
        coding->cmp_data_start = 0;                                     \
       }                                                                        \
   } while (0)
-  
 
 
-static void encode_eol P_ ((struct coding_system *, unsigned char *,
+
+static void encode_eol P_ ((struct coding_system *, const unsigned char *,
                            unsigned char *, int, int));
 
 static void
 encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
                            unsigned char *, int, int));
 
 static void
 encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
-  unsigned char *src_end = source + src_bytes;
+  const unsigned char *src = source;
+  const unsigned char *src_end = source + src_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
-  unsigned char *src_base;
+  const unsigned char *src_base;
   int c;
   int char_offset;
   int *data;
   int c;
   int char_offset;
   int *data;
@@ -1112,7 +1170,22 @@ encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
            EMIT_ONE_BYTE ('\r');
        }
       else if (SINGLE_BYTE_CHAR_P (c))
            EMIT_ONE_BYTE ('\r');
        }
       else if (SINGLE_BYTE_CHAR_P (c))
-       EMIT_ONE_BYTE (c);
+       {
+         if (coding->flags && ! ASCII_BYTE_P (c))
+           {
+             /* As we are auto saving, retain the multibyte form for
+                8-bit chars.  */
+             unsigned char buf[MAX_MULTIBYTE_LENGTH];
+             int bytes = CHAR_STRING (c, buf);
+
+             if (bytes == 1)
+               EMIT_ONE_BYTE (buf[0]);
+             else
+               EMIT_TWO_BYTES (buf[0], buf[1]);
+           }
+         else
+           EMIT_ONE_BYTE (c);
+       }
       else
        EMIT_BYTES (src_base, src);
       coding->consumed_char++;
       else
        EMIT_BYTES (src_base, src);
       coding->consumed_char++;
@@ -1306,7 +1379,7 @@ enum iso_code_class_type iso_code_class[256];
 #define CHARSET_OK(idx, charset, c)                                    \
   (coding_system_table[idx]                                            \
    && (charset == CHARSET_ASCII                                                \
 #define CHARSET_OK(idx, charset, c)                                    \
   (coding_system_table[idx]                                            \
    && (charset == CHARSET_ASCII                                                \
-       || (safe_chars = coding_safe_chars (coding_system_table[idx]),  \
+       || (safe_chars = coding_safe_chars (coding_system_table[idx]->symbol), \
           CODING_SAFE_CHAR_P (safe_chars, c)))                         \
    && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding_system_table[idx],        \
                                              charset)                  \
           CODING_SAFE_CHAR_P (safe_chars, c)))                         \
    && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding_system_table[idx],        \
                                              charset)                  \
@@ -1315,6 +1388,9 @@ enum iso_code_class_type iso_code_class[256];
 #define SHIFT_OUT_OK(idx) \
   (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0)
 
 #define SHIFT_OUT_OK(idx) \
   (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0)
 
+#define COMPOSITION_OK(idx)    \
+  (coding_system_table[idx]->composing != COMPOSITION_DISABLED)
+
 /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
    Check if a text is encoded in ISO2022.  If it is, return an
    integer in which appropriate flag bits any of:
 /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
    Check if a text is encoded in ISO2022.  If it is, return an
    integer in which appropriate flag bits any of:
@@ -1345,6 +1421,7 @@ detect_coding_iso2022 (src, src_end, multibytep)
   while (mask && src < src_end)
     {
       ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);
   while (mask && src < src_end)
     {
       ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);
+    retry:
       switch (c)
        {
        case ISO_CODE_ESC:
       switch (c)
        {
        case ISO_CODE_ESC:
@@ -1391,7 +1468,30 @@ detect_coding_iso2022 (src, src_end, multibytep)
          else if (c >= '0' && c <= '4')
            {
              /* ESC <Fp> for start/end composition.  */
          else if (c >= '0' && c <= '4')
            {
              /* ESC <Fp> for start/end composition.  */
-             mask_found |= CODING_CATEGORY_MASK_ISO;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7))
+               mask_found |= CODING_CATEGORY_MASK_ISO_7;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_7;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT))
+               mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_1))
+               mask_found |= CODING_CATEGORY_MASK_ISO_8_1;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_8_1;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_2))
+               mask_found |= CODING_CATEGORY_MASK_ISO_8_2;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_ELSE))
+               mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE;
+             if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_ELSE))
+               mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE;
+             else
+               mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE;
              break;
            }
          else
              break;
            }
          else
@@ -1433,7 +1533,7 @@ detect_coding_iso2022 (src, src_end, multibytep)
              mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;
            }
          break;
              mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;
            }
          break;
-         
+
        case ISO_CODE_SI:
          if (inhibit_iso_escape_detection)
            break;
        case ISO_CODE_SI:
          if (inhibit_iso_escape_detection)
            break;
@@ -1519,6 +1619,8 @@ detect_coding_iso2022 (src, src_end, multibytep)
                  && mask & CODING_CATEGORY_MASK_ISO_8_2)
                {
                  int i = 1;
                  && mask & CODING_CATEGORY_MASK_ISO_8_2)
                {
                  int i = 1;
+
+                 c = -1;
                  while (src < src_end)
                    {
                      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);
                  while (src < src_end)
                    {
                      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);
@@ -1531,6 +1633,9 @@ detect_coding_iso2022 (src, src_end, multibytep)
                    mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
                  else
                    mask_found |= CODING_CATEGORY_MASK_ISO_8_2;
                    mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
                  else
                    mask_found |= CODING_CATEGORY_MASK_ISO_8_2;
+                 if (c >= 0)
+                   /* This means that we have read one extra byte.  */
+                   goto retry;
                }
            }
          break;
                }
            }
          break;
@@ -1606,6 +1711,7 @@ coding_allocate_composition_data (coding, char_offset)
     coding->cmp_data->next = cmp_data;
   coding->cmp_data = cmp_data;
   coding->cmp_data_start = 0;
     coding->cmp_data->next = cmp_data;
   coding->cmp_data = cmp_data;
   coding->cmp_data_start = 0;
+  coding->composing = COMPOSITION_NO;
 }
 
 /* Handle composition start sequence ESC 0, ESC 2, ESC 3, or ESC 4.
 }
 
 /* Handle composition start sequence ESC 0, ESC 2, ESC 3, or ESC 4.
@@ -1665,7 +1771,7 @@ coding_allocate_composition_data (coding, char_offset)
 
 #define DECODE_COMPOSITION_END(c1)                                     \
   do {                                                                 \
 
 #define DECODE_COMPOSITION_END(c1)                                     \
   do {                                                                 \
-    if (coding->composing == COMPOSITION_DISABLED)                     \
+    if (! COMPOSING_P (coding))                                                \
       {                                                                        \
        *dst++ = ISO_CODE_ESC;                                          \
        *dst++ = c1;                                                    \
       {                                                                        \
        *dst++ = ISO_CODE_ESC;                                          \
        *dst++ = c1;                                                    \
@@ -1709,11 +1815,12 @@ coding_allocate_composition_data (coding, char_offset)
 static void
 decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
-  unsigned char *src_end = source + src_bytes;
+  const unsigned char *src = source;
+  const unsigned char *src_end = source + src_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
@@ -1724,12 +1831,12 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
   int c, charset;
   Lisp_Object translation_table;
   Lisp_Object safe_chars;
 
   int c, charset;
   Lisp_Object translation_table;
   Lisp_Object safe_chars;
 
-  safe_chars = coding_safe_chars (coding);
+  safe_chars = coding_safe_chars (coding->symbol);
 
   if (NILP (Venable_character_translation))
     translation_table = Qnil;
 
   if (NILP (Venable_character_translation))
     translation_table = Qnil;
@@ -1744,7 +1851,7 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
 
   while (1)
     {
 
   while (1)
     {
-      int c1, c2;
+      int c1, c2 = 0;
 
       src_base = src;
       ONE_MORE_BYTE (c1);
 
       src_base = src;
       ONE_MORE_BYTE (c1);
@@ -1820,11 +1927,6 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
              ONE_MORE_BYTE (c1);
              if (c1 != ISO_CODE_LF)
                {
              ONE_MORE_BYTE (c1);
              if (c1 != ISO_CODE_LF)
                {
-                 if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
-                   {
-                     coding->result = CODING_FINISH_INCONSISTENT_EOL;
-                     goto label_end_of_loop;
-                   }
                  src--;
                  c1 = '\r';
                }
                  src--;
                  c1 = '\r';
                }
@@ -1989,6 +2091,81 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
                }
              continue;
 
                }
              continue;
 
+           case '%':
+             if (COMPOSING_P (coding))
+               DECODE_COMPOSITION_END ('1');
+             ONE_MORE_BYTE (c1);
+             if (c1 == '/')
+               {
+                 /* CTEXT extended segment:
+                    ESC % / [0-4] M L --ENCODING-NAME-- \002 --BYTES--
+                    We keep these bytes as is for the moment.
+                    They may be decoded by post-read-conversion.  */
+                 int dim, M, L;
+                 int size, required;
+                 int produced_chars;
+
+                 ONE_MORE_BYTE (dim);
+                 ONE_MORE_BYTE (M);
+                 ONE_MORE_BYTE (L);
+                 size = ((M - 128) * 128) + (L - 128);
+                 required = 8 + size * 2;
+                 if (dst + required > (dst_bytes ? dst_end : src))
+                   goto label_end_of_loop;
+                 *dst++ = ISO_CODE_ESC;
+                 *dst++ = '%';
+                 *dst++ = '/';
+                 *dst++ = dim;
+                 produced_chars = 4;
+                 dst += CHAR_STRING (M, dst), produced_chars++;
+                 dst += CHAR_STRING (L, dst), produced_chars++;
+                 while (size-- > 0)
+                   {
+                     ONE_MORE_BYTE (c1);
+                     dst += CHAR_STRING (c1, dst), produced_chars++;
+                   }
+                 coding->produced_char += produced_chars;
+               }
+             else if (c1 == 'G')
+               {
+                 unsigned char *d = dst;
+                 int produced_chars;
+
+                 /* XFree86 extension for embedding UTF-8 in CTEXT:
+                    ESC % G --UTF-8-BYTES-- ESC % @
+                    We keep these bytes as is for the moment.
+                    They may be decoded by post-read-conversion.  */
+                 if (d + 6 > (dst_bytes ? dst_end : src))
+                   goto label_end_of_loop;
+                 *d++ = ISO_CODE_ESC;
+                 *d++ = '%';
+                 *d++ = 'G';
+                 produced_chars = 3;
+                 while (d + 1 < (dst_bytes ? dst_end : src))
+                   {
+                     ONE_MORE_BYTE (c1);
+                     if (c1 == ISO_CODE_ESC
+                         && src + 1 < src_end
+                         && src[0] == '%'
+                         && src[1] == '@')
+                       {
+                         src += 2;
+                         break;
+                       }
+                     d += CHAR_STRING (c1, d), produced_chars++;
+                   }
+                 if (d + 3 > (dst_bytes ? dst_end : src))
+                   goto label_end_of_loop;
+                 *d++ = ISO_CODE_ESC;
+                 *d++ = '%';
+                 *d++ = '@';
+                 dst = d;
+                 coding->produced_char += produced_chars + 3;
+               }
+             else
+               goto label_invalid_code;
+             continue;
+
            default:
              if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))
                goto label_invalid_code;
            default:
              if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))
                goto label_invalid_code;
@@ -2031,6 +2208,8 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
        DECODE_COMPOSITION_END ('1');
       src = src_base;
       c = *src++;
        DECODE_COMPOSITION_END ('1');
       src = src_base;
       c = *src++;
+      if (! NILP (translation_table))
+       c = translate_char (translation_table, c, 0, 0, 0);
       EMIT_CHAR (c);
     }
 
       EMIT_CHAR (c);
     }
 
@@ -2254,11 +2433,11 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
 
 /* Instead of encoding character C, produce one or two `?'s.  */
 
 
 /* Instead of encoding character C, produce one or two `?'s.  */
 
-#define ENCODE_UNSAFE_CHARACTER(c)                                     \
-  do {                                                                 \
-    ENCODE_ISO_CHARACTER (CODING_INHIBIT_CHARACTER_SUBSTITUTION);      \
-    if (CHARSET_WIDTH (CHAR_CHARSET (c)) > 1)                          \
-      ENCODE_ISO_CHARACTER (CODING_INHIBIT_CHARACTER_SUBSTITUTION);    \
+#define ENCODE_UNSAFE_CHARACTER(c)                             \
+  do {                                                         \
+    ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);       \
+    if (CHARSET_WIDTH (CHAR_CHARSET (c)) > 1)                  \
+      ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);     \
   } while (0)
 
 
   } while (0)
 
 
@@ -2425,7 +2604,8 @@ static unsigned char *
 encode_designation_at_bol (coding, translation_table, src, src_end, dst)
      struct coding_system *coding;
      Lisp_Object translation_table;
 encode_designation_at_bol (coding, translation_table, src, src_end, dst)
      struct coding_system *coding;
      Lisp_Object translation_table;
-     unsigned char *src, *src_end, *dst;
+     const unsigned char *src, *src_end;
+     unsigned char *dst;
 {
   int charset, c, found = 0, reg;
   /* Table of charsets to be designated to each graphic register.  */
 {
   int charset, c, found = 0, reg;
   /* Table of charsets to be designated to each graphic register.  */
@@ -2439,7 +2619,7 @@ encode_designation_at_bol (coding, translation_table, src, src_end, dst)
       ONE_MORE_CHAR (c);
       if (c == '\n')
        break;
       ONE_MORE_CHAR (c);
       if (c == '\n')
        break;
-      
+
       charset = CHAR_CHARSET (c);
       reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);
       if (reg != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION && r[reg] < 0)
       charset = CHAR_CHARSET (c);
       reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);
       if (reg != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION && r[reg] < 0)
@@ -2466,11 +2646,12 @@ encode_designation_at_bol (coding, translation_table, src, src_end, dst)
 static void
 encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
-  unsigned char *src_end = source + src_bytes;
+  const unsigned char *src = source;
+  const unsigned char *src_end = source + src_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* Since the maximum bytes produced by each loop is 20, we subtract 19
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* Since the maximum bytes produced by each loop is 20, we subtract 19
@@ -2482,12 +2663,15 @@ encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
      analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
      there's not enough destination area to produce encoded codes
      (within macro EMIT_BYTES).  */
      analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
      there's not enough destination area to produce encoded codes
      (within macro EMIT_BYTES).  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
   int c;
   Lisp_Object translation_table;
   Lisp_Object safe_chars;
 
   int c;
   Lisp_Object translation_table;
   Lisp_Object safe_chars;
 
-  safe_chars = coding_safe_chars (coding);
+  if (coding->flags & CODING_FLAG_ISO_SAFE)
+    coding->mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
+
+  safe_chars = coding_safe_chars (coding->symbol);
 
   if (NILP (Venable_character_translation))
     translation_table = Qnil;
 
   if (NILP (Venable_character_translation))
     translation_table = Qnil;
@@ -2554,7 +2738,7 @@ encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
                    }
                  else
                    {
                    }
                  else
                    {
-                     if (coding->flags & CODING_FLAG_ISO_SAFE
+                     if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR
                          && ! CODING_SAFE_CHAR_P (safe_chars, c))
                        ENCODE_UNSAFE_CHARACTER (c);
                      else
                          && ! CODING_SAFE_CHAR_P (safe_chars, c))
                        ENCODE_UNSAFE_CHARACTER (c);
                      else
@@ -2609,7 +2793,7 @@ encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
                *dst++ = ISO_CODE_CR;
              CODING_SPEC_ISO_BOL (coding) = 1;
            }
                *dst++ = ISO_CODE_CR;
              CODING_SPEC_ISO_BOL (coding) = 1;
            }
-         else 
+         else
            {
              if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)
                ENCODE_RESET_PLANE_AND_REGISTER;
            {
              if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)
                ENCODE_RESET_PLANE_AND_REGISTER;
@@ -2623,7 +2807,7 @@ encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
          *dst++ = c;
          coding->errors++;
        }
          *dst++ = c;
          coding->errors++;
        }
-      else if (coding->flags & CODING_FLAG_ISO_SAFE
+      else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR
               && ! CODING_SAFE_CHAR_P (safe_chars, c))
        ENCODE_UNSAFE_CHARACTER (c);
       else
               && ! CODING_SAFE_CHAR_P (safe_chars, c))
        ENCODE_UNSAFE_CHARACTER (c);
       else
@@ -2681,7 +2865,7 @@ encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
 
 /* Macros to decode or encode a character of Big5 in BIG5.  B1 and B2
    are the 1st and 2nd position-codes of Big5 in BIG5 coding system.
 
 /* Macros to decode or encode a character of Big5 in BIG5.  B1 and B2
    are the 1st and 2nd position-codes of Big5 in BIG5 coding system.
-   C1 and C2 are the 1st and 2nd position-codes of of Emacs' internal
+   C1 and C2 are the 1st and 2nd position-codes of Emacs' internal
    format.  CHARSET is `charset_big5_1' or `charset_big5_2'.  */
 
 /* Number of Big5 characters which have the same code in 1st byte.  */
    format.  CHARSET is `charset_big5_1' or `charset_big5_2'.  */
 
 /* Number of Big5 characters which have the same code in 1st byte.  */
@@ -2850,7 +3034,7 @@ detect_coding_utf_16 (src, src_end, multibytep)
      int multibytep;
 {
   unsigned char c1, c2;
      int multibytep;
 {
   unsigned char c1, c2;
-  /* Dummy for TWO_MORE_BYTES.  */
+  /* Dummy for ONE_MORE_BYTE_CHECK_MULTIBYTE.  */
   struct coding_system dummy_coding;
   struct coding_system *coding = &dummy_coding;
 
   struct coding_system dummy_coding;
   struct coding_system *coding = &dummy_coding;
 
@@ -2873,12 +3057,13 @@ static void
 decode_coding_sjis_big5 (coding, source, destination,
                         src_bytes, dst_bytes, sjis_p)
      struct coding_system *coding;
 decode_coding_sjis_big5 (coding, source, destination,
                         src_bytes, dst_bytes, sjis_p)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char  *destination;
      int src_bytes, dst_bytes;
      int sjis_p;
 {
      int src_bytes, dst_bytes;
      int sjis_p;
 {
-  unsigned char *src = source;
-  unsigned char *src_end = source + src_bytes;
+  const unsigned char *src = source;
+  const unsigned char *src_end = source + src_bytes;
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* SRC_BASE remembers the start position in source in each loop.
   unsigned char *dst = destination;
   unsigned char *dst_end = destination + dst_bytes;
   /* SRC_BASE remembers the start position in source in each loop.
@@ -2886,7 +3071,7 @@ decode_coding_sjis_big5 (coding, source, destination,
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
   Lisp_Object translation_table;
 
   if (NILP (Venable_character_translation))
   Lisp_Object translation_table;
 
   if (NILP (Venable_character_translation))
@@ -2901,7 +3086,7 @@ decode_coding_sjis_big5 (coding, source, destination,
   coding->produced_char = 0;
   while (1)
     {
   coding->produced_char = 0;
   while (1)
     {
-      int c, charset, c1, c2;
+      int c, charset, c1, c2 = 0;
 
       src_base = src;
       ONE_MORE_BYTE (c1);
 
       src_base = src;
       ONE_MORE_BYTE (c1);
@@ -2918,12 +3103,6 @@ decode_coding_sjis_big5 (coding, source, destination,
                      ONE_MORE_BYTE (c2);
                      if (c2 == '\n')
                        c1 = c2;
                      ONE_MORE_BYTE (c2);
                      if (c2 == '\n')
                        c1 = c2;
-                     else if (coding->mode
-                              & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
-                       {
-                         coding->result = CODING_FINISH_INCONSISTENT_EOL;
-                         goto label_end_of_loop;
-                       }
                      else
                        /* To process C2 again, SRC is subtracted by 1.  */
                        src--;
                      else
                        /* To process C2 again, SRC is subtracted by 1.  */
                        src--;
@@ -3032,14 +3211,14 @@ encode_coding_sjis_big5 (coding, source, destination,
 
       src_base = src;
       ONE_MORE_CHAR (c);
 
       src_base = src;
       ONE_MORE_CHAR (c);
-      
+
       /* Now encode the character C.  */
       if (SINGLE_BYTE_CHAR_P (c))
        {
          switch (c)
            {
            case '\r':
       /* Now encode the character C.  */
       if (SINGLE_BYTE_CHAR_P (c))
        {
          switch (c)
            {
            case '\r':
-             if (!coding->mode & CODING_MODE_SELECTIVE_DISPLAY)
+             if (!(coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
                {
                  EMIT_ONE_BYTE (c);
                  break;
                {
                  EMIT_ONE_BYTE (c);
                  break;
@@ -3072,6 +3251,12 @@ encode_coding_sjis_big5 (coding, source, destination,
                EMIT_ONE_BYTE (c1 | 0x80);
              else if (charset == charset_latin_jisx0201)
                EMIT_ONE_BYTE (c1);
                EMIT_ONE_BYTE (c1 | 0x80);
              else if (charset == charset_latin_jisx0201)
                EMIT_ONE_BYTE (c1);
+             else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)
+               {
+                 EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
+                 if (CHARSET_WIDTH (charset) > 1)
+                   EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
+               }
              else
                /* There's no way other than producing the internal
                   codes as is.  */
              else
                /* There's no way other than producing the internal
                   codes as is.  */
@@ -3084,6 +3269,12 @@ encode_coding_sjis_big5 (coding, source, destination,
                  ENCODE_BIG5 (charset, c1, c2, c1, c2);
                  EMIT_TWO_BYTES (c1, c2);
                }
                  ENCODE_BIG5 (charset, c1, c2, c1, c2);
                  EMIT_TWO_BYTES (c1, c2);
                }
+             else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)
+               {
+                 EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
+                 if (CHARSET_WIDTH (charset) > 1)
+                   EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
+               }
              else
                /* There's no way other than producing the internal
                   codes as is.  */
              else
                /* There's no way other than producing the internal
                   codes as is.  */
@@ -3140,12 +3331,13 @@ detect_coding_ccl (src, src_end, multibytep)
 static void
 decode_eol (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 decode_eol (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
+  const unsigned char *src = source;
   unsigned char *dst = destination;
   unsigned char *dst = destination;
-  unsigned char *src_end = src + src_bytes;
+  const unsigned char *src_end = src + src_bytes;
   unsigned char *dst_end = dst + dst_bytes;
   Lisp_Object translation_table;
   /* SRC_BASE remembers the start position in source in each loop.
   unsigned char *dst_end = dst + dst_bytes;
   Lisp_Object translation_table;
   /* SRC_BASE remembers the start position in source in each loop.
@@ -3153,7 +3345,7 @@ decode_eol (coding, source, destination, src_bytes, dst_bytes)
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
      (within macro ONE_MORE_BYTE), or when there's not enough
      destination area to produce a character (within macro
      EMIT_CHAR).  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
   int c;
 
   translation_table = Qnil;
   int c;
 
   translation_table = Qnil;
@@ -3169,11 +3361,6 @@ decode_eol (coding, source, destination, src_bytes, dst_bytes)
              ONE_MORE_BYTE (c);
              if (c != '\n')
                {
              ONE_MORE_BYTE (c);
              if (c != '\n')
                {
-                 if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
-                   {
-                     coding->result = CODING_FINISH_INCONSISTENT_EOL;
-                     goto label_end_of_loop;
-                   }
                  src--;
                  c = '\r';
                }
                  src--;
                  c = '\r';
                }
@@ -3232,12 +3419,13 @@ decode_eol (coding, source, destination, src_bytes, dst_bytes)
 static void
 encode_eol (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 static void
 encode_eol (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
-  unsigned char *src = source;
+  const unsigned char *src = source;
   unsigned char *dst = destination;
   unsigned char *dst = destination;
-  unsigned char *src_end = src + src_bytes;
+  const unsigned char *src_end = src + src_bytes;
   unsigned char *dst_end = dst + dst_bytes;
   Lisp_Object translation_table;
   /* SRC_BASE remembers the start position in source in each loop.
   unsigned char *dst_end = dst + dst_bytes;
   Lisp_Object translation_table;
   /* SRC_BASE remembers the start position in source in each loop.
@@ -3245,7 +3433,8 @@ encode_eol (coding, source, destination, src_bytes, dst_bytes)
      analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
      there's not enough destination area to produce encoded codes
      (within macro EMIT_BYTES).  */
      analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
      there's not enough destination area to produce encoded codes
      (within macro EMIT_BYTES).  */
-  unsigned char *src_base;
+  const unsigned char *src_base;
+  unsigned char *tmp;
   int c;
   int selective_display = coding->mode & CODING_MODE_SELECTIVE_DISPLAY;
 
   int c;
   int selective_display = coding->mode & CODING_MODE_SELECTIVE_DISPLAY;
 
@@ -3295,13 +3484,13 @@ encode_eol (coding, source, destination, src_bytes, dst_bytes)
        }
       if (coding->eol_type == CODING_EOL_CR)
        {
        }
       if (coding->eol_type == CODING_EOL_CR)
        {
-         for (src = destination; src < dst; src++)
-           if (*src == '\n') *src = '\r';
+         for (tmp = destination; tmp < dst; tmp++)
+           if (*tmp == '\n') *tmp = '\r';
        }
       else if (selective_display)
        {
        }
       else if (selective_display)
        {
-         for (src = destination; src < dst; src++)
-           if (*src == '\r') *src = '\n';
+         for (tmp = destination; tmp < dst; tmp++)
+           if (*tmp == '\r') *tmp = '\n';
        }
     }
   if (coding->src_multibyte)
        }
     }
   if (coding->src_multibyte)
@@ -3357,7 +3546,7 @@ encode_eol (coding, source, destination, src_bytes, dst_bytes)
 
        If the value is nil, graphic register N is never used on
        encoding.
 
        If the value is nil, graphic register N is never used on
        encoding.
-   
+
    sub-element[N] where N is 4 through 11: to be set in `coding->flags'
        Each value takes t or nil.  See the section ISO2022 of
        `coding.h' for more information.
    sub-element[N] where N is 4 through 11: to be set in `coding->flags'
        Each value takes t or nil.  See the section ISO2022 of
        `coding.h' for more information.
@@ -3481,7 +3670,7 @@ setup_coding_system (coding_system, coding)
     }
   else
     goto label_invalid_coding_system;
     }
   else
     goto label_invalid_coding_system;
-  
+
   /* If the coding system has non-nil `composition' property, enable
      composition handling.  */
   val = Fplist_get (plist, Qcomposition);
   /* If the coding system has non-nil `composition' property, enable
      composition handling.  */
   val = Fplist_get (plist, Qcomposition);
@@ -3494,7 +3683,6 @@ setup_coding_system (coding_system, coding)
       coding->type = coding_type_emacs_mule;
       coding->common_flags
        |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
       coding->type = coding_type_emacs_mule;
       coding->common_flags
        |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
-      coding->composing = COMPOSITION_NO;
       if (!NILP (coding->post_read_conversion))
        coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
       if (!NILP (coding->pre_write_conversion))
       if (!NILP (coding->post_read_conversion))
        coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
       if (!NILP (coding->pre_write_conversion))
@@ -3576,8 +3764,8 @@ setup_coding_system (coding_system, coding)
            = CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION;
        for (i = 0; i < 4; i++)
          {
            = CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION;
        for (i = 0; i < 4; i++)
          {
-           if (INTEGERP (flags[i])
-               && (charset = XINT (flags[i]), CHARSET_VALID_P (charset))
+           if ((INTEGERP (flags[i])
+                && (charset = XINT (flags[i]), CHARSET_VALID_P (charset)))
                || (charset = get_charset_id (flags[i])) >= 0)
              {
                CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
                || (charset = get_charset_id (flags[i])) >= 0)
              {
                CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
@@ -3595,9 +3783,9 @@ setup_coding_system (coding_system, coding)
                tail = flags[i];
 
                coding->flags |= CODING_FLAG_ISO_DESIGNATION;
                tail = flags[i];
 
                coding->flags |= CODING_FLAG_ISO_DESIGNATION;
-               if (INTEGERP (XCAR (tail))
-                   && (charset = XINT (XCAR (tail)),
-                       CHARSET_VALID_P (charset))
+               if ((INTEGERP (XCAR (tail))
+                    && (charset = XINT (XCAR (tail)),
+                        CHARSET_VALID_P (charset)))
                    || (charset = get_charset_id (XCAR (tail))) >= 0)
                  {
                    CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
                    || (charset = get_charset_id (XCAR (tail))) >= 0)
                  {
                    CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
@@ -3608,9 +3796,9 @@ setup_coding_system (coding_system, coding)
                tail = XCDR (tail);
                while (CONSP (tail))
                  {
                tail = XCDR (tail);
                while (CONSP (tail))
                  {
-                   if (INTEGERP (XCAR (tail))
-                       && (charset = XINT (XCAR (tail)),
-                           CHARSET_VALID_P (charset))
+                   if ((INTEGERP (XCAR (tail))
+                        && (charset = XINT (XCAR (tail)),
+                            CHARSET_VALID_P (charset)))
                        || (charset = get_charset_id (XCAR (tail))) >= 0)
                      CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
                        = i;
                        || (charset = get_charset_id (XCAR (tail))) >= 0)
                      CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
                        = i;
@@ -3621,7 +3809,7 @@ setup_coding_system (coding_system, coding)
              }
            else
              CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
              }
            else
              CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
-           
+
            CODING_SPEC_ISO_DESIGNATION (coding, i)
              = CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i);
          }
            CODING_SPEC_ISO_DESIGNATION (coding, i)
              = CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i);
          }
@@ -3870,7 +4058,7 @@ setup_raw_text_coding_system (coding)
    o coding-category-utf-8
 
        The category for a coding system which has the same code range
    o coding-category-utf-8
 
        The category for a coding system which has the same code range
-       as UTF-8 (cf. RFC2279).  Assigned the coding-system (Lisp
+       as UTF-8 (cf. RFC3629).  Assigned the coding-system (Lisp
        symbol) `utf-8' by default.
 
    o coding-category-utf-16-be
        symbol) `utf-8' by default.
 
    o coding-category-utf-16-be
@@ -3994,7 +4182,7 @@ detect_coding_mask (source, src_bytes, priorities, skip, multibytep)
                  | CODING_CATEGORY_MASK_UTF_16_LE);
 
          /* Or, if C is a special latin extra code,
                  | CODING_CATEGORY_MASK_UTF_16_LE);
 
          /* Or, if C is a special latin extra code,
-            or is an ISO2022 specific control code of C1 (SS2 or SS3), 
+            or is an ISO2022 specific control code of C1 (SS2 or SS3),
             or is an ISO2022 control-sequence-introducer (CSI),
             we should also consider the possibility of ISO2022 codings.  */
          if ((VECTORP (Vlatin_extra_code_table)
             or is an ISO2022 control-sequence-introducer (CSI),
             we should also consider the possibility of ISO2022 codings.  */
          if ((VECTORP (Vlatin_extra_code_table)
@@ -4037,7 +4225,7 @@ detect_coding_mask (source, src_bytes, priorities, skip, multibytep)
              if (!iso2022_examined_p
                  && (priorities[i] & try & CODING_CATEGORY_MASK_ISO))
                {
              if (!iso2022_examined_p
                  && (priorities[i] & try & CODING_CATEGORY_MASK_ISO))
                {
-                 mask |= detect_coding_iso2022 (src, src_end);
+                 mask |= detect_coding_iso2022 (src, src_end, multibytep);
                  iso2022_examined_p = 1;
                }
              else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS)
                  iso2022_examined_p = 1;
                }
              else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS)
@@ -4090,7 +4278,7 @@ detect_coding_mask (source, src_bytes, priorities, skip, multibytep)
 void
 detect_coding (coding, src, src_bytes)
      struct coding_system *coding;
 void
 detect_coding (coding, src, src_bytes)
      struct coding_system *coding;
-     unsigned char *src;
+     const unsigned char *src;
      int src_bytes;
 {
   unsigned int idx;
      int src_bytes;
 {
   unsigned int idx;
@@ -4263,7 +4451,7 @@ detect_eol_type_in_2_octet_form (source, src_bytes, skip, big_endian_p)
 void
 detect_eol (coding, src, src_bytes)
      struct coding_system *coding;
 void
 detect_eol (coding, src, src_bytes)
      struct coding_system *coding;
-     unsigned char *src;
+     const unsigned char *src;
      int src_bytes;
 {
   Lisp_Object val;
      int src_bytes;
 {
   Lisp_Object val;
@@ -4313,11 +4501,13 @@ detect_eol (coding, src, src_bytes)
     {
       int src_multibyte = coding->src_multibyte;
       int dst_multibyte = coding->dst_multibyte;
     {
       int src_multibyte = coding->src_multibyte;
       int dst_multibyte = coding->dst_multibyte;
+      struct composition_data *cmp_data = coding->cmp_data;
 
       setup_coding_system (XVECTOR (val)->contents[eol_type], coding);
       coding->src_multibyte = src_multibyte;
       coding->dst_multibyte = dst_multibyte;
       coding->heading_ascii = skip;
 
       setup_coding_system (XVECTOR (val)->contents[eol_type], coding);
       coding->src_multibyte = src_multibyte;
       coding->dst_multibyte = dst_multibyte;
       coding->heading_ascii = skip;
+      coding->cmp_data = cmp_data;
     }
 }
 
     }
 }
 
@@ -4353,7 +4543,11 @@ encoding_buffer_size (coding, src_bytes)
   int magnification;
 
   if (coding->type == coding_type_ccl)
   int magnification;
 
   if (coding->type == coding_type_ccl)
-    magnification = coding->spec.ccl.encoder.buf_magnification;
+    {
+      magnification = coding->spec.ccl.encoder.buf_magnification;
+      if (coding->eol_type == CODING_EOL_CRLF)
+       magnification *= 2;
+    }
   else if (CODING_REQUIRE_ENCODING (coding))
     magnification = 3;
   else
   else if (CODING_REQUIRE_ENCODING (coding))
     magnification = 3;
   else
@@ -4370,10 +4564,6 @@ struct conversion_buffer
   unsigned char *data;
 };
 
   unsigned char *data;
 };
 
-/* Don't use alloca for allocating memory space larger than this, lest
-   we overflow their stack.  */
-#define MAX_ALLOCA 16*1024
-
 /* Allocate LEN bytes of memory for BUF (struct conversion_buffer).  */
 #define allocate_conversion_buffer(buf, len)           \
   do {                                                 \
 /* Allocate LEN bytes of memory for BUF (struct conversion_buffer).  */
 #define allocate_conversion_buffer(buf, len)           \
   do {                                                 \
@@ -4438,7 +4628,10 @@ ccl_coding_driver (coding, source, destination, src_bytes, dst_bytes, encodep)
       if (ccl->eol_type ==CODING_EOL_UNDECIDED)
        ccl->eol_type = CODING_EOL_LF;
       ccl->cr_consumed = coding->spec.ccl.cr_carryover;
       if (ccl->eol_type ==CODING_EOL_UNDECIDED)
        ccl->eol_type = CODING_EOL_LF;
       ccl->cr_consumed = coding->spec.ccl.cr_carryover;
+      ccl->eight_bit_control = coding->dst_multibyte;
     }
     }
+  else
+    ccl->eight_bit_control = 1;
   ccl->multibyte = coding->src_multibyte;
   if (coding->spec.ccl.eight_bit_carryover[0] != 0)
     {
   ccl->multibyte = coding->src_multibyte;
   if (coding->spec.ccl.eight_bit_carryover[0] != 0)
     {
@@ -4586,7 +4779,7 @@ decode_eol_post_ccl (coding, ptr, bytes)
        {
          /* If the last character is CR, we can't handle it here
             because LF will be in the not-yet-decoded source text.
        {
          /* If the last character is CR, we can't handle it here
             because LF will be in the not-yet-decoded source text.
-            Recorded that the CR is not yet processed.  */
+            Record that the CR is not yet processed.  */
          coding->spec.ccl.cr_carryover = 1;
          coding->produced--;
          coding->produced_char--;
          coding->spec.ccl.cr_carryover = 1;
          coding->produced--;
          coding->produced_char--;
@@ -4679,9 +4872,12 @@ decode_eol_post_ccl (coding, ptr, bytes)
 int
 decode_coding (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 int
 decode_coding (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
      int src_bytes, dst_bytes;
 {
+  int extra = 0;
+
   if (coding->type == coding_type_undecided)
     detect_coding (coding, source, src_bytes);
 
   if (coding->type == coding_type_undecided)
     detect_coding (coding, source, src_bytes);
 
@@ -4724,18 +4920,24 @@ decode_coding (coding, source, destination, src_bytes, dst_bytes)
     case coding_type_ccl:
       if (coding->spec.ccl.cr_carryover)
        {
     case coding_type_ccl:
       if (coding->spec.ccl.cr_carryover)
        {
-         /* Set the CR which is not processed by the previous call of
-            decode_eol_post_ccl in DESTINATION.  */
+         /* Put the CR which was not processed by the previous call
+            of decode_eol_post_ccl in DESTINATION.  It will be
+            decoded together with the following LF by the call to
+            decode_eol_post_ccl below.  */
          *destination = '\r';
          coding->produced++;
          coding->produced_char++;
          dst_bytes--;
          *destination = '\r';
          coding->produced++;
          coding->produced_char++;
          dst_bytes--;
+         extra = coding->spec.ccl.cr_carryover;
        }
        }
-      ccl_coding_driver (coding, source,
-                        destination + coding->spec.ccl.cr_carryover,
+      ccl_coding_driver (coding, source, destination + extra,
                         src_bytes, dst_bytes, 0);
       if (coding->eol_type != CODING_EOL_LF)
                         src_bytes, dst_bytes, 0);
       if (coding->eol_type != CODING_EOL_LF)
-       decode_eol_post_ccl (coding, destination, coding->produced);
+       {
+         coding->produced += extra;
+         coding->produced_char += extra;
+         decode_eol_post_ccl (coding, destination, coding->produced);
+       }
       break;
 
     default:
       break;
 
     default:
@@ -4750,7 +4952,7 @@ decode_coding (coding, source, destination, src_bytes, dst_bytes)
   if (coding->mode & CODING_MODE_LAST_BLOCK
       && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
     {
   if (coding->mode & CODING_MODE_LAST_BLOCK
       && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
     {
-      unsigned char *src = source + coding->consumed;
+      const unsigned char *src = source + coding->consumed;
       unsigned char *dst = destination + coding->produced;
 
       src_bytes -= coding->consumed;
       unsigned char *dst = destination + coding->produced;
 
       src_bytes -= coding->consumed;
@@ -4784,7 +4986,8 @@ decode_coding (coding, source, destination, src_bytes, dst_bytes)
 int
 encode_coding (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
 int
 encode_coding (coding, source, destination, src_bytes, dst_bytes)
      struct coding_system *coding;
-     unsigned char *source, *destination;
+     const unsigned char *source;
+     unsigned char *destination;
      int src_bytes, dst_bytes;
 {
   coding->produced = coding->produced_char = 0;
      int src_bytes, dst_bytes;
 {
   coding->produced = coding->produced_char = 0;
@@ -4826,8 +5029,7 @@ encode_coding (coding, source, destination, src_bytes, dst_bytes)
   if (coding->mode & CODING_MODE_LAST_BLOCK
       && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
     {
   if (coding->mode & CODING_MODE_LAST_BLOCK
       && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
     {
-      unsigned char *src = source + coding->consumed;
-      unsigned char *src_end = src + src_bytes;
+      const unsigned char *src = source + coding->consumed;
       unsigned char *dst = destination + coding->produced;
 
       if (coding->type == coding_type_iso2022)
       unsigned char *dst = destination + coding->produced;
 
       if (coding->type == coding_type_iso2022)
@@ -4838,7 +5040,7 @@ encode_coding (coding, source, destination, src_bytes, dst_bytes)
        {
          int len = src_bytes - coding->consumed;
 
        {
          int len = src_bytes - coding->consumed;
 
-         BCOPY_SHORT (source + coding->consumed, dst, len);
+         BCOPY_SHORT (src, dst, len);
          if (coding->src_multibyte)
            len = str_as_unibyte (dst, len);
          dst += len;
          if (coding->src_multibyte)
            len = str_as_unibyte (dst, len);
          dst += len;
@@ -5048,7 +5250,7 @@ shrink_encoding_region (beg, end, coding, str)
   if (coding->type == coding_type_ccl
       || coding->eol_type == CODING_EOL_CRLF
       || coding->eol_type == CODING_EOL_CR
   if (coding->type == coding_type_ccl
       || coding->eol_type == CODING_EOL_CRLF
       || coding->eol_type == CODING_EOL_CR
-      || coding->cmp_data && coding->cmp_data->used > 0)
+      || (coding->cmp_data && coding->cmp_data->used > 0))
     {
       /* We can't skip any data.  */
       return;
     {
       /* We can't skip any data.  */
       return;
@@ -5102,7 +5304,7 @@ shrink_encoding_region (beg, end, coding, str)
        break;
       if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL)
        {
        break;
       if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL)
        {
-         unsigned char *bol = begp; 
+         unsigned char *bol = begp;
          while (begp < endp && *begp < 0x80)
            {
              begp++;
          while (begp < endp && *begp < 0x80)
            {
              begp++;
@@ -5151,11 +5353,17 @@ static int shrink_conversion_region_threshhold = 1024;
       }                                                                        \
   } while (0)
 
       }                                                                        \
   } while (0)
 
+/* ARG is (CODING . BUFFER) where CODING is what to be set in
+   Vlast_coding_system_used and BUFFER if non-nil is a buffer to
+   kill.  */
 static Lisp_Object
 static Lisp_Object
-code_convert_region_unwind (dummy)
-     Lisp_Object dummy;
+code_convert_region_unwind (arg)
+     Lisp_Object arg;
 {
   inhibit_pre_post_conversion = 0;
 {
   inhibit_pre_post_conversion = 0;
+  Vlast_coding_system_used = XCAR (arg);
+  if (! NILP (XCDR (arg)))
+    Fkill_buffer (XCDR (arg));
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -5211,7 +5419,7 @@ coding_save_composition (coding, from, to, obj)
              else if (VECTORP (val) || STRINGP (val))
                {
                  int len = (VECTORP (val)
              else if (VECTORP (val) || STRINGP (val))
                {
                  int len = (VECTORP (val)
-                            ? XVECTOR (val)->size : XSTRING (val)->size);
+                            ? XVECTOR (val)->size : SCHARS (val));
                  int i;
                  for (i = 0; i < len; i++)
                    {
                  int i;
                  for (i = 0; i < len; i++)
                    {
@@ -5266,6 +5474,10 @@ coding_restore_composition (coding, obj)
          enum composition_method method = (enum composition_method) data[3];
          Lisp_Object components;
 
          enum composition_method method = (enum composition_method) data[3];
          Lisp_Object components;
 
+         if (data[0] < 0 || i + data[0] > cmp_data->used)
+           /* Invalid composition data.  */
+           break;
+
          if (method == COMPOSITION_RELATIVE)
            components = Qnil;
          else
          if (method == COMPOSITION_RELATIVE)
            components = Qnil;
          else
@@ -5273,10 +5485,17 @@ coding_restore_composition (coding, obj)
              int len = data[0] - 4, j;
              Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
 
              int len = data[0] - 4, j;
              Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
 
+             if (method == COMPOSITION_WITH_RULE_ALTCHARS
+                 && len % 2 == 0)
+               len --;
+             if (len < 1)
+               /* Invalid composition data.  */
+               break;
              for (j = 0; j < len; j++)
                args[j] = make_number (data[4 + j]);
              components = (method == COMPOSITION_WITH_ALTCHARS
              for (j = 0; j < len; j++)
                args[j] = make_number (data[4 + j]);
              components = (method == COMPOSITION_WITH_ALTCHARS
-                           ? Fstring (len, args) : Fvector (len, args));
+                           ? Fstring (len, args)
+                           : Fvector (len, args));
            }
          compose_text (data[1], data[2], components, Qnil, obj);
        }
            }
          compose_text (data[1], data[2], components, Qnil, obj);
        }
@@ -5306,6 +5525,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
      struct coding_system *coding;
 {
   int len = to - from, len_byte = to_byte - from_byte;
      struct coding_system *coding;
 {
   int len = to - from, len_byte = to_byte - from_byte;
+  int nchars_del = 0, nbytes_del = 0;
   int require, inserted, inserted_byte;
   int head_skip, tail_skip, total_skip = 0;
   Lisp_Object saved_coding_symbol;
   int require, inserted, inserted_byte;
   int head_skip, tail_skip, total_skip = 0;
   Lisp_Object saved_coding_symbol;
@@ -5394,9 +5614,9 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
          new buffer.  */
       struct buffer *prev = current_buffer;
       Lisp_Object new;
          new buffer.  */
       struct buffer *prev = current_buffer;
       Lisp_Object new;
-      int count = specpdl_ptr - specpdl;
 
 
-      record_unwind_protect (code_convert_region_unwind, Qnil);
+      record_unwind_protect (code_convert_region_unwind,
+                            Fcons (Vlast_coding_system_used, Qnil));
       /* We should not call any more pre-write/post-read-conversion
          functions while this pre-write-conversion is running.  */
       inhibit_pre_post_conversion = 1;
       /* We should not call any more pre-write/post-read-conversion
          functions while this pre-write-conversion is running.  */
       inhibit_pre_post_conversion = 1;
@@ -5429,7 +5649,15 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
     }
 
   if (replace)
     }
 
   if (replace)
-    deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
+    {
+      if (! EQ (current_buffer->undo_list, Qt))
+       deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
+      else
+       {
+         nchars_del = to - from;
+         nbytes_del = to_byte - from_byte;
+       }
+    }
 
   if (coding->composing != COMPOSITION_DISABLED)
     {
 
   if (coding->composing != COMPOSITION_DISABLED)
     {
@@ -5439,8 +5667,11 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
        coding_allocate_composition_data (coding, from);
     }
 
        coding_allocate_composition_data (coding, from);
     }
 
-  /* Try to skip the heading and tailing ASCIIs.  */
-  if (coding->type != coding_type_ccl)
+  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
+     if we must run CCL program or there are compositions to
+     encode.  */
+  if (coding->type != coding_type_ccl
+      && (! coding->cmp_data || coding->cmp_data->used == 0))
     {
       int from_byte_orig = from_byte, to_byte_orig = to_byte;
 
     {
       int from_byte_orig = from_byte, to_byte_orig = to_byte;
 
@@ -5456,6 +5687,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
          if (!replace)
            /* We must record and adjust for this new text now.  */
            adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
          if (!replace)
            /* We must record and adjust for this new text now.  */
            adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
+         coding_free_composition_data (coding);
          return 0;
        }
 
          return 0;
        }
 
@@ -5518,7 +5750,11 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
       if (encodep)
        result = encode_coding (coding, src, dst, len_byte, 0);
       else
       if (encodep)
        result = encode_coding (coding, src, dst, len_byte, 0);
       else
-       result = decode_coding (coding, src, dst, len_byte, 0);
+       {
+         if (coding->composing != COMPOSITION_DISABLED)
+           coding->cmp_data->char_offset = from + inserted;
+         result = decode_coding (coding, src, dst, len_byte, 0);
+       }
 
       /* The buffer memory is now:
         +--------+-------converted-text----+--+------original-text----+---+
 
       /* The buffer memory is now:
         +--------+-------converted-text----+--+------original-text----+---+
@@ -5601,7 +5837,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
            coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];
          else
            coding->symbol = saved_coding_symbol;
            coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];
          else
            coding->symbol = saved_coding_symbol;
-         
+
          continue;
        }
       if (len_byte <= 0)
          continue;
        }
       if (len_byte <= 0)
@@ -5619,7 +5855,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
          if (multibyte_p)
            {
              unsigned char *start = dst;
          if (multibyte_p)
            {
              unsigned char *start = dst;
-             
+
              inserted += len_byte;
              while (len_byte--)
                {
              inserted += len_byte;
              while (len_byte--)
                {
@@ -5662,9 +5898,19 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
                REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
                REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
             Here, we are sure that NEW >= ORIG.  */
                REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
                REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
             Here, we are sure that NEW >= ORIG.  */
-         float ratio = coding->produced - coding->consumed;
-         ratio /= coding->consumed;
-         require = len_byte * ratio;
+
+         if (coding->produced <= coding->consumed)
+           {
+             /* This happens because of CCL-based coding system with
+                eol-type CRLF.  */
+             require = 0;
+           }
+         else
+           {
+             float ratio = coding->produced - coding->consumed;
+             ratio /= coding->consumed;
+             require = len_byte * ratio;
+           }
          first = 0;
        }
       if ((src - dst) < (require + 2000))
          first = 0;
        }
       if ((src - dst) < (require + 2000))
@@ -5702,7 +5948,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
       inserted_byte = str_to_multibyte (GPT_ADDR, GAP_SIZE, inserted_byte);
     }
 
       inserted_byte = str_to_multibyte (GPT_ADDR, GAP_SIZE, inserted_byte);
     }
 
-  /* If we shrank the conversion area, adjust it now.  */ 
+  /* If we shrank the conversion area, adjust it now.  */
   if (total_skip > 0)
     {
       if (tail_skip > 0)
   if (total_skip > 0)
     {
       if (tail_skip > 0)
@@ -5717,7 +5963,11 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
     }
 
   prev_Z = Z;
     }
 
   prev_Z = Z;
-  adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte);
+  if (! EQ (current_buffer->undo_list, Qt))
+    adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte);
+  else
+    adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del,
+                                inserted, inserted_byte);
   inserted = Z - prev_Z;
 
   if (!encodep && coding->cmp_data && coding->cmp_data->used)
   inserted = Z - prev_Z;
 
   if (!encodep && coding->cmp_data && coding->cmp_data->used)
@@ -5728,20 +5978,25 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
       && ! encodep && ! NILP (coding->post_read_conversion))
     {
       Lisp_Object val;
       && ! encodep && ! NILP (coding->post_read_conversion))
     {
       Lisp_Object val;
-      int count = specpdl_ptr - specpdl;
+      Lisp_Object saved_coding_system;
 
       if (from != PT)
        TEMP_SET_PT_BOTH (from, from_byte);
       prev_Z = Z;
 
       if (from != PT)
        TEMP_SET_PT_BOTH (from, from_byte);
       prev_Z = Z;
-      record_unwind_protect (code_convert_region_unwind, Qnil);
+      record_unwind_protect (code_convert_region_unwind,
+                            Fcons (Vlast_coding_system_used, Qnil));
+      saved_coding_system = Vlast_coding_system_used;
+      Vlast_coding_system_used = coding->symbol;
       /* We should not call any more pre-write/post-read-conversion
          functions while this post-read-conversion is running.  */
       inhibit_pre_post_conversion = 1;
       val = call1 (coding->post_read_conversion, make_number (inserted));
       inhibit_pre_post_conversion = 0;
       /* We should not call any more pre-write/post-read-conversion
          functions while this post-read-conversion is running.  */
       inhibit_pre_post_conversion = 1;
       val = call1 (coding->post_read_conversion, make_number (inserted));
       inhibit_pre_post_conversion = 0;
+      coding->symbol = Vlast_coding_system_used;
+      Vlast_coding_system_used = saved_coding_system;
       /* Discard the unwind protect.  */
       specpdl_ptr--;
       /* Discard the unwind protect.  */
       specpdl_ptr--;
-      CHECK_NUMBER (val, 0);
+      CHECK_NUMBER (val);
       inserted += Z - prev_Z;
     }
 
       inserted += Z - prev_Z;
     }
 
@@ -5770,42 +6025,155 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
   return 0;
 }
 
   return 0;
 }
 
+/* Name (or base name) of work buffer for code conversion.  */
+static Lisp_Object Vcode_conversion_workbuf_name;
+
+/* Set the current buffer to the working buffer prepared for
+   code-conversion.  MULTIBYTE specifies the multibyteness of the
+   buffer.  Return the buffer we set if it must be killed after use.
+   Otherwise return Qnil.  */
+
+static Lisp_Object
+set_conversion_work_buffer (multibyte)
+     int multibyte;
+{
+  Lisp_Object buffer, buffer_to_kill;
+  struct buffer *buf;
+
+  buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
+  buf = XBUFFER (buffer);
+  if (buf == current_buffer)
+    {
+      /* As we are already in the work buffer, we must generate a new
+        buffer for the work.  */
+      Lisp_Object name;
+       
+      name = Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
+      buffer = buffer_to_kill = Fget_buffer_create (name);
+      buf = XBUFFER (buffer);
+    }
+  else
+    buffer_to_kill = Qnil;
+
+  delete_all_overlays (buf);
+  buf->directory = current_buffer->directory;
+  buf->read_only = Qnil;
+  buf->filename = Qnil;
+  buf->undo_list = Qt;
+  eassert (buf->overlays_before == NULL);
+  eassert (buf->overlays_after == NULL);
+  set_buffer_internal (buf);
+  if (BEG != BEGV || Z != ZV)
+    Fwiden ();
+  del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
+  buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+  return buffer_to_kill;
+}
+
 Lisp_Object
 run_pre_post_conversion_on_str (str, coding, encodep)
      Lisp_Object str;
      struct coding_system *coding;
      int encodep;
 {
 Lisp_Object
 run_pre_post_conversion_on_str (str, coding, encodep)
      Lisp_Object str;
      struct coding_system *coding;
      int encodep;
 {
-  int count = specpdl_ptr - specpdl;
-  struct gcpro gcpro1;
+  int count = SPECPDL_INDEX ();
+  struct gcpro gcpro1, gcpro2;
   int multibyte = STRING_MULTIBYTE (str);
   int multibyte = STRING_MULTIBYTE (str);
+  Lisp_Object old_deactivate_mark;
+  Lisp_Object buffer_to_kill;
 
   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 
   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-  record_unwind_protect (code_convert_region_unwind, Qnil);
-  GCPRO1 (str);
-  temp_output_buffer_setup (" *code-converting-work*");
-  set_buffer_internal (XBUFFER (Vstandard_output));
+  /* It is not crucial to specbind this.  */
+  old_deactivate_mark = Vdeactivate_mark;
+  GCPRO2 (str, old_deactivate_mark);
+
   /* We must insert the contents of STR as is without
      unibyte<->multibyte conversion.  For that, we adjust the
      multibyteness of the working buffer to that of STR.  */
   /* We must insert the contents of STR as is without
      unibyte<->multibyte conversion.  For that, we adjust the
      multibyteness of the working buffer to that of STR.  */
-  Ferase_buffer ();
-  current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil;
+  buffer_to_kill = set_conversion_work_buffer (multibyte);
+  record_unwind_protect (code_convert_region_unwind,
+                        Fcons (Vlast_coding_system_used, buffer_to_kill));
+
   insert_from_string (str, 0, 0,
   insert_from_string (str, 0, 0,
-                     XSTRING (str)->size, STRING_BYTES (XSTRING (str)), 0);
+                     SCHARS (str), SBYTES (str), 0);
   UNGCPRO;
   inhibit_pre_post_conversion = 1;
   if (encodep)
     call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));
   else
     {
   UNGCPRO;
   inhibit_pre_post_conversion = 1;
   if (encodep)
     call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));
   else
     {
+      Vlast_coding_system_used = coding->symbol;
       TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
       call1 (coding->post_read_conversion, make_number (Z - BEG));
       TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
       call1 (coding->post_read_conversion, make_number (Z - BEG));
+      coding->symbol = Vlast_coding_system_used;
     }
   inhibit_pre_post_conversion = 0;
     }
   inhibit_pre_post_conversion = 0;
+  Vdeactivate_mark = old_deactivate_mark;
   str = make_buffer_string (BEG, Z, 1);
   return unbind_to (count, str);
 }
 
   str = make_buffer_string (BEG, Z, 1);
   return unbind_to (count, str);
 }
 
+
+/* Run pre-write-conversion function of CODING on NCHARS/NBYTES
+   text in *STR.  *SIZE is the allocated bytes for STR.  As it
+   is intended that this function is called from encode_terminal_code,
+   the pre-write-conversion function is run by safe_call and thus
+   "Error during redisplay: ..." is logged when an error occurs.
+
+   Store the resulting text in *STR and set CODING->produced_char and
+   CODING->produced to the number of characters and bytes
+   respectively.  If the size of *STR is too small, enlarge it by
+   xrealloc and update *STR and *SIZE.  */
+
+void
+run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
+     unsigned char **str;
+     int *size, nchars, nbytes;
+     struct coding_system *coding;
+{
+  struct gcpro gcpro1, gcpro2;
+  struct buffer *cur = current_buffer;
+  Lisp_Object old_deactivate_mark, old_last_coding_system_used;
+  Lisp_Object args[3];
+  Lisp_Object buffer_to_kill;
+
+  /* It is not crucial to specbind this.  */
+  old_deactivate_mark = Vdeactivate_mark;
+  old_last_coding_system_used = Vlast_coding_system_used;
+  GCPRO2 (old_deactivate_mark, old_last_coding_system_used);
+
+  /* We must insert the contents of STR as is without
+     unibyte<->multibyte conversion.  For that, we adjust the
+     multibyteness of the working buffer to that of STR.  */
+  buffer_to_kill = set_conversion_work_buffer (coding->src_multibyte);
+  insert_1_both (*str, nchars, nbytes, 0, 0, 0);
+  UNGCPRO;
+  inhibit_pre_post_conversion = 1;
+  args[0] = coding->pre_write_conversion;
+  args[1] = make_number (BEG);
+  args[2] = make_number (Z);
+  safe_call (3, args);
+  inhibit_pre_post_conversion = 0;
+  Vdeactivate_mark = old_deactivate_mark;
+  Vlast_coding_system_used = old_last_coding_system_used;
+  coding->produced_char = Z - BEG;
+  coding->produced = Z_BYTE - BEG_BYTE;
+  if (coding->produced > *size)
+    {
+      *size = coding->produced;
+      *str = xrealloc (*str, *size);
+    }
+  if (BEG < GPT && GPT < Z)
+    move_gap (BEG);
+  bcopy (BEG_ADDR, *str, coding->produced);
+  coding->src_multibyte
+    = ! NILP (current_buffer->enable_multibyte_characters);
+  set_buffer_internal (cur);
+  if (! NILP (buffer_to_kill))
+    Fkill_buffer (buffer_to_kill);
+}
+
+
 Lisp_Object
 decode_coding_string (str, coding, nocopy)
      Lisp_Object str;
 Lisp_Object
 decode_coding_string (str, coding, nocopy)
      Lisp_Object str;
@@ -5815,7 +6183,6 @@ decode_coding_string (str, coding, nocopy)
   int len;
   struct conversion_buffer buf;
   int from, to_byte;
   int len;
   struct conversion_buffer buf;
   int from, to_byte;
-  struct gcpro gcpro1;
   Lisp_Object saved_coding_symbol;
   int result;
   int require_decoding;
   Lisp_Object saved_coding_symbol;
   int result;
   int require_decoding;
@@ -5824,7 +6191,7 @@ decode_coding_string (str, coding, nocopy)
   int consumed, consumed_char, produced, produced_char;
 
   from = 0;
   int consumed, consumed_char, produced, produced_char;
 
   from = 0;
-  to_byte = STRING_BYTES (XSTRING (str));
+  to_byte = SBYTES (str);
 
   saved_coding_symbol = coding->symbol;
   coding->src_multibyte = STRING_MULTIBYTE (str);
 
   saved_coding_symbol = coding->symbol;
   coding->src_multibyte = STRING_MULTIBYTE (str);
@@ -5834,7 +6201,7 @@ decode_coding_string (str, coding, nocopy)
       /* See the comments in code_convert_region.  */
       if (coding->type == coding_type_undecided)
        {
       /* See the comments in code_convert_region.  */
       if (coding->type == coding_type_undecided)
        {
-         detect_coding (coding, XSTRING (str)->data, to_byte);
+         detect_coding (coding, SDATA (str), to_byte);
          if (coding->type == coding_type_undecided)
            {
              coding->type = coding_type_emacs_mule;
          if (coding->type == coding_type_undecided)
            {
              coding->type = coding_type_emacs_mule;
@@ -5849,7 +6216,7 @@ decode_coding_string (str, coding, nocopy)
          && coding->type != coding_type_ccl)
        {
          saved_coding_symbol = coding->symbol;
          && coding->type != coding_type_ccl)
        {
          saved_coding_symbol = coding->symbol;
-         detect_eol (coding, XSTRING (str)->data, to_byte);
+         detect_eol (coding, SDATA (str), to_byte);
          if (coding->eol_type == CODING_EOL_UNDECIDED)
            coding->eol_type = CODING_EOL_LF;
          /* We had better recover the original eol format if we
          if (coding->eol_type == CODING_EOL_UNDECIDED)
            coding->eol_type = CODING_EOL_LF;
          /* We had better recover the original eol format if we
@@ -5868,7 +6235,7 @@ decode_coding_string (str, coding, nocopy)
     {
       /* Decoding routines expect the source text to be unibyte.  */
       str = Fstring_as_unibyte (str);
     {
       /* Decoding routines expect the source text to be unibyte.  */
       str = Fstring_as_unibyte (str);
-      to_byte = STRING_BYTES (XSTRING (str));
+      to_byte = SBYTES (str);
       nocopy = 1;
       coding->src_multibyte = 0;
     }
       nocopy = 1;
       coding->src_multibyte = 0;
     }
@@ -5876,24 +6243,26 @@ decode_coding_string (str, coding, nocopy)
   /* Try to skip the heading and tailing ASCIIs.  */
   if (require_decoding && coding->type != coding_type_ccl)
     {
   /* Try to skip the heading and tailing ASCIIs.  */
   if (require_decoding && coding->type != coding_type_ccl)
     {
-      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
+      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
                                0);
       if (from == to_byte)
        require_decoding = 0;
                                0);
       if (from == to_byte)
        require_decoding = 0;
-      shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte);
+      shrinked_bytes = from + (SBYTES (str) - to_byte);
     }
 
     }
 
-  if (!require_decoding)
+  if (!require_decoding
+      && !(SYMBOLP (coding->post_read_conversion)
+          && !NILP (Ffboundp (coding->post_read_conversion))))
     {
     {
-      coding->consumed = STRING_BYTES (XSTRING (str));
-      coding->consumed_char = XSTRING (str)->size;
+      coding->consumed = SBYTES (str);
+      coding->consumed_char = SCHARS (str);
       if (coding->dst_multibyte)
        {
          str = Fstring_as_multibyte (str);
          nocopy = 1;
        }
       if (coding->dst_multibyte)
        {
          str = Fstring_as_multibyte (str);
          nocopy = 1;
        }
-      coding->produced = STRING_BYTES (XSTRING (str));
-      coding->produced_char = XSTRING (str)->size;
+      coding->produced = SBYTES (str);
+      coding->produced_char = SCHARS (str);
       return (nocopy ? str : Fcopy_sequence (str));
     }
 
       return (nocopy ? str : Fcopy_sequence (str));
     }
 
@@ -5905,7 +6274,7 @@ decode_coding_string (str, coding, nocopy)
   consumed = consumed_char = produced = produced_char = 0;
   while (1)
     {
   consumed = consumed_char = produced = produced_char = 0;
   while (1)
     {
-      result = decode_coding (coding, XSTRING (str)->data + from + consumed,
+      result = decode_coding (coding, SDATA (str) + from + consumed,
                              buf.data + produced, to_byte - from - consumed,
                              buf.size - produced);
       consumed += coding->consumed;
                              buf.data + produced, to_byte - from - consumed,
                              buf.size - produced);
       consumed += coding->consumed;
@@ -5913,6 +6282,7 @@ decode_coding_string (str, coding, nocopy)
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
+         || result == CODING_FINISH_INTERRUPT
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
@@ -5946,7 +6316,7 @@ decode_coding_string (str, coding, nocopy)
                }
              produced += num_eol;
              produced_char += num_eol;
                }
              produced += num_eol;
              produced_char += num_eol;
-           } 
+           }
          /* Suppress eol-format conversion in the further conversion.  */
          coding->eol_type = CODING_EOL_LF;
 
          /* Suppress eol-format conversion in the further conversion.  */
          coding->eol_type = CODING_EOL_LF;
 
@@ -5974,14 +6344,19 @@ decode_coding_string (str, coding, nocopy)
   else
     newstr = make_uninit_string (produced + shrinked_bytes);
   if (from > 0)
   else
     newstr = make_uninit_string (produced + shrinked_bytes);
   if (from > 0)
-    bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from);
-  bcopy (buf.data, XSTRING (newstr)->data + from, produced);
+    STRING_COPYIN (newstr, 0, SDATA (str), from);
+  STRING_COPYIN (newstr, from, buf.data, produced);
   if (shrinked_bytes > from)
   if (shrinked_bytes > from)
-    bcopy (XSTRING (str)->data + to_byte,
-          XSTRING (newstr)->data + from + produced,
-          shrinked_bytes - from);
+    STRING_COPYIN (newstr, from + produced,
+                  SDATA (str) + to_byte,
+                  shrinked_bytes - from);
   free_conversion_buffer (&buf);
 
   free_conversion_buffer (&buf);
 
+  coding->consumed += shrinked_bytes;
+  coding->consumed_char += shrinked_bytes;
+  coding->produced += shrinked_bytes;
+  coding->produced_char += shrinked_bytes;
+
   if (coding->cmp_data && coding->cmp_data->used)
     coding_restore_composition (coding, newstr);
   coding_free_composition_data (coding);
   if (coding->cmp_data && coding->cmp_data->used)
     coding_restore_composition (coding, newstr);
   coding_free_composition_data (coding);
@@ -6009,41 +6384,41 @@ encode_coding_string (str, coding, nocopy)
 
   if (SYMBOLP (coding->pre_write_conversion)
       && !NILP (Ffboundp (coding->pre_write_conversion)))
 
   if (SYMBOLP (coding->pre_write_conversion)
       && !NILP (Ffboundp (coding->pre_write_conversion)))
-    str = run_pre_post_conversion_on_str (str, coding, 1);
+    {
+      str = run_pre_post_conversion_on_str (str, coding, 1);
+      /* As STR is just newly generated, we don't have to copy it
+        anymore.  */
+      nocopy = 1;
+    }
 
   from = 0;
 
   from = 0;
-  to = XSTRING (str)->size;
-  to_byte = STRING_BYTES (XSTRING (str));
+  to = SCHARS (str);
+  to_byte = SBYTES (str);
 
   /* Encoding routines determine the multibyteness of the source text
      by coding->src_multibyte.  */
 
   /* Encoding routines determine the multibyteness of the source text
      by coding->src_multibyte.  */
-  coding->src_multibyte = STRING_MULTIBYTE (str);
+  coding->src_multibyte = SCHARS (str) < SBYTES (str);
   coding->dst_multibyte = 0;
   if (! CODING_REQUIRE_ENCODING (coding))
   coding->dst_multibyte = 0;
   if (! CODING_REQUIRE_ENCODING (coding))
-    {
-      coding->consumed = STRING_BYTES (XSTRING (str));
-      coding->consumed_char = XSTRING (str)->size;
-      if (STRING_MULTIBYTE (str))
-       {
-         str = Fstring_as_unibyte (str);
-         nocopy = 1;
-       }
-      coding->produced = STRING_BYTES (XSTRING (str));
-      coding->produced_char = XSTRING (str)->size;
-      return (nocopy ? str : Fcopy_sequence (str));
-    }
+    goto no_need_of_encoding;
 
   if (coding->composing != COMPOSITION_DISABLED)
     coding_save_composition (coding, from, to, str);
 
 
   if (coding->composing != COMPOSITION_DISABLED)
     coding_save_composition (coding, from, to, str);
 
-  /* Try to skip the heading and tailing ASCIIs.  */
-  if (coding->type != coding_type_ccl)
+  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
+     if we must run CCL program or there are compositions to
+     encode.  */
+  if (coding->type != coding_type_ccl
+      && (! coding->cmp_data || coding->cmp_data->used == 0))
     {
     {
-      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
+      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
                                1);
       if (from == to_byte)
                                1);
       if (from == to_byte)
-       return (nocopy ? str : Fcopy_sequence (str));
-      shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte);
+       {
+         coding_free_composition_data (coding);
+         goto no_need_of_encoding;
+       }
+      shrinked_bytes = from + (SBYTES (str) - to_byte);
     }
 
   len = encoding_buffer_size (coding, to_byte - from);
     }
 
   len = encoding_buffer_size (coding, to_byte - from);
@@ -6052,7 +6427,7 @@ encode_coding_string (str, coding, nocopy)
   consumed = consumed_char = produced = produced_char = 0;
   while (1)
     {
   consumed = consumed_char = produced = produced_char = 0;
   while (1)
     {
-      result = encode_coding (coding, XSTRING (str)->data + from + consumed,
+      result = encode_coding (coding, SDATA (str) + from + consumed,
                              buf.data + produced, to_byte - from - consumed,
                              buf.size - produced);
       consumed += coding->consumed;
                              buf.data + produced, to_byte - from - consumed,
                              buf.size - produced);
       consumed += coding->consumed;
@@ -6060,6 +6435,7 @@ encode_coding_string (str, coding, nocopy)
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
+         || result == CODING_FINISH_INTERRUPT
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
@@ -6074,17 +6450,36 @@ encode_coding_string (str, coding, nocopy)
 
   newstr = make_uninit_string (produced + shrinked_bytes);
   if (from > 0)
 
   newstr = make_uninit_string (produced + shrinked_bytes);
   if (from > 0)
-    bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from);
-  bcopy (buf.data, XSTRING (newstr)->data + from, produced);
+    STRING_COPYIN (newstr, 0, SDATA (str), from);
+  STRING_COPYIN (newstr, from, buf.data, produced);
   if (shrinked_bytes > from)
   if (shrinked_bytes > from)
-    bcopy (XSTRING (str)->data + to_byte,
-          XSTRING (newstr)->data + from + produced,
-          shrinked_bytes - from);
+    STRING_COPYIN (newstr, from + produced,
+                  SDATA (str) + to_byte,
+                  shrinked_bytes - from);
 
   free_conversion_buffer (&buf);
   coding_free_composition_data (coding);
 
   return newstr;
 
   free_conversion_buffer (&buf);
   coding_free_composition_data (coding);
 
   return newstr;
+
+ no_need_of_encoding:
+  coding->consumed = SBYTES (str);
+  coding->consumed_char = SCHARS (str);
+  if (STRING_MULTIBYTE (str))
+    {
+      if (nocopy)
+       /* We are sure that STR doesn't contain a multibyte
+          character.  */
+       STRING_SET_UNIBYTE (str);
+      else
+       {
+         str = Fstring_as_unibyte (str);
+         nocopy = 1;
+       }
+    }
+  coding->produced = SBYTES (str);
+  coding->produced_char = SCHARS (str);
+  return (nocopy ? str : Fcopy_sequence (str));
 }
 
 \f
 }
 
 \f
@@ -6092,16 +6487,18 @@ encode_coding_string (str, coding, nocopy)
 /*** 8. Emacs Lisp library functions ***/
 
 DEFUN ("coding-system-p", Fcoding_system_p, Scoding_system_p, 1, 1, 0,
 /*** 8. Emacs Lisp library functions ***/
 
 DEFUN ("coding-system-p", Fcoding_system_p, Scoding_system_p, 1, 1, 0,
-  "Return t if OBJECT is nil or a coding-system.\n\
-See the documentation of `make-coding-system' for information\n\
-about coding-system objects.")
-  (obj)
+       doc: /* Return t if OBJECT is nil or a coding-system.
+See the documentation of `make-coding-system' for information
+about coding-system objects.  */)
+     (obj)
      Lisp_Object obj;
 {
   if (NILP (obj))
     return Qt;
   if (!SYMBOLP (obj))
     return Qnil;
      Lisp_Object obj;
 {
   if (NILP (obj))
     return Qt;
   if (!SYMBOLP (obj))
     return Qnil;
+  if (! NILP (Fget (obj, Qcoding_system_define_form)))
+    return Qt;
   /* Get coding-spec vector for OBJ.  */
   obj = Fget (obj, Qcoding_system);
   return ((VECTORP (obj) && XVECTOR (obj)->size == 5)
   /* Get coding-spec vector for OBJ.  */
   obj = Fget (obj, Qcoding_system);
   return ((VECTORP (obj) && XVECTOR (obj)->size == 5)
@@ -6110,8 +6507,8 @@ about coding-system objects.")
 
 DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,
        Sread_non_nil_coding_system, 1, 1, 0,
 
 DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,
        Sread_non_nil_coding_system, 1, 1, 0,
-  "Read a coding system from the minibuffer, prompting with string PROMPT.")
-  (prompt)
+       doc: /* Read a coding system from the minibuffer, prompting with string PROMPT.  */)
+     (prompt)
      Lisp_Object prompt;
 {
   Lisp_Object val;
      Lisp_Object prompt;
 {
   Lisp_Object val;
@@ -6120,35 +6517,42 @@ DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,
       val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                              Qt, Qnil, Qcoding_system_history, Qnil, Qnil);
     }
       val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                              Qt, Qnil, Qcoding_system_history, Qnil, Qnil);
     }
-  while (XSTRING (val)->size == 0);
+  while (SCHARS (val) == 0);
   return (Fintern (val, Qnil));
 }
 
 DEFUN ("read-coding-system", Fread_coding_system, Sread_coding_system, 1, 2, 0,
   return (Fintern (val, Qnil));
 }
 
 DEFUN ("read-coding-system", Fread_coding_system, Sread_coding_system, 1, 2, 0,
-  "Read a coding system from the minibuffer, prompting with string PROMPT.\n\
-If the user enters null input, return second argument DEFAULT-CODING-SYSTEM.")
-  (prompt, default_coding_system)
+       doc: /* Read a coding system from the minibuffer, prompting with string PROMPT.
+If the user enters null input, return second argument DEFAULT-CODING-SYSTEM.  */)
+     (prompt, default_coding_system)
      Lisp_Object prompt, default_coding_system;
 {
   Lisp_Object val;
   if (SYMBOLP (default_coding_system))
      Lisp_Object prompt, default_coding_system;
 {
   Lisp_Object val;
   if (SYMBOLP (default_coding_system))
-    XSETSTRING (default_coding_system, XSYMBOL (default_coding_system)->name);
+    default_coding_system = SYMBOL_NAME (default_coding_system);
   val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                          Qt, Qnil, Qcoding_system_history,
                          default_coding_system, Qnil);
   val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                          Qt, Qnil, Qcoding_system_history,
                          default_coding_system, Qnil);
-  return (XSTRING (val)->size == 0 ? Qnil : Fintern (val, Qnil));
+  return (SCHARS (val) == 0 ? Qnil : Fintern (val, Qnil));
 }
 
 DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,
        1, 1, 0,
 }
 
 DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,
        1, 1, 0,
-  "Check validity of CODING-SYSTEM.\n\
-If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.\n\
-It is valid if it is a symbol with a non-nil `coding-system' property.\n\
-The value of property should be a vector of length 5.")
-  (coding_system)
+       doc: /* Check validity of CODING-SYSTEM.
+If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.
+It is valid if it is nil or a symbol with a non-nil `coding-system' property.
+The value of this property should be a vector of length 5.  */)
+     (coding_system)
      Lisp_Object coding_system;
 {
      Lisp_Object coding_system;
 {
-  CHECK_SYMBOL (coding_system, 0);
+  Lisp_Object define_form;
+
+  define_form = Fget (coding_system, Qcoding_system_define_form);
+  if (! NILP (define_form))
+    {
+      Fput (coding_system, Qcoding_system_define_form, Qnil);
+      safe_eval (define_form);
+    }
   if (!NILP (Fcoding_system_p (coding_system)))
     return coding_system;
   while (1)
   if (!NILP (Fcoding_system_p (coding_system)))
     return coding_system;
   while (1)
@@ -6157,7 +6561,7 @@ The value of property should be a vector of length 5.")
 \f
 Lisp_Object
 detect_coding_system (src, src_bytes, highest, multibytep)
 \f
 Lisp_Object
 detect_coding_system (src, src_bytes, highest, multibytep)
-     unsigned char *src;
+     const unsigned char *src;
      int src_bytes, highest;
      int multibytep;
 {
      int src_bytes, highest;
      int multibytep;
 {
@@ -6216,28 +6620,31 @@ detect_coding_system (src, src_bytes, highest, multibytep)
        }
     }
   return (highest ? XCAR (val) : val);
        }
     }
   return (highest ? XCAR (val) : val);
-}  
+}
 
 DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,
        2, 3, 0,
 
 DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,
        2, 3, 0,
-  "Detect coding system of the text in the region between START and END.\n\
-Return a list of possible coding systems ordered by priority.\n\
-\n\
-If only ASCII characters are found, it returns a list of single element\n\
-`undecided' or its subsidiary coding system according to a detected\n\
-end-of-line format.\n\
-\n\
-If optional argument HIGHEST is non-nil, return the coding system of\n\
-highest priority.")
-  (start, end, highest)
+       doc: /* Detect how the byte sequence in the region is encoded.
+Return a list of possible coding systems used on decoding a byte
+sequence containing the bytes in the region between START and END when
+the coding system `undecided' is specified.  The list is ordered by
+priority decided in the current language environment.
+
+If only ASCII characters are found, it returns a list of single element
+`undecided' or its subsidiary coding system according to a detected
+end-of-line format.
+
+If optional argument HIGHEST is non-nil, return the coding system of
+highest priority.  */)
+     (start, end, highest)
      Lisp_Object start, end, highest;
 {
   int from, to;
   int from_byte, to_byte;
   int include_anchor_byte = 0;
 
      Lisp_Object start, end, highest;
 {
   int from, to;
   int from_byte, to_byte;
   int include_anchor_byte = 0;
 
-  CHECK_NUMBER_COERCE_MARKER (start, 0);
-  CHECK_NUMBER_COERCE_MARKER (end, 1);
+  CHECK_NUMBER_COERCE_MARKER (start);
+  CHECK_NUMBER_COERCE_MARKER (end);
 
   validate_region (&start, &end);
   from = XINT (start), to = XINT (end);
 
   validate_region (&start, &end);
   from = XINT (start), to = XINT (end);
@@ -6250,7 +6657,7 @@ highest priority.")
      the detecting source.  Then code detectors can handle the tailing
      byte sequence more accurately.
 
      the detecting source.  Then code detectors can handle the tailing
      byte sequence more accurately.
 
-     Fix me: This is not an perfect solution.  It is better that we
+     Fix me: This is not a perfect solution.  It is better that we
      add one more argument, say LAST_BLOCK, to all detect_coding_XXX.
   */
   if (to == Z || (to == GPT && GAP_SIZE > 0))
      add one more argument, say LAST_BLOCK, to all detect_coding_XXX.
   */
   if (to == Z || (to == GPT && GAP_SIZE > 0))
@@ -6264,56 +6671,42 @@ highest priority.")
 
 DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string,
        1, 2, 0,
 
 DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string,
        1, 2, 0,
-  "Detect coding system of the text in STRING.\n\
-Return a list of possible coding systems ordered by priority.\n\
-\n\
-If only ASCII characters are found, it returns a list of single element\n\
-`undecided' or its subsidiary coding system according to a detected\n\
-end-of-line format.\n\
-\n\
-If optional argument HIGHEST is non-nil, return the coding system of\n\
-highest priority.")
-  (string, highest)
+       doc: /* Detect how the byte sequence in STRING is encoded.
+Return a list of possible coding systems used on decoding a byte
+sequence containing the bytes in STRING when the coding system
+`undecided' is specified.  The list is ordered by priority decided in
+the current language environment.
+
+If only ASCII characters are found, it returns a list of single element
+`undecided' or its subsidiary coding system according to a detected
+end-of-line format.
+
+If optional argument HIGHEST is non-nil, return the coding system of
+highest priority.  */)
+     (string, highest)
      Lisp_Object string, highest;
 {
      Lisp_Object string, highest;
 {
-  CHECK_STRING (string, 0);
+  CHECK_STRING (string);
 
 
-  return detect_coding_system (XSTRING (string)->data,
+  return detect_coding_system (SDATA (string),
                               /* "+ 1" is to include the anchor byte
                                  `\0'.  With this, code detectors can
                                  handle the tailing bytes more
                                  accurately.  */
                               /* "+ 1" is to include the anchor byte
                                  `\0'.  With this, code detectors can
                                  handle the tailing bytes more
                                  accurately.  */
-                              STRING_BYTES (XSTRING (string)) + 1,
+                              SBYTES (string) + 1,
                               !NILP (highest),
                               STRING_MULTIBYTE (string));
 }
 
                               !NILP (highest),
                               STRING_MULTIBYTE (string));
 }
 
-/* Return an intersection of lists L1 and L2.  */
-
-static Lisp_Object
-intersection (l1, l2)
-     Lisp_Object l1, l2;
-{
-  Lisp_Object val;
-
-  for (val = Qnil; CONSP (l1); l1 = XCDR (l1))
-    {
-      if (!NILP (Fmemq (XCAR (l1), l2)))
-       val = Fcons (XCAR (l1), val);
-    }
-  return val;
-}
-
-
-/*  Subroutine for Fsafe_coding_systems_region_internal.
+/*  Subroutine for Ffind_coding_systems_region_internal.
 
     Return a list of coding systems that safely encode the multibyte
 
     Return a list of coding systems that safely encode the multibyte
-    text between P and PEND.  SAFE_CODINGS, if non-nil, is a list of
+    text between P and PEND.  SAFE_CODINGS, if non-nil, is an alist of
     possible coding systems.  If it is nil, it means that we have not
     yet found any coding systems.
 
     possible coding systems.  If it is nil, it means that we have not
     yet found any coding systems.
 
-    WORK_TABLE is a copy of the char-table Vchar_coding_system_table.  An
-    element of WORK_TABLE is set to t once the element is looked up.
+    WORK_TABLE a char-table of which element is set to t once the
+    element is looked up.
 
     If a non-ASCII single byte char is found, set
     *single_byte_char_found to 1.  */
 
     If a non-ASCII single byte char is found, set
     *single_byte_char_found to 1.  */
@@ -6324,9 +6717,12 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
      Lisp_Object safe_codings, work_table;
      int *single_byte_char_found;
 {
      Lisp_Object safe_codings, work_table;
      int *single_byte_char_found;
 {
-  int c, len, idx;
-  Lisp_Object val;
+  int c, len;
+  Lisp_Object val, ch;
+  Lisp_Object prev, tail;
 
 
+  if (NILP (safe_codings))
+    goto done_safe_codings;
   while (p < pend)
     {
       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
   while (p < pend)
     {
       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
@@ -6336,58 +6732,140 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
        continue;
       if (SINGLE_BYTE_CHAR_P (c))
        *single_byte_char_found = 1;
        continue;
       if (SINGLE_BYTE_CHAR_P (c))
        *single_byte_char_found = 1;
-      if (NILP (safe_codings))
-       continue;
       /* Check the safe coding systems for C.  */
       /* Check the safe coding systems for C.  */
-      val = char_table_ref_and_index (work_table, c, &idx);
+      ch = make_number (c);
+      val = Faref (work_table, ch);
       if (EQ (val, Qt))
        /* This element was already checked.  Ignore it.  */
        continue;
       /* Remember that we checked this element.  */
       if (EQ (val, Qt))
        /* This element was already checked.  Ignore it.  */
        continue;
       /* Remember that we checked this element.  */
-      CHAR_TABLE_SET (work_table, make_number (idx), Qt);
+      Faset (work_table, ch, Qt);
 
 
-      /* If there are some safe coding systems for C and we have
-        already found the other set of coding systems for the
-        different characters, get the intersection of them.  */
-      if (!EQ (safe_codings, Qt) && !NILP (val))
-       val = intersection (safe_codings, val);
-      safe_codings = val;
+      for (prev = tail = safe_codings; CONSP (tail); tail = XCDR (tail))
+       {
+         Lisp_Object elt, translation_table, hash_table, accept_latin_extra;
+         int encodable;
+
+         elt = XCAR (tail);
+         if (CONSP (XCDR (elt)))
+           {
+             /* This entry has this format now:
+                ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE
+                         ACCEPT-LATIN-EXTRA ) */
+             val = XCDR (elt);
+             encodable = ! NILP (Faref (XCAR (val), ch));
+             if (! encodable)
+               {
+                 val = XCDR (val);
+                 translation_table = XCAR (val);
+                 hash_table = XCAR (XCDR (val));
+                 accept_latin_extra = XCAR (XCDR (XCDR (val)));
+               }
+           }
+         else
+           {
+             /* This entry has this format now: ( CODING . SAFE-CHARS) */
+             encodable = ! NILP (Faref (XCDR (elt), ch));
+             if (! encodable)
+               {
+                 /* Transform the format to:
+                    ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE
+                      ACCEPT-LATIN-EXTRA )  */
+                 val = Fget (XCAR (elt), Qcoding_system);
+                 translation_table
+                   = Fplist_get (AREF (val, 3),
+                                 Qtranslation_table_for_encode);
+                 if (SYMBOLP (translation_table))
+                   translation_table = Fget (translation_table,
+                                             Qtranslation_table);
+                 hash_table
+                   = (CHAR_TABLE_P (translation_table)
+                      ? XCHAR_TABLE (translation_table)->extras[1]
+                      : Qnil);
+                 accept_latin_extra
+                   = ((EQ (AREF (val, 0), make_number (2))
+                       && VECTORP (AREF (val, 4)))
+                      ? AREF (AREF (val, 4), 16)
+                      : Qnil);
+                 XSETCAR (tail, list5 (XCAR (elt), XCDR (elt),
+                                       translation_table, hash_table,
+                                       accept_latin_extra));
+               }
+           }
+
+         if (! encodable
+             && ((CHAR_TABLE_P (translation_table)
+                  && ! NILP (Faref (translation_table, ch)))
+                 || (HASH_TABLE_P (hash_table)
+                     && ! NILP (Fgethash (ch, hash_table, Qnil)))
+                 || (SINGLE_BYTE_CHAR_P (c)
+                     && ! NILP (accept_latin_extra)
+                     && VECTORP (Vlatin_extra_code_table)
+                     && ! NILP (AREF (Vlatin_extra_code_table, c)))))
+           encodable = 1;
+         if (encodable)
+           prev = tail;
+         else
+           {
+             /* Exclude this coding system from SAFE_CODINGS.  */
+             if (EQ (tail, safe_codings))
+               {
+                 safe_codings = XCDR (safe_codings);
+                 if (NILP (safe_codings))
+                   goto done_safe_codings;
+               }
+             else
+               XSETCDR (prev, XCDR (tail));
+           }
+       }
     }
     }
+
+ done_safe_codings:
+  /* If the above loop was terminated before P reaches PEND, it means
+     SAFE_CODINGS was set to nil.  If we have not yet found an
+     non-ASCII single-byte char, check it now.  */
+  if (! *single_byte_char_found)
+    while (p < pend)
+      {
+       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+       p += len;
+       if (! ASCII_BYTE_P (c)
+           && SINGLE_BYTE_CHAR_P (c))
+         {
+           *single_byte_char_found = 1;
+           break;
+         }
+      }
   return safe_codings;
 }
 
   return safe_codings;
 }
 
-
-/* Return a list of coding systems that safely encode the text between
-   START and END.  If the text contains only ASCII or is unibyte,
-   return t.  */
-
 DEFUN ("find-coding-systems-region-internal",
        Ffind_coding_systems_region_internal,
        Sfind_coding_systems_region_internal, 2, 2, 0,
 DEFUN ("find-coding-systems-region-internal",
        Ffind_coding_systems_region_internal,
        Sfind_coding_systems_region_internal, 2, 2, 0,
-  "Internal use only.")
-  (start, end)
+       doc: /* Internal use only.  */)
+     (start, end)
      Lisp_Object start, end;
 {
   Lisp_Object work_table, safe_codings;
   int non_ascii_p = 0;
   int single_byte_char_found = 0;
      Lisp_Object start, end;
 {
   Lisp_Object work_table, safe_codings;
   int non_ascii_p = 0;
   int single_byte_char_found = 0;
-  unsigned char *p1, *p1end, *p2, *p2end, *p;
+  const unsigned char *p1, *p1end, *p2, *p2end, *p;
 
   if (STRINGP (start))
     {
       if (!STRING_MULTIBYTE (start))
        return Qt;
 
   if (STRINGP (start))
     {
       if (!STRING_MULTIBYTE (start))
        return Qt;
-      p1 = XSTRING (start)->data, p1end = p1 + STRING_BYTES (XSTRING (start));
+      p1 = SDATA (start), p1end = p1 + SBYTES (start);
       p2 = p2end = p1end;
       p2 = p2end = p1end;
-      if (XSTRING (start)->size != STRING_BYTES (XSTRING (start)))
+      if (SCHARS (start) != SBYTES (start))
        non_ascii_p = 1;
     }
   else
     {
       int from, to, stop;
 
        non_ascii_p = 1;
     }
   else
     {
       int from, to, stop;
 
-      CHECK_NUMBER_COERCE_MARKER (start, 0);
-      CHECK_NUMBER_COERCE_MARKER (end, 1);
+      CHECK_NUMBER_COERCE_MARKER (start);
+      CHECK_NUMBER_COERCE_MARKER (end);
       if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
        args_out_of_range (start, end);
       if (NILP (current_buffer->enable_multibyte_characters))
       if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
        args_out_of_range (start, end);
       if (NILP (current_buffer->enable_multibyte_characters))
@@ -6412,36 +6890,182 @@ DEFUN ("find-coding-systems-region-internal",
       for (p = p1; p < p1end && ASCII_BYTE_P (*p); p++);
       if (p == p1end)
        {
       for (p = p1; p < p1end && ASCII_BYTE_P (*p); p++);
       if (p == p1end)
        {
-         for (p = p2; p < p2end && ASCII_BYTE_P (*p); p++);      
+         for (p = p2; p < p2end && ASCII_BYTE_P (*p); p++);
          if (p == p2end)
            return Qt;
        }
     }
 
   /* The text contains non-ASCII characters.  */
          if (p == p2end)
            return Qt;
        }
     }
 
   /* The text contains non-ASCII characters.  */
-  work_table = Fcopy_sequence (Vchar_coding_system_table);
-  safe_codings = find_safe_codings (p1, p1end, Qt, work_table,
+
+  work_table = Fmake_char_table (Qchar_coding_system, Qnil);
+  safe_codings = Fcopy_sequence (XCDR (Vcoding_system_safe_chars));
+
+  safe_codings = find_safe_codings (p1, p1end, safe_codings, work_table,
                                    &single_byte_char_found);
   if (p2 < p2end)
     safe_codings = find_safe_codings (p2, p2end, safe_codings, work_table,
                                      &single_byte_char_found);
                                    &single_byte_char_found);
   if (p2 < p2end)
     safe_codings = find_safe_codings (p2, p2end, safe_codings, work_table,
                                      &single_byte_char_found);
+  if (EQ (safe_codings, XCDR (Vcoding_system_safe_chars)))
+    safe_codings = Qt;
+  else
+    {
+      /* Turn safe_codings to a list of coding systems... */
+      Lisp_Object val;
+
+      if (single_byte_char_found)
+       /* ... and append these for eight-bit chars.  */
+       val = Fcons (Qraw_text,
+                    Fcons (Qemacs_mule, Fcons (Qno_conversion, Qnil)));
+      else
+       /* ... and append generic coding systems.  */
+       val = Fcopy_sequence (XCAR (Vcoding_system_safe_chars));
+
+      for (; CONSP (safe_codings); safe_codings = XCDR (safe_codings))
+       val = Fcons (XCAR (XCAR (safe_codings)), val);
+      safe_codings = val;
+    }
+
+  return safe_codings;
+}
+
+
+/* Search from position POS for such characters that are unencodable
+   accoding to SAFE_CHARS, and return a list of their positions.  P
+   points where in the memory the character at POS exists.  Limit the
+   search at PEND or when Nth unencodable characters are found.
+
+   If SAFE_CHARS is a char table, an element for an unencodable
+   character is nil.
+
+   If SAFE_CHARS is nil, all non-ASCII characters are unencodable.
 
 
-  if (EQ (safe_codings, Qt))
-    ; /* Nothing to be done.  */
-  else if (!single_byte_char_found)
+   Otherwise, SAFE_CHARS is t, and only eight-bit-contrl and
+   eight-bit-graphic characters are unencodable.  */
+
+static Lisp_Object
+unencodable_char_position (safe_chars, pos, p, pend, n)
+     Lisp_Object safe_chars;
+     int pos;
+     unsigned char *p, *pend;
+     int n;
+{
+  Lisp_Object pos_list;
+
+  pos_list = Qnil;
+  while (p < pend)
     {
     {
-      /* Append generic coding systems.  */
-      Lisp_Object args[2];
-      args[0] = safe_codings;
-      args[1] = Fchar_table_extra_slot (Vchar_coding_system_table,
-                                       make_number (0));
-      safe_codings = Fappend (2, args);
+      int len;
+      int c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
+
+      if (c >= 128
+         && (CHAR_TABLE_P (safe_chars)
+             ? NILP (CHAR_TABLE_REF (safe_chars, c))
+             : (NILP (safe_chars) || c < 256)))
+       {
+         pos_list = Fcons (make_number (pos), pos_list);
+         if (--n <= 0)
+           break;
+       }
+      pos++;
+      p += len;
+    }
+  return Fnreverse (pos_list);
+}
+
+
+DEFUN ("unencodable-char-position", Funencodable_char_position,
+       Sunencodable_char_position, 3, 5, 0,
+       doc: /*
+Return position of first un-encodable character in a region.
+START and END specfiy the region and CODING-SYSTEM specifies the
+encoding to check.  Return nil if CODING-SYSTEM does encode the region.
+
+If optional 4th argument COUNT is non-nil, it specifies at most how
+many un-encodable characters to search.  In this case, the value is a
+list of positions.
+
+If optional 5th argument STRING is non-nil, it is a string to search
+for un-encodable characters.  In that case, START and END are indexes
+to the string.  */)
+     (start, end, coding_system, count, string)
+     Lisp_Object start, end, coding_system, count, string;
+{
+  int n;
+  Lisp_Object safe_chars;
+  struct coding_system coding;
+  Lisp_Object positions;
+  int from, to;
+  unsigned char *p, *pend;
+
+  if (NILP (string))
+    {
+      validate_region (&start, &end);
+      from = XINT (start);
+      to = XINT (end);
+      if (NILP (current_buffer->enable_multibyte_characters))
+       return Qnil;
+      p = CHAR_POS_ADDR (from);
+      if (to == GPT)
+       pend = GPT_ADDR;
+      else
+       pend = CHAR_POS_ADDR (to);
     }
   else
     }
   else
-    safe_codings = Fcons (Qraw_text,
-                         Fcons (Qemacs_mule,
-                                Fcons (Qno_conversion, safe_codings)));
-  return safe_codings;
+    {
+      CHECK_STRING (string);
+      CHECK_NATNUM (start);
+      CHECK_NATNUM (end);
+      from = XINT (start);
+      to = XINT (end);
+      if (from > to
+         || to > SCHARS (string))
+       args_out_of_range_3 (string, start, end);
+      if (! STRING_MULTIBYTE (string))
+       return Qnil;
+      p = SDATA (string) + string_char_to_byte (string, from);
+      pend = SDATA (string) + string_char_to_byte (string, to);
+    }
+
+  setup_coding_system (Fcheck_coding_system (coding_system), &coding);
+
+  if (NILP (count))
+    n = 1;
+  else
+    {
+      CHECK_NATNUM (count);
+      n = XINT (count);
+    }
+
+  if (coding.type == coding_type_no_conversion
+      || coding.type == coding_type_raw_text)
+    return Qnil;
+
+  if (coding.type == coding_type_undecided)
+    safe_chars = Qnil;
+  else
+    safe_chars = coding_safe_chars (coding_system);
+
+  if (STRINGP (string)
+      || from >= GPT || to <= GPT)
+    positions = unencodable_char_position (safe_chars, from, p, pend, n);
+  else
+    {
+      Lisp_Object args[2];
+
+      args[0] = unencodable_char_position (safe_chars, from, p, GPT_ADDR, n);
+      n -= XINT (Flength (args[0]));
+      if (n <= 0)
+       positions = args[0];
+      else
+       {
+         args[1] = unencodable_char_position (safe_chars, GPT, GAP_END_ADDR,
+                                              pend, n);
+         positions = Fappend (2, args);
+       }
+    }
+
+  return  (NILP (count) ? Fcar (positions) : positions);
 }
 
 
 }
 
 
@@ -6453,9 +7077,9 @@ code_convert_region1 (start, end, coding_system, encodep)
   struct coding_system coding;
   int from, to;
 
   struct coding_system coding;
   int from, to;
 
-  CHECK_NUMBER_COERCE_MARKER (start, 0);
-  CHECK_NUMBER_COERCE_MARKER (end, 1);
-  CHECK_SYMBOL (coding_system, 2);
+  CHECK_NUMBER_COERCE_MARKER (start);
+  CHECK_NUMBER_COERCE_MARKER (end);
+  CHECK_SYMBOL (coding_system);
 
   validate_region (&start, &end);
   from = XFASTINT (start);
 
   validate_region (&start, &end);
   from = XFASTINT (start);
@@ -6465,7 +7089,7 @@ code_convert_region1 (start, end, coding_system, encodep)
     return make_number (to - from);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
     return make_number (to - from);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
-    error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data);
+    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 
   coding.mode |= CODING_MODE_LAST_BLOCK;
   coding.src_multibyte = coding.dst_multibyte
 
   coding.mode |= CODING_MODE_LAST_BLOCK;
   coding.src_multibyte = coding.dst_multibyte
@@ -6478,14 +7102,14 @@ code_convert_region1 (start, end, coding_system, encodep)
 
 DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
        3, 3, "r\nzCoding system: ",
 
 DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
        3, 3, "r\nzCoding system: ",
-  "Decode the current region from the specified coding system.\n\
-When called from a program, takes three arguments:\n\
-START, END, and CODING-SYSTEM.  START and END are buffer positions.\n\
-This function sets `last-coding-system-used' to the precise coding system\n\
-used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
-not fully specified.)\n\
-It returns the length of the decoded text.")
-  (start, end, coding_system)
+       doc: /* Decode the current region from the specified coding system.
+When called from a program, takes three arguments:
+START, END, and CODING-SYSTEM.  START and END are buffer positions.
+This function sets `last-coding-system-used' to the precise coding system
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
+not fully specified.)
+It returns the length of the decoded text.  */)
+     (start, end, coding_system)
      Lisp_Object start, end, coding_system;
 {
   return code_convert_region1 (start, end, coding_system, 0);
      Lisp_Object start, end, coding_system;
 {
   return code_convert_region1 (start, end, coding_system, 0);
@@ -6493,14 +7117,14 @@ It returns the length of the decoded text.")
 
 DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,
        3, 3, "r\nzCoding system: ",
 
 DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,
        3, 3, "r\nzCoding system: ",
-  "Encode the current region into the specified coding system.\n\
-When called from a program, takes three arguments:\n\
-START, END, and CODING-SYSTEM.  START and END are buffer positions.\n\
-This function sets `last-coding-system-used' to the precise coding system\n\
-used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
-not fully specified.)\n\
-It returns the length of the encoded text.")
-  (start, end, coding_system)
+       doc: /* Encode the current region into the specified coding system.
+When called from a program, takes three arguments:
+START, END, and CODING-SYSTEM.  START and END are buffer positions.
+This function sets `last-coding-system-used' to the precise coding system
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
+not fully specified.)
+It returns the length of the encoded text.  */)
+     (start, end, coding_system)
      Lisp_Object start, end, coding_system;
 {
   return code_convert_region1 (start, end, coding_system, 1);
      Lisp_Object start, end, coding_system;
 {
   return code_convert_region1 (start, end, coding_system, 1);
@@ -6513,14 +7137,14 @@ code_convert_string1 (string, coding_system, nocopy, encodep)
 {
   struct coding_system coding;
 
 {
   struct coding_system coding;
 
-  CHECK_STRING (string, 0);
-  CHECK_SYMBOL (coding_system, 1);
+  CHECK_STRING (string);
+  CHECK_SYMBOL (coding_system);
 
   if (NILP (coding_system))
     return (NILP (nocopy) ? Fcopy_sequence (string) : string);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
 
   if (NILP (coding_system))
     return (NILP (nocopy) ? Fcopy_sequence (string) : string);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
-    error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data);
+    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 
   coding.mode |= CODING_MODE_LAST_BLOCK;
   string = (encodep
 
   coding.mode |= CODING_MODE_LAST_BLOCK;
   string = (encodep
@@ -6533,13 +7157,13 @@ code_convert_string1 (string, coding_system, nocopy, encodep)
 
 DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
        2, 3, 0,
 
 DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
        2, 3, 0,
-  "Decode STRING which is encoded in CODING-SYSTEM, and return the result.\n\
-Optional arg NOCOPY non-nil means it is OK to return STRING itself\n\
-if the decoding operation is trivial.\n\
-This function sets `last-coding-system-used' to the precise coding system\n\
-used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
-not fully specified.)")
-  (string, coding_system, nocopy)
+       doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.
+Optional arg NOCOPY non-nil means it is OK to return STRING itself
+if the decoding operation is trivial.
+This function sets `last-coding-system-used' to the precise coding system
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
+not fully specified.)  */)
+     (string, coding_system, nocopy)
      Lisp_Object string, coding_system, nocopy;
 {
   return code_convert_string1 (string, coding_system, nocopy, 0);
      Lisp_Object string, coding_system, nocopy;
 {
   return code_convert_string1 (string, coding_system, nocopy, 0);
@@ -6547,13 +7171,13 @@ not fully specified.)")
 
 DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
        2, 3, 0,
 
 DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
        2, 3, 0,
-  "Encode STRING to CODING-SYSTEM, and return the result.\n\
-Optional arg NOCOPY non-nil means it is OK to return STRING itself\n\
-if the encoding operation is trivial.\n\
-This function sets `last-coding-system-used' to the precise coding system\n\
-used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
-not fully specified.)")
-  (string, coding_system, nocopy)
+       doc: /* Encode STRING to CODING-SYSTEM, and return the result.
+Optional arg NOCOPY non-nil means it is OK to return STRING itself
+if the encoding operation is trivial.
+This function sets `last-coding-system-used' to the precise coding system
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
+not fully specified.)  */)
+     (string, coding_system, nocopy)
      Lisp_Object string, coding_system, nocopy;
 {
   return code_convert_string1 (string, coding_system, nocopy, 1);
      Lisp_Object string, coding_system, nocopy;
 {
   return code_convert_string1 (string, coding_system, nocopy, 1);
@@ -6572,14 +7196,14 @@ code_convert_string_norecord (string, coding_system, encodep)
 {
   struct coding_system coding;
 
 {
   struct coding_system coding;
 
-  CHECK_STRING (string, 0);
-  CHECK_SYMBOL (coding_system, 1);
+  CHECK_STRING (string);
+  CHECK_SYMBOL (coding_system);
 
   if (NILP (coding_system))
     return string;
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
 
   if (NILP (coding_system))
     return string;
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
-    error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data);
+    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 
   coding.composing = COMPOSITION_DISABLED;
   coding.mode |= CODING_MODE_LAST_BLOCK;
 
   coding.composing = COMPOSITION_DISABLED;
   coding.mode |= CODING_MODE_LAST_BLOCK;
@@ -6589,15 +7213,15 @@ code_convert_string_norecord (string, coding_system, encodep)
 }
 \f
 DEFUN ("decode-sjis-char", Fdecode_sjis_char, Sdecode_sjis_char, 1, 1, 0,
 }
 \f
 DEFUN ("decode-sjis-char", Fdecode_sjis_char, Sdecode_sjis_char, 1, 1, 0,
-  "Decode a Japanese character which has CODE in shift_jis encoding.\n\
-Return the corresponding character.")
-  (code)
+       doc: /* Decode a Japanese character which has CODE in shift_jis encoding.
+Return the corresponding character.  */)
+     (code)
      Lisp_Object code;
 {
   unsigned char c1, c2, s1, s2;
   Lisp_Object val;
 
      Lisp_Object code;
 {
   unsigned char c1, c2, s1, s2;
   Lisp_Object val;
 
-  CHECK_NUMBER (code, 0);
+  CHECK_NUMBER (code);
   s1 = (XFASTINT (code)) >> 8, s2 = (XFASTINT (code)) & 0xFF;
   if (s1 == 0)
     {
   s1 = (XFASTINT (code)) >> 8, s2 = (XFASTINT (code)) & 0xFF;
   if (s1 == 0)
     {
@@ -6610,7 +7234,7 @@ Return the corresponding character.")
     }
   else
     {
     }
   else
     {
-      if ((s1 < 0x80 || s1 > 0x9F && s1 < 0xE0 || s1 > 0xEF)
+      if ((s1 < 0x80 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF)
          || (s2 < 0x40 || s2 == 0x7F || s2 > 0xFC))
        error ("Invalid Shift JIS code: %x", XFASTINT (code));
       DECODE_SJIS (s1, s2, c1, c2);
          || (s2 < 0x40 || s2 == 0x7F || s2 > 0xFC))
        error ("Invalid Shift JIS code: %x", XFASTINT (code));
       DECODE_SJIS (s1, s2, c1, c2);
@@ -6620,15 +7244,15 @@ Return the corresponding character.")
 }
 
 DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,
 }
 
 DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,
-  "Encode a Japanese character CHAR to shift_jis encoding.\n\
-Return the corresponding code in SJIS.")
-  (ch)
+       doc: /* Encode a Japanese character CHAR to shift_jis encoding.
+Return the corresponding code in SJIS.  */)
+     (ch)
      Lisp_Object ch;
 {
   int charset, c1, c2, s1, s2;
   Lisp_Object val;
 
      Lisp_Object ch;
 {
   int charset, c1, c2, s1, s2;
   Lisp_Object val;
 
-  CHECK_NUMBER (ch, 0);
+  CHECK_NUMBER (ch);
   SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
   if (charset == CHARSET_ASCII)
     {
   SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
   if (charset == CHARSET_ASCII)
     {
@@ -6651,16 +7275,16 @@ Return the corresponding code in SJIS.")
 }
 
 DEFUN ("decode-big5-char", Fdecode_big5_char, Sdecode_big5_char, 1, 1, 0,
 }
 
 DEFUN ("decode-big5-char", Fdecode_big5_char, Sdecode_big5_char, 1, 1, 0,
-  "Decode a Big5 character which has CODE in BIG5 coding system.\n\
-Return the corresponding character.")
-  (code)
+       doc: /* Decode a Big5 character which has CODE in BIG5 coding system.
+Return the corresponding character.  */)
+     (code)
      Lisp_Object code;
 {
   int charset;
   unsigned char b1, b2, c1, c2;
   Lisp_Object val;
 
      Lisp_Object code;
 {
   int charset;
   unsigned char b1, b2, c1, c2;
   Lisp_Object val;
 
-  CHECK_NUMBER (code, 0);
+  CHECK_NUMBER (code);
   b1 = (XFASTINT (code)) >> 8, b2 = (XFASTINT (code)) & 0xFF;
   if (b1 == 0)
     {
   b1 = (XFASTINT (code)) >> 8, b2 = (XFASTINT (code)) & 0xFF;
   if (b1 == 0)
     {
@@ -6680,15 +7304,15 @@ Return the corresponding character.")
 }
 
 DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,
 }
 
 DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,
-  "Encode the Big5 character CHAR to BIG5 coding system.\n\
-Return the corresponding character code in Big5.")
-  (ch)
+       doc: /* Encode the Big5 character CHAR to BIG5 coding system.
+Return the corresponding character code in Big5.  */)
+     (ch)
      Lisp_Object ch;
 {
   int charset, c1, c2, b1, b2;
   Lisp_Object val;
 
      Lisp_Object ch;
 {
   int charset, c1, c2, b1, b2;
   Lisp_Object val;
 
-  CHECK_NUMBER (ch, 0);
+  CHECK_NUMBER (ch);
   SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
   if (charset == CHARSET_ASCII)
     {
   SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
   if (charset == CHARSET_ASCII)
     {
@@ -6707,16 +7331,16 @@ Return the corresponding character code in Big5.")
   return val;
 }
 \f
   return val;
 }
 \f
-DEFUN ("set-terminal-coding-system-internal",
-       Fset_terminal_coding_system_internal,
-       Sset_terminal_coding_system_internal, 1, 1, 0, "")
-  (coding_system)
+DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_internal,
+       Sset_terminal_coding_system_internal, 1, 1, 0,
+       doc: /* Internal use only.  */)
+     (coding_system)
      Lisp_Object coding_system;
 {
      Lisp_Object coding_system;
 {
-  CHECK_SYMBOL (coding_system, 0);
+  CHECK_SYMBOL (coding_system);
   setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding);
   /* We had better not send unsafe characters to terminal.  */
   setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding);
   /* We had better not send unsafe characters to terminal.  */
-  terminal_coding.flags |= CODING_FLAG_ISO_SAFE;
+  terminal_coding.mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
   /* Character composition should be disabled.  */
   terminal_coding.composing = COMPOSITION_DISABLED;
   /* Error notification should be suppressed.  */
   /* Character composition should be disabled.  */
   terminal_coding.composing = COMPOSITION_DISABLED;
   /* Error notification should be suppressed.  */
@@ -6726,49 +7350,49 @@ DEFUN ("set-terminal-coding-system-internal",
   return Qnil;
 }
 
   return Qnil;
 }
 
-DEFUN ("set-safe-terminal-coding-system-internal",
-       Fset_safe_terminal_coding_system_internal,
-       Sset_safe_terminal_coding_system_internal, 1, 1, 0, "")
-  (coding_system)
+DEFUN ("set-safe-terminal-coding-system-internal", Fset_safe_terminal_coding_system_internal,
+       Sset_safe_terminal_coding_system_internal, 1, 1, 0,
+       doc: /* Internal use only.  */)
+     (coding_system)
      Lisp_Object coding_system;
 {
      Lisp_Object coding_system;
 {
-  CHECK_SYMBOL (coding_system, 0);
+  CHECK_SYMBOL (coding_system);
   setup_coding_system (Fcheck_coding_system (coding_system),
                       &safe_terminal_coding);
   /* Character composition should be disabled.  */
   safe_terminal_coding.composing = COMPOSITION_DISABLED;
   /* Error notification should be suppressed.  */
   setup_coding_system (Fcheck_coding_system (coding_system),
                       &safe_terminal_coding);
   /* Character composition should be disabled.  */
   safe_terminal_coding.composing = COMPOSITION_DISABLED;
   /* Error notification should be suppressed.  */
-  terminal_coding.suppress_error = 1;
+  safe_terminal_coding.suppress_error = 1;
   safe_terminal_coding.src_multibyte = 1;
   safe_terminal_coding.dst_multibyte = 0;
   return Qnil;
 }
 
   safe_terminal_coding.src_multibyte = 1;
   safe_terminal_coding.dst_multibyte = 0;
   return Qnil;
 }
 
-DEFUN ("terminal-coding-system",
-       Fterminal_coding_system, Sterminal_coding_system, 0, 0, 0,
-  "Return coding system specified for terminal output.")
-  ()
+DEFUN ("terminal-coding-system", Fterminal_coding_system,
+       Sterminal_coding_system, 0, 0, 0,
+       doc: /* Return coding system specified for terminal output.  */)
+     ()
 {
   return terminal_coding.symbol;
 }
 
 {
   return terminal_coding.symbol;
 }
 
-DEFUN ("set-keyboard-coding-system-internal",
-       Fset_keyboard_coding_system_internal,
-       Sset_keyboard_coding_system_internal, 1, 1, 0, "")
-  (coding_system)
+DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_internal,
+       Sset_keyboard_coding_system_internal, 1, 1, 0,
+       doc: /* Internal use only.  */)
+     (coding_system)
      Lisp_Object coding_system;
 {
      Lisp_Object coding_system;
 {
-  CHECK_SYMBOL (coding_system, 0);
+  CHECK_SYMBOL (coding_system);
   setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding);
   /* Character composition should be disabled.  */
   keyboard_coding.composing = COMPOSITION_DISABLED;
   return Qnil;
 }
 
   setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding);
   /* Character composition should be disabled.  */
   keyboard_coding.composing = COMPOSITION_DISABLED;
   return Qnil;
 }
 
-DEFUN ("keyboard-coding-system",
-       Fkeyboard_coding_system, Skeyboard_coding_system, 0, 0, 0,
-  "Return coding system specified for decoding keyboard input.")
-  ()
+DEFUN ("keyboard-coding-system", Fkeyboard_coding_system,
+       Skeyboard_coding_system, 0, 0, 0,
+       doc: /* Return coding system specified for decoding keyboard input.  */)
+     ()
 {
   return keyboard_coding.symbol;
 }
 {
   return keyboard_coding.symbol;
 }
@@ -6776,37 +7400,37 @@ DEFUN ("keyboard-coding-system",
 \f
 DEFUN ("find-operation-coding-system", Ffind_operation_coding_system,
        Sfind_operation_coding_system,  1, MANY, 0,
 \f
 DEFUN ("find-operation-coding-system", Ffind_operation_coding_system,
        Sfind_operation_coding_system,  1, MANY, 0,
-  "Choose a coding system for an operation based on the target name.\n\
-The value names a pair of coding systems: (DECODING-SYSTEM . ENCODING-SYSTEM).\n\
-DECODING-SYSTEM is the coding system to use for decoding\n\
-\(in case OPERATION does decoding), and ENCODING-SYSTEM is the coding system\n\
-for encoding (in case OPERATION does encoding).\n\
-\n\
-The first argument OPERATION specifies an I/O primitive:\n\
-  For file I/O, `insert-file-contents' or `write-region'.\n\
-  For process I/O, `call-process', `call-process-region', or `start-process'.\n\
-  For network I/O, `open-network-stream'.\n\
-\n\
-The remaining arguments should be the same arguments that were passed\n\
-to the primitive.  Depending on which primitive, one of those arguments\n\
-is selected as the TARGET.  For example, if OPERATION does file I/O,\n\
-whichever argument specifies the file name is TARGET.\n\
-\n\
-TARGET has a meaning which depends on OPERATION:\n\
-  For file I/O, TARGET is a file name.\n\
-  For process I/O, TARGET is a process name.\n\
-  For network I/O, TARGET is a service name or a port number\n\
-\n\
-This function looks up what specified for TARGET in,\n\
-`file-coding-system-alist', `process-coding-system-alist',\n\
-or `network-coding-system-alist' depending on OPERATION.\n\
-They may specify a coding system, a cons of coding systems,\n\
-or a function symbol to call.\n\
-In the last case, we call the function with one argument,\n\
-which is a list of all the arguments given to this function.\n\
-\n\
-usage: (find-operation-coding-system OPERATION ARGUMENTS ...)")
-  (nargs, args)
+       doc: /* Choose a coding system for an operation based on the target name.
+The value names a pair of coding systems: (DECODING-SYSTEM . ENCODING-SYSTEM).
+DECODING-SYSTEM is the coding system to use for decoding
+\(in case OPERATION does decoding), and ENCODING-SYSTEM is the coding system
+for encoding (in case OPERATION does encoding).
+
+The first argument OPERATION specifies an I/O primitive:
+  For file I/O, `insert-file-contents' or `write-region'.
+  For process I/O, `call-process', `call-process-region', or `start-process'.
+  For network I/O, `open-network-stream'.
+
+The remaining arguments should be the same arguments that were passed
+to the primitive.  Depending on which primitive, one of those arguments
+is selected as the TARGET.  For example, if OPERATION does file I/O,
+whichever argument specifies the file name is TARGET.
+
+TARGET has a meaning which depends on OPERATION:
+  For file I/O, TARGET is a file name.
+  For process I/O, TARGET is a process name.
+  For network I/O, TARGET is a service name or a port number
+
+This function looks up what specified for TARGET in,
+`file-coding-system-alist', `process-coding-system-alist',
+or `network-coding-system-alist' depending on OPERATION.
+They may specify a coding system, a cons of coding systems,
+or a function symbol to call.
+In the last case, we call the function with one argument,
+which is a list of all the arguments given to this function.
+
+usage: (find-operation-coding-system OPERATION ARGUMENTS ...)  */)
+     (nargs, args)
      int nargs;
      Lisp_Object *args;
 {
      int nargs;
      Lisp_Object *args;
 {
@@ -6821,7 +7445,14 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS ...)")
     error ("Invalid first argument");
   if (nargs < 1 + XINT (target_idx))
     error ("Too few arguments for operation: %s",
     error ("Invalid first argument");
   if (nargs < 1 + XINT (target_idx))
     error ("Too few arguments for operation: %s",
-          XSYMBOL (operation)->name->data);
+          SDATA (SYMBOL_NAME (operation)));
+  /* For write-region, if the 6th argument (i.e. VISIT, the 5th
+     argument to write-region) is string, it must be treated as a
+     target file name.  */
+  if (EQ (operation, Qwrite_region)
+      && nargs > 5
+      && STRINGP (args[5]))
+    target_idx = make_number (4);
   target = args[XINT (target_idx) + 1];
   if (!(STRINGP (target)
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
   target = args[XINT (target_idx) + 1];
   if (!(STRINGP (target)
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
@@ -6872,10 +7503,10 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS ...)")
 
 DEFUN ("update-coding-systems-internal",  Fupdate_coding_systems_internal,
        Supdate_coding_systems_internal, 0, 0, 0,
 
 DEFUN ("update-coding-systems-internal",  Fupdate_coding_systems_internal,
        Supdate_coding_systems_internal, 0, 0, 0,
-  "Update internal database for ISO2022 and CCL based coding systems.\n\
-When values of any coding categories are changed, you must\n\
-call this function")
-  ()
+       doc: /* Update internal database for ISO2022 and CCL based coding systems.
+When values of any coding categories are changed, you must
+call this function.  */)
+     ()
 {
   int i;
 
 {
   int i;
 
@@ -6903,9 +7534,9 @@ call this function")
 
 DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal,
        Sset_coding_priority_internal, 0, 0, 0,
 
 DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal,
        Sset_coding_priority_internal, 0, 0, 0,
-  "Update internal database for the current value of `coding-category-list'.\n\
-This function is internal use only.")
-  ()
+       doc: /* Update internal database for the current value of `coding-category-list'.
+This function is internal use only.  */)
+     ()
 {
   int i = 0, idx;
   Lisp_Object val;
 {
   int i = 0, idx;
   Lisp_Object val;
@@ -6931,6 +7562,40 @@ This function is internal use only.")
   return Qnil;
 }
 
   return Qnil;
 }
 
+DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
+       Sdefine_coding_system_internal, 1, 1, 0,
+       doc: /* Register CODING-SYSTEM as a base coding system.
+This function is internal use only.  */)
+     (coding_system)
+     Lisp_Object coding_system;
+{
+  Lisp_Object safe_chars, slot;
+
+  if (NILP (Fcheck_coding_system (coding_system)))
+    Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));
+  safe_chars = coding_safe_chars (coding_system);
+  if (! EQ (safe_chars, Qt) && ! CHAR_TABLE_P (safe_chars))
+    error ("No valid safe-chars property for %s",
+          SDATA (SYMBOL_NAME (coding_system)));
+  if (EQ (safe_chars, Qt))
+    {
+      if (NILP (Fmemq (coding_system, XCAR (Vcoding_system_safe_chars))))
+       XSETCAR (Vcoding_system_safe_chars,
+                Fcons (coding_system, XCAR (Vcoding_system_safe_chars)));
+    }
+  else
+    {
+      slot = Fassq (coding_system, XCDR (Vcoding_system_safe_chars));
+      if (NILP (slot))
+       XSETCDR (Vcoding_system_safe_chars,
+                nconc2 (XCDR (Vcoding_system_safe_chars),
+                        Fcons (Fcons (coding_system, safe_chars), Qnil)));
+      else
+       XSETCDR (slot, safe_chars);
+    }
+  return Qnil;
+}
+
 #endif /* emacs */
 
 \f
 #endif /* emacs */
 
 \f
@@ -6941,7 +7606,7 @@ init_coding_once ()
 {
   int i;
 
 {
   int i;
 
-  /* Emacs' internal format specific initialize routine.  */ 
+  /* Emacs' internal format specific initialize routine.  */
   for (i = 0; i <= 0x20; i++)
     emacs_code_class[i] = EMACS_control_code;
   emacs_code_class[0x0A] = EMACS_linefeed_code;
   for (i = 0; i <= 0x20; i++)
     emacs_code_class[i] = EMACS_control_code;
   emacs_code_class[0x0A] = EMACS_linefeed_code;
@@ -7001,6 +7666,9 @@ init_coding_once ()
 void
 syms_of_coding ()
 {
 void
 syms_of_coding ()
 {
+  staticpro (&Vcode_conversion_workbuf_name);
+  Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
+
   Qtarget_idx = intern ("target-idx");
   staticpro (&Qtarget_idx);
 
   Qtarget_idx = intern ("target-idx");
   staticpro (&Qtarget_idx);
 
@@ -7084,9 +7752,12 @@ syms_of_coding ()
       }
   }
 
       }
   }
 
+  Vcoding_system_safe_chars = Fcons (Qnil, Qnil);
+  staticpro (&Vcoding_system_safe_chars);
+
   Qtranslation_table = intern ("translation-table");
   staticpro (&Qtranslation_table);
   Qtranslation_table = intern ("translation-table");
   staticpro (&Qtranslation_table);
-  Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (1));
+  Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2));
 
   Qtranslation_table_id = intern ("translation-table-id");
   staticpro (&Qtranslation_table_id);
 
   Qtranslation_table_id = intern ("translation-table-id");
   staticpro (&Qtranslation_table_id);
@@ -7108,7 +7779,7 @@ syms_of_coding ()
      But don't staticpro it here--that is done in alloc.c.  */
   Qchar_table_extra_slots = intern ("char-table-extra-slots");
   Fput (Qsafe_chars, Qchar_table_extra_slots, make_number (0));
      But don't staticpro it here--that is done in alloc.c.  */
   Qchar_table_extra_slots = intern ("char-table-extra-slots");
   Fput (Qsafe_chars, Qchar_table_extra_slots, make_number (0));
-  Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (1));
+  Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (0));
 
   Qvalid_codes = intern ("valid-codes");
   staticpro (&Qvalid_codes);
 
   Qvalid_codes = intern ("valid-codes");
   staticpro (&Qvalid_codes);
@@ -7119,6 +7790,12 @@ syms_of_coding ()
   Qraw_text = intern ("raw-text");
   staticpro (&Qraw_text);
 
   Qraw_text = intern ("raw-text");
   staticpro (&Qraw_text);
 
+  Qutf_8 = intern ("utf-8");
+  staticpro (&Qutf_8);
+
+  Qcoding_system_define_form = intern ("coding-system-define-form");
+  staticpro (&Qcoding_system_define_form);
+
   defsubr (&Scoding_system_p);
   defsubr (&Sread_coding_system);
   defsubr (&Sread_non_nil_coding_system);
   defsubr (&Scoding_system_p);
   defsubr (&Sread_coding_system);
   defsubr (&Sread_non_nil_coding_system);
@@ -7126,6 +7803,7 @@ syms_of_coding ()
   defsubr (&Sdetect_coding_region);
   defsubr (&Sdetect_coding_string);
   defsubr (&Sfind_coding_systems_region_internal);
   defsubr (&Sdetect_coding_region);
   defsubr (&Sdetect_coding_string);
   defsubr (&Sfind_coding_systems_region_internal);
+  defsubr (&Sunencodable_char_position);
   defsubr (&Sdecode_coding_region);
   defsubr (&Sencode_coding_region);
   defsubr (&Sdecode_coding_string);
   defsubr (&Sdecode_coding_region);
   defsubr (&Sencode_coding_region);
   defsubr (&Sdecode_coding_string);
@@ -7142,32 +7820,35 @@ syms_of_coding ()
   defsubr (&Sfind_operation_coding_system);
   defsubr (&Supdate_coding_systems_internal);
   defsubr (&Sset_coding_priority_internal);
   defsubr (&Sfind_operation_coding_system);
   defsubr (&Supdate_coding_systems_internal);
   defsubr (&Sset_coding_priority_internal);
+  defsubr (&Sdefine_coding_system_internal);
 
   DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,
 
   DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,
-    "List of coding systems.\n\
-\n\
-Do not alter the value of this variable manually.  This variable should be\n\
-updated by the functions `make-coding-system' and\n\
-`define-coding-system-alias'.");
+              doc: /* List of coding systems.
+
+Do not alter the value of this variable manually.  This variable should be
+updated by the functions `make-coding-system' and
+`define-coding-system-alias'.  */);
   Vcoding_system_list = Qnil;
 
   DEFVAR_LISP ("coding-system-alist", &Vcoding_system_alist,
   Vcoding_system_list = Qnil;
 
   DEFVAR_LISP ("coding-system-alist", &Vcoding_system_alist,
-    "Alist of coding system names.\n\
-Each element is one element list of coding system name.\n\
-This variable is given to `completing-read' as TABLE argument.\n\
-\n\
-Do not alter the value of this variable manually.  This variable should be\n\
-updated by the functions `make-coding-system' and\n\
-`define-coding-system-alias'.");
+              doc: /* Alist of coding system names.
+Each element is one element list of coding system name.
+This variable is given to `completing-read' as TABLE argument.
+
+Do not alter the value of this variable manually.  This variable should be
+updated by the functions `make-coding-system' and
+`define-coding-system-alias'.  */);
   Vcoding_system_alist = Qnil;
 
   DEFVAR_LISP ("coding-category-list", &Vcoding_category_list,
   Vcoding_system_alist = Qnil;
 
   DEFVAR_LISP ("coding-category-list", &Vcoding_category_list,
-    "List of coding-categories (symbols) ordered by priority.\n\
-\n\
-On detecting a coding system, Emacs tries code detection algorithms\n\
-associated with each coding-category one by one in this order.  When\n\
-one algorithm agrees with a byte sequence of source text, the coding\n\
-system bound to the corresponding coding-category is selected.");
+              doc: /* List of coding-categories (symbols) ordered by priority.
+
+On detecting a coding system, Emacs tries code detection algorithms
+associated with each coding-category one by one in this order.  When
+one algorithm agrees with a byte sequence of source text, the coding
+system bound to the corresponding coding-category is selected.
+
+Don't modify this variable directly, but use `set-coding-priority'.  */);
   {
     int i;
 
   {
     int i;
 
@@ -7179,194 +7860,206 @@ system bound to the corresponding coding-category is selected.");
   }
 
   DEFVAR_LISP ("coding-system-for-read", &Vcoding_system_for_read,
   }
 
   DEFVAR_LISP ("coding-system-for-read", &Vcoding_system_for_read,
-    "Specify the coding system for read operations.\n\
-It is useful to bind this variable with `let', but do not set it globally.\n\
-If the value is a coding system, it is used for decoding on read operation.\n\
-If not, an appropriate element is used from one of the coding system alists:\n\
-There are three such tables, `file-coding-system-alist',\n\
-`process-coding-system-alist', and `network-coding-system-alist'.");
+              doc: /* Specify the coding system for read operations.
+It is useful to bind this variable with `let', but do not set it globally.
+If the value is a coding system, it is used for decoding on read operation.
+If not, an appropriate element is used from one of the coding system alists:
+There are three such tables, `file-coding-system-alist',
+`process-coding-system-alist', and `network-coding-system-alist'.  */);
   Vcoding_system_for_read = Qnil;
 
   DEFVAR_LISP ("coding-system-for-write", &Vcoding_system_for_write,
   Vcoding_system_for_read = Qnil;
 
   DEFVAR_LISP ("coding-system-for-write", &Vcoding_system_for_write,
-    "Specify the coding system for write operations.\n\
-Programs bind this variable with `let', but you should not set it globally.\n\
-If the value is a coding system, it is used for encoding of output,\n\
-when writing it to a file and when sending it to a file or subprocess.\n\
-\n\
-If this does not specify a coding system, an appropriate element\n\
-is used from one of the coding system alists:\n\
-There are three such tables, `file-coding-system-alist',\n\
-`process-coding-system-alist', and `network-coding-system-alist'.\n\
-For output to files, if the above procedure does not specify a coding system,\n\
-the value of `buffer-file-coding-system' is used.");
+              doc: /* Specify the coding system for write operations.
+Programs bind this variable with `let', but you should not set it globally.
+If the value is a coding system, it is used for encoding of output,
+when writing it to a file and when sending it to a file or subprocess.
+
+If this does not specify a coding system, an appropriate element
+is used from one of the coding system alists:
+There are three such tables, `file-coding-system-alist',
+`process-coding-system-alist', and `network-coding-system-alist'.
+For output to files, if the above procedure does not specify a coding system,
+the value of `buffer-file-coding-system' is used.  */);
   Vcoding_system_for_write = Qnil;
 
   DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,
   Vcoding_system_for_write = Qnil;
 
   DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,
-    "Coding system used in the latest file or process I/O.");
+              doc: /* Coding system used in the latest file or process I/O.
+Also set by `encode-coding-region', `decode-coding-region',
+`encode-coding-string' and `decode-coding-string'.  */);
   Vlast_coding_system_used = Qnil;
 
   DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,
   Vlast_coding_system_used = Qnil;
 
   DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,
-    "*Non-nil means always inhibit code conversion of end-of-line format.\n\
-See info node `Coding Systems' and info node `Text and Binary' concerning\n\
-such conversion.");
+              doc: /* *Non-nil means always inhibit code conversion of end-of-line format.
+See info node `Coding Systems' and info node `Text and Binary' concerning
+such conversion.  */);
   inhibit_eol_conversion = 0;
 
   DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,
   inhibit_eol_conversion = 0;
 
   DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,
-    "Non-nil means process buffer inherits coding system of process output.\n\
-Bind it to t if the process output is to be treated as if it were a file\n\
-read from some filesystem.");
+              doc: /* Non-nil means process buffer inherits coding system of process output.
+Bind it to t if the process output is to be treated as if it were a file
+read from some filesystem.  */);
   inherit_process_coding_system = 0;
 
   DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
   inherit_process_coding_system = 0;
 
   DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
-    "Alist to decide a coding system to use for a file I/O operation.\n\
-The format is ((PATTERN . VAL) ...),\n\
-where PATTERN is a regular expression matching a file name,\n\
-VAL is a coding system, a cons of coding systems, or a function symbol.\n\
-If VAL is a coding system, it is used for both decoding and encoding\n\
-the file contents.\n\
-If VAL is a cons of coding systems, the car part is used for decoding,\n\
-and the cdr part is used for encoding.\n\
-If VAL is a function symbol, the function must return a coding system\n\
-or a cons of coding systems which are used as above.\n\
-\n\
-See also the function `find-operation-coding-system'\n\
-and the variable `auto-coding-alist'.");
+              doc: /* Alist to decide a coding system to use for a file I/O operation.
+The format is ((PATTERN . VAL) ...),
+where PATTERN is a regular expression matching a file name,
+VAL is a coding system, a cons of coding systems, or a function symbol.
+If VAL is a coding system, it is used for both decoding and encoding
+the file contents.
+If VAL is a cons of coding systems, the car part is used for decoding,
+and the cdr part is used for encoding.
+If VAL is a function symbol, the function must return a coding system
+or a cons of coding systems which are used as above.  The function gets
+the arguments with which `find-operation-coding-system' was called.
+
+See also the function `find-operation-coding-system'
+and the variable `auto-coding-alist'.  */);
   Vfile_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,
   Vfile_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,
-    "Alist to decide a coding system to use for a process I/O operation.\n\
-The format is ((PATTERN . VAL) ...),\n\
-where PATTERN is a regular expression matching a program name,\n\
-VAL is a coding system, a cons of coding systems, or a function symbol.\n\
-If VAL is a coding system, it is used for both decoding what received\n\
-from the program and encoding what sent to the program.\n\
-If VAL is a cons of coding systems, the car part is used for decoding,\n\
-and the cdr part is used for encoding.\n\
-If VAL is a function symbol, the function must return a coding system\n\
-or a cons of coding systems which are used as above.\n\
-\n\
-See also the function `find-operation-coding-system'.");
+    doc: /* Alist to decide a coding system to use for a process I/O operation.
+The format is ((PATTERN . VAL) ...),
+where PATTERN is a regular expression matching a program name,
+VAL is a coding system, a cons of coding systems, or a function symbol.
+If VAL is a coding system, it is used for both decoding what received
+from the program and encoding what sent to the program.
+If VAL is a cons of coding systems, the car part is used for decoding,
+and the cdr part is used for encoding.
+If VAL is a function symbol, the function must return a coding system
+or a cons of coding systems which are used as above.
+
+See also the function `find-operation-coding-system'.  */);
   Vprocess_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,
   Vprocess_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,
-    "Alist to decide a coding system to use for a network I/O operation.\n\
-The format is ((PATTERN . VAL) ...),\n\
-where PATTERN is a regular expression matching a network service name\n\
-or is a port number to connect to,\n\
-VAL is a coding system, a cons of coding systems, or a function symbol.\n\
-If VAL is a coding system, it is used for both decoding what received\n\
-from the network stream and encoding what sent to the network stream.\n\
-If VAL is a cons of coding systems, the car part is used for decoding,\n\
-and the cdr part is used for encoding.\n\
-If VAL is a function symbol, the function must return a coding system\n\
-or a cons of coding systems which are used as above.\n\
-\n\
-See also the function `find-operation-coding-system'.");
+    doc: /* Alist to decide a coding system to use for a network I/O operation.
+The format is ((PATTERN . VAL) ...),
+where PATTERN is a regular expression matching a network service name
+or is a port number to connect to,
+VAL is a coding system, a cons of coding systems, or a function symbol.
+If VAL is a coding system, it is used for both decoding what received
+from the network stream and encoding what sent to the network stream.
+If VAL is a cons of coding systems, the car part is used for decoding,
+and the cdr part is used for encoding.
+If VAL is a function symbol, the function must return a coding system
+or a cons of coding systems which are used as above.
+
+See also the function `find-operation-coding-system'.  */);
   Vnetwork_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("locale-coding-system", &Vlocale_coding_system,
   Vnetwork_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("locale-coding-system", &Vlocale_coding_system,
-    "Coding system to use with system messages.  Also used for decoding\n\
-keyboard input on X Window system.");
+              doc: /* Coding system to use with system messages.
+Also used for decoding keyboard input on X Window system.  */);
   Vlocale_coding_system = Qnil;
 
   /* The eol mnemonics are reset in startup.el system-dependently.  */
   DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix,
   Vlocale_coding_system = Qnil;
 
   /* The eol mnemonics are reset in startup.el system-dependently.  */
   DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix,
-    "*String displayed in mode line for UNIX-like (LF) end-of-line format.");
+              doc: /* *String displayed in mode line for UNIX-like (LF) end-of-line format.  */);
   eol_mnemonic_unix = build_string (":");
 
   DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos,
   eol_mnemonic_unix = build_string (":");
 
   DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos,
-    "*String displayed in mode line for DOS-like (CRLF) end-of-line format.");
+              doc: /* *String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);
   eol_mnemonic_dos = build_string ("\\");
 
   DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac,
   eol_mnemonic_dos = build_string ("\\");
 
   DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac,
-    "*String displayed in mode line for MAC-like (CR) end-of-line format.");
+              doc: /* *String displayed in mode line for MAC-like (CR) end-of-line format.  */);
   eol_mnemonic_mac = build_string ("/");
 
   DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided,
   eol_mnemonic_mac = build_string ("/");
 
   DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided,
-    "*String displayed in mode line when end-of-line format is not yet determined.");
+              doc: /* *String displayed in mode line when end-of-line format is not yet determined.  */);
   eol_mnemonic_undecided = build_string (":");
 
   DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,
   eol_mnemonic_undecided = build_string (":");
 
   DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,
-    "*Non-nil enables character translation while encoding and decoding.");
+              doc: /* *Non-nil enables character translation while encoding and decoding.  */);
   Venable_character_translation = Qt;
 
   DEFVAR_LISP ("standard-translation-table-for-decode",
   Venable_character_translation = Qt;
 
   DEFVAR_LISP ("standard-translation-table-for-decode",
-    &Vstandard_translation_table_for_decode,
-    "Table for translating characters while decoding.");
+              &Vstandard_translation_table_for_decode,
+              doc: /* Table for translating characters while decoding.  */);
   Vstandard_translation_table_for_decode = Qnil;
 
   DEFVAR_LISP ("standard-translation-table-for-encode",
   Vstandard_translation_table_for_decode = Qnil;
 
   DEFVAR_LISP ("standard-translation-table-for-encode",
-    &Vstandard_translation_table_for_encode,
-    "Table for translating characters while encoding.");
+              &Vstandard_translation_table_for_encode,
+              doc: /* Table for translating characters while encoding.  */);
   Vstandard_translation_table_for_encode = Qnil;
 
   DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,
   Vstandard_translation_table_for_encode = Qnil;
 
   DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,
-    "Alist of charsets vs revision numbers.\n\
-While encoding, if a charset (car part of an element) is found,\n\
-designate it with the escape sequence identifying revision (cdr part of the element).");
+              doc: /* Alist of charsets vs revision numbers.
+While encoding, if a charset (car part of an element) is found,
+designate it with the escape sequence identifying revision (cdr part of the element).  */);
   Vcharset_revision_alist = Qnil;
 
   DEFVAR_LISP ("default-process-coding-system",
               &Vdefault_process_coding_system,
   Vcharset_revision_alist = Qnil;
 
   DEFVAR_LISP ("default-process-coding-system",
               &Vdefault_process_coding_system,
-    "Cons of coding systems used for process I/O by default.\n\
-The car part is used for decoding a process output,\n\
-the cdr part is used for encoding a text to be sent to a process.");
+              doc: /* Cons of coding systems used for process I/O by default.
+The car part is used for decoding a process output,
+the cdr part is used for encoding a text to be sent to a process.  */);
   Vdefault_process_coding_system = Qnil;
 
   DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table,
   Vdefault_process_coding_system = Qnil;
 
   DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table,
-    "Table of extra Latin codes in the range 128..159 (inclusive).\n\
-This is a vector of length 256.\n\
-If Nth element is non-nil, the existence of code N in a file\n\
-\(or output of subprocess) doesn't prevent it to be detected as\n\
-a coding system of ISO 2022 variant which has a flag\n\
-`accept-latin-extra-code' t (e.g. iso-latin-1) on reading a file\n\
-or reading output of a subprocess.\n\
-Only 128th through 159th elements has a meaning.");
+              doc: /* Table of extra Latin codes in the range 128..159 (inclusive).
+This is a vector of length 256.
+If Nth element is non-nil, the existence of code N in a file
+\(or output of subprocess) doesn't prevent it to be detected as
+a coding system of ISO 2022 variant which has a flag
+`accept-latin-extra-code' t (e.g. iso-latin-1) on reading a file
+or reading output of a subprocess.
+Only 128th through 159th elements has a meaning.  */);
   Vlatin_extra_code_table = Fmake_vector (make_number (256), Qnil);
 
   DEFVAR_LISP ("select-safe-coding-system-function",
               &Vselect_safe_coding_system_function,
   Vlatin_extra_code_table = Fmake_vector (make_number (256), Qnil);
 
   DEFVAR_LISP ("select-safe-coding-system-function",
               &Vselect_safe_coding_system_function,
-    "Function to call to select safe coding system for encoding a text.\n\
-\n\
-If set, this function is called to force a user to select a proper\n\
-coding system which can encode the text in the case that a default\n\
-coding system used in each operation can't encode the text.\n\
-\n\
-The default value is `select-safe-coding-system' (which see).");
+              doc: /* Function to call to select safe coding system for encoding a text.
+
+If set, this function is called to force a user to select a proper
+coding system which can encode the text in the case that a default
+coding system used in each operation can't encode the text.
+
+The default value is `select-safe-coding-system' (which see).  */);
   Vselect_safe_coding_system_function = Qnil;
 
   Vselect_safe_coding_system_function = Qnil;
 
-  DEFVAR_LISP ("char-coding-system-table", &Vchar_coding_system_table,
-    "Char-table containing safe coding systems of each characters.\n\
-Each element doesn't include such generic coding systems that can\n\
-encode any characters.   They are in the first extra slot.");
-  Vchar_coding_system_table = Fmake_char_table (Qchar_coding_system, Qnil);
+  DEFVAR_BOOL ("coding-system-require-warning",
+              &coding_system_require_warning,
+              doc: /* Internal use only.
+If non-nil, on writing a file, `select-safe-coding-system-function' is
+called even if `coding-system-for-write' is non-nil.  The command
+`universal-coding-system-argument' binds this variable to t temporarily.  */);
+  coding_system_require_warning = 0;
+
 
   DEFVAR_BOOL ("inhibit-iso-escape-detection",
               &inhibit_iso_escape_detection,
 
   DEFVAR_BOOL ("inhibit-iso-escape-detection",
               &inhibit_iso_escape_detection,
-    "If non-nil, Emacs ignores ISO2022's escape sequence on code detection.\n\
-\n\
-By default, on reading a file, Emacs tries to detect how the text is\n\
-encoded.  This code detection is sensitive to escape sequences.  If\n\
-the sequence is valid as ISO2022, the code is determined as one of\n\
-the ISO2022 encodings, and the file is decoded by the corresponding\n\
-coding system (e.g. `iso-2022-7bit').\n\
-\n\
-However, there may be a case that you want to read escape sequences in\n\
-a file as is.  In such a case, you can set this variable to non-nil.\n\
-Then, as the code detection ignores any escape sequences, no file is\n\
-detected as encoded in some ISO2022 encoding.  The result is that all\n\
-escape sequences become visible in a buffer.\n\
-\n\
-The default value is nil, and it is strongly recommended not to change\n\
-it.  That is because many Emacs Lisp source files that contain\n\
-non-ASCII characters are encoded by the coding system `iso-2022-7bit'\n\
-in Emacs's distribution, and they won't be decoded correctly on\n\
-reading if you suppress escape sequence detection.\n\
-\n\
-The other way to read escape sequences in a file without decoding is\n\
-to explicitly specify some coding system that doesn't use ISO2022's\n\
-escape sequence (e.g `latin-1') on reading by \\[universal-coding-system-argument].");
+              doc: /* If non-nil, Emacs ignores ISO2022's escape sequence on code detection.
+
+By default, on reading a file, Emacs tries to detect how the text is
+encoded.  This code detection is sensitive to escape sequences.  If
+the sequence is valid as ISO2022, the code is determined as one of
+the ISO2022 encodings, and the file is decoded by the corresponding
+coding system (e.g. `iso-2022-7bit').
+
+However, there may be a case that you want to read escape sequences in
+a file as is.  In such a case, you can set this variable to non-nil.
+Then, as the code detection ignores any escape sequences, no file is
+detected as encoded in some ISO2022 encoding.  The result is that all
+escape sequences become visible in a buffer.
+
+The default value is nil, and it is strongly recommended not to change
+it.  That is because many Emacs Lisp source files that contain
+non-ASCII characters are encoded by the coding system `iso-2022-7bit'
+in Emacs's distribution, and they won't be decoded correctly on
+reading if you suppress escape sequence detection.
+
+The other way to read escape sequences in a file without decoding is
+to explicitly specify some coding system that doesn't use ISO2022's
+escape sequence (e.g `latin-1') on reading by \\[universal-coding-system-argument].  */);
   inhibit_iso_escape_detection = 0;
   inhibit_iso_escape_detection = 0;
+
+  DEFVAR_LISP ("translation-table-for-input", &Vtranslation_table_for_input,
+              doc: /* Char table for translating self-inserting characters.
+This is applied to the result of input methods, not their input.  See also
+`keyboard-translate-table'.  */);
+    Vtranslation_table_for_input = Qnil;
 }
 
 char *
 }
 
 char *
@@ -7383,7 +8076,7 @@ emacs_strerror (error_number)
       Lisp_Object dec = code_convert_string_norecord (build_string (str),
                                                      Vlocale_coding_system,
                                                      0);
       Lisp_Object dec = code_convert_string_norecord (build_string (str),
                                                      Vlocale_coding_system,
                                                      0);
-      str = (char *) XSTRING (dec)->data;
+      str = (char *) SDATA (dec);
     }
 
   return str;
     }
 
   return str;
@@ -7391,3 +8084,5 @@ emacs_strerror (error_number)
 
 #endif /* emacs */
 
 
 #endif /* emacs */
 
+/* arch-tag: 3a3a2b01-5ff6-4071-9afe-f5b808d9229d
+   (do not change this comment) */