]> code.delx.au - gnu-emacs/blobdiff - src/coding.c
*** empty log message ***
[gnu-emacs] / src / coding.c
index e5f1ae82cd5653b57e0d2edaef676de3821c1178..c3804630d729eb371242827e7fe2e1acdc7d5a20 100644 (file)
@@ -1,8 +1,8 @@
 /* Coding system handler (conversion, detection, etc).
    Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
-   Licensed to the Free Software Foundation.
+     Licensed to the Free Software Foundation.
    Copyright (C) 2001, 2002 Free Software Foundation, Inc.
-   Copyright (C) 2001, 2002
+   Copyright (C) 2003
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
@@ -86,7 +86,7 @@ CODING SYSTEM
   variants of ISO2022.
 
   o 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 8.
@@ -318,6 +318,8 @@ Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;
 Lisp_Object Qstart_process, Qopen_network_stream;
 Lisp_Object Qtarget_idx;
 
+int coding_system_require_warning;
+
 Lisp_Object Vselect_safe_coding_system_function;
 
 /* Mnemonic string for each format of end-of-line.  */
@@ -335,6 +337,7 @@ Lisp_Object Qcoding_system_p, Qcoding_system_error;
 /* Coding system emacs-mule and raw-text are for converting only
    end-of-line format.  */
 Lisp_Object Qemacs_mule, Qraw_text;
+Lisp_Object Qutf_8_emacs;
 
 /* Coding-systems are handed between Emacs Lisp programs and C internal
    routines by the following three variables.  */
@@ -395,6 +398,9 @@ static Lisp_Object Vcharset_revision_table;
 /* 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
@@ -589,8 +595,7 @@ enum iso_code_class_type
 #define CODING_CCL_ENCODER(coding)     \
   AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_encoder)
 #define CODING_CCL_VALIDS(coding)                                         \
-  (XSTRING (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)) \
-   ->data)
+  (SDATA (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)))
 
 /* Index for each coding category in `coding_categories' */
 
@@ -850,7 +855,7 @@ static struct coding_system coding_categories[coding_category_max];
     c = DECODE_CHAR (charset, code);                                        \
     if (charset_map_loaded)                                                 \
       {                                                                             \
-       unsigned char *orig = coding->source;                                \
+       const unsigned char *orig = coding->source;                          \
        EMACS_INT offset;                                                    \
                                                                             \
        coding_set_source (coding);                                          \
@@ -890,8 +895,7 @@ coding_set_source (coding)
     }
   else if (STRINGP (coding->src_object))
     {
-      coding->source = (XSTRING (coding->src_object)->data
-                       + coding->src_pos_byte);
+      coding->source = SDATA (coding->src_object) + coding->src_pos_byte;
     }
   else
     /* Otherwise, the source is C string and is never relocated
@@ -963,7 +967,7 @@ coding_alloc_by_making_gap (coding, bytes)
       set_buffer_internal (XBUFFER (this_buffer));
     }
 }
-     
+
 
 static unsigned char *
 alloc_destination (coding, nbytes, dst)
@@ -1055,8 +1059,8 @@ detect_coding_utf_8 (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int found = 0;
@@ -1127,9 +1131,9 @@ static void
 decode_coding_utf_8 (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size;
   int consumed_chars = 0, consumed_chars_base;
@@ -1264,7 +1268,7 @@ encode_coding_utf_8 (coding)
       while (charbuf < charbuf_end)
        {
          unsigned char str[MAX_MULTIBYTE_LENGTH], *p, *pend = str;
-         
+
          ASSURE_DESTINATION (safe_room);
          c = *charbuf++;
          if (CHAR_BYTE8_P (c))
@@ -1320,8 +1324,8 @@ detect_coding_utf_16 (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int c1, c2;
@@ -1357,9 +1361,9 @@ static void
 decode_coding_utf_16 (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size;
   int consumed_chars = 0, consumed_chars_base;
@@ -1440,7 +1444,7 @@ decode_coding_utf_16 (coding)
            CODING_UTF_16_SURROGATE (coding) = surrogate = c;
          else
            *charbuf++ = c;
-       }         
+       }
     }
 
  no_more_source:
@@ -1592,9 +1596,9 @@ emacs_mule_char (coding, src, nbytes, nchars, id)
      unsigned char *src;
      int *nbytes, *nchars, *id;
 {
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base = src;
   int multibytep = coding->src_multibyte;
-  unsigned char *src_base = src;
   struct charset *charset;
   unsigned code;
   int c;
@@ -1676,8 +1680,8 @@ detect_coding_emacs_mule (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int c;
@@ -1700,7 +1704,7 @@ detect_coding_emacs_mule (coding, detect_info)
             it because analyzing it is too heavy for detecting.  But,
             at least, we check that the composite character
             constitues of more than 4 bytes.  */
-         unsigned char *src_base;
+         const unsigned char *src_base;
 
        repeat:
          src_base = src;
