Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / src / coding.c
index 4d47b28..5c3048f 100644 (file)
@@ -1,6 +1,5 @@
 /* Coding system handler (conversion, detection, etc).
-   Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2001-2012 Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
      2005, 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
@@ -56,8 +55,8 @@ CODING SYSTEM
   character sequence of emacs-utf-8 to a byte sequence of a specific
   coding system.
 
-  In Emacs Lisp, a coding system is represented by a Lisp symbol.  In
-  C level, a coding system is represented by a vector of attributes
+  In Emacs Lisp, a coding system is represented by a Lisp symbol.  On
+  the C level, a coding system is represented by a vector of attributes
   stored in the hash table Vcharset_hash_table.  The conversion from
   coding system symbol to attributes vector is done by looking up
   Vcharset_hash_table by the symbol.
@@ -160,7 +159,7 @@ detect_coding_XXX (struct coding_system *coding,
   const unsigned char *src = coding->source;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int found = 0;
   ...;
 
@@ -267,7 +266,7 @@ encode_coding_XXX (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   unsigned char *adjusted_dst_end = dst_end - _MAX_BYTES_PRODUCED_IN_LOOP_;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
 
   for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++)
     {
@@ -301,27 +300,30 @@ encode_coding_XXX (struct coding_system *coding)
 
 Lisp_Object Vcoding_system_hash_table;
 
-Lisp_Object Qcoding_system, Qcoding_aliases, Qeol_type;
+static Lisp_Object Qcoding_system, Qeol_type;
+static Lisp_Object Qcoding_aliases;
 Lisp_Object Qunix, Qdos;
 Lisp_Object Qbuffer_file_coding_system;
-Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
-Lisp_Object Qdefault_char;
+static Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
+static Lisp_Object Qdefault_char;
 Lisp_Object Qno_conversion, Qundecided;
-Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5;
-Lisp_Object Qbig, Qlittle;
-Lisp_Object Qcoding_system_history;
-Lisp_Object Qvalid_codes;
-Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
-Lisp_Object QCdecode_translation_table, QCencode_translation_table;
-Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
-Lisp_Object QCascii_compatible_p;
+Lisp_Object Qcharset, Qutf_8;
+static Lisp_Object Qiso_2022;
+static Lisp_Object Qutf_16, Qshift_jis, Qbig5;
+static Lisp_Object Qbig, Qlittle;
+static Lisp_Object Qcoding_system_history;
+static Lisp_Object Qvalid_codes;
+static Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
+static Lisp_Object QCdecode_translation_table, QCencode_translation_table;
+static Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
+static Lisp_Object QCascii_compatible_p;
 
 Lisp_Object Qcall_process, Qcall_process_region;
 Lisp_Object Qstart_process, Qopen_network_stream;
-Lisp_Object Qtarget_idx;
+static Lisp_Object Qtarget_idx;
 
-Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
-Lisp_Object Qinterrupted, Qinsufficient_memory;
+static Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
+static Lisp_Object Qinterrupted, Qinsufficient_memory;
 
 /* If a symbol has this property, evaluate the value to define the
    symbol as a coding system.  */
@@ -352,12 +354,12 @@ struct coding_system safe_terminal_coding;
 
 Lisp_Object Qtranslation_table;
 Lisp_Object Qtranslation_table_id;
-Lisp_Object Qtranslation_table_for_decode;
-Lisp_Object Qtranslation_table_for_encode;
+static Lisp_Object Qtranslation_table_for_decode;
+static Lisp_Object Qtranslation_table_for_encode;
 
 /* Two special coding systems.  */
-Lisp_Object Vsjis_coding_system;
-Lisp_Object Vbig5_coding_system;
+static Lisp_Object Vsjis_coding_system;
+static Lisp_Object Vbig5_coding_system;
 
 /* ISO2022 section */
 
@@ -396,8 +398,6 @@ Lisp_Object Vbig5_coding_system;
 
 /* Control characters of ISO2022.  */
                        /* code */      /* function */
-#define ISO_CODE_LF    0x0A            /* line-feed */
-#define ISO_CODE_CR    0x0D            /* carriage-return */
 #define ISO_CODE_SO    0x0E            /* shift-out */
 #define ISO_CODE_SI    0x0F            /* shift-in */
 #define ISO_CODE_SS2_7 0x19            /* single-shift-2 for 7-bit code */
@@ -480,7 +480,7 @@ enum iso_code_class_type
 
 #define CODING_ISO_FLAG_COMPOSITION    0x2000
 
-#define CODING_ISO_FLAG_EUC_TW_SHIFT   0x4000
+/* #define CODING_ISO_FLAG_EUC_TW_SHIFT        0x4000 */
 
 #define CODING_ISO_FLAG_USE_ROMAN      0x8000
 
@@ -722,25 +722,6 @@ static struct coding_system coding_categories[coding_category_max];
   } while (0)
 
 
-#define ONE_MORE_BYTE_NO_CHECK(c)                      \
-  do {                                                 \
-    c = *src++;                                                \
-    if (multibytep && (c & 0x80))                      \
-      {                                                        \
-       if ((c & 0xFE) == 0xC0)                         \
-         c = ((c & 1) << 6) | *src++;                  \
-       else                                            \
-         {                                             \
-           src--;                                      \
-           c = - string_char (src, &src, NULL);        \
-           record_conversion_result                    \
-             (coding, CODING_RESULT_INVALID_SRC);      \
-         }                                             \
-      }                                                        \
-    consumed_chars++;                                  \
-  } while (0)
-
-
 /* Store a byte C in the place pointed by DST and increment DST to the
    next free point, and increment PRODUCED_CHARS.  The caller should
    assure that C is 0..127, and declare and set the variable `dst'
@@ -775,7 +756,7 @@ static struct coding_system coding_categories[coding_category_max];
     produced_chars++;                  \
     if (multibytep)                    \
       {                                        \
-       int ch = (c);                   \
+       unsigned ch = (c);              \
        if (ch >= 0x80)                 \
          ch = BYTE8_TO_CHAR (ch);      \
        CHAR_STRING_ADVANCE (ch, dst);  \
@@ -792,7 +773,7 @@ static struct coding_system coding_categories[coding_category_max];
     produced_chars += 2;               \
     if (multibytep)                    \
       {                                        \
-       int ch;                         \
+       unsigned ch;                    \
                                        \
        ch = (c1);                      \
        if (ch >= 0x80)                 \
@@ -866,17 +847,16 @@ static int encode_coding_ccl (struct coding_system *);
 static void decode_coding_raw_text (struct coding_system *);
 static int encode_coding_raw_text (struct coding_system *);
 
-static void coding_set_source (struct coding_system *);
-static void coding_set_destination (struct coding_system *);
+static EMACS_INT coding_set_source (struct coding_system *);
+static EMACS_INT coding_set_destination (struct coding_system *);
 static void coding_alloc_by_realloc (struct coding_system *, EMACS_INT);
 static void coding_alloc_by_making_gap (struct coding_system *,
                                         EMACS_INT, EMACS_INT);
 static unsigned char *alloc_destination (struct coding_system *,
                                          EMACS_INT, unsigned char *);
 static void setup_iso_safe_charsets (Lisp_Object);
-static unsigned char *encode_designation_at_bol (struct coding_system *,
-                                                 int *, int *,
-                                                 unsigned char *);
+static int encode_designation_at_bol (struct coding_system *,
+                                     int *, int *, unsigned char *);
 static int detect_eol (const unsigned char *,
                        EMACS_INT, enum coding_category);
 static Lisp_Object adjust_coding_eol_type (struct coding_system *, int);
@@ -884,21 +864,21 @@ static void decode_eol (struct coding_system *);
 static Lisp_Object get_translation_table (Lisp_Object, int, int *);
 static Lisp_Object get_translation (Lisp_Object, int *, int *);
 static int produce_chars (struct coding_system *, Lisp_Object, int);
-static INLINE void produce_charset (struct coding_system *, int *,
+static inline void produce_charset (struct coding_system *, int *,
                                     EMACS_INT);
 static void produce_annotation (struct coding_system *, EMACS_INT);
 static int decode_coding (struct coding_system *);
-static INLINE int *handle_composition_annotation (EMACS_INT, EMACS_INT,
+static inline int *handle_composition_annotation (EMACS_INT, EMACS_INT,
                                                   struct coding_system *,
                                                   int *, EMACS_INT *);
-static INLINE int *handle_charset_annotation (EMACS_INT, EMACS_INT,
+static inline int *handle_charset_annotation (EMACS_INT, EMACS_INT,
                                               struct coding_system *,
                                               int *, EMACS_INT *);
 static void consume_chars (struct coding_system *, Lisp_Object, int);
 static int encode_coding (struct coding_system *);
 static Lisp_Object make_conversion_work_buffer (int);
 static Lisp_Object code_conversion_restore (Lisp_Object);
-static INLINE int char_encodable_p (int, Lisp_Object);
+static inline int char_encodable_p (int, Lisp_Object);
 static Lisp_Object make_subsidiaries (Lisp_Object);
 
 static void
@@ -935,27 +915,68 @@ record_conversion_result (struct coding_system *coding,
     }
 }
 
-/* This wrapper macro is used to preserve validity of pointers into
-   buffer text across calls to decode_char, which could cause
-   relocation of buffers if it loads a charset map, because loading a
-   charset map allocates large structures.  */
+/* These wrapper macros are used to preserve validity of pointers into
+   buffer text across calls to decode_char, encode_char, etc, which
+   could cause relocation of buffers if it loads a charset map,
+   because loading a charset map allocates large structures.  */
+
 #define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \
   do {                                                                      \
+    EMACS_INT offset;                                                       \
+                                                                            \
     charset_map_loaded = 0;                                                 \
     c = DECODE_CHAR (charset, code);                                        \
-    if (charset_map_loaded)                                                 \
+    if (charset_map_loaded                                                  \
+       && (offset = coding_set_source (coding)))                            \
       {                                                                             \
-       const unsigned char *orig = coding->source;                          \
-       EMACS_INT offset;                                                    \
-                                                                            \
-       coding_set_source (coding);                                          \
-       offset = coding->source - orig;                                      \
        src += offset;                                                       \
        src_base += offset;                                                  \
        src_end += offset;                                                   \
       }                                                                             \
   } while (0)
 
