Merge from trunk.
[bpt/emacs.git] / src / coding.c
index 5fd59d3..be7166e 100644 (file)
@@ -1,5 +1,5 @@
 /* Coding system handler (conversion, detection, etc).
-   Copyright (C) 2001-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)
@@ -159,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   ...;
 
@@ -266,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_;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
 
   for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++)
     {
@@ -847,33 +847,33 @@ 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 void coding_alloc_by_realloc (struct coding_system *, EMACS_INT);
+static ptrdiff_t coding_set_source (struct coding_system *);
+static ptrdiff_t coding_set_destination (struct coding_system *);
+static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t);
 static void coding_alloc_by_making_gap (struct coding_system *,
-                                        EMACS_INT, EMACS_INT);
+                                        ptrdiff_t, ptrdiff_t);
 static unsigned char *alloc_destination (struct coding_system *,
-                                         EMACS_INT, unsigned char *);
+                                         ptrdiff_t, unsigned char *);
 static void setup_iso_safe_charsets (Lisp_Object);
-static unsigned char *encode_designation_at_bol (struct coding_system *,
-                                                 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);
+                       ptrdiff_t, enum coding_category);
 static Lisp_Object adjust_coding_eol_type (struct coding_system *, int);
 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 *,
-                                    EMACS_INT);
-static void produce_annotation (struct coding_system *, EMACS_INT);
+                                    ptrdiff_t);
+static void produce_annotation (struct coding_system *, ptrdiff_t);
 static int decode_coding (struct coding_system *);
-static inline int *handle_composition_annotation (EMACS_INT, EMACS_INT,
+static inline int *handle_composition_annotation (ptrdiff_t, ptrdiff_t,
                                                   struct coding_system *,
-                                                  int *, EMACS_INT *);
-static inline int *handle_charset_annotation (EMACS_INT, EMACS_INT,
+                                                  int *, ptrdiff_t *);
+static inline int *handle_charset_annotation (ptrdiff_t, ptrdiff_t,
                                               struct coding_system *,
-                                              int *, EMACS_INT *);
+                                              int *, ptrdiff_t *);
 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);
@@ -915,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 {                                                                      \
+    ptrdiff_t 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 {                                                                 \
+    ptrdiff_t 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 {                                                                 \
+    ptrdiff_t 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 {                                                                 \
+    ptrdiff_t 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
@@ -946,7 +987,7 @@ record_conversion_result (struct coding_system *coding,
   do {                                                         \
     if (dst + (bytes) >= dst_end)                              \
       {                                                                \
-       EMACS_INT more_bytes = charbuf_end - charbuf + (bytes); \
+       ptrdiff_t more_bytes = charbuf_end - charbuf + (bytes); \
                                                                \
        dst = alloc_destination (coding, more_bytes, dst);      \
        dst_end = coding->destination + coding->dst_bytes;      \
@@ -1015,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 ptrdiff_t
 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);
@@ -1036,14 +1082,21 @@ coding_set_source (struct coding_system *coding)
       /* 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 ptrdiff_t
 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
@@ -1065,11 +1118,12 @@ coding_set_destination (struct coding_system *coding)
       /* 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)
+coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes)
 {
   if (STRING_BYTES_BOUND - coding->dst_bytes < bytes)
     string_overflow ();
@@ -1080,7 +1134,7 @@ coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
 
 static void
 coding_alloc_by_making_gap (struct coding_system *coding,
-                           EMACS_INT gap_head_used, EMACS_INT bytes)
+                           ptrdiff_t gap_head_used, ptrdiff_t bytes)
 {
   if (EQ (coding->src_object, coding->dst_object))
     {
@@ -1088,7 +1142,7 @@ coding_alloc_by_making_gap (struct coding_system *coding,
         consumed data at the tail.  To preserve those data, we at
         first make the gap size to zero, then increase the gap
         size.  */
-      EMACS_INT add = GAP_SIZE;
+      ptrdiff_t add = GAP_SIZE;
 
       GPT += gap_head_used, GPT_BYTE += gap_head_used;
       GAP_SIZE = 0; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