@@ -1725,7 +1729,7 @@ detect_coding_emacs_mule (coding, detect_info)
        }
       else
        {
-         unsigned char *src_base = src - 1;
+         const unsigned char *src_base = src - 1;
 
          do
            {
@@ -1923,9 +1927,9 @@ static void
 decode_coding_emacs_mule (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
   int consumed_chars = 0, consumed_chars_base;
@@ -2378,16 +2382,16 @@ setup_iso_safe_charsets (attrs)
       charset = CHARSET_FROM_ID (XINT (id));
       reg = Fcdr (Fassq (id, request));
       if (! NILP (reg))
-       XSTRING (safe_charsets)->data[XINT (id)] = XINT (reg);
+       SSET (safe_charsets, XINT (id), XINT (reg));
       else if (charset->iso_chars_96)
        {
          if (reg96 < 4)
-           XSTRING (safe_charsets)->data[XINT (id)] = reg96;
+           SSET (safe_charsets, XINT (id), reg96);
        }
       else
        {
          if (reg94 < 4)
-           XSTRING (safe_charsets)->data[XINT (id)] = reg94;
+           SSET (safe_charsets, XINT (id), reg94);
        }
     }
   ASET (attrs, coding_attr_safe_charsets, safe_charsets);
@@ -2403,8 +2407,8 @@ detect_coding_iso_2022 (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int single_shifting = 0;
   int id;
@@ -2426,8 +2430,8 @@ detect_coding_iso_2022 (coding, detect_info)
          && ! EQ (CODING_ATTR_SAFE_CHARSETS (attrs), Viso_2022_charset_list))
        setup_iso_safe_charsets (attrs);
       val = CODING_ATTR_SAFE_CHARSETS (attrs);
-      this->max_charset_id = XSTRING (val)->size - 1;
-      this->safe_charsets = (char *) XSTRING (val)->data;
+      this->max_charset_id = SCHARS (val) - 1;
+      this->safe_charsets = (char *) SDATA (val);
     }
 
   /* A coding system of this category is always ASCII compatible.  */
@@ -2523,7 +2527,7 @@ detect_coding_iso_2022 (coding, detect_info)
          rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
          found |= CATEGORY_MASK_ISO_ELSE;
          break;
-         
+
        case ISO_CODE_CSI:
          /* Control sequence introducer.  */
          single_shifting = 0;
@@ -2685,7 +2689,7 @@ detect_coding_iso_2022 (coding, detect_info)
       }                                                                        \
     else                                                               \
       {                                                                        \
-       unsigned char *p;                                               \
+       const unsigned char *p;                                         \
                                                                        \
        MAYBE_FINISH_COMPOSITION ();                                    \
        if (charbuf + MAX_COMPOSITION_COMPONENTS > charbuf_end)         \
@@ -2721,7 +2725,7 @@ detect_coding_iso_2022 (coding, detect_info)
                  : (component_idx + 1) / 2);                           \
     int i;                                                             \
     int *saved_charbuf = charbuf;                                      \
-    int from = coding->produced_char + char_offset;                    \
+    int from = char_offset;                                            \
     int to = from + nchars;                                            \
                                                                        \
     ADD_COMPOSITION_DATA (charbuf, from, to, method);                  \
@@ -2777,9 +2781,9 @@ static void
 decode_coding_iso_2022 (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end
     = charbuf + coding->charbuf_size - 4 - MAX_ANNOTATION_LENGTH;
@@ -2882,7 +2886,7 @@ decode_coding_iso_2022 (coding)
                    {
                      coding->result = CODING_RESULT_INSUFFICIENT_SRC;
                      goto no_more_source;
-                   }                 
+                   }
                  if (*src == '\n')
                    ONE_MORE_BYTE (c1);
                }
@@ -3071,7 +3075,7 @@ decode_coding_iso_2022 (coding)
                     They may be decoded by post-read-conversion.  */
                  int dim, M, L;
                  int size;
-                 
+
                  ONE_MORE_BYTE (dim);
                  ONE_MORE_BYTE (M);
                  ONE_MORE_BYTE (L);
@@ -3648,8 +3652,7 @@ encode_coding_iso_2022 (coding)
   setup_iso_safe_charsets (attrs);
   /* Charset list may have been changed.  */
   charset_list = CODING_ATTR_CHARSET_LIST (attrs);             \
-  coding->safe_charsets
-    = (char *) XSTRING (CODING_ATTR_SAFE_CHARSETS(attrs))->data;
+  coding->safe_charsets = (char *) SDATA (CODING_ATTR_SAFE_CHARSETS(attrs));
 
   ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 