+#define CODING_ENCODE_CHAR(coding, dst, dst_end, charset, c, code)     \
+  do {                                                                 \
+    EMACS_INT offset;                                                  \
+                                                                       \
+    charset_map_loaded = 0;                                            \
+    code = ENCODE_CHAR (charset, c);                                   \
+    if (charset_map_loaded                                             \
+       && (offset = coding_set_destination (coding)))                  \
+      {                                                                        \
+       dst += offset;                                                  \
+       dst_end += offset;                                              \
+      }                                                                        \
+  } while (0)
+
+#define CODING_CHAR_CHARSET(coding, dst, dst_end, c, charset_list, code_return, charset) \
+  do {                                                                 \
+    EMACS_INT offset;                                                  \
+                                                                       \
+    charset_map_loaded = 0;                                            \
+    charset = char_charset (c, charset_list, code_return);             \
+    if (charset_map_loaded                                             \
+       && (offset = coding_set_destination (coding)))                  \
+      {                                                                        \
+       dst += offset;                                                  \
+       dst_end += offset;                                              \
+      }                                                                        \
+  } while (0)
+
+#define CODING_CHAR_CHARSET_P(coding, dst, dst_end, c, charset, result)        \
+  do {                                                                 \
+    EMACS_INT offset;                                                  \
+                                                                       \
+    charset_map_loaded = 0;                                            \
+    result = CHAR_CHARSET_P (c, charset);                              \
+    if (charset_map_loaded                                             \
+       && (offset = coding_set_destination (coding)))                  \
+      {                                                                        \
+       dst += offset;                                                  \
+       dst_end += offset;                                              \
+      }                                                                        \
+  } while (0)
+
 
 /* If there are at least BYTES length of room at dst, allocate memory
    for coding->destination and update dst and dst_end.  We don't have
@@ -966,7 +987,7 @@ record_conversion_result (struct coding_system *coding,
   do {                                                         \
     if (dst + (bytes) >= dst_end)                              \
       {                                                                \
-       int more_bytes = charbuf_end - charbuf + (bytes);       \
+       EMACS_INT more_bytes = charbuf_end - charbuf + (bytes); \
                                                                \
        dst = alloc_destination (coding, more_bytes, dst);      \
        dst_end = coding->destination + coding->dst_bytes;      \
@@ -1035,9 +1056,14 @@ record_conversion_result (struct coding_system *coding,
        | ((p)[-1] & 0x3F))))
 
 
-static void
+/* Update coding->source from coding->src_object, and return how many
+   bytes coding->source was changed.  */
+
+static EMACS_INT
 coding_set_source (struct coding_system *coding)
 {
+  const unsigned char *orig = coding->source;
+
   if (BUFFERP (coding->src_object))
     {
       struct buffer *buf = XBUFFER (coding->src_object);
@@ -1052,17 +1078,25 @@ coding_set_source (struct coding_system *coding)
       coding->source = SDATA (coding->src_object) + coding->src_pos_byte;
     }
   else
-    /* Otherwise, the source is C string and is never relocated
-       automatically.  Thus we don't have to update anything.  */
-    ;
+    {
+      /* Otherwise, the source is C string and is never relocated
+        automatically.  Thus we don't have to update anything.  */
+    }
+  return coding->source - orig;
 }
 