@@ -1109,10 +1163,10 @@ coding_alloc_by_making_gap (struct coding_system *coding,
 
 
 static unsigned char *
-alloc_destination (struct coding_system *coding, EMACS_INT nbytes,
+alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
                   unsigned char *dst)
 {
-  EMACS_INT offset = dst - coding->destination;
+  ptrdiff_t offset = dst - coding->destination;
 
   if (BUFFERP (coding->dst_object))
     {
@@ -1213,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int bom_found = 0;
   int found = 0;
 
@@ -1298,7 +1352,7 @@ 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;
-  EMACS_INT consumed_chars = 0, consumed_chars_base = 0;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base = 0;
   int multibytep = coding->src_multibyte;
   enum utf_bom_type bom = CODING_UTF_8_BOM (coding);
   int eol_dos =
@@ -1449,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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int c;
 
   if (CODING_UTF_8_BOM (coding) == utf_with_bom)
@@ -1607,7 +1661,7 @@ 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;
-  EMACS_INT consumed_chars = 0, consumed_chars_base = 0;
+  ptrdiff_t 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);
@@ -1734,7 +1788,7 @@ 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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int c;
 
   if (bom != utf_without_bom)
@@ -1868,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int c;
   int found = 0;
 
@@ -2338,10 +2392,10 @@ decode_coding_emacs_mule (struct coding_system *coding)
     = 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;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
-  EMACS_INT char_offset = coding->produced_char;
-  EMACS_INT last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -2413,7 +2467,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
             original pointer to buffer text, and fix up all related
             pointers after the call.  */
          const unsigned char *orig = coding->source;
-         EMACS_INT offset;
+         ptrdiff_t offset;
 
          c = emacs_mule_char (coding, src_base, &nbytes, &nchars, &id,
                               cmp_status);
@@ -2594,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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int c;
   int preferred_charset_id = -1;
@@ -2650,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;
@@ -2666,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);
@@ -2881,7 +2941,7 @@ setup_iso_safe_charsets (Lisp_Object attrs)
   Lisp_Object request;
   Lisp_Object reg_usage;
   Lisp_Object tail;
-  int reg94, reg96;
+  EMACS_INT reg94, reg96;
   int flags = XINT (AREF (attrs, coding_attr_iso_flags));
   int max_charset_id;
 
@@ -2952,7 +3012,7 @@ detect_coding_iso_2022 (struct coding_system *coding,
   int single_shifting = 0;
   int id;
   int c, c1;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int i;
   int rejected = 0;
   int found = 0;
@@ -3462,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);
-  EMACS_INT consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t 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);
@@ -3472,8 +3532,8 @@ decode_coding_iso_2022 (struct coding_system *coding)
   int c;
   struct composition_status *cmp_status = CODING_ISO_CMP_STATUS (coding);
   Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
-  EMACS_INT char_offset = coding->produced_char;
-  EMACS_INT last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -4185,7 +4245,8 @@ decode_coding_iso_2022 (struct coding_system *coding)
 
 #define ENCODE_ISO_CHARACTER(charset, c)                                  \
   do {                                                                    \
-    int code = ENCODE_CHAR ((charset), (c));                              \
+    unsigned code;                                                        \
+    CODING_ENCODE_CHAR (coding, dst, dst_end, (charset), (c), code);      \
                                                                           \
     if (CHARSET_DIMENSION (charset) == 1)                                 \
       ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code);                  \
@@ -4201,10 +4262,10 @@ decode_coding_iso_2022 (struct coding_system *coding)
 static unsigned char *
 encode_invocation_designation (struct charset *charset,
                               struct coding_system *coding,
-                              unsigned char *dst, EMACS_INT *p_nchars)
+                              unsigned char *dst, ptrdiff_t *p_nchars)
 {
   int multibytep = coding->dst_multibyte;
-  EMACS_INT produced_chars = *p_nchars;
+  ptrdiff_t produced_chars = *p_nchars;
   int reg;                     /* graphic register number */
   int id = CHARSET_ID (charset);
 
@@ -4283,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,
+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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int multibytep = coding->dst_multibyte;
   Lisp_Object attrs;
   Lisp_Object charset_list;
@@ -4309,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;
 
@@ -4334,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".  */
@@ -4351,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));
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, eol_type, charset_list;
   int ascii_compatible;
   int c;