@@ -3818,8 +3821,8 @@ detect_coding_sjis (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int found = 0;
@@ -3871,8 +3874,8 @@ detect_coding_big5 (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int found = 0;
@@ -3920,9 +3923,9 @@ static void
 decode_coding_sjis (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
   int consumed_chars = 0, consumed_chars_base;
@@ -4031,9 +4034,9 @@ static void
 decode_coding_big5 (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
   int consumed_chars = 0, consumed_chars_base;
@@ -4291,8 +4294,8 @@ detect_coding_ccl (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   int found = 0;
@@ -4329,7 +4332,7 @@ decode_coding_ccl (coding)
      struct coding_system *coding;
 {
   const unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size;
   int consumed_chars = 0;
@@ -4357,7 +4360,7 @@ decode_coding_ccl (coding)
       else
        while (i < 1024 && p < src_end)
          source_charbuf[i++] = *p++;
-      
+
       if (p == src_end && coding->mode & CODING_MODE_LAST_BLOCK)
        ccl.last_block = 1;
 
@@ -4556,7 +4559,7 @@ encode_coding_raw_text (coding)
          while (charbuf < charbuf_end && dst < dst_end)
            *dst++ = *charbuf++;
          produced_chars = dst - (coding->destination + coding->dst_bytes);
-       } 
+       }
     }
   coding->result = CODING_RESULT_SUCCESS;
   coding->produced_char += produced_chars;
@@ -4573,8 +4576,8 @@ detect_coding_charset (coding, detect_info)
      struct coding_system *coding;
      struct coding_detection_info *detect_info;
 {
-  unsigned char *src = coding->source, *src_base = src;
-  unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src = coding->source, *src_base = src;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int consumed_chars = 0;
   Lisp_Object attrs, valids;
@@ -4611,9 +4614,9 @@ static void
 decode_coding_charset (coding)
      struct coding_system *coding;
 {
-  unsigned char *src = coding->source + coding->consumed;
-  unsigned char *src_end = coding->source + coding->src_bytes;
-  unsigned char *src_base;
+  const unsigned char *src = coding->source + coding->consumed;
+  const unsigned char *src_end = coding->source + coding->src_bytes;
+  const unsigned char *src_base;
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
   int consumed_chars = 0, consumed_chars_base;
@@ -4754,7 +4757,7 @@ encode_coding_charset (coding)
     {
       struct charset *charset;
       unsigned code;
-      
+
       ASSURE_DESTINATION (safe_room);
       c = *charbuf++;
       if (ascii_compatible && ASCII_CHAR_P (c))
@@ -4829,10 +4832,12 @@ setup_coding_system (coding_system, coding)
     coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
   if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
     coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
+  if (! NILP (CODING_ATTR_FOR_UNIBYTE (attrs)))
+    coding->common_flags |= CODING_FOR_UNIBYTE_MASK;
 
   val = CODING_ATTR_SAFE_CHARSETS (attrs);
-  coding->max_charset_id = XSTRING (val)->size - 1;
-  coding->safe_charsets = (char *) XSTRING (val)->data;
+  coding->max_charset_id = SCHARS (val) - 1;
+  coding->safe_charsets = (char *) SDATA (val);
   coding->default_char = XINT (CODING_ATTR_DEFAULT_CHAR (attrs));
 
   coding_type = CODING_ATTR_TYPE (attrs);
@@ -4876,8 +4881,8 @@ setup_coding_system (coding_system, coding)
        {
          setup_iso_safe_charsets (attrs);
          val = CODING_ATTR_SAFE_CHARSETS (attrs);
-         coding->max_charset_id = XSTRING (val)->size - 1;
-         coding->safe_charsets = (char *) XSTRING (val)->data;
+         coding->max_charset_id = SCHARS (val) - 1;
+         coding->safe_charsets = (char *) SDATA (val);
        }
       CODING_ISO_FLAGS (coding) = flags;
     }
@@ -4945,9 +4950,9 @@ setup_coding_system (coding_system, coding)
                                        make_number (255));
          for (tail = Vemacs_mule_charset_list; CONSP (tail);
               tail = XCDR (tail))
-           XSTRING (safe_charsets)->data[XFASTINT (XCAR (tail))] = 0;
+           SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
          coding->max_charset_id = max_charset_id;
-         coding->safe_charsets = (char *) XSTRING (safe_charsets)->data;
+         coding->safe_charsets = (char *) SDATA (safe_charsets);
        }
     }
   else if (EQ (coding_type, Qshift_jis))
@@ -4971,7 +4976,6 @@ setup_coding_system (coding_system, coding)
       coding->detector = NULL;
       coding->decoder = decode_coding_raw_text;
       coding->encoder = encode_coding_raw_text;
-      coding->common_flags |= CODING_FOR_UNIBYTE_MASK;
     }
 
   return;
@@ -4991,7 +4995,7 @@ raw_text_coding_system (coding_system)
     return Qraw_text;
   spec = CODING_SYSTEM_SPEC (coding_system);
   attrs = AREF (spec, 0);
-  
+
   if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
     return coding_system;
 
@@ -5196,7 +5200,7 @@ detect_eol (source, src_bytes, category)
                       || src[lsb + 2] != '\n')
                this_eol = EOL_SEEN_CR;
              else
-               this_eol = EOL_SEEN_CRLF; 
+               this_eol = EOL_SEEN_CRLF;
 
              if (eol_seen == EOL_SEEN_NONE)
                /* This is the first end-of-line.  */