-static void
+
+/* Update coding->destination from coding->dst_object, and return how
+   many bytes coding->destination was changed.  */
+
+static EMACS_INT
 coding_set_destination (struct coding_system *coding)
 {
+  const unsigned char *orig = coding->destination;
+
   if (BUFFERP (coding->dst_object))
     {
-      if (coding->src_pos < 0)
+      if (BUFFERP (coding->src_object) && coding->src_pos < 0)
        {
          coding->destination = BEG_ADDR + coding->dst_pos_byte - BEG_BYTE;
          coding->dst_bytes = (GAP_END_ADDR
@@ -1080,15 +1114,19 @@ coding_set_destination (struct coding_system *coding)
        }
     }
   else
-    /* Otherwise, the destination is C string and is never relocated
-       automatically.  Thus we don't have to update anything.  */
-    ;
+    {
+      /* Otherwise, the destination is C string and is never relocated
+        automatically.  Thus we don't have to update anything.  */
+    }
+  return coding->destination - orig;
 }
 
 
 static void
 coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
 {
+  if (STRING_BYTES_BOUND - coding->dst_bytes < bytes)
+    string_overflow ();
   coding->destination = (unsigned char *) xrealloc (coding->destination,
                                                    coding->dst_bytes + bytes);
   coding->dst_bytes += bytes;
@@ -1218,7 +1256,6 @@ alloc_destination (struct coding_system *coding, EMACS_INT nbytes,
 #define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0)
 #define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8)
 
-#define UTF_BOM 0xFEFF
 #define UTF_8_BOM_1 0xEF
 #define UTF_8_BOM_2 0xBB
 #define UTF_8_BOM_3 0xBF
@@ -1230,7 +1267,7 @@ detect_coding_utf_8 (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int bom_found = 0;
   int found = 0;
 
@@ -1315,16 +1352,13 @@ decode_coding_utf_8 (struct coding_system *coding)
   const unsigned char *src_base;
   int *charbuf = coding->charbuf + coding->charbuf_used;
   int *charbuf_end = coding->charbuf + coding->charbuf_size;
-  int consumed_chars = 0, consumed_chars_base = 0;
+  EMACS_INT consumed_chars = 0, consumed_chars_base = 0;
   int multibytep = coding->src_multibyte;
   enum utf_bom_type bom = CODING_UTF_8_BOM (coding);
-  Lisp_Object attr, charset_list;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
-  CODING_GET_INFO (coding, attr, charset_list);
-
   if (bom != utf_without_bom)
     {
       int c1, c2, c3;
@@ -1380,7 +1414,7 @@ decode_coding_utf_8 (struct coding_system *coding)
        }
       else if (UTF_8_1_OCTET_P (c1))
        {
-         if (eol_crlf && c1 == '\r')
+         if (eol_dos && c1 == '\r')
            ONE_MORE_BYTE (byte_after_cr);
          c = c1;
        }
@@ -1469,7 +1503,7 @@ encode_coding_utf_8 (struct coding_system *coding)
   int *charbuf_end = charbuf + coding->charbuf_used;
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   int c;
 
   if (CODING_UTF_8_BOM (coding) == utf_with_bom)
@@ -1534,11 +1568,6 @@ encode_coding_utf_8 (struct coding_system *coding)
 #define UTF_16_LOW_SURROGATE_P(val) \
   (((val) & 0xFC00) == 0xDC00)
 
-#define UTF_16_INVALID_P(val)  \
-  (((val) == 0xFFFE)           \
-   || ((val) == 0xFFFF)                \
-   || UTF_16_LOW_SURROGATE_P (val))
-
 
 static int
 detect_coding_utf_16 (struct coding_system *coding,
@@ -1632,18 +1661,15 @@ decode_coding_utf_16 (struct coding_system *coding)
   int *charbuf = coding->charbuf + coding->charbuf_used;
   /* We may produces at most 3 chars in one loop.  */
   int *charbuf_end = coding->charbuf + coding->charbuf_size - 2;
-  int consumed_chars = 0, consumed_chars_base = 0;
+  EMACS_INT consumed_chars = 0, consumed_chars_base = 0;
   int multibytep = coding->src_multibyte;
   enum utf_bom_type bom = CODING_UTF_16_BOM (coding);
   enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding);
   int surrogate = CODING_UTF_16_SURROGATE (coding);
-  Lisp_Object attr, charset_list;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr1 = -1, byte_after_cr2 = -1;
 
-  CODING_GET_INFO (coding, attr, charset_list);
-
   if (bom == utf_with_bom)
     {
       int c, c1, c2;
@@ -1735,7 +1761,7 @@ decode_coding_utf_16 (struct coding_system *coding)
            CODING_UTF_16_SURROGATE (coding) = surrogate = c;
          else
            {
-             if (eol_crlf && c == '\r')
+             if (eol_dos && c == '\r')
                {
                  ONE_MORE_BYTE (byte_after_cr1);
                  ONE_MORE_BYTE (byte_after_cr2);
@@ -1762,12 +1788,9 @@ encode_coding_utf_16 (struct coding_system *coding)
   int safe_room = 8;
   enum utf_bom_type bom = CODING_UTF_16_BOM (coding);
   int big_endian = CODING_UTF_16_ENDIAN (coding) == utf_16_big_endian;
-  int produced_chars = 0;
-  Lisp_Object attrs, charset_list;
+  EMACS_INT produced_chars = 0;
   int c;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
-
   if (bom != utf_without_bom)
     {
       ASSURE_DESTINATION (safe_room);
@@ -1899,7 +1922,7 @@ detect_coding_emacs_mule (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int c;
   int found = 0;
 
@@ -1919,17 +1942,17 @@ detect_coding_emacs_mule (struct coding_system *coding,
             it because analyzing it is too heavy for detecting.  But,
             at least, we check that the composite character
             constitutes of more than 4 bytes.  */
-         const unsigned char *src_base;
+         const unsigned char *src_start;
 
        repeat:
-         src_base = src;
+         src_start = src;
          do
            {
              ONE_MORE_BYTE (c);
            }
          while (c >= 0xA0);
 
-         if (src - src_base <= 4)
+         if (src - src_start <= 4)
            break;
          found = CATEGORY_MASK_EMACS_MULE;
          if (c == 0x80)
@@ -1981,7 +2004,7 @@ detect_coding_emacs_mule (struct coding_system *coding,
    the decoded character or rule.  If an invalid byte is found, return
    -1.  If SRC is too short, return -2.  */
 
-int
+static int
 emacs_mule_char (struct coding_system *coding, const unsigned char *src,
                 int *nbytes, int *nchars, int *id,
                 struct composition_status *cmp_status)
@@ -1989,7 +2012,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
   const unsigned char *src_end = coding->source + coding->src_bytes;
   const unsigned char *src_base = src;
   int multibytep = coding->src_multibyte;
-  int charset_id;
+  int charset_ID;
   unsigned code;
   int c;
   int consumed_chars = 0;
@@ -1999,7 +2022,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
   if (c < 0)
     {
       c = -c;
-      charset_id = emacs_mule_charset[0];
+      charset_ID = emacs_mule_charset[0];
     }
   else
     {
@@ -2035,7 +2058,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
       switch (emacs_mule_bytes[c])
        {
        case 2:
-         if ((charset_id = emacs_mule_charset[c]) < 0)
+         if ((charset_ID = emacs_mule_charset[c]) < 0)
            goto invalid_code;
          ONE_MORE_BYTE (c);
          if (c < 0xA0)
@@ -2048,7 +2071,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
              || c == EMACS_MULE_LEADING_CODE_PRIVATE_12)
            {
              ONE_MORE_BYTE (c);
-             if (c < 0xA0 || (charset_id = emacs_mule_charset[c]) < 0)
+             if (c < 0xA0 || (charset_ID = emacs_mule_charset[c]) < 0)
                goto invalid_code;
              ONE_MORE_BYTE (c);
              if (c < 0xA0)
@@ -2057,7 +2080,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
            }
          else
            {
-             if ((charset_id = emacs_mule_charset[c]) < 0)
+             if ((charset_ID = emacs_mule_charset[c]) < 0)
                goto invalid_code;
              ONE_MORE_BYTE (c);
              if (c < 0xA0)
@@ -2072,7 +2095,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
 
        case 4:
          ONE_MORE_BYTE (c);
-         if (c < 0 || (charset_id = emacs_mule_charset[c]) < 0)
+         if (c < 0 || (charset_ID = emacs_mule_charset[c]) < 0)
            goto invalid_code;
          ONE_MORE_BYTE (c);
          if (c < 0xA0)
@@ -2086,21 +2109,21 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
 
        case 1:
          code = c;
-         charset_id = ASCII_BYTE_P (code) ? charset_ascii : charset_eight_bit;
+         charset_ID = ASCII_BYTE_P (code) ? charset_ascii : charset_eight_bit;
          break;
 
        default:
          abort ();
        }
       CODING_DECODE_CHAR (coding, src, src_base, src_end,
-                         CHARSET_FROM_ID (charset_id), code, c);
+                         CHARSET_FROM_ID (charset_ID), code, c);
       if (c < 0)
        goto invalid_code;
     }
   *nbytes = src - src_base;
   *nchars = consumed_chars;
   if (id)
-    *id = charset_id;
+    *id = charset_ID;
   return (mseq_found ? -c : c);
 
  no_more_source:
@@ -2366,24 +2389,25 @@ decode_coding_emacs_mule (struct coding_system *coding)
   /* We may produce two annotations (charset and composition) in one
      loop and one more charset annotation at the end.  */
   int *charbuf_end
-    = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3);
-  int consumed_chars = 0, consumed_chars_base;
+    = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3)
+      /* We can produce up to 2 characters in a loop.  */
+      - 1;
+  EMACS_INT consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
-  Lisp_Object attrs, charset_list;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  EMACS_INT char_offset = coding->produced_char;
+  EMACS_INT last_offset = char_offset;
   int last_id = charset_ascii;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
   struct composition_status *cmp_status = &coding->spec.emacs_mule.cmp_status;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
-
   if (cmp_status->state != COMPOSING_NO)
     {
       int i;
 
+      if (charbuf_end - charbuf < cmp_status->length)
+       abort ();
       for (i = 0; i < cmp_status->length; i++)
        *charbuf++ = cmp_status->carryover[i];
       coding->annotated = 1;
@@ -2391,7 +2415,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
 
   while (1)
     {
-      int c, id;
+      int c, id IF_LINT (= 0);
 
       src_base = src;
       consumed_chars_base = consumed_chars;
@@ -2423,7 +2447,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
 
       if (c < 0x80)
        {
-         if (eol_crlf && c == '\r')
+         if (eol_dos && c == '\r')
            ONE_MORE_BYTE (byte_after_cr);
          id = charset_ascii;
          if (cmp_status->state != COMPOSING_NO)
@@ -2436,7 +2460,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
        }
       else
        {
-         int nchars, nbytes;
+         int nchars IF_LINT (= 0), nbytes IF_LINT (= 0);
          /* emacs_mule_char can load a charset map from a file, which
             allocates a large structure and might cause buffer text
             to be relocated as result.  Thus, we need to remember the
@@ -2624,7 +2648,7 @@ encode_coding_emacs_mule (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 8;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int c;
   int preferred_charset_id = -1;
@@ -2680,14 +2704,19 @@ encode_coding_emacs_mule (struct coding_system *coding)
 
          if (preferred_charset_id >= 0)
            {
+             int result;
+
              charset = CHARSET_FROM_ID (preferred_charset_id);
-             if (CHAR_CHARSET_P (c, charset))
+             CODING_CHAR_CHARSET_P (coding, dst, dst_end, c, charset, result);
+             if (result)
                code = ENCODE_CHAR (charset, c);
              else
-               charset = char_charset (c, charset_list, &code);
+               CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                                    &code, charset);
            }
          else
-           charset = char_charset (c, charset_list, &code);
+           CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                                &code, charset);
          if (! charset)
            {
              c = coding->default_char;
@@ -2696,7 +2725,8 @@ encode_coding_emacs_mule (struct coding_system *coding)
                  EMIT_ONE_ASCII_BYTE (c);
                  continue;
                }
-             charset = char_charset (c, charset_list, &code);
+             CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                                  &code, charset);
            }
          dimension = CHARSET_DIMENSION (charset);
          emacs_mule_id = CHARSET_EMACS_MULE_ID (charset);
@@ -2898,16 +2928,12 @@ encode_coding_emacs_mule (struct coding_system *coding)
   COMPOSITION_WITH_RULE_ALTCHARS:
        ESC 4 ALTCHAR [ RULE ALTCHAR ] ESC 0 CHAR [ CHAR ] ESC 1 */
 
-enum iso_code_class_type iso_code_class[256];
+static enum iso_code_class_type iso_code_class[256];
 
 #define SAFE_CHARSET_P(coding, id)     \
   ((id) <= (coding)->max_charset_id    \
    && (coding)->safe_charsets[id] != 255)
 
-
-#define SHIFT_OUT_OK(category) \
-  (CODING_ISO_INITIAL (&coding_categories[category], 1) >= 0)
-
 static void
 setup_iso_safe_charsets (Lisp_Object attrs)
 {
@@ -2986,7 +3012,7 @@ detect_coding_iso_2022 (struct coding_system *coding,
   int single_shifting = 0;
   int id;
   int c, c1;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int i;
   int rejected = 0;
   int found = 0;
@@ -3024,40 +3050,11 @@ detect_coding_iso_2022 (struct coding_system *coding,
            break;
          single_shifting = 0;
          ONE_MORE_BYTE (c);
-         if (c >= '(' && c <= '/')
-           {
-             /* Designation sequence for a charset of dimension 1.  */
-             ONE_MORE_BYTE (c1);
-             if (c1 < ' ' || c1 >= 0x80
-                 || (id = iso_charset_table[0][c >= ','][c1]) < 0)
-               /* Invalid designation sequence.  Just ignore.  */
-               break;
-           }
-         else if (c == '$')
-           {
-             /* Designation sequence for a charset of dimension 2.  */
-             ONE_MORE_BYTE (c);
-             if (c >= '@' && c <= 'B')
-               /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
-               id = iso_charset_table[1][0][c];
-             else if (c >= '(' && c <= '/')
-               {
-                 ONE_MORE_BYTE (c1);
-                 if (c1 < ' ' || c1 >= 0x80
-                     || (id = iso_charset_table[1][c >= ','][c1]) < 0)
-                   /* Invalid designation sequence.  Just ignore.  */
-                   break;
-               }
-             else
-               /* Invalid designation sequence.  Just ignore it.  */
-               break;
-           }
-         else if (c == 'N' || c == 'O')
+         if (c == 'N' || c == 'O')
            {
              /* ESC <Fe> for SS2 or SS3.  */
              single_shifting = 1;
              rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
-             break;
            }
          else if (c == '1')
            {
@@ -3073,36 +3070,66 @@ detect_coding_iso_2022 (struct coding_system *coding,
            {
              /* ESC <Fp> for start/end composition.  */
              composition_count = 0;
-             break;
            }
          else
            {
-             /* Invalid escape sequence.  Just ignore it.  */
-             break;
-           }
+             if (c >= '(' && c <= '/')
+               {
+                 /* Designation sequence for a charset of dimension 1.  */
+                 ONE_MORE_BYTE (c1);
+                 if (c1 < ' ' || c1 >= 0x80
+                     || (id = iso_charset_table[0][c >= ','][c1]) < 0)
+                   /* Invalid designation sequence.  Just ignore.  */
+                   break;
+               }
+             else if (c == '$')
+               {
+                 /* Designation sequence for a charset of dimension 2.  */
+                 ONE_MORE_BYTE (c);
+                 if (c >= '@' && c <= 'B')
+                   /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
+                   id = iso_charset_table[1][0][c];
+                 else if (c >= '(' && c <= '/')
+                   {
+                     ONE_MORE_BYTE (c1);
+                     if (c1 < ' ' || c1 >= 0x80
+                         || (id = iso_charset_table[1][c >= ','][c1]) < 0)
+                       /* Invalid designation sequence.  Just ignore.  */
+                       break;
+                   }
+                 else
+                   /* Invalid designation sequence.  Just ignore it.  */
+                   break;
+               }
+             else
+               {
+                 /* Invalid escape sequence.  Just ignore it.  */
+                 break;
+               }
 
-         /* We found a valid designation sequence for CHARSET.  */
-         rejected |= CATEGORY_MASK_ISO_8BIT;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
-                             id))
-           found |= CATEGORY_MASK_ISO_7;
-         else
-           rejected |= CATEGORY_MASK_ISO_7;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
-                             id))
-           found |= CATEGORY_MASK_ISO_7_TIGHT;
-         else
-           rejected |= CATEGORY_MASK_ISO_7_TIGHT;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
-                             id))
-           found |= CATEGORY_MASK_ISO_7_ELSE;
-         else
-           rejected |= CATEGORY_MASK_ISO_7_ELSE;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
-                             id))
-           found |= CATEGORY_MASK_ISO_8_ELSE;
-         else
-           rejected |= CATEGORY_MASK_ISO_8_ELSE;
+             /* We found a valid designation sequence for CHARSET.  */
+             rejected |= CATEGORY_MASK_ISO_8BIT;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7;
+             else
+               rejected |= CATEGORY_MASK_ISO_7;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7_TIGHT;
+             else
+               rejected |= CATEGORY_MASK_ISO_7_TIGHT;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7_ELSE;
+             else
+               rejected |= CATEGORY_MASK_ISO_7_ELSE;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
+                                 id))
+               found |= CATEGORY_MASK_ISO_8_ELSE;
+             else
+               rejected |= CATEGORY_MASK_ISO_8_ELSE;
+           }
          break;
 
        case ISO_CODE_SO:
@@ -3130,13 +3157,32 @@ detect_coding_iso_2022 (struct coding_system *coding,
          rejected |= CATEGORY_MASK_ISO_7BIT;
          if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
              & CODING_ISO_FLAG_SINGLE_SHIFT)
-           found |= CATEGORY_MASK_ISO_8_1, single_shifting = 1;
+           {
+             found |= CATEGORY_MASK_ISO_8_1;
+             single_shifting = 1;
+           }
          if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2])
              & CODING_ISO_FLAG_SINGLE_SHIFT)
-           found |= CATEGORY_MASK_ISO_8_2, single_shifting = 1;
+           {
+             found |= CATEGORY_MASK_ISO_8_2;
+             single_shifting = 1;
+           }
          if (single_shifting)
            break;
-         goto check_extra_latin;
+       check_extra_latin:
+         if (! VECTORP (Vlatin_extra_code_table)
+             || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
+           {
+             rejected = CATEGORY_MASK_ISO;
+             break;
+           }
+         if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
+             & CODING_ISO_FLAG_LATIN_EXTRA)
+           found |= CATEGORY_MASK_ISO_8_1;
+         else
+           rejected |= CATEGORY_MASK_ISO_8_1;
+         rejected |= CATEGORY_MASK_ISO_8_2;
+         break;
 
        default:
          if (c < 0)
@@ -3159,7 +3205,7 @@ detect_coding_iso_2022 (struct coding_system *coding,
              if (! single_shifting
                  && ! (rejected & CATEGORY_MASK_ISO_8_2))
                {
-                 int i = 1;
+                 int len = 1;
                  while (src < src_end)
                    {
                      src_base = src;
@@ -3169,38 +3215,24 @@ detect_coding_iso_2022 (struct coding_system *coding,
                          src = src_base;
                          break;
                        }
-                     i++;
+                     len++;
                    }
 
-                 if (i & 1 && src < src_end)
+                 if (len & 1 && src < src_end)
                    {
                      rejected |= CATEGORY_MASK_ISO_8_2;
                      if (composition_count >= 0)
-                       composition_count += i;
+                       composition_count += len;
                    }
                  else
                    {
                      found |= CATEGORY_MASK_ISO_8_2;
                      if (composition_count >= 0)
-                       composition_count += i / 2;
+                       composition_count += len / 2;
                    }
                }
              break;
            }
-       check_extra_latin:
-         single_shifting = 0;
-         if (! VECTORP (Vlatin_extra_code_table)
-             || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
-           {
-             rejected = CATEGORY_MASK_ISO;
-             break;
-           }
-         if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
-             & CODING_ISO_FLAG_LATIN_EXTRA)
-           found |= CATEGORY_MASK_ISO_8_1;
-         else
-           rejected |= CATEGORY_MASK_ISO_8_1;
-         rejected |= CATEGORY_MASK_ISO_8_2;
        }
     }
   detect_info->rejected |= CATEGORY_MASK_ISO;