@@ -4378,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, dst);
-         bol_designation = 0;
+         unsigned char desig_buf[16];
+         int nbytes;
+         ptrdiff_t 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++;
@@ -4455,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)
@@ -4471,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);
@@ -4539,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   int c;
   Lisp_Object attrs, charset_list;
@@ -4596,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   int c;
 
@@ -4647,13 +4731,13 @@ decode_coding_sjis (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  EMACS_INT consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t 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;
-  EMACS_INT char_offset = coding->produced_char;
-  EMACS_INT last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -4765,12 +4849,12 @@ decode_coding_big5 (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  EMACS_INT consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   struct charset *charset_roman, *charset_big5;
   Lisp_Object attrs, charset_list, val;
-  EMACS_INT char_offset = coding->produced_char;
-  EMACS_INT last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -4867,7 +4951,7 @@ 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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
   struct charset *charset_kanji, *charset_kana;
@@ -4897,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)
            {
@@ -4909,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))
@@ -4958,7 +5045,7 @@ 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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
   struct charset *charset_big5;
@@ -4984,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)
            {
@@ -4996,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))
@@ -5033,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   unsigned char *valids;
-  EMACS_INT head_ascii = coding->head_ascii;
+  ptrdiff_t head_ascii = coding->head_ascii;
   Lisp_Object attrs;
 
   detect_info->checked |= CATEGORY_MASK_CCL;
@@ -5073,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int multibytep = coding->src_multibyte;
   struct ccl_program *ccl = &coding->spec.ccl->ccl;
   int source_charbuf[1024];
@@ -5145,7 +5235,7 @@ 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];
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int i;
   Lisp_Object attrs, charset_list;
 
@@ -5154,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);
@@ -5176,6 +5266,7 @@ encode_coding_ccl (struct coding_system *coding)
          || ccl->status == CCL_STAT_INVALID_CMD)
        break;
     }