@@ -5212,7 +5216,7 @@ detect_eol (source, src_bytes, category)
            }
          src += 2;
        }
-    }   
+    }
   else
     {
       while (src < src_end)
@@ -5253,7 +5257,7 @@ adjust_coding_eol_type (coding, eol_seen)
      int eol_seen;
 {
   Lisp_Object eol_type;
-  
+
   eol_type = CODING_ID_EOL_TYPE (coding->id);
   if (eol_seen & EOL_SEEN_LF)
     coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0));
@@ -5271,7 +5275,7 @@ void
 detect_coding (coding)
      struct coding_system *coding;
 {
-  unsigned char *src, *src_end;
+  const unsigned char *src, *src_end;
   Lisp_Object attrs, coding_type;
 
   coding->consumed = coding->consumed_char = 0;
@@ -5408,7 +5412,7 @@ decode_eol (coding)
     {
       unsigned char *p = CHAR_POS_ADDR (coding->dst_pos);
       unsigned char *pend = p + coding->produced;
-      
+
       for (; p < pend; p++)
        if (*p == '\r')
          *p = '\n';
@@ -5479,13 +5483,13 @@ produce_chars (coding)
 
       if (BUFFERP (coding->src_object)
          && EQ (coding->src_object, coding->dst_object))
-       dst_end = coding->source + coding->consumed;
+       dst_end = ((unsigned char *) coding->source) + coding->consumed;
       adjusted_dst_end = dst_end - MAX_MULTIBYTE_LENGTH;
 
       while (buf < buf_end)
        {
          int c = *buf++;
-         
+
          if (dst >= adjusted_dst_end)
            {
              dst = alloc_destination (coding,
@@ -5511,8 +5515,8 @@ produce_chars (coding)
     }
   else
     {
-      unsigned char *src = coding->source;
-      unsigned char *src_end = src + coding->src_bytes;
+      const unsigned char *src = coding->source;
+      const unsigned char *src_end = src + coding->src_bytes;
       Lisp_Object eol_type;
 
       eol_type = CODING_ID_EOL_TYPE (coding->id);
@@ -5526,7 +5530,7 @@ produce_chars (coding)
 
              while (1)
                {
-                 unsigned char *src_base = src;
+                 const unsigned char *src_base = src;
                  int c;
 
                  ONE_MORE_BYTE (c);
@@ -5550,7 +5554,7 @@ produce_chars (coding)
                      coding->consumed = src - coding->source;
 
                    if (EQ (coding->src_object, coding->dst_object))
-                     dst_end = src;
+                     dst_end = (unsigned char *) src;
                    if (dst == dst_end)
                      {
                        dst = alloc_destination (coding, src_end - src + 1,
@@ -5589,7 +5593,7 @@ produce_chars (coding)
                    coding->consumed = src - coding->source;
 
                    if (EQ (coding->src_object, coding->dst_object))
-                     dst_end = src;
+                     dst_end = (unsigned char *) src;
                    if (dst >= dst_end - 1)
                      {
                        dst = alloc_destination (coding, src_end - src + 2,
@@ -5844,7 +5848,7 @@ decode_coding (coding)
   if (coding->consumed < coding->src_bytes)
     {
       int nbytes = coding->src_bytes - coding->consumed;
-      unsigned char *src;
+      const unsigned char *src;
 
       coding_set_source (coding);
       coding_set_destination (coding);
@@ -5931,7 +5935,7 @@ handle_composition_annotation (pos, limit, coding, buf, stop)
                }
              else if (STRINGP (components))
                {
-                 len = XSTRING (components)->size;
+                 len = SCHARS (components);
                  i = i_byte = 0;
                  while (i < len)
                    {
@@ -6192,7 +6196,7 @@ make_conversion_work_buffer (multibytep, depth)
   set_buffer_internal (XBUFFER (buf));
   current_buffer->undo_list = Qt;
   Ferase_buffer ();
-  Fset_buffer_multibyte (multibytep ? Qt : Qnil, Qnil);
+  Fset_buffer_multibyte (multibytep ? Qt : Qnil);
   set_buffer_internal (current);
   return buf;
 }
@@ -6260,21 +6264,18 @@ decode_coding_gap (coding, chars, bytes)
 
   if (CODING_REQUIRE_DETECTION (coding))
     detect_coding (coding);
-    
+
   decode_coding (coding);
 
   attrs = CODING_ID_ATTRS (coding->id);
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
     {
-      struct gcpro gcpro1;
       EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
 
       TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
-      GCPRO1 (buffer);
       val = call1 (CODING_ATTR_POST_READ (attrs),
                   make_number (coding->produced_char));
-      UNGCPRO;
       CHECK_NATNUM (val);
       coding->produced_char += Z - prev_Z;
       coding->produced += Z_BYTE - prev_Z_BYTE;
@@ -6679,7 +6680,7 @@ 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);
     }
-  while (XSTRING (val)->size == 0);
+  while (SCHARS (val) == 0);
   return (Fintern (val, Qnil));
 }
 
@@ -6691,11 +6692,11 @@ If the user enters null input, return second argument DEFAULT-CODING-SYSTEM.  */
 {
   Lisp_Object val;
   if (SYMBOLP (default_coding_system))
-    XSETSTRING (default_coding_system, XSYMBOL (default_coding_system)->name);
+    XSETSTRING (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);
-  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,
@@ -6731,12 +6732,12 @@ If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.  */)
 
 Lisp_Object
 detect_coding_system (src, src_bytes, highest, multibytep, coding_system)
-     unsigned char *src;
+     const unsigned char *src;
      int src_bytes, highest;
      int multibytep;
      Lisp_Object coding_system;
 {
-  unsigned char *src_end = src + src_bytes;
+  const unsigned char *src_end = src + src_bytes;
   Lisp_Object attrs, eol_type;
   Lisp_Object val;
   struct coding_system coding;
@@ -6987,10 +6988,8 @@ highest priority.  */)
 {
   CHECK_STRING (string);
 
-  return detect_coding_system (XSTRING (string)->data,
-                              STRING_BYTES (XSTRING (string)),
-                              !NILP (highest),
-                              STRING_MULTIBYTE (string),
+  return detect_coding_system (SDATA (string), SBYTES (string),
+                              !NILP (highest), STRING_MULTIBYTE (string),
                               Qnil);
 }
 
@@ -7036,10 +7035,10 @@ DEFUN ("find-coding-systems-region-internal",
   if (STRINGP (start))
     {
       if (!STRING_MULTIBYTE (start)
-         || XSTRING (start)->size == STRING_BYTES (XSTRING (start)))
+         || SCHARS (start) == SBYTES (start))
        return Qt;
       start_byte = 0;
-      end_byte = STRING_BYTES (XSTRING (start));
+      end_byte = SBYTES (start);
     }
   else
     {
@@ -7077,7 +7076,7 @@ DEFUN ("find-coding-systems-region-internal",
       }
 
   if (STRINGP (start))
-    p = pbeg = XSTRING (start)->data;
+    p = pbeg = SDATA (start);
   else
     p = pbeg = BYTE_POS_ADDR (start_byte);
   pend = p + (end_byte - start_byte);
@@ -7117,7 +7116,7 @@ DEFUN ("find-coding-systems-region-internal",
              EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
-               pbeg = XSTRING (start)->data;
+               pbeg = SDATA (start);
              else
                pbeg = BYTE_POS_ADDR (start_byte);
              p = pbeg + p_offset;
@@ -7135,6 +7134,113 @@ DEFUN ("find-coding-systems-region-internal",
 }
 
 
+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;
+  struct coding_system coding;
+  Lisp_Object attrs, charset_list;
+  Lisp_Object positions;
+  int from, to;
+  const unsigned char *p, *stop, *pend;
+  int ascii_compatible;
+
+  setup_coding_system (Fcheck_coding_system (coding_system), &coding);
+  attrs = CODING_ID_ATTRS (coding.id);
+  if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
+    return Qnil;
+  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
+  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
+
+  if (NILP (string))
+    {
+      validate_region (&start, &end);
+      from = XINT (start);
+      to = XINT (end);
+      if (NILP (current_buffer->enable_multibyte_characters)
+         || (ascii_compatible
+             && (to - from) == (CHAR_TO_BYTE (to) - (CHAR_TO_BYTE (from)))))
+       return Qnil;
+      p = CHAR_POS_ADDR (from);
+      pend = CHAR_POS_ADDR (to);
+      if (from < GPT && to >= GPT)
+       stop = GPT_ADDR;
+      else
+       stop = pend;
+    }
+  else
+    {
+      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);
+      stop = pend = SDATA (string) + string_char_to_byte (string, to);
+      if (ascii_compatible && (to - from) == (pend - p))
+       return Qnil;
+    }
+
+  if (NILP (count))
+    n = 1;
+  else
+    {
+      CHECK_NATNUM (count);
+      n = XINT (count);
+    }
+
+  positions = Qnil;
+  while (1)
+    {
+      int c;
+
+      if (ascii_compatible)
+       while (p < stop && ASCII_BYTE_P (*p))
+         p++, from++;
+      if (p >= stop)
+       {
+         if (p >= pend)
+           break;
+         stop = pend;
+         p = GAP_END_ADDR;
+       }
+
+      c = STRING_CHAR_ADVANCE (p);
+      if (! (ASCII_CHAR_P (c) && ascii_compatible)
+         && ! char_charset (c, charset_list, NULL))
+       {
+         positions = Fcons (make_number (from), positions);
+         n--;
+         if (n == 0)
+           break;
+       }
+
+      from++;
+    }
+
+  return (NILP (count) ? Fcar (positions) : Fnreverse (positions));
+}
+
+
 DEFUN ("check-coding-systems-region", Fcheck_coding_systems_region,
        Scheck_coding_systems_region, 3, 3, 0,
        doc: /* Check if the region is encodable by coding systems.
@@ -7166,10 +7272,10 @@ buffer positions.  END is ignored.  */)
   if (STRINGP (start))
     {
       if (!STRING_MULTIBYTE (start)
-         && XSTRING (start)->size != STRING_BYTES (XSTRING (start)))
+         && SCHARS (start) != SBYTES (start))
        return Qnil;
       start_byte = 0;
-      end_byte = STRING_BYTES (XSTRING (start));
+      end_byte = SBYTES (start);
       pos = 0;
     }
   else
@@ -7205,7 +7311,7 @@ buffer positions.  END is ignored.  */)
     }
 
   if (STRINGP (start))
-    p = pbeg = XSTRING (start)->data;
+    p = pbeg = SDATA (start);
   else
     p = pbeg = BYTE_POS_ADDR (start_byte);
   pend = p + (end_byte - start_byte);
@@ -7233,7 +7339,7 @@ buffer positions.  END is ignored.  */)
              EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
-               pbeg = XSTRING (start)->data;
+               pbeg = SDATA (start);
              else
                pbeg = BYTE_POS_ADDR (start_byte);
              p = pbeg + p_offset;
@@ -7378,8 +7484,8 @@ code_convert_string (string, coding_system, dst_object,
 
   setup_coding_system (coding_system, &coding);
   coding.mode |= CODING_MODE_LAST_BLOCK;
-  chars = XSTRING (string)->size;
-  bytes = STRING_BYTES (XSTRING (string));
+  chars = SCHARS (string);
+  bytes = SBYTES (string);
   if (encodep)
     encode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object);
   else
@@ -7608,7 +7714,7 @@ DEFUN ("set-terminal-coding-system-internal",
   CHECK_SYMBOL (coding_system);
   setup_coding_system (Fcheck_coding_system (coding_system),
                        &terminal_coding);
-  
+
   /* We had better not send unsafe characters to terminal.  */
   terminal_coding.mode |= CODING_MODE_SAFE_ENCODING;
   /* Characer composition should be disabled.  */
@@ -7714,7 +7820,7 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS ...)  */)
     error ("Invalid first arguement");
   if (nargs < 1 + XINT (target_idx))
     error ("Too few arguments for operation: %s",
-          XSYMBOL (operation)->name->data);
+          SDATA (SYMBOL_NAME (operation)));
   target = args[XINT (target_idx) + 1];
   if (!(STRINGP (target)
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
@@ -7856,11 +7962,11 @@ make_subsidiaries (base)
      Lisp_Object base;
 {
   Lisp_Object subsidiaries;
-  int base_name_len = STRING_BYTES (XSYMBOL (base)->name);
+  int base_name_len = SBYTES (SYMBOL_NAME (base));
   char *buf = (char *) alloca (base_name_len + 6);
   int i;
-      
-  bcopy (XSYMBOL (base)->name->data, buf, base_name_len);
+
+  bcopy (SDATA (SYMBOL_NAME (base)), buf, base_name_len);
   subsidiaries = Fmake_vector (make_number (3), Qnil);
   for (i = 0; i < 3; i++)
     {
@@ -7942,9 +8048,9 @@ usage: (define-coding-system-internal ...)  */)
              ? CHARSET_EMACS_MULE_ID (charset) < 0
              : 0)
            error ("Can't handle charset `%s'",
-                  XSYMBOL (CHARSET_NAME (charset))->name->data);
+                  SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 
-         XCAR (tail) = make_number (charset->id);
+         XSETCAR (tail, make_number (charset->id));
          if (max_charset_id < charset->id)
            max_charset_id = charset->id;
        }
@@ -7954,7 +8060,7 @@ usage: (define-coding-system-internal ...)  */)
   safe_charsets = Fmake_string (make_number (max_charset_id + 1),
                                make_number (255));
   for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
-    XSTRING (safe_charsets)->data[XFASTINT (XCAR (tail))] = 0;
+    SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
   CODING_ATTR_SAFE_CHARSETS (attrs) = safe_charsets;
 
   CODING_ATTR_ASCII_COMPAT (attrs) = args[coding_arg_ascii_compatible_p];
@@ -7982,10 +8088,13 @@ usage: (define-coding-system-internal ...)  */)
     CODING_ATTR_DEFAULT_CHAR (attrs) = make_number (' ');
   else
     {
-      CHECK_CHARACTER (val); 
+      CHECK_CHARACTER (val);
       CODING_ATTR_DEFAULT_CHAR (attrs) = val;
     }
 
+  val = args[coding_arg_for_unibyte];
+  CODING_ATTR_FOR_UNIBYTE (attrs) = NILP (val) ? Qnil : Qt;
+
   val = args[coding_arg_plist];
   CHECK_LIST (val);
   CODING_ATTR_PLIST (attrs) = val;
@@ -8014,7 +8123,7 @@ usage: (define-coding-system-internal ...)  */)
            {
              val = CHARSET_SUPERSET (charset);
              for (; CONSP (val); val = XCDR (val))
-               list = Fcons (XCAR (XCAR (val)), list); 
+               list = Fcons (XCAR (XCAR (val)), list);
            }
          else
            list = Fcons (XCAR (tail), list);
@@ -8027,7 +8136,7 @@ usage: (define-coding-system-internal ...)  */)
          struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail)));
          int dim = CHARSET_DIMENSION (charset);
          int idx = (dim - 1) * 4;