@@ -3290,15 +3322,14 @@ detect_coding_iso_2022 (struct coding_system *coding,
 */
 
 /* Decode a composition rule C1 and maybe one more byte from the
-   source, and set RULE to the encoded composition rule, NBYTES to the
-   length of the composition rule.  If the rule is invalid, set RULE
-   to some negative value.  */
+   source, and set RULE to the encoded composition rule.  If the rule
+   is invalid, goto invalid_code.  */
 
-#define DECODE_COMPOSITION_RULE(rule, nbytes)                          \
+#define DECODE_COMPOSITION_RULE(rule)                                  \
   do {                                                                 \
     rule = c1 - 32;                                                    \
     if (rule < 0)                                                      \
-      break;                                                           \
+      goto invalid_code;                                               \
     if (rule < 81)             /* old format (before ver.21) */        \
       {                                                                        \
        int gref = (rule) / 9;                                          \
@@ -3306,17 +3337,16 @@ detect_coding_iso_2022 (struct coding_system *coding,
        if (gref == 4) gref = 10;                                       \
        if (nref == 4) nref = 10;                                       \
        rule = COMPOSITION_ENCODE_RULE (gref, nref);                    \
-       nbytes = 1;                                                     \
       }                                                                        \
     else                       /* new format (after ver.21) */         \
       {                                                                        \
-       int c;                                                          \
+       int b;                                                          \
                                                                        \
-       ONE_MORE_BYTE (c);                                              \
-       rule = COMPOSITION_ENCODE_RULE (rule - 81, c - 32);             \
-       if (rule >= 0)                                                  \
-         rule += 0x100;   /* to destinguish it from the old format */  \
-       nbytes = 2;                                                     \
+       ONE_MORE_BYTE (b);                                              \
+       if (! COMPOSITION_ENCODE_RULE_VALID (rule - 81, b - 32))        \
+         goto invalid_code;                                            \
+       rule = COMPOSITION_ENCODE_RULE (rule - 81, b - 32);             \
+       rule += 0x100;   /* Distinguish it from the old format.  */     \
       }                                                                        \
   } while (0)
 
@@ -3492,7 +3522,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
      loop and one more charset annotation at the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3);
-  int consumed_chars = 0, consumed_chars_base;
+  EMACS_INT consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
   int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
@@ -3501,23 +3531,22 @@ decode_coding_iso_2022 (struct coding_system *coding)
   struct charset *charset;
   int c;
   struct composition_status *cmp_status = CODING_ISO_CMP_STATUS (coding);
-  Lisp_Object attrs, charset_list;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
+  EMACS_INT char_offset = coding->produced_char;
+  EMACS_INT last_offset = char_offset;
   int last_id = charset_ascii;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
   int i;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
   setup_iso_safe_charsets (attrs);
-  /* Charset list may have been changed.  */
-  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   coding->safe_charsets = SDATA (CODING_ATTR_SAFE_CHARSETS (attrs));
 
   if (cmp_status->state != COMPOSING_NO)
     {
+      if (charbuf_end - charbuf < cmp_status->length)
+       abort ();
       for (i = 0; i < cmp_status->length; i++)
        *charbuf++ = cmp_status->carryover[i];
       coding->annotated = 1;
@@ -3583,11 +3612,9 @@ decode_coding_iso_2022 (struct coding_system *coding)
           || cmp_status->state == COMPOSING_COMPONENT_RULE)
          && c1 != ISO_CODE_ESC)
        {
-         int rule, nbytes;
+         int rule;
 
-         DECODE_COMPOSITION_RULE (rule, nbytes);
-         if (rule < 0)
-           goto invalid_code;
+         DECODE_COMPOSITION_RULE (rule);
          STORE_COMPOSITION_RULE (rule);
          continue;
        }
@@ -3625,7 +3652,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
          break;
 
        case ISO_control_0:
-         if (eol_crlf && c1 == '\r')
+         if (eol_dos && c1 == '\r')
            ONE_MORE_BYTE (byte_after_cr);
          MAYBE_FINISH_COMPOSITION ();
          charset = CHARSET_FROM_ID (charset_ascii);
@@ -3898,6 +3925,10 @@ decode_coding_iso_2022 (struct coding_system *coding)
              }
              continue;
            }
+         break;
+
+       default:
+         abort ();
        }
 
       if (cmp_status->state == COMPOSING_NO
@@ -4030,7 +4061,6 @@ decode_coding_iso_2022 (struct coding_system *coding)
     const char *intermediate_char_94 = "()*+";                         \
     const char *intermediate_char_96 = ",-./";                         \
     int revision = -1;                                                 \
-    int c;                                                             \
                                                                        \
     if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_REVISION)          \
       revision = CHARSET_ISO_REVISION (charset);                       \