+  while (charbuf < charbuf_end);
 
   switch (ccl->status)
     {
@@ -5232,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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int c;
 
   if (multibytep)
@@ -5315,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;
-  EMACS_INT consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   Lisp_Object attrs, valids, name;
   int found = 0;
-  EMACS_INT head_ascii = coding->head_ascii;
+  ptrdiff_t head_ascii = coding->head_ascii;
   int check_latin_extra = 0;
 
   detect_info->checked |= CATEGORY_MASK_CHARSET;
@@ -5422,12 +5513,12 @@ decode_coding_charset (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  EMACS_INT consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
   Lisp_Object valids;
-  EMACS_INT char_offset = coding->produced_char;
-  EMACS_INT last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -5548,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;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int ascii_compatible;
   int c;
@@ -5572,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)
@@ -6095,7 +6188,7 @@ complement_process_encoding_system (Lisp_Object coding_system)
 #define MAX_EOL_CHECK_COUNT 3
 
 static int
-detect_eol (const unsigned char *source, EMACS_INT src_bytes,
+detect_eol (const unsigned char *source, ptrdiff_t src_bytes,
            enum coding_category category)
 {
   const unsigned char *src = source, *src_end = src + src_bytes;
@@ -6456,7 +6549,7 @@ decode_eol (struct coding_system *coding)
     }
   else if (EQ (eol_type, Qdos))
     {
-      EMACS_INT n = 0;
+      ptrdiff_t n = 0;
 
       if (NILP (coding->dst_object))
        {
@@ -6471,9 +6564,9 @@ decode_eol (struct coding_system *coding)
        }
       else
        {
-         EMACS_INT pos_byte = coding->dst_pos_byte;
-         EMACS_INT pos = coding->dst_pos;
-         EMACS_INT pos_end = pos + coding->produced_char - 1;
+         ptrdiff_t pos_byte = coding->dst_pos_byte;
+         ptrdiff_t pos = coding->dst_pos;
+         ptrdiff_t pos_end = pos + coding->produced_char - 1;
 
          while (pos < pos_end)
            {
@@ -6613,8 +6706,8 @@ get_translation (Lisp_Object trans, int *buf, int *buf_end)
     {
       Lisp_Object val = XCAR (trans);
       Lisp_Object from = XCAR (val);
-      int len = ASIZE (from);
-      int i;
+      ptrdiff_t len = ASIZE (from);
+      ptrdiff_t i;
 
       for (i = 0; i < len; i++)
        {
@@ -6636,8 +6729,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 {
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  EMACS_INT produced;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced;
+  ptrdiff_t produced_chars = 0;
   int carryover = 0;
 
   if (! coding->chars_at_source)
@@ -6658,7 +6751,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 
          if (c >= 0)
            {
-             EMACS_INT from_nchars = 1, to_nchars = 1;
+             ptrdiff_t from_nchars = 1, to_nchars = 1;
              Lisp_Object trans = Qnil;
 
              LOOKUP_TRANSLATION_TABLE (translation_table, c, trans);
@@ -6735,7 +6828,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
          if (coding->src_multibyte)
            {
              int multibytep = 1;
-             EMACS_INT consumed_chars = 0;
+             ptrdiff_t consumed_chars = 0;
 
              while (1)
                {
@@ -6749,7 +6842,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                        dst_end = (unsigned char *) src;
                      if (dst == dst_end)
                        {
-                         EMACS_INT offset = src - coding->source;
+                         ptrdiff_t offset = src - coding->source;
 
                          dst = alloc_destination (coding, src_end - src + 1,
                                                   dst);
@@ -6779,8 +6872,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                      dst_end = (unsigned char *) src;
                    if (dst >= dst_end - 1)
                      {
-                       EMACS_INT offset = src - coding->source;
-                       EMACS_INT more_bytes;
+                       ptrdiff_t offset = src - coding->source;
+                       ptrdiff_t more_bytes;
 
                        if (EQ (coding->src_object, coding->dst_object))
                          more_bytes = ((src_end - src) / 2) + 2;
@@ -6802,11 +6895,11 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
        {
          if (!EQ (coding->src_object, coding->dst_object))
            {
-             EMACS_INT require = coding->src_bytes - coding->dst_bytes;
+             ptrdiff_t require = coding->src_bytes - coding->dst_bytes;
 
              if (require > 0)
                {
-                 EMACS_INT offset = src - coding->source;
+                 ptrdiff_t offset = src - coding->source;
 
                  dst = alloc_destination (coding, require, dst);
                  coding_set_source (coding);
@@ -6834,10 +6927,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
  */
 
 static inline void
-produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
+produce_composition (struct coding_system *coding, int *charbuf, ptrdiff_t pos)
 {
   int len;
-  EMACS_INT to;
+  ptrdiff_t to;
   enum composition_method method;
   Lisp_Object components;
 
@@ -6878,9 +6971,9 @@ produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
  */
 
 static inline void
-produce_charset (struct coding_system *coding, int *charbuf, EMACS_INT pos)
+produce_charset (struct coding_system *coding, int *charbuf, ptrdiff_t pos)
 {
-  EMACS_INT from = pos - charbuf[2];
+  ptrdiff_t from = pos - charbuf[2];
   struct charset *charset = CHARSET_FROM_ID (charbuf[3]);
 
   Fput_text_property (make_number (from), make_number (pos),
@@ -6913,7 +7006,7 @@ produce_charset (struct coding_system *coding, int *charbuf, EMACS_INT pos)
 
 
 static void
-produce_annotation (struct coding_system *coding, EMACS_INT pos)
+produce_annotation (struct coding_system *coding, ptrdiff_t pos)
 {
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_used;
@@ -7013,7 +7106,7 @@ decode_coding (struct coding_system *coding)
     }
   do
     {
-      EMACS_INT pos = coding->dst_pos + coding->produced_char;
+      ptrdiff_t pos = coding->dst_pos + coding->produced_char;
 
       coding_set_source (coding);
       coding->annotated = 0;
@@ -7106,11 +7199,11 @@ decode_coding (struct coding_system *coding)
    return BUF.  */
 
 static inline int *
-handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
+handle_composition_annotation (ptrdiff_t pos, ptrdiff_t limit,
                               struct coding_system *coding, int *buf,
-                              EMACS_INT *stop)
+                              ptrdiff_t *stop)
 {
-  EMACS_INT start, end;
+  ptrdiff_t start, end;
   Lisp_Object prop;
 
   if (! find_composition (pos, limit, &start, &end, &prop, coding->src_object)
@@ -7132,7 +7225,7 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
          if (method != COMPOSITION_RELATIVE)
            {
              Lisp_Object components;
-             int len, i, i_byte;
+             ptrdiff_t i, len, i_byte;
 
              components = COMPOSITION_COMPONENTS (prop);
              if (VECTORP (components))
@@ -7189,9 +7282,9 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
    property value is non-nil (limiting by LIMIT), and return BUF.  */
 
 static inline int *
-handle_charset_annotation (EMACS_INT pos, EMACS_INT limit,
+handle_charset_annotation (ptrdiff_t pos, ptrdiff_t limit,
                           struct coding_system *coding, int *buf,
-                          EMACS_INT *stop)
+                          ptrdiff_t *stop)
 {
   Lisp_Object val, next;
   int id;
@@ -7218,12 +7311,12 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
   int *buf_end = coding->charbuf + coding->charbuf_size;
   const unsigned char *src = coding->source + coding->consumed;
   const unsigned char *src_end = coding->source + coding->src_bytes;
-  EMACS_INT pos = coding->src_pos + coding->consumed_char;
-  EMACS_INT end_pos = coding->src_pos + coding->src_chars;
+  ptrdiff_t pos = coding->src_pos + coding->consumed_char;
+  ptrdiff_t end_pos = coding->src_pos + coding->src_chars;
   int multibytep = coding->src_multibyte;
   Lisp_Object eol_type;
   int c;
-  EMACS_INT stop, stop_composition, stop_charset;
+  ptrdiff_t stop, stop_composition, stop_charset;
   int *lookup_buf = NULL;
 
   if (! NILP (translation_table))
@@ -7272,7 +7365,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
 
       if (! multibytep)
        {
-         EMACS_INT bytes;
+         int bytes;
 
          if (coding->encoder == encode_coding_raw_text
              || coding->encoder == encode_coding_ccl)
@@ -7303,7 +7396,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
        *buf++ = c;
       else
        {
-         int from_nchars = 1, to_nchars = 1;
+         ptrdiff_t from_nchars = 1, to_nchars = 1;
          int *lookup_buf_end;
          const unsigned char *p = src;
          int i;
@@ -7324,7 +7417,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
              else
                {
                  to_nchars = ASIZE (trans);
-                 if (buf + to_nchars > buf_end)
+                 if (buf_end - buf < to_nchars)
                    break;
                  c = XINT (AREF (trans, 0));
                }
@@ -7498,9 +7591,9 @@ code_conversion_save (int with_work_buf, int multibyte)
 
 int
 decode_coding_gap (struct coding_system *coding,
-                  EMACS_INT chars, EMACS_INT bytes)
+                  ptrdiff_t chars, ptrdiff_t bytes)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object attrs;
 
   code_conversion_save (0, 0);
@@ -7527,7 +7620,7 @@ decode_coding_gap (struct coding_system *coding,
   attrs = CODING_ID_ATTRS (coding->id);
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
     {
-      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
+      ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
 
       TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
@@ -7575,15 +7668,15 @@ decode_coding_gap (struct coding_system *coding,
 void
 decode_coding_object (struct coding_system *coding,
                      Lisp_Object src_object,
-                     EMACS_INT from, EMACS_INT from_byte,
-                     EMACS_INT to, EMACS_INT to_byte,
+                     ptrdiff_t from, ptrdiff_t from_byte,
+                     ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   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;
+  ptrdiff_t dst_bytes IF_LINT (= 0);
+  ptrdiff_t chars = to - from;
+  ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
   int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
@@ -7676,7 +7769,7 @@ decode_coding_object (struct coding_system *coding,
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
     {
       struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
-      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
+      ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
 
       TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
@@ -7765,13 +7858,13 @@ decode_coding_object (struct coding_system *coding,
 void
 encode_coding_object (struct coding_system *coding,
                      Lisp_Object src_object,
-                     EMACS_INT from, EMACS_INT from_byte,
-                     EMACS_INT to, EMACS_INT to_byte,
+                     ptrdiff_t from, ptrdiff_t from_byte,
+                     ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  int count = SPECPDL_INDEX ();
-  EMACS_INT chars = to - from;
-  EMACS_INT bytes = to_byte - from_byte;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  ptrdiff_t chars = to - from;
+  ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
   int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
@@ -8019,7 +8112,7 @@ are lower-case).  */)
   (Lisp_Object prompt, Lisp_Object default_coding_system)
 {
   Lisp_Object val;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   if (SYMBOLP (default_coding_system))
     default_coding_system = SYMBOL_NAME (default_coding_system);
@@ -8071,7 +8164,7 @@ function `define-coding-system'.  */)
 
 Lisp_Object
 detect_coding_system (const unsigned char *src,
-                     EMACS_INT src_chars, EMACS_INT src_bytes,
+                     ptrdiff_t src_chars, ptrdiff_t src_bytes,
                      int highest, int multibytep,
                      Lisp_Object coding_system)
 {
@@ -8391,8 +8484,8 @@ If optional argument HIGHEST is non-nil, return the coding system of
 highest priority.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object highest)
 {
-  int from, to;
-  int from_byte, to_byte;
+  ptrdiff_t from, to;
+  ptrdiff_t from_byte, to_byte;
 
   CHECK_NUMBER_COERCE_MARKER (start);
   CHECK_NUMBER_COERCE_MARKER (end);
@@ -8472,7 +8565,7 @@ DEFUN ("find-coding-systems-region-internal",
   (Lisp_Object start, Lisp_Object end, Lisp_Object exclude)
 {
   Lisp_Object coding_attrs_list, safe_codings;
-  EMACS_INT start_byte, end_byte;
+  ptrdiff_t start_byte, end_byte;
   const unsigned char *p, *pbeg, *pend;
   int c;
   Lisp_Object tail, elt, work_table;
@@ -8566,7 +8659,7 @@ DEFUN ("find-coding-systems-region-internal",
            }
          if (charset_map_loaded)
            {
-             EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
+             ptrdiff_t p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
                pbeg = SDATA (start);
@@ -8604,11 +8697,11 @@ for un-encodable characters.  In that case, START and END are indexes
 to the string.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object count, Lisp_Object string)
 {
-  int n;
+  EMACS_INT n;
   struct coding_system coding;
   Lisp_Object attrs, charset_list, translation_table;
   Lisp_Object positions;
-  int from, to;
+  ptrdiff_t from, to;
   const unsigned char *p, *stop, *pend;
   int ascii_compatible;
 
@@ -8641,11 +8734,10 @@ to the string.  */)
       CHECK_STRING (string);
       CHECK_NATNUM (start);
       CHECK_NATNUM (end);
+      if (! (XINT (start) <= XINT (end) && XINT (end) <= SCHARS (string)))
+       args_out_of_range_3 (string, start, end);
       from = XINT (start);
       to = XINT (end);
-      if (from > to
-         || to > SCHARS (string))
-       args_out_of_range_3 (string, start, end);
       if (! STRING_MULTIBYTE (string))
        return Qnil;
       p = SDATA (string) + string_char_to_byte (string, from);
@@ -8663,6 +8755,7 @@ to the string.  */)
     }
 
   positions = Qnil;
+  charset_map_loaded = 0;
   while (1)
     {
       int c;
@@ -8690,6 +8783,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));
@@ -8720,8 +8823,8 @@ is nil.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system_list)
 {
   Lisp_Object list;
-  EMACS_INT start_byte, end_byte;
-  int pos;
+  ptrdiff_t start_byte, end_byte;
+  ptrdiff_t pos;
   const unsigned char *p, *pbeg, *pend;
   int c;
   Lisp_Object tail, elt, attrs;
@@ -8794,7 +8897,7 @@ is nil.  */)
            }
          if (charset_map_loaded)
            {
-             EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
+             ptrdiff_t p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
                pbeg = SDATA (start);
@@ -8827,7 +8930,7 @@ code_convert_region (Lisp_Object start, Lisp_Object end,
                     int encodep, int norecord)
 {
   struct coding_system coding;
-  EMACS_INT from, from_byte, to, to_byte;
+  ptrdiff_t from, from_byte, to, to_byte;
   Lisp_Object src_object;
 
   CHECK_NUMBER_COERCE_MARKER (start);
@@ -8915,7 +9018,7 @@ code_convert_string (Lisp_Object string, Lisp_Object coding_system,
                     Lisp_Object dst_object, int encodep, int nocopy, int norecord)
 {
   struct coding_system coding;
-  EMACS_INT chars, bytes;
+  ptrdiff_t chars, bytes;
 
   CHECK_STRING (string);
   if (NILP (coding_system))
@@ -9208,7 +9311,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);
 }
 
@@ -9290,9 +9393,9 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)
     error ("Too few arguments");
   operation = args[0];
   if (!SYMBOLP (operation)
-      || !NATNUMP (target_idx = Fget (operation, Qtarget_idx)))
+      || (target_idx = Fget (operation, Qtarget_idx), !NATNUMP (target_idx)))
     error ("Invalid first argument");
-  if (nargs < 1 + XFASTINT (target_idx))
+  if (nargs <= 1 + XFASTINT (target_idx))
     error ("Too few arguments for operation `%s'",
           SDATA (SYMBOL_NAME (operation)));
   target = args[XFASTINT (target_idx) + 1];
@@ -9511,8 +9614,12 @@ usage: (define-coding-system-internal ...)  */)
          charset_list = Vemacs_mule_charset_list;
        }
       for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
-       if (max_charset_id < XFASTINT (XCAR (tail)))
-         max_charset_id = XFASTINT (XCAR (tail));
+       {
+         if (! RANGED_INTEGERP (0, XCAR (tail), INT_MAX - 1))
+           error ("Invalid charset-list");
+         if (max_charset_id < XFASTINT (XCAR (tail)))
+           max_charset_id = XFASTINT (XCAR (tail));
+       }
     }
   else
     {
@@ -9672,23 +9779,23 @@ usage: (define-coding-system-internal ...)  */)
          val = Fcar (tail);
          if (INTEGERP (val))
            {
-             from = to = XINT (val);
-             if (from < 0 || from > 255)
+             if (! (0 <= XINT (val) && XINT (val) <= 255))
                args_out_of_range_3 (val, make_number (0), make_number (255));
+             from = to = XINT (val);
            }
          else
            {
              CHECK_CONS (val);
              CHECK_NATNUM_CAR (val);
-             CHECK_NATNUM_CDR (val);
-             from = XINT (XCAR (val));
-             if (from > 255)
+             CHECK_NUMBER_CDR (val);
+             if (XINT (XCAR (val)) > 255)
                args_out_of_range_3 (XCAR (val),
                                     make_number (0), make_number (255));
-             to = XINT (XCDR (val));
-             if (to < from || to > 255)
+             from = XINT (XCAR (val));
+             if (! (from <= XINT (XCDR (val)) && XINT (XCDR (val)) <= 255))
                args_out_of_range_3 (XCDR (val),
                                     XCAR (val), make_number (255));
+             to = XINT (XCDR (val));
            }
          for (i = from; i <= to; i++)
            SSET (valids, i, 1);
@@ -9783,9 +9890,10 @@ usage: (define-coding-system-internal ...)  */)
 
       flags = args[coding_arg_iso2022_flags];
       CHECK_NATNUM (flags);
-      i = XINT (flags);
+      i = XINT (flags) & INT_MAX;
       if (EQ (args[coding_arg_charset_list], Qiso_2022))
-       flags = make_number (i | CODING_ISO_FLAG_FULL_SUPPORT);
+       i |= CODING_ISO_FLAG_FULL_SUPPORT;
+      flags = make_number (i);
 
       ASET (attrs, coding_attr_iso_initial, initial);
       ASET (attrs, coding_attr_iso_usage, reg_usage);
@@ -9895,8 +10003,6 @@ usage: (define-coding-system-internal ...)  */)
     {
       Lisp_Object bom;
 
-      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
-
       if (nargs < coding_arg_utf8_max)
        goto short_args;
 
@@ -9910,6 +10016,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