-         
+
          if (CHARSET_ASCII_COMPATIBLE_P (charset))
            CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 
@@ -8073,7 +8182,7 @@ usage: (define-coding-system-internal ...)  */)
   else if (EQ (coding_type, Qccl))
     {
       Lisp_Object valids;
-      
+
       if (nargs < coding_arg_ccl_max)
        goto short_args;
 
@@ -8105,10 +8214,10 @@ usage: (define-coding-system-internal ...)  */)
          else
            {
              CHECK_CONS (val);
-             CHECK_NUMBER (XCAR (val));
-             CHECK_NUMBER (XCDR (val));
+             CHECK_NATNUM_CAR (val);
+             CHECK_NATNUM_CDR (val);
              from = XINT (XCAR (val));
-             if (from < 0 || from > 255)
+             if (from > 255)
                args_out_of_range_3 (XCAR (val),
                                     make_number (0), make_number (255));
              to = XINT (XCDR (val));
@@ -8117,10 +8226,10 @@ usage: (define-coding-system-internal ...)  */)
                                     XCAR (val), make_number (255));
            }
          for (i = from; i <= to; i++)
-           XSTRING (valids)->data[i] = 1;
+           SSET (valids, i, 1);
        }
       ASET (attrs, coding_attr_ccl_valids, valids);