@@ -4043,11 +4073,12 @@ decode_coding_iso_2022 (struct coding_system *coding)
     EMIT_ONE_ASCII_BYTE (ISO_CODE_ESC);                                        \
     if (CHARSET_DIMENSION (charset) == 1)                              \
       {                                                                        \
+       int b;                                                          \
        if (! CHARSET_ISO_CHARS_96 (charset))                           \
-         c = intermediate_char_94[reg];                                \
+         b = intermediate_char_94[reg];                                \
        else                                                            \
-         c = intermediate_char_96[reg];                                \
-       EMIT_ONE_ASCII_BYTE (c);                                        \
+         b = intermediate_char_96[reg];                                \
+       EMIT_ONE_ASCII_BYTE (b);                                        \
       }                                                                        \
     else                                                               \
       {                                                                        \
@@ -4214,7 +4245,8 @@ decode_coding_iso_2022 (struct coding_system *coding)
 
 #define ENCODE_ISO_CHARACTER(charset, c)                                  \
   do {                                                                    \
-    int code = ENCODE_CHAR ((charset), (c));                              \
+    int code;                                                             \
+    CODING_ENCODE_CHAR (coding, dst, dst_end, (charset), (c), code);      \
                                                                           \
     if (CHARSET_DIMENSION (charset) == 1)                                 \
       ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code);                  \
@@ -4227,13 +4259,13 @@ decode_coding_iso_2022 (struct coding_system *coding)
    to use CHARSET.  The element `spec.iso_2022' of *CODING is updated.
    Return new DST.  */
 
-unsigned char *
+static unsigned char *
 encode_invocation_designation (struct charset *charset,
                               struct coding_system *coding,
-                              unsigned char *dst, int *p_nchars)
+                              unsigned char *dst, EMACS_INT *p_nchars)
 {
   int multibytep = coding->dst_multibyte;
-  int produced_chars = *p_nchars;
+  EMACS_INT produced_chars = *p_nchars;
   int reg;                     /* graphic register number */
   int id = CHARSET_ID (charset);
 
@@ -4290,30 +4322,6 @@ encode_invocation_designation (struct charset *charset,
   return dst;
 }
 
-/* The following three macros produce codes for indicating direction
-   of text.  */
-#define ENCODE_CONTROL_SEQUENCE_INTRODUCER                             \
-  do {                                                                 \
-    if (CODING_ISO_FLAGS (coding) == CODING_ISO_FLAG_SEVEN_BITS)       \
-      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '[');                                \
-    else                                                               \
-      EMIT_ONE_BYTE (ISO_CODE_CSI);                                    \
-  } while (0)
-
-
-#define ENCODE_DIRECTION_R2L()                 \
-  do {                                         \
-    ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst);  \
-    EMIT_TWO_ASCII_BYTES ('2', ']');           \
-  } while (0)
-
-
-#define ENCODE_DIRECTION_L2R()                 \
-  do {                                         \
-    ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst);  \
-    EMIT_TWO_ASCII_BYTES ('0', ']');           \
-  } while (0)
-
 
 /* Produce codes for designation and invocation to reset the graphic
    planes and registers to initial state.  */
@@ -4336,20 +4344,24 @@ encode_invocation_designation (struct charset *charset,
 
 
 /* Produce designation sequences of charsets in the line started from
-   SRC to a place pointed by DST, and return updated DST.
+   CHARBUF to a place pointed by DST, and return the number of
+   produced bytes.  DST should not directly point a buffer text area
+   which may be relocated by char_charset call.
 
    If the current block ends before any end-of-line, we may fail to
    find all the necessary designations.  */
 
-static unsigned char *
-encode_designation_at_bol (struct coding_system *coding, int *charbuf,
-                          int *charbuf_end, unsigned char *dst)
+static int
+encode_designation_at_bol (struct coding_system *coding,
+                          int *charbuf, int *charbuf_end,
+                          unsigned char *dst)
 {
+  unsigned char *orig = dst;
   struct charset *charset;
   /* Table of charsets to be designated to each graphic register.  */
   int r[4];
   int c, found = 0, reg;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   int multibytep = coding->dst_multibyte;
   Lisp_Object attrs;
   Lisp_Object charset_list;
@@ -4362,7 +4374,7 @@ encode_designation_at_bol (struct coding_system *coding, int *charbuf,
   for (reg = 0; reg < 4; reg++)
     r[reg] = -1;
 
-  while (found < 4)
+  while (charbuf < charbuf_end && found < 4)
     {
       int id;
 
@@ -4387,7 +4399,7 @@ encode_designation_at_bol (struct coding_system *coding, int *charbuf,
          ENCODE_DESIGNATION (CHARSET_FROM_ID (r[reg]), reg, coding);
     }
 
-  return dst;
+  return dst - orig;
 }
 
 /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".  */
@@ -4404,7 +4416,7 @@ encode_coding_iso_2022 (struct coding_system *coding)
   int bol_designation
     = (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL
        && CODING_ISO_BOL (coding));
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   Lisp_Object attrs, eol_type, charset_list;
   int ascii_compatible;
   int c;
@@ -4431,13 +4443,26 @@ encode_coding_iso_2022 (struct coding_system *coding)
 
       if (bol_designation)
        {
-         unsigned char *dst_prev = dst;
-
          /* We have to produce designation sequences if any now.  */
-         dst = encode_designation_at_bol (coding, charbuf, charbuf_end, dst);
-         bol_designation = 0;
+         unsigned char desig_buf[16];
+         int nbytes;
+         EMACS_INT offset;
+
+         charset_map_loaded = 0;
+         nbytes = encode_designation_at_bol (coding, charbuf, charbuf_end,
+                                             desig_buf);
+         if (charset_map_loaded
+             && (offset = coding_set_destination (coding)))
+           {
+             dst += offset;
+             dst_end += offset;
+           }
+         memcpy (dst, desig_buf, nbytes);
+         dst += nbytes;
          /* We are sure that designation sequences are all ASCII bytes.  */
-         produced_chars += dst - dst_prev;
+         produced_chars += nbytes;
+         bol_designation = 0;
+         ASSURE_DESTINATION (safe_room);
        }
 
       c = *charbuf++;
@@ -4508,12 +4533,17 @@ encode_coding_iso_2022 (struct coding_system *coding)
 
          if (preferred_charset_id >= 0)
            {
+             int result;
+
              charset = CHARSET_FROM_ID (preferred_charset_id);
-             if (! CHAR_CHARSET_P (c, charset))
-               charset = char_charset (c, charset_list, NULL);
+             CODING_CHAR_CHARSET_P (coding, dst, dst_end, c, charset, result);
+             if (! result)
+               CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                                    NULL, charset);
            }
          else
-           charset = char_charset (c, charset_list, NULL);
+           CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                                NULL, charset);
          if (!charset)
            {
              if (coding->mode & CODING_MODE_SAFE_ENCODING)
@@ -4524,7 +4554,8 @@ encode_coding_iso_2022 (struct coding_system *coding)
              else
                {
                  c = coding->default_char;
-                 charset = char_charset (c, charset_list, NULL);
+                 CODING_CHAR_CHARSET (coding, dst, dst_end, c,
+                                      charset_list, NULL, charset);
                }
            }
          ENCODE_ISO_CHARACTER (charset, c);
@@ -4592,7 +4623,7 @@ detect_coding_sjis (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int found = 0;
   int c;
   Lisp_Object attrs, charset_list;
@@ -4649,7 +4680,7 @@ detect_coding_big5 (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int found = 0;
   int c;
 
@@ -4700,15 +4731,15 @@ decode_coding_sjis (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  EMACS_INT consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   struct charset *charset_roman, *charset_kanji, *charset_kana;
   struct charset *charset_kanji2;
   Lisp_Object attrs, charset_list, val;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  EMACS_INT char_offset = coding->produced_char;
+  EMACS_INT last_offset = char_offset;
   int last_id = charset_ascii;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
@@ -4743,7 +4774,7 @@ decode_coding_sjis (struct coding_system *coding)
        goto invalid_code;
       if (c < 0x80)
        {
-         if (eol_crlf && c == '\r')
+         if (eol_dos && c == '\r')
            ONE_MORE_BYTE (byte_after_cr);
          charset = charset_roman;
        }
@@ -4818,14 +4849,14 @@ decode_coding_big5 (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  EMACS_INT consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   struct charset *charset_roman, *charset_big5;
   Lisp_Object attrs, charset_list, val;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  EMACS_INT char_offset = coding->produced_char;
+  EMACS_INT last_offset = char_offset;
   int last_id = charset_ascii;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
@@ -4858,7 +4889,7 @@ decode_coding_big5 (struct coding_system *coding)
        goto invalid_code;
       if (c < 0x80)
        {
-         if (eol_crlf && c == '\r')
+         if (eol_dos && c == '\r')
            ONE_MORE_BYTE (byte_after_cr);
          charset = charset_roman;
        }
@@ -4920,16 +4951,15 @@ encode_coding_sjis (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 4;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
-  struct charset *charset_roman, *charset_kanji, *charset_kana;
+  struct charset *charset_kanji, *charset_kana;
   struct charset *charset_kanji2;
   int c;
 
   CODING_GET_INFO (coding, attrs, charset_list);
-  val = charset_list;
-  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
+  val = XCDR (charset_list);
   charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji2 = NILP (val) ? NULL : CHARSET_FROM_ID (XINT (XCAR (val)));
@@ -4951,7 +4981,9 @@ encode_coding_sjis (struct coding_system *coding)
       else
        {
          unsigned code;
-         struct charset *charset = char_charset (c, charset_list, &code);
+         struct charset *charset;
+         CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                              &code, charset);
 
          if (!charset)
            {
@@ -4963,7 +4995,8 @@ encode_coding_sjis (struct coding_system *coding)
              else
                {
                  c = coding->default_char;
-                 charset = char_charset (c, charset_list, &code);
+                 CODING_CHAR_CHARSET (coding, dst, dst_end, c,
+                                      charset_list, &code, charset);
                }
            }
          if (code == CHARSET_INVALID_CODE (charset))
@@ -5012,15 +5045,14 @@ encode_coding_big5 (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 4;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
-  struct charset *charset_roman, *charset_big5;
+  struct charset *charset_big5;
   int c;
 
   CODING_GET_INFO (coding, attrs, charset_list);
-  val = charset_list;
-  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
+  val = XCDR (charset_list);
   charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
   ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 
@@ -5039,7 +5071,9 @@ encode_coding_big5 (struct coding_system *coding)
       else
        {
          unsigned code;
-         struct charset *charset = char_charset (c, charset_list, &code);
+         struct charset *charset;
+         CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                              &code, charset);
 
          if (! charset)
            {
@@ -5051,7 +5085,8 @@ encode_coding_big5 (struct coding_system *coding)
              else
                {
                  c = coding->default_char;
-                 charset = char_charset (c, charset_list, &code);
+                 CODING_CHAR_CHARSET (coding, dst, dst_end, c,
+                                      charset_list, &code, charset);
                }
            }
          if (code == CHARSET_INVALID_CODE (charset))
@@ -5088,10 +5123,10 @@ detect_coding_ccl (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int found = 0;
   unsigned char *valids;
-  int head_ascii = coding->head_ascii;
+  EMACS_INT head_ascii = coding->head_ascii;
   Lisp_Object attrs;
 
   detect_info->checked |= CATEGORY_MASK_CCL;
@@ -5128,7 +5163,7 @@ decode_coding_ccl (struct coding_system *coding)
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int *charbuf = coding->charbuf + coding->charbuf_used;
   int *charbuf_end = coding->charbuf + coding->charbuf_size;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   int multibytep = coding->src_multibyte;
   struct ccl_program *ccl = &coding->spec.ccl->ccl;
   int source_charbuf[1024];
@@ -5200,7 +5235,8 @@ encode_coding_ccl (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int destination_charbuf[1024];
-  int i, produced_chars = 0;
+  EMACS_INT produced_chars = 0;
+  int i;
   Lisp_Object attrs, charset_list;
 
   CODING_GET_INFO (coding, attrs, charset_list);
@@ -5208,7 +5244,7 @@ encode_coding_ccl (struct coding_system *coding)
       && coding->mode & CODING_MODE_LAST_BLOCK)
     ccl->last_block = 1;
 
-  while (charbuf < charbuf_end)
+  do
     {
       ccl_driver (ccl, charbuf, destination_charbuf,
                  charbuf_end - charbuf, 1024, charset_list);
@@ -5230,6 +5266,7 @@ encode_coding_ccl (struct coding_system *coding)
          || ccl->status == CCL_STAT_INVALID_CMD)
        break;
     }
+  while (charbuf < charbuf_end);
 
   switch (ccl->status)
     {
@@ -5262,13 +5299,13 @@ encode_coding_ccl (struct coding_system *coding)
 static void
 decode_coding_raw_text (struct coding_system *coding)
 {
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
 
   coding->chars_at_source = 1;
   coding->consumed_char = coding->src_chars;
   coding->consumed = coding->src_bytes;
-  if (eol_crlf && coding->source[coding->src_bytes - 1] == '\r')
+  if (eol_dos && coding->source[coding->src_bytes - 1] == '\r')
     {
       coding->consumed_char--;
       coding->consumed--;
@@ -5286,7 +5323,7 @@ encode_coding_raw_text (struct coding_system *coding)
   int *charbuf_end = coding->charbuf + coding->charbuf_used;
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   int c;
 
   if (multibytep)
@@ -5310,11 +5347,12 @@ encode_coding_raw_text (struct coding_system *coding)
                unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str;
 
                CHAR_STRING_ADVANCE (c, p1);
-               while (p0 < p1)
+               do
                  {
                    EMIT_ONE_BYTE (*p0);
                    p0++;
                  }
+               while (p0 < p1);
              }
          }
       else
@@ -5368,10 +5406,10 @@ detect_coding_charset (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  EMACS_INT consumed_chars = 0;
   Lisp_Object attrs, valids, name;
   int found = 0;
-  int head_ascii = coding->head_ascii;
+  EMACS_INT head_ascii = coding->head_ascii;
   int check_latin_extra = 0;
 
   detect_info->checked |= CATEGORY_MASK_CHARSET;
@@ -5380,9 +5418,9 @@ detect_coding_charset (struct coding_system *coding,
   attrs = CODING_ID_ATTRS (coding->id);
   valids = AREF (attrs, coding_attr_charset_valids);
   name = CODING_ID_NAME (coding->id);
-  if (strncmp ((char *) SDATA (SYMBOL_NAME (name)),
+  if (strncmp (SSDATA (SYMBOL_NAME (name)),
               "iso-8859-", sizeof ("iso-8859-") - 1) == 0
-      || strncmp ((char *) SDATA (SYMBOL_NAME (name)),
+      || strncmp (SSDATA (SYMBOL_NAME (name)),
                  "iso-latin-", sizeof ("iso-latin-") - 1) == 0)
     check_latin_extra = 1;
 
@@ -5421,8 +5459,8 @@ detect_coding_charset (struct coding_system *coding,
              if (src == src_end)
                goto too_short;
              ONE_MORE_BYTE (c);
-             if (c < charset->code_space[(dim - 1 - idx) * 2]
-                 || c > charset->code_space[(dim - 1 - idx) * 2 + 1])
+             if (c < charset->code_space[(dim - 1 - idx) * 4]
+                 || c > charset->code_space[(dim - 1 - idx) * 4 + 1])
                break;
            }
          if (idx < dim)
@@ -5475,17 +5513,17 @@ decode_coding_charset (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  EMACS_INT consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
-  Lisp_Object attrs, charset_list, valids;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
+  Lisp_Object valids;
+  EMACS_INT char_offset = coding->produced_char;
+  EMACS_INT last_offset = char_offset;
   int last_id = charset_ascii;
-  int eol_crlf =
+  int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
   valids = AREF (attrs, coding_attr_charset_valids);
 
   while (1)
@@ -5515,7 +5553,7 @@ decode_coding_charset (struct coding_system *coding)
       else
        {
          ONE_MORE_BYTE (c);
-         if (eol_crlf && c == '\r')
+         if (eol_dos && c == '\r')
            ONE_MORE_BYTE (byte_after_cr);
        }
       if (c < 0)
@@ -5601,7 +5639,7 @@ encode_coding_charset (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = MAX_MULTIBYTE_LENGTH;
-  int produced_chars = 0;
+  EMACS_INT produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int ascii_compatible;
   int c;
@@ -5625,7 +5663,9 @@ encode_coding_charset (struct coding_system *coding)
        }
       else
        {
-         charset = char_charset (c, charset_list, &code);
+         CODING_CHAR_CHARSET (coding, dst, dst_end, c, charset_list,
+                              &code, charset);
+
          if (charset)
            {
              if (CHARSET_DIMENSION (charset) == 1)
@@ -5891,7 +5931,7 @@ coding_charset_list (struct coding_system *coding)
 Lisp_Object
 coding_system_charset_list (Lisp_Object coding_system)
 {
-  int id;
+  ptrdiff_t id;
   Lisp_Object attrs, charset_list;
 
   CHECK_CODING_SYSTEM_GET_ID (coding_system, id);
@@ -6273,7 +6313,7 @@ adjust_coding_eol_type (struct coding_system *coding, int eol_seen)
    system is detected, update fields of CODING by the detected coding
    system.  */
 
-void
+static void
 detect_coding (struct coding_system *coding)
 {
   const unsigned char *src, *src_end;
@@ -6509,7 +6549,7 @@ decode_eol (struct coding_system *coding)
     }
   else if (EQ (eol_type, Qdos))
     {
-      int n = 0;
+      EMACS_INT n = 0;
 
       if (NILP (coding->dst_object))
        {
@@ -6524,9 +6564,9 @@ decode_eol (struct coding_system *coding)
        }
       else
        {
-         int pos_byte = coding->dst_pos_byte;
-         int pos = coding->dst_pos;
-         int pos_end = pos + coding->produced_char - 1;
+         EMACS_INT pos_byte = coding->dst_pos_byte;
+         EMACS_INT pos = coding->dst_pos;
+         EMACS_INT pos_end = pos + coding->produced_char - 1;
 
          while (pos < pos_end)
            {
@@ -6608,15 +6648,15 @@ get_translation_table (Lisp_Object attrs, int encodep, int *max_lookup)
        }
       else if (CONSP (translation_table))
        {
-         Lisp_Object tail, val;
+         Lisp_Object tail;
 
          for (tail = translation_table; CONSP (tail); tail = XCDR (tail))
            if (CHAR_TABLE_P (XCAR (tail))
                && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (XCAR (tail))) > 1)
              {
-               val = XCHAR_TABLE (XCAR (tail))->extras[1];
-               if (NATNUMP (val) && *max_lookup < XFASTINT (val))
-                 *max_lookup = XFASTINT (val);
+               Lisp_Object tailval = XCHAR_TABLE (XCAR (tail))->extras[1];
+               if (NATNUMP (tailval) && *max_lookup < XFASTINT (tailval))
+                 *max_lookup = XFASTINT (tailval);
              }
        }
     }
@@ -6711,7 +6751,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 
          if (c >= 0)
            {
-             int from_nchars = 1, to_nchars = 1;
+             EMACS_INT from_nchars = 1, to_nchars = 1;
              Lisp_Object trans = Qnil;
 
              LOOKUP_TRANSLATION_TABLE (translation_table, c, trans);
@@ -6736,8 +6776,12 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                    break;
                }
 
-             if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end)
+             if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
                {
+                 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
+                      / MAX_MULTIBYTE_LENGTH)
+                     < to_nchars)
+                   memory_full (SIZE_MAX);
                  dst = alloc_destination (coding,
                                           buf_end - buf
                                           + MAX_MULTIBYTE_LENGTH * to_nchars,
@@ -6882,7 +6926,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
      [ -LENGTH ANNOTATION_MASK NCHARS NBYTES METHOD [ COMPONENTS... ] ]
  */
 
-static INLINE void
+static inline void
 produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
 {
   int len;
@@ -6926,7 +6970,7 @@ produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
      [ -LENGTH ANNOTATION_MASK NCHARS CHARSET-ID ]
  */
 
-static INLINE void
+static inline void
 produce_charset (struct coding_system *coding, int *charbuf, EMACS_INT pos)
 {
   EMACS_INT from = pos - charbuf[2];
@@ -7039,8 +7083,8 @@ decode_coding (struct coding_system *coding)
        set_buffer_internal (XBUFFER (coding->dst_object));
       if (GPT != PT)
        move_gap_both (PT, PT_BYTE);
-      undo_list = current_buffer->undo_list;
-      current_buffer->undo_list = Qt;
+      undo_list = BVAR (current_buffer, undo_list);
+      BVAR (current_buffer, undo_list) = Qt;
     }
 
   coding->consumed = coding->consumed_char = 0;
@@ -7137,7 +7181,7 @@ decode_coding (struct coding_system *coding)
     decode_eol (coding);
   if (BUFFERP (coding->dst_object))
     {
-      current_buffer->undo_list = undo_list;
+      BVAR (current_buffer, undo_list) = undo_list;
       record_insert (coding->dst_pos, coding->produced_char);
     }
   return coding->result;
@@ -7154,7 +7198,7 @@ decode_coding (struct coding_system *coding)
    position of a composition after POS (if any) or to LIMIT, and
    return BUF.  */
 
-static INLINE int *
+static inline int *
 handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
                               struct coding_system *coding, int *buf,
                               EMACS_INT *stop)
@@ -7186,7 +7230,7 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
              components = COMPOSITION_COMPONENTS (prop);
              if (VECTORP (components))
                {
-                 len = XVECTOR (components)->size;
+                 len = ASIZE (components);
                  for (i = 0; i < len; i++)
                    *buf++ = XINT (AREF (components, i));
                }
@@ -7237,7 +7281,7 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
    If the property value is nil, set *STOP to the position where the
    property value is non-nil (limiting by LIMIT), and return BUF.  */
 
-static INLINE int *
+static inline int *
 handle_charset_annotation (EMACS_INT pos, EMACS_INT limit,
                           struct coding_system *coding, int *buf,
                           EMACS_INT *stop)
@@ -7434,7 +7478,7 @@ encode_coding (struct coding_system *coding)
     {
       set_buffer_internal (XBUFFER (coding->dst_object));
       coding->dst_multibyte
-       = ! NILP (current_buffer->enable_multibyte_characters);
+       = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
     }
 
   coding->consumed = coding->consumed_char = 0;
@@ -7505,8 +7549,8 @@ make_conversion_work_buffer (int multibyte)
      doesn't compile new regexps.  */
   Fset (Fmake_local_variable (Qinhibit_modification_hooks), Qt);
   Ferase_buffer ();
-  current_buffer->undo_list = Qt;
-  current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil;
+  BVAR (current_buffer, undo_list) = Qt;
+  BVAR (current_buffer, enable_multibyte_characters) = multibyte ? Qt : Qnil;
   set_buffer_internal (current);
   return workbuf;
 }
@@ -7563,7 +7607,7 @@ decode_coding_gap (struct coding_system *coding,
   coding->dst_object = coding->src_object;
   coding->dst_pos = PT;
   coding->dst_pos_byte = PT_BYTE;
-  coding->dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
+  coding->dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
 
   if (CODING_REQUIRE_DETECTION (coding))
     detect_coding (coding);
@@ -7591,30 +7635,6 @@ decode_coding_gap (struct coding_system *coding,
   return coding->result;
 }
 
-int
-encode_coding_gap (struct coding_system *coding,
-                  EMACS_INT chars, EMACS_INT bytes)
-{
-  int count = SPECPDL_INDEX ();
-
-  code_conversion_save (0, 0);
-
-  coding->src_object = Fcurrent_buffer ();
-  coding->src_chars = chars;
-  coding->src_bytes = bytes;
-  coding->src_pos = -chars;
-  coding->src_pos_byte = -bytes;
-  coding->src_multibyte = chars < bytes;
-  coding->dst_object = coding->src_object;
-  coding->dst_pos = PT;
-  coding->dst_pos_byte = PT_BYTE;
-
-  encode_coding (coding);
-
-  unbind_to (count, Qnil);
-  return coding->result;
-}
-
 
 /* Decode the text in the range FROM/FROM_BYTE and TO/TO_BYTE in
    SRC_OBJECT into DST_OBJECT by coding context CODING.
@@ -7653,12 +7673,12 @@ decode_coding_object (struct coding_system *coding,
                      Lisp_Object dst_object)
 {
   int count = SPECPDL_INDEX ();
-  unsigned char *destination;
-  EMACS_INT dst_bytes;
+  unsigned char *destination IF_LINT (= NULL);
+  EMACS_INT dst_bytes IF_LINT (= 0);
   EMACS_INT chars = to - from;
   EMACS_INT bytes = to_byte - from_byte;
   Lisp_Object attrs;
-  int saved_pt = -1, saved_pt_byte;
+  int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
   Lisp_Object old_deactivate_mark;
 
@@ -7729,7 +7749,7 @@ decode_coding_object (struct coding_system *coding,
       coding->dst_pos = BUF_PT (XBUFFER (dst_object));
       coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object));
       coding->dst_multibyte
-       = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
+       = ! NILP (BVAR (XBUFFER (dst_object), enable_multibyte_characters));
     }
   else
     {
@@ -7799,7 +7819,7 @@ decode_coding_object (struct coding_system *coding,
        TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
       else if (saved_pt < from + chars)
        TEMP_SET_PT_BOTH (from, from_byte);
-      else if (! NILP (current_buffer->enable_multibyte_characters))
+      else if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
        TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
                          saved_pt_byte + (coding->produced - bytes));
       else
@@ -7823,7 +7843,7 @@ decode_coding_object (struct coding_system *coding,
                  {
                    tail->bytepos = from_byte + coding->produced;
                    tail->charpos
-                     = (NILP (current_buffer->enable_multibyte_characters)
+                     = (NILP (BVAR (current_buffer, enable_multibyte_characters))
                         ? tail->bytepos : from + coding->produced_char);
                  }
              }
@@ -7846,7 +7866,7 @@ encode_coding_object (struct coding_system *coding,
   EMACS_INT chars = to - from;
   EMACS_INT bytes = to_byte - from_byte;
   Lisp_Object attrs;
-  int saved_pt = -1, saved_pt_byte;
+  int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
   int kill_src_buffer = 0;
   Lisp_Object old_deactivate_mark;
@@ -7881,7 +7901,7 @@ encode_coding_object (struct coding_system *coding,
       else if (BUFFERP (src_object))
        insert_from_buffer (XBUFFER (src_object), from, chars, 0);
       else
-       insert_1_both (coding->source + from, chars, bytes, 0, 0, 0);
+       insert_1_both ((char *) coding->source + from, chars, bytes, 0, 0, 0);
 
       if (EQ (src_object, dst_object))
        {
@@ -7961,15 +7981,14 @@ encode_coding_object (struct coding_system *coding,
          set_buffer_temp (current);
        }
       coding->dst_multibyte
-       = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
+       = ! NILP (BVAR (XBUFFER (dst_object), enable_multibyte_characters));
     }
   else if (EQ (dst_object, Qt))
     {
+      ptrdiff_t dst_bytes = max (1, coding->src_chars);
       coding->dst_object = Qnil;
-      coding->dst_bytes = coding->src_chars;
-      if (coding->dst_bytes == 0)
-       coding->dst_bytes = 1;
-      coding->destination = (unsigned char *) xmalloc (coding->dst_bytes);
+      coding->destination = (unsigned char *) xmalloc (dst_bytes);
+      coding->dst_bytes = dst_bytes;
       coding->dst_multibyte = 0;
     }
   else
@@ -8004,7 +8023,7 @@ encode_coding_object (struct coding_system *coding,
        TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
       else if (saved_pt < from + chars)
        TEMP_SET_PT_BOTH (from, from_byte);
-      else if (! NILP (current_buffer->enable_multibyte_characters))
+      else if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
        TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
                          saved_pt_byte + (coding->produced - bytes));
       else
@@ -8028,7 +8047,7 @@ encode_coding_object (struct coding_system *coding,
                  {
                    tail->bytepos = from_byte + coding->produced;
                    tail->charpos
-                     = (NILP (current_buffer->enable_multibyte_characters)
+                     = (NILP (BVAR (current_buffer, enable_multibyte_characters))
                         ? tail->bytepos : from + coding->produced_char);
                  }
              }
@@ -8153,7 +8172,7 @@ detect_coding_system (const unsigned char *src,
   Lisp_Object attrs, eol_type;
   Lisp_Object val = Qnil;
   struct coding_system coding;
-  int id;
+  ptrdiff_t id;
   struct coding_detection_info detect_info;
   enum coding_category base_category;
   int null_byte_found = 0, eight_bit_found = 0;
@@ -8179,8 +8198,8 @@ detect_coding_system (const unsigned char *src,
   base_category = XINT (CODING_ATTR_CATEGORY (attrs));
   if (base_category == coding_category_undecided)
     {
-      enum coding_category category;
-      struct coding_system *this;
+      enum coding_category category IF_LINT (= 0);
+      struct coding_system *this IF_LINT (= NULL);
       int c, i;
 
       /* Skip all ASCII bytes except for a few ISO2022 controls.  */
@@ -8482,8 +8501,8 @@ highest priority.  */)
   return detect_coding_system (BYTE_POS_ADDR (from_byte),
                               to - from, to_byte - from_byte,
                               !NILP (highest),
-                              !NILP (current_buffer
-                                     ->enable_multibyte_characters),
+                              !NILP (BVAR (current_buffer
+                                     , enable_multibyte_characters)),
                               Qnil);
 }
 
@@ -8512,7 +8531,7 @@ highest priority.  */)
 }
 
 
-static INLINE int
+static inline int
 char_encodable_p (int c, Lisp_Object attrs)
 {
   Lisp_Object tail;
@@ -8565,7 +8584,7 @@ DEFUN ("find-coding-systems-region-internal",
       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 (NILP (BVAR (current_buffer, enable_multibyte_characters)))
        return Qt;
       start_byte = CHAR_TO_BYTE (XINT (start));
       end_byte = CHAR_TO_BYTE (XINT (end));
@@ -8699,7 +8718,7 @@ to the string.  */)
       validate_region (&start, &end);
       from = XINT (start);
       to = XINT (end);
-      if (NILP (current_buffer->enable_multibyte_characters)
+      if (NILP (BVAR (current_buffer, enable_multibyte_characters))
          || (ascii_compatible
              && (to - from) == (CHAR_TO_BYTE (to) - (CHAR_TO_BYTE (from)))))
        return Qnil;
@@ -8737,6 +8756,7 @@ to the string.  */)
     }
 
   positions = Qnil;
+  charset_map_loaded = 0;
   while (1)
     {
       int c;
@@ -8764,6 +8784,16 @@ to the string.  */)
        }
 
       from++;
+      if (charset_map_loaded && NILP (string))
+       {
+         p = CHAR_POS_ADDR (from);
+         pend = CHAR_POS_ADDR (to);
+         if (from < GPT && to >= GPT)
+           stop = GPT_ADDR;
+         else
+           stop = pend;
+         charset_map_loaded = 0;
+       }
     }
 
   return (NILP (count) ? Fcar (positions) : Fnreverse (positions));
@@ -8815,7 +8845,7 @@ is nil.  */)
       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 (NILP (BVAR (current_buffer, enable_multibyte_characters)))
        return Qnil;
       start_byte = CHAR_TO_BYTE (XINT (start));
       end_byte = CHAR_TO_BYTE (XINT (end));
@@ -8895,7 +8925,7 @@ is nil.  */)
 }
 
 
-Lisp_Object
+static Lisp_Object
 code_convert_region (Lisp_Object start, Lisp_Object end,
                     Lisp_Object coding_system, Lisp_Object dst_object,
                     int encodep, int norecord)
@@ -9077,7 +9107,7 @@ not fully specified.)  */)
   (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer)
 {
   return code_convert_string (string, coding_system, buffer,
-                             1, ! NILP (nocopy), 1);
+                             1, ! NILP (nocopy), 0);
 }
 
 \f
@@ -9088,14 +9118,15 @@ Return the corresponding character.  */)
 {
   Lisp_Object spec, attrs, val;
   struct charset *charset_roman, *charset_kanji, *charset_kana, *charset;
+  EMACS_INT ch;
   int c;
 
   CHECK_NATNUM (code);
-  c = XFASTINT (code);
+  ch = XFASTINT (code);
   CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (c)
+  if (ASCII_BYTE_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -9104,26 +9135,31 @@ Return the corresponding character.  */)
   charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
 
-  if (c <= 0x7F)
-    charset = charset_roman;
-  else if (c >= 0xA0 && c < 0xDF)
+  if (ch <= 0x7F)
+    {
+      c = ch;
+      charset = charset_roman;
+    }
+  else if (ch >= 0xA0 && ch < 0xDF)
     {
+      c = ch - 0x80;
       charset = charset_kana;
-      c -= 0x80;
     }
   else
     {
-      int s1 = c >> 8, s2 = c & 0xFF;
+      EMACS_INT c1 = ch >> 8;
+      int c2 = ch & 0xFF;
 
-      if (s1 < 0x81 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF
-         || s2 < 0x40 || s2 == 0x7F || s2 > 0xFC)
-       error ("Invalid code: %d", code);
+      if (c1 < 0x81 || (c1 > 0x9F && c1 < 0xE0) || c1 > 0xEF
+         || c2 < 0x40 || c2 == 0x7F || c2 > 0xFC)
+       error ("Invalid code: %"pI"d", ch);
+      c = ch;
       SJIS_TO_JIS (c);
       charset = charset_kanji;
     }
   c = DECODE_CHAR (charset, c);
   if (c < 0)
-    error ("Invalid code: %d", code);
+    error ("Invalid code: %"pI"d", ch);
   return make_number (c);
 }
 
@@ -9150,7 +9186,7 @@ Return the corresponding code in SJIS.  */)
   charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   charset = char_charset (c, charset_list, &code);
   if (code == CHARSET_INVALID_CODE (charset))
-    error ("Can't encode by shift_jis encoding: %d", c);
+    error ("Can't encode by shift_jis encoding: %c", c);
   JIS_TO_SJIS (code);
 
   return make_number (code);
@@ -9163,14 +9199,15 @@ Return the corresponding character.  */)
 {
   Lisp_Object spec, attrs, val;
   struct charset *charset_roman, *charset_big5, *charset;
+  EMACS_INT ch;
   int c;
 
   CHECK_NATNUM (code);
-  c = XFASTINT (code);
+  ch = XFASTINT (code);
   CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (c)
+  if (ASCII_BYTE_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -9178,19 +9215,24 @@ Return the corresponding character.  */)
   charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
 
-  if (c <= 0x7F)
-    charset = charset_roman;
+  if (ch <= 0x7F)
+    {
+      c = ch;
+      charset = charset_roman;
+    }
   else
     {
-      int b1 = c >> 8, b2 = c & 0x7F;
+      EMACS_INT b1 = ch >> 8;
+      int b2 = ch & 0x7F;
       if (b1 < 0xA1 || b1 > 0xFE
          || b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE)
-       error ("Invalid code: %d", code);
+       error ("Invalid code: %"pI"d", ch);
+      c = ch;
       charset = charset_big5;
     }
-  c = DECODE_CHAR (charset, (unsigned )c);
+  c = DECODE_CHAR (charset, c);
   if (c < 0)
-    error ("Invalid code: %d", code);
+    error ("Invalid code: %"pI"d", ch);
   return make_number (c);
 }
 
@@ -9215,7 +9257,7 @@ Return the corresponding character code in Big5.  */)
   charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   charset = char_charset (c, charset_list, &code);
   if (code == CHARSET_INVALID_CODE (charset))
-    error ("Can't encode by Big5 encoding: %d", c);
+    error ("Can't encode by Big5 encoding: %c", c);
 
   return make_number (code);
 }
@@ -9270,7 +9312,7 @@ frame's terminal device.  */)
     = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1));
   Lisp_Object coding_system = CODING_ID_NAME (terminal_coding->id);
 
-  /* For backward compatibility, return nil if it is `undecided'. */
+  /* For backward compatibility, return nil if it is `undecided'.  */
   return (! EQ (coding_system, Qundecided) ? coding_system : Qnil);
 }
 