-      
+
       category = coding_category_ccl;
     }
   else if (EQ (coding_type, Qutf_16))
@@ -8136,8 +8245,10 @@ usage: (define-coding-system-internal ...)  */)
       if (! NILP (bom) && ! EQ (bom, Qt))
        {
          CHECK_CONS (bom);
-         CHECK_CODING_SYSTEM (XCAR (bom));
-         CHECK_CODING_SYSTEM (XCDR (bom));
+         val = XCAR (bom);
+         CHECK_CODING_SYSTEM (val);
+         val = XCDR (bom);
+         CHECK_CODING_SYSTEM (val);
        }
       ASET (attrs, coding_attr_utf_16_bom, bom);
 
@@ -8146,7 +8257,7 @@ usage: (define-coding-system-internal ...)  */)
       if (NILP (endian))
        endian = Qbig;
       else if (! EQ (endian, Qbig) && ! EQ (endian, Qlittle))
-       error ("Invalid endian: %s", XSYMBOL (endian)->name->data);
+       error ("Invalid endian: %s", SDATA (SYMBOL_NAME (endian)));
       ASET (attrs, coding_attr_utf_16_endian, endian);
 
       category = (CONSP (bom)
@@ -8187,21 +8298,23 @@ usage: (define-coding-system-internal ...)  */)
 
       reg_usage = args[coding_arg_iso2022_reg_usage];
       CHECK_CONS (reg_usage);
-      CHECK_NATNUM (XCAR (reg_usage));
-      CHECK_NATNUM (XCDR (reg_usage));
+      CHECK_NUMBER_CAR (reg_usage);
+      CHECK_NUMBER_CDR (reg_usage);
 
       request = Fcopy_sequence (args[coding_arg_iso2022_request]);
       for (tail = request; ! NILP (tail); tail = Fcdr (tail))
        {
          int id;
+         Lisp_Object tmp;
 
          val = Fcar (tail);
          CHECK_CONS (val);
-         CHECK_CHARSET_GET_ID (XCAR (val), id);
-         CHECK_NATNUM (XCDR (val));
+         tmp = XCAR (val);
+         CHECK_CHARSET_GET_ID (tmp, id);
+         CHECK_NATNUM_CDR (val);
          if (XINT (XCDR (val)) >= 4)
            error ("Invalid graphic register number: %d", XINT (XCDR (val)));
-         XCAR (val) = make_number (id);
+         XSETCAR (val, make_number (id));
        }
 
       flags = args[coding_arg_iso2022_flags];
@@ -8257,7 +8370,7 @@ usage: (define-coding-system-internal ...)  */)
       charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       if (CHARSET_DIMENSION (charset) != 1)
        error ("Dimension of charset %s is not one",
-              XSYMBOL (CHARSET_NAME (charset))->name->data);
+              SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
       if (CHARSET_ASCII_COMPATIBLE_P (charset))
        CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 