@@ -9343,7 +9385,7 @@ function to call for FILENAME, that function should examine the
 contents of BUFFER instead of reading the file.
 
 usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object operation, target_idx, target, val;
   register Lisp_Object chain;
@@ -9352,17 +9394,18 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)
     error ("Too few arguments");
   operation = args[0];
   if (!SYMBOLP (operation)
-      || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))
+      || !NATNUMP (target_idx = Fget (operation, Qtarget_idx)))
     error ("Invalid first argument");
-  if (nargs < 1 + XINT (target_idx))
-    error ("Too few arguments for operation: %s",
+  if (nargs < 1 + XFASTINT (target_idx))
+    error ("Too few arguments for operation `%s'",
           SDATA (SYMBOL_NAME (operation)));
-  target = args[XINT (target_idx) + 1];
+  target = args[XFASTINT (target_idx) + 1];
   if (!(STRINGP (target)
        || (EQ (operation, Qinsert_file_contents) && CONSP (target)
            && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
-    error ("Invalid %dth argument", XINT (target_idx) + 1);
+    error ("Invalid argument %"pI"d of operation `%s'",
+          XFASTINT (target_idx) + 1, SDATA (SYMBOL_NAME (operation)));
   if (CONSP (target))
     target = XCAR (target);
 
@@ -9419,9 +9462,9 @@ If multiple coding systems belong to the same category,
 all but the first one are ignored.
 
 usage: (set-coding-system-priority &rest coding-systems)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
-  int i, j;
+  ptrdiff_t i, j;
   int changed[coding_category_max];
   enum coding_category priorities[coding_category_max];
 
@@ -9464,7 +9507,7 @@ usage: (set-coding-system-priority &rest coding-systems)  */)
 
   /* Update `coding-category-list'.  */
   Vcoding_category_list = Qnil;
-  for (i = coding_category_max - 1; i >= 0; i--)
+  for (i = coding_category_max; i-- > 0; )
     Vcoding_category_list
       = Fcons (AREF (Vcoding_category_table, priorities[i]),
               Vcoding_category_list);
@@ -9506,7 +9549,7 @@ static Lisp_Object
 make_subsidiaries (Lisp_Object base)
 {
   Lisp_Object subsidiaries;
-  int base_name_len = SBYTES (SYMBOL_NAME (base));
+  ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base));
   char *buf = (char *) alloca (base_name_len + 6);
   int i;
 
@@ -9514,7 +9557,7 @@ make_subsidiaries (Lisp_Object base)
   subsidiaries = Fmake_vector (make_number (3), Qnil);
   for (i = 0; i < 3; i++)
     {
-      memcpy (buf + base_name_len, suffixes[i], strlen (suffixes[i]) + 1);
+      strcpy (buf + base_name_len, suffixes[i]);
       ASET (subsidiaries, i, intern (buf));
     }
   return subsidiaries;
@@ -9525,7 +9568,7 @@ DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
        Sdefine_coding_system_internal, coding_arg_max, MANY, 0,
        doc: /* For internal use only.
 usage: (define-coding-system-internal ...)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object name;
   Lisp_Object spec_vec;                /* [ ATTRS ALIASE EOL_TYPE ] */
@@ -9799,7 +9842,6 @@ usage: (define-coding-system-internal ...)  */)
   else if (EQ (coding_type, Qiso_2022))
     {
       Lisp_Object initial, reg_usage, request, flags;
-      int i;
 
       if (nargs < coding_arg_iso2022_max)
        goto short_args;
@@ -9831,15 +9873,15 @@ usage: (define-coding-system-internal ...)  */)
       for (tail = request; ! NILP (tail); tail = Fcdr (tail))
        {
          int id;
-         Lisp_Object tmp;
+         Lisp_Object tmp1;
 
          val = Fcar (tail);
          CHECK_CONS (val);
-         tmp = XCAR (val);
-         CHECK_CHARSET_GET_ID (tmp, id);
+         tmp1 = XCAR (val);
+         CHECK_CHARSET_GET_ID (tmp1, id);
          CHECK_NATNUM_CDR (val);
          if (XINT (XCDR (val)) >= 4)
-           error ("Invalid graphic register number: %d", XINT (XCDR (val)));
+           error ("Invalid graphic register number: %"pI"d", XINT (XCDR (val)));
          XSETCAR (val, make_number (id));
        }
 
@@ -9957,8 +9999,6 @@ usage: (define-coding-system-internal ...)  */)
     {
       Lisp_Object bom;
 
-      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
-
       if (nargs < coding_arg_utf8_max)
        goto short_args;
 
@@ -9972,6 +10012,8 @@ usage: (define-coding-system-internal ...)  */)
          CHECK_CODING_SYSTEM (val);
        }
       ASET (attrs, coding_attr_utf_bom, bom);
+      if (NILP (bom))
+       CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 
       category = (CONSP (bom) ? coding_category_utf_8_auto
                  : NILP (bom) ? coding_category_utf_8_nosig
@@ -10827,7 +10869,7 @@ emacs_strerror (int error_number)
       Lisp_Object dec = code_convert_string_norecord (build_string (str),
                                                      Vlocale_coding_system,
                                                      0);
-      str = (char *) SDATA (dec);
+      str = SSDATA (dec);
     }
 
   return str;