@@ -8265,13 +8378,13 @@ usage: (define-coding-system-internal ...)  */)
       charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       if (CHARSET_DIMENSION (charset) != 1)
        error ("Dimension of charset %s is not one",
-              XSYMBOL (CHARSET_NAME (charset))->name->data);
+              SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 
       charset_list = XCDR (charset_list);
       charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       if (CHARSET_DIMENSION (charset) != 2)
        error ("Dimension of charset %s is not two",
-              XSYMBOL (CHARSET_NAME (charset))->name->data);
+              SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 
       category = coding_category_sjis;
       Vsjis_coding_system = name;
@@ -8286,7 +8399,7 @@ usage: (define-coding-system-internal ...)  */)
       charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       if (CHARSET_DIMENSION (charset) != 1)
        error ("Dimension of charset %s is not one",
-              XSYMBOL (CHARSET_NAME (charset))->name->data);
+              SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
       if (CHARSET_ASCII_COMPATIBLE_P (charset))
        CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 
@@ -8294,7 +8407,7 @@ usage: (define-coding-system-internal ...)  */)
       charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       if (CHARSET_DIMENSION (charset) != 2)
        error ("Dimension of charset %s is not two",
-              XSYMBOL (CHARSET_NAME (charset))->name->data);
+              SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 
       category = coding_category_big5;
       Vbig5_coding_system = name;
@@ -8313,7 +8426,7 @@ usage: (define-coding-system-internal ...)  */)
     category = coding_category_undecided;
   else
     error ("Invalid coding system type: %s",
-          XSYMBOL (coding_type)->name->data);
+          SDATA (SYMBOL_NAME (coding_type)));
 
   CODING_ATTR_CATEGORY (attrs) = make_number (category);
   CODING_ATTR_PLIST (attrs)
@@ -8388,7 +8501,7 @@ DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias,
   aliases = AREF (spec, 1);
   while (!NILP (XCDR (aliases)))
     aliases = XCDR (aliases);
-  XCDR (aliases) = Fcons (alias, Qnil);
+  XSETCDR (aliases, Fcons (alias, Qnil));
 
   eol_type = AREF (spec, 2);
   if (VECTORP (eol_type))
@@ -8540,7 +8653,12 @@ void
 syms_of_coding ()
 {
   staticpro (&Vcoding_system_hash_table);
-  Vcoding_system_hash_table = Fmakehash (Qeq);
+  {
+    Lisp_Object args[2];
+    args[0] = QCtest;
+    args[1] = Qeq;
+    Vcoding_system_hash_table = Fmake_hash_table (2, args);
+  }
 
   staticpro (&Vsjis_coding_system);
   Vsjis_coding_system = Qnil;
@@ -8598,6 +8716,7 @@ syms_of_coding ()
   DEFSYM (Qiso_2022, "iso-2022");
 
   DEFSYM (Qutf_8, "utf-8");
+  DEFSYM (Qutf_8_emacs, "utf-8-emacs");
 
   DEFSYM (Qutf_16, "utf-16");
   DEFSYM (Qbig, "big");
@@ -8682,6 +8801,7 @@ syms_of_coding ()
   defsubr (&Sdetect_coding_region);
   defsubr (&Sdetect_coding_string);
   defsubr (&Sfind_coding_systems_region_internal);
+  defsubr (&Sunencodable_char_position);
   defsubr (&Scheck_coding_systems_region);
   defsubr (&Sdecode_coding_region);
   defsubr (&Sencode_coding_region);
@@ -8913,6 +9033,15 @@ 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;
 
+  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,
               doc: /*
@@ -8941,9 +9070,15 @@ 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;
 
+  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;
+
   {
     Lisp_Object args[coding_arg_max];
-    Lisp_Object plist[14];
+    Lisp_Object plist[16];
     int i;
 
     for (i = 0; i < coding_arg_max; i++)
@@ -8959,15 +9094,17 @@ escape sequence (e.g `latin-1') on reading by \\[universal-coding-system-argumen
     plist[7] = args[coding_arg_ascii_compatible_p] = Qt;
     plist[8] = intern (":default-char");
     plist[9] = args[coding_arg_default_char] = make_number (0);
-    plist[10] = intern (":docstring");
-    plist[11] = build_string ("Do no conversion.\n\
+    plist[10] = intern (":for-unibyte");
+    plist[11] = args[coding_arg_for_unibyte] = Qt;
+    plist[12] = intern (":docstring");
+    plist[13] = build_string ("Do no conversion.\n\
 \n\
 When you visit a file with this coding, the file is read into a\n\
 unibyte buffer as is, thus each byte of a file is treated as a\n\
 character.");
-    plist[12] = intern (":eol-type");
-    plist[13] = args[coding_arg_eol_type] = Qunix;
-    args[coding_arg_plist] = Flist (14, plist);
+    plist[14] = intern (":eol-type");
+    plist[15] = args[coding_arg_eol_type] = Qunix;
+    args[coding_arg_plist] = Flist (16, plist);
     Fdefine_coding_system_internal (coding_arg_max, args);
   }
 
@@ -8997,7 +9134,7 @@ emacs_strerror (error_number)
       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;