*** empty log message ***
[bpt/emacs.git] / src / coding.c
index 5b6955e..bd7e219 100644 (file)
@@ -411,47 +411,6 @@ Lisp_Object Vtranslation_table_for_input;
 Lisp_Object Vsjis_coding_system;
 Lisp_Object Vbig5_coding_system;
 
-static void record_conversion_result (struct coding_system *coding,
-                                     enum coding_result_code result);
-static int detect_coding_utf_8 P_ ((struct coding_system *,
-                                   struct coding_detection_info *info));
-static void decode_coding_utf_8 P_ ((struct coding_system *));
-static int encode_coding_utf_8 P_ ((struct coding_system *));
-
-static int detect_coding_utf_16 P_ ((struct coding_system *,
-                                    struct coding_detection_info *info));
-static void decode_coding_utf_16 P_ ((struct coding_system *));
-static int encode_coding_utf_16 P_ ((struct coding_system *));
-
-static int detect_coding_iso_2022 P_ ((struct coding_system *,
-                                      struct coding_detection_info *info));
-static void decode_coding_iso_2022 P_ ((struct coding_system *));
-static int encode_coding_iso_2022 P_ ((struct coding_system *));
-
-static int detect_coding_emacs_mule P_ ((struct coding_system *,
-                                        struct coding_detection_info *info));
-static void decode_coding_emacs_mule P_ ((struct coding_system *));
-static int encode_coding_emacs_mule P_ ((struct coding_system *));
-
-static int detect_coding_sjis P_ ((struct coding_system *,
-                                  struct coding_detection_info *info));
-static void decode_coding_sjis P_ ((struct coding_system *));
-static int encode_coding_sjis P_ ((struct coding_system *));
-
-static int detect_coding_big5 P_ ((struct coding_system *,
-                                  struct coding_detection_info *info));
-static void decode_coding_big5 P_ ((struct coding_system *));
-static int encode_coding_big5 P_ ((struct coding_system *));
-
-static int detect_coding_ccl P_ ((struct coding_system *,
-                                 struct coding_detection_info *info));
-static void decode_coding_ccl P_ ((struct coding_system *));
-static int encode_coding_ccl P_ ((struct coding_system *));
-
-static void decode_coding_raw_text P_ ((struct coding_system *));
-static int encode_coding_raw_text P_ ((struct coding_system *));
-
-
 /* ISO2022 section */
 
 #define CODING_ISO_INITIAL(coding, reg)                        \
@@ -858,6 +817,85 @@ static struct coding_system coding_categories[coding_category_max];
   } while (0)
 
 
+/* Prototypes for static functions.  */
+static void record_conversion_result P_ ((struct coding_system *coding,
+                                         enum coding_result_code result));
+static int detect_coding_utf_8 P_ ((struct coding_system *,
+                                   struct coding_detection_info *info));
+static void decode_coding_utf_8 P_ ((struct coding_system *));
+static int encode_coding_utf_8 P_ ((struct coding_system *));
+
+static int detect_coding_utf_16 P_ ((struct coding_system *,
+                                    struct coding_detection_info *info));
+static void decode_coding_utf_16 P_ ((struct coding_system *));
+static int encode_coding_utf_16 P_ ((struct coding_system *));
+
+static int detect_coding_iso_2022 P_ ((struct coding_system *,
+                                      struct coding_detection_info *info));
+static void decode_coding_iso_2022 P_ ((struct coding_system *));
+static int encode_coding_iso_2022 P_ ((struct coding_system *));
+
+static int detect_coding_emacs_mule P_ ((struct coding_system *,
+                                        struct coding_detection_info *info));
+static void decode_coding_emacs_mule P_ ((struct coding_system *));
+static int encode_coding_emacs_mule P_ ((struct coding_system *));
+
+static int detect_coding_sjis P_ ((struct coding_system *,
+                                  struct coding_detection_info *info));
+static void decode_coding_sjis P_ ((struct coding_system *));
+static int encode_coding_sjis P_ ((struct coding_system *));
+
+static int detect_coding_big5 P_ ((struct coding_system *,
+                                  struct coding_detection_info *info));
+static void decode_coding_big5 P_ ((struct coding_system *));
+static int encode_coding_big5 P_ ((struct coding_system *));
+
+static int detect_coding_ccl P_ ((struct coding_system *,
+                                 struct coding_detection_info *info));
+static void decode_coding_ccl P_ ((struct coding_system *));
+static int encode_coding_ccl P_ ((struct coding_system *));
+
+static void decode_coding_raw_text P_ ((struct coding_system *));
+static int encode_coding_raw_text P_ ((struct coding_system *));
+
+static void coding_set_source P_ ((struct coding_system *));
+static void coding_set_destination P_ ((struct coding_system *));
+static void coding_alloc_by_realloc P_ ((struct coding_system *, EMACS_INT));
+static void coding_alloc_by_making_gap P_ ((struct coding_system *,
+                                           EMACS_INT));
+static unsigned char *alloc_destination P_ ((struct coding_system *,
+                                            EMACS_INT, unsigned char *));
+static void setup_iso_safe_charsets P_ ((Lisp_Object));
+static unsigned char *encode_designation_at_bol P_ ((struct coding_system *,
+                                                    int *, int *,
+                                                    unsigned char *));
+static int detect_eol P_ ((const unsigned char *,
+                          EMACS_INT, enum coding_category));
+static Lisp_Object adjust_coding_eol_type P_ ((struct coding_system *, int));
+static void decode_eol P_ ((struct coding_system *));
+static Lisp_Object get_translation_table P_ ((Lisp_Object, int, int *));
+static Lisp_Object get_translation P_ ((Lisp_Object, int *, int *,
+                                       int, int *, int *));
+static int produce_chars P_ ((struct coding_system *, Lisp_Object, int));
+static INLINE void produce_composition P_ ((struct coding_system *, int *,
+                                           EMACS_INT));
+static INLINE void produce_charset P_ ((struct coding_system *, int *,
+                                       EMACS_INT));
+static void produce_annotation P_ ((struct coding_system *, EMACS_INT));
+static int decode_coding P_ ((struct coding_system *));
+static INLINE int *handle_composition_annotation P_ ((EMACS_INT, EMACS_INT,
+                                                     struct coding_system *, 
+                                                     int *, EMACS_INT *));
+static INLINE int *handle_charset_annotation P_ ((EMACS_INT, EMACS_INT,
+                                                 struct coding_system *,
+                                                 int *, EMACS_INT *));
+static void consume_chars P_ ((struct coding_system *, Lisp_Object, int));
+static int encode_coding P_ ((struct coding_system *));
+static Lisp_Object make_conversion_work_buffer P_ ((int));
+static Lisp_Object code_conversion_restore P_ ((Lisp_Object));
+static INLINE int char_encodable_p P_ ((int, Lisp_Object));
+static Lisp_Object make_subsidiaries P_ ((Lisp_Object));
+
 static void
 record_conversion_result (struct coding_system *coding,
                          enum coding_result_code result)
@@ -1311,7 +1349,10 @@ encode_coding_utf_8 (coding)
        {
          ASSURE_DESTINATION (safe_room);
          c = *charbuf++;
-         dst += CHAR_STRING (c, dst);
+         if (CHAR_BYTE8_P (c))
+           *dst++ = CHAR_TO_BYTE8 (c);
+         else
+           dst += CHAR_STRING (c, dst);
          produced_chars++;
        }
     }
@@ -1377,26 +1418,6 @@ detect_coding_utf_16 (coding, detect_info)
     }
   else if (c1 >= 0 && c2 >= 0)
     {
-      unsigned char b1[256], b2[256];
-      int b1_variants = 1, b2_variants = 1;
-      int n;
-
-      bzero (b1, 256), bzero (b2, 256);
-      b1[c1]++, b2[c2]++;
-      for (n = 0; n < 256 && src < src_end; n++)
-       {
-         src_base = src;
-         ONE_MORE_BYTE (c1);
-         ONE_MORE_BYTE (c2);
-         if (c1 < 0 || c2 < 0)
-           break;
-         if (! b1[c1++]) b1_variants++;
-         if (! b2[c2++]) b2_variants++;
-       }
-      if (b1_variants < b2_variants)
-       detect_info->found |= CATEGORY_MASK_UTF_16_BE_NOSIG;
-      else
-       detect_info->found |= CATEGORY_MASK_UTF_16_LE_NOSIG;      
       detect_info->rejected
        |= (CATEGORY_MASK_UTF_16_BE | CATEGORY_MASK_UTF_16_LE);
     }
@@ -1676,7 +1697,7 @@ emacs_mule_char (coding, src, nbytes, nchars, id)
          if (! (charset = emacs_mule_charset[c]))
            goto invalid_code;
          ONE_MORE_BYTE (c);
-         if (c < 0)
+         if (c < 0xA0)
            goto invalid_code;
          code = c & 0x7F;
          break;
@@ -1686,10 +1707,10 @@ emacs_mule_char (coding, src, nbytes, nchars, id)
              || c == EMACS_MULE_LEADING_CODE_PRIVATE_12)
            {
              ONE_MORE_BYTE (c);
-             if (c < 0 || ! (charset = emacs_mule_charset[c]))
+             if (c < 0xA0 || ! (charset = emacs_mule_charset[c]))
                goto invalid_code;
              ONE_MORE_BYTE (c);
-             if (c < 0)
+             if (c < 0xA0)
                goto invalid_code;
              code = c & 0x7F;
            }
@@ -1698,11 +1719,11 @@ emacs_mule_char (coding, src, nbytes, nchars, id)
              if (! (charset = emacs_mule_charset[c]))
                goto invalid_code;
              ONE_MORE_BYTE (c);
-             if (c < 0)
+             if (c < 0xA0)
                goto invalid_code;
              code = (c & 0x7F) << 8;
              ONE_MORE_BYTE (c);
-             if (c < 0)
+             if (c < 0xA0)
                goto invalid_code;
              code |= c & 0x7F;
            }
@@ -1713,11 +1734,11 @@ emacs_mule_char (coding, src, nbytes, nchars, id)
          if (c < 0 || ! (charset = emacs_mule_charset[c]))
            goto invalid_code;
          ONE_MORE_BYTE (c);
-         if (c < 0)
+         if (c < 0xA0)
            goto invalid_code;
          code = (c & 0x7F) << 8;
          ONE_MORE_BYTE (c);
-         if (c < 0)
+         if (c < 0xA0)
            goto invalid_code;
          code |= c & 0x7F;
          break;
@@ -2689,7 +2710,8 @@ detect_coding_iso_2022 (coding, detect_info)
 }
 
 
-/* Set designation state into CODING.  */
+/* Set designation state into CODING.  Set CHARS_96 to -1 if the
+   escape sequence should be kept.  */
 #define DECODE_DESIGNATION(reg, dim, chars_96, final)                  \
   do {                                                                 \
     int id, prev;                                                      \
@@ -2699,7 +2721,8 @@ detect_coding_iso_2022 (coding, detect_info)
        || !SAFE_CHARSET_P (coding, id))                                \
       {                                                                        \
        CODING_ISO_DESIGNATION (coding, reg) = -2;                      \
-       goto invalid_code;                                              \
+       chars_96 = -1;                                                  \
+       break;                                                          \
       }                                                                        \
     prev = CODING_ISO_DESIGNATION (coding, reg);                       \
     if (id == charset_jisx0201_roman)                                  \
@@ -2717,7 +2740,7 @@ detect_coding_iso_2022 (coding, detect_info)
        designation is ASCII to REG, we should keep this designation    \
        sequence.  */                                                   \
     if (prev == -2 && id == charset_ascii)                             \
-      goto invalid_code;                                               \
+      chars_96 = -1;                                                   \
   } while (0)
 
 
@@ -2865,6 +2888,7 @@ decode_coding_iso_2022 (coding)
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
   int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
   int charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
+  int charset_id_2, charset_id_3;
   struct charset *charset;
   int c;
   /* For handling composition sequence.  */
@@ -2936,7 +2960,10 @@ decode_coding_iso_2022 (coding)
                  continue;
                }
            }
-         charset = CHARSET_FROM_ID (charset_id_0);
+         if (charset_id_0 < 0)
+           charset = CHARSET_FROM_ID (charset_ascii);
+         else
+           charset = CHARSET_FROM_ID (charset_id_0);
          break;
 
        case ISO_0xA0_or_0xFF:
@@ -3017,27 +3044,36 @@ decode_coding_iso_2022 (coding)
            case '$':           /* designation of 2-byte character set */
              if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
                goto invalid_code;
-             ONE_MORE_BYTE (c1);
-             if (c1 >= '@' && c1 <= 'B')
-               {       /* designation of JISX0208.1978, GB2312.1980,
+             {
+               int reg, chars96;
+
+               ONE_MORE_BYTE (c1);
+               if (c1 >= '@' && c1 <= 'B')
+                 {     /* designation of JISX0208.1978, GB2312.1980,
                           or JISX0208.1980 */
-                 DECODE_DESIGNATION (0, 2, 0, c1);
-               }
-             else if (c1 >= 0x28 && c1 <= 0x2B)
-               {       /* designation of DIMENSION2_CHARS94 character set */
-                 ONE_MORE_BYTE (c2);
-                 DECODE_DESIGNATION (c1 - 0x28, 2, 0, c2);
-               }
-             else if (c1 >= 0x2C && c1 <= 0x2F)
-               {       /* designation of DIMENSION2_CHARS96 character set */
-                 ONE_MORE_BYTE (c2);
-                 DECODE_DESIGNATION (c1 - 0x2C, 2, 1, c2);
-               }
-             else
-               goto invalid_code;
-             /* We must update these variables now.  */
-             charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
-             charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
+                   reg = 0, chars96 = 0;
+                 }
+               else if (c1 >= 0x28 && c1 <= 0x2B)
+                 { /* designation of DIMENSION2_CHARS94 character set */
+                   reg = c1 - 0x28, chars96 = 0;
+                   ONE_MORE_BYTE (c1);
+                 }
+               else if (c1 >= 0x2C && c1 <= 0x2F)
+                 { /* designation of DIMENSION2_CHARS96 character set */
+                   reg = c1 - 0x2C, chars96 = 1;
+                   ONE_MORE_BYTE (c1);
+                 }
+               else
+                 goto invalid_code;
+               DECODE_DESIGNATION (reg, 2, chars96, c1);
+               /* We must update these variables now.  */
+               if (reg == 0)
+                 charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
+               else if (reg == 1)
+                 charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
+               if (chars96 < 0)
+                 goto invalid_code;
+             }
              continue;
 
            case 'n':           /* invocation of locking-shift-2 */
@@ -3060,7 +3096,11 @@ decode_coding_iso_2022 (coding)
              if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
                  || CODING_ISO_DESIGNATION (coding, 2) < 0)
                goto invalid_code;
-             charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 2));
+             charset_id_2 = CODING_ISO_DESIGNATION (coding, 2);
+             if (charset_id_2 < 0)
+               charset = CHARSET_FROM_ID (charset_ascii);
+             else
+               charset = CHARSET_FROM_ID (charset_id_2);
              ONE_MORE_BYTE (c1);
              if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
                goto invalid_code;
@@ -3070,7 +3110,11 @@ decode_coding_iso_2022 (coding)
              if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
                  || CODING_ISO_DESIGNATION (coding, 3) < 0)
                goto invalid_code;
-             charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 3));
+             charset_id_3 = CODING_ISO_DESIGNATION (coding, 3);
+             if (charset_id_3 < 0)
+               charset = CHARSET_FROM_ID (charset_ascii);
+             else
+               charset = CHARSET_FROM_ID (charset_id_3);
              ONE_MORE_BYTE (c1);
              if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
                goto invalid_code;
@@ -3171,7 +3215,10 @@ decode_coding_iso_2022 (coding)
                          && src + 1 < src_end
                          && src[0] == '%'
                          && src[1] == '@')
-                       break;
+                       {
+                         src += 2;
+                         break;
+                       }
                      *p++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
                    }
                  if (p + 3 > charbuf_end)
@@ -3189,21 +3236,30 @@ decode_coding_iso_2022 (coding)
            default:
              if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
                goto invalid_code;
-             if (c1 >= 0x28 && c1 <= 0x2B)
-               {       /* designation of DIMENSION1_CHARS94 character set */
-                 ONE_MORE_BYTE (c2);
-                 DECODE_DESIGNATION (c1 - 0x28, 1, 0, c2);
-               }
-             else if (c1 >= 0x2C && c1 <= 0x2F)
-               {       /* designation of DIMENSION1_CHARS96 character set */
-                 ONE_MORE_BYTE (c2);
-                 DECODE_DESIGNATION (c1 - 0x2C, 1, 1, c2);
-               }
-             else
-               goto invalid_code;
-             /* We must update these variables now.  */
-             charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
-             charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
+             {
+               int reg, chars96;
+
+               if (c1 >= 0x28 && c1 <= 0x2B)
+                 { /* designation of DIMENSION1_CHARS94 character set */
+                   reg = c1 - 0x28, chars96 = 0;
+                   ONE_MORE_BYTE (c1);
+                 }
+               else if (c1 >= 0x2C && c1 <= 0x2F)
+                 { /* designation of DIMENSION1_CHARS96 character set */
+                   reg = c1 - 0x2C, chars96 = 1;
+                   ONE_MORE_BYTE (c1);
+                 }
+               else
+                 goto invalid_code;
+               DECODE_DESIGNATION (reg, 1, chars96, c1);
+               /* We must update these variables now.  */
+               if (reg == 0)
+                 charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
+               else if (reg == 1)
+                 charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
+               if (chars96 < 0)
+                 goto invalid_code;
+             }
              continue;
            }
        }
@@ -5017,6 +5073,13 @@ setup_coding_system (coding_system, coding)
       coding->detector = NULL;
       coding->decoder = decode_coding_raw_text;
       coding->encoder = encode_coding_raw_text;
+      if (! EQ (eol_type, Qunix))
+       {
+         coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
+         if (! VECTORP (eol_type))
+           coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
+       }
+
     }
 
   return;
@@ -5209,11 +5272,11 @@ coding_inherit_eol_type (coding_system, parent)
 
 static int
 detect_eol (source, src_bytes, category)
-     unsigned char *source;
+     const unsigned char *source;
      EMACS_INT src_bytes;
      enum coding_category category;
 {
-  unsigned char *src = source, *src_end = src + src_bytes;
+  const unsigned char *src = source, *src_end = src + src_bytes;
   unsigned char c;
   int total  = 0;
   int eol_seen = EOL_SEEN_NONE;
@@ -5326,7 +5389,6 @@ detect_coding (coding)
      struct coding_system *coding;
 {
   const unsigned char *src, *src_end;
-  Lisp_Object attrs, coding_type;
 
   coding->consumed = coding->consumed_char = 0;
   coding->produced = coding->produced_char = 0;
@@ -5339,53 +5401,78 @@ detect_coding (coding)
   if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided))
     {
       int c, i;
+      struct coding_detection_info detect_info;
 
+      detect_info.checked = detect_info.found = detect_info.rejected = 0;
       for (i = 0, src = coding->source; src < src_end; i++, src++)
        {
          c = *src;
-         if (c & 0x80 || (c < 0x20 && (c == ISO_CODE_ESC
-                                       || c == ISO_CODE_SI
-                                       || c == ISO_CODE_SO)))
+         if (c & 0x80)
            break;
+         if (c < 0x20
+             && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)
+             && ! inhibit_iso_escape_detection
+             && ! detect_info.checked)
+           {
+             coding->head_ascii = src - (coding->source + coding->consumed);
+             if (detect_coding_iso_2022 (coding, &detect_info))
+               {
+                 /* We have scanned the whole data.  */
+                 if (! (detect_info.rejected & CATEGORY_MASK_ISO_7_ELSE))
+                   /* We didn't find an 8-bit code.  */
+                   src = src_end;
+                 break;
+               }
+           }
        }
       coding->head_ascii = src - (coding->source + coding->consumed);
 
-      if (coding->head_ascii < coding->src_bytes)
+      if (coding->head_ascii < coding->src_bytes
+         || detect_info.found)
        {
-         struct coding_detection_info detect_info;
          enum coding_category category;
          struct coding_system *this;
 
-         detect_info.checked = detect_info.found = detect_info.rejected = 0;
-         for (i = 0; i < coding_category_raw_text; i++)
-           {
-             category = coding_priorities[i];
-             this = coding_categories + category;
-             if (this->id < 0)
-               {
-                 /* No coding system of this category is defined.  */
-                 detect_info.rejected |= (1 << category);
-               }
-             else if (category >= coding_category_raw_text)
-               continue;
-             else if (detect_info.checked & (1 << category))
-               {
-                 if (detect_info.found & (1 << category))
-                   break;
-               }
-             else if ((*(this->detector)) (coding, &detect_info)
-                      && detect_info.found & (1 << category))
-               {
-                 if (category == coding_category_utf_16_auto)
-                   {
-                     if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
-                       category = coding_category_utf_16_le;
-                     else
-                       category = coding_category_utf_16_be;
-                   }
+         if (coding->head_ascii == coding->src_bytes)
+           /* As all bytes are 7-bit, we can ignore non-ISO-2022 codings.  */
+           for (i = 0; i < coding_category_raw_text; i++)
+             {
+               category = coding_priorities[i];
+               this = coding_categories + category;
+               if (detect_info.found & (1 << category))
                  break;
-               }
-           }
+             }
+         else
+           for (i = 0; i < coding_category_raw_text; i++)
+             {
+               category = coding_priorities[i];
+               this = coding_categories + category;
+               if (this->id < 0)
+                 {
+                   /* No coding system of this category is defined.  */
+                   detect_info.rejected |= (1 << category);
+                 }
+               else if (category >= coding_category_raw_text)
+                 continue;
+               else if (detect_info.checked & (1 << category))
+                 {
+                   if (detect_info.found & (1 << category))
+                     break;
+                 }
+               else if ((*(this->detector)) (coding, &detect_info)
+                        && detect_info.found & (1 << category))
+                 {
+                   if (category == coding_category_utf_16_auto)
+                     {
+                       if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
+                         category = coding_category_utf_16_le;
+                       else
+                         category = coding_category_utf_16_be;
+                     }
+                   break;
+                 }
+             }
+         
          if (i < coding_category_raw_text)
            setup_coding_system (CODING_ID_NAME (this->id), coding);
          else if (detect_info.rejected == CATEGORY_MASK_ANY)
@@ -5878,11 +5965,14 @@ produce_composition (coding, charbuf, pos)
 
   len = -charbuf[0];
   to = pos + charbuf[2];
+  if (to <= pos)
+    return;
   method = (enum composition_method) (charbuf[3]);
 
   if (method == COMPOSITION_RELATIVE)
     components = Qnil;
-  else
+  else if (method >= COMPOSITION_WITH_RULE
+          && method <= COMPOSITION_WITH_RULE_ALTCHARS)
     {
       Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
       int i;
@@ -5890,10 +5980,16 @@ produce_composition (coding, charbuf, pos)
       len -= 4;
       charbuf += 4;
       for (i = 0; i < len; i++)
-       args[i] = make_number (charbuf[i]);
+       {
+         args[i] = make_number (charbuf[i]);
+         if (args[i] < 0)
+           return;
+       }
       components = (method == COMPOSITION_WITH_ALTCHARS
                    ? Fstring (len, args) : Fvector (len, args));
     }
+  else
+    return;
   compose_text (pos, to, components, Qnil, coding->dst_object);
 }
 
@@ -6085,7 +6181,7 @@ decode_coding (coding)
 
              coding->charbuf[coding->charbuf_used++] = (c & 0x80 ? - c : c);
            }
-         produce_chars (coding);
+         produce_chars (coding, Qnil, 1);
        }
       else
        {
@@ -6297,11 +6393,12 @@ consume_chars (coding, translation_table, max_lookup)
        {
          EMACS_INT bytes;
 
-         if (! CODING_FOR_UNIBYTE (coding)
-             && (bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
+         if (coding->encoder == encode_coding_raw_text)
+           c = *src++, pos++;
+         else if ((bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
            c = STRING_CHAR_ADVANCE (src), pos += bytes;
          else
-           c = *src++, pos++;
+           c = BYTE8_TO_CHAR (*src), src++, pos++;
        }
       else
        c = STRING_CHAR_ADVANCE (src), pos++;
@@ -6383,7 +6480,10 @@ encode_coding (coding)
   int max_lookup;
 
   attrs = CODING_ID_ATTRS (coding->id);
-  translation_table = get_translation_table (attrs, 1, &max_lookup);
+  if (coding->encoder == encode_coding_raw_text)
+    translation_table = Qnil, max_lookup = 0;
+  else
+    translation_table = get_translation_table (attrs, 1, &max_lookup);
 
   if (BUFFERP (coding->dst_object))
     {
@@ -6430,8 +6530,9 @@ static int reused_workbuf_in_use;
 /* Return a working buffer of code convesion.  MULTIBYTE specifies the
    multibyteness of returning buffer.  */
 
-Lisp_Object
+static Lisp_Object
 make_conversion_work_buffer (multibyte)
+     int multibyte;
 {
   Lisp_Object name, workbuf;
   struct buffer *current;
@@ -6950,7 +7051,9 @@ If the user enters null input, return second argument DEFAULT-CODING-SYSTEM.  */
 DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,
        1, 1, 0,
        doc: /* Check validity of CODING-SYSTEM.
-If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.  */)
+If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.
+It is valid if it is nil or a symbol defined as a coding system by the
+function `define-coding-system'.  */)
   (coding_system)
      Lisp_Object coding_system;
 {
@@ -7022,49 +7125,73 @@ detect_coding_system (src, src_chars, src_bytes, highest, multibytep,
       for (i = 0; src < src_end; i++, src++)
        {
          c = *src;
-         if (c & 0x80 || (c < 0x20 && (c == ISO_CODE_ESC
-                                       || c == ISO_CODE_SI
-                                       || c == ISO_CODE_SO)))
+         if (c & 0x80)
            break;
+         if (c < 0x20
+             && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)
+             && inhibit_iso_escape_detection)
+           {
+             coding.head_ascii = src - coding.source;
+             if (detect_coding_iso_2022 (&coding, &detect_info))
+               {
+                 /* We have scanned the whole data.  */
+                 if (! (detect_info.rejected & CATEGORY_MASK_ISO_7_ELSE))
+                   /* We didn't find an 8-bit code.  */
+                   src = src_end;
+                 break;
+               }
+           }
        }
       coding.head_ascii = src - coding.source;
 
-      if (src < src_end)
-       for (i = 0; i < coding_category_raw_text; i++)
-         {
-           category = coding_priorities[i];
-           this = coding_categories + category;
-
-           if (this->id < 0)
-             {
-               /* No coding system of this category is defined.  */
-               detect_info.rejected |= (1 << category);
-             }
-           else if (category >= coding_category_raw_text)
-             continue;
-           else if (detect_info.checked & (1 << category))
+      if (src < src_end
+         || detect_info.found)
+       {
+         if (src == src_end)
+           /* As all bytes are 7-bit, we can ignore non-ISO-2022 codings.  */
+           for (i = 0; i < coding_category_raw_text; i++)
              {
-               if (highest
-                   && (detect_info.found & (1 << category)))
+               category = coding_priorities[i];
+               if (detect_info.found & (1 << category))
                  break;
              }
-           else
+         else
+           for (i = 0; i < coding_category_raw_text; i++)
              {
-               if ((*(this->detector)) (&coding, &detect_info)
-                   && highest
-                   && (detect_info.found & (1 << category)))
+               category = coding_priorities[i];
+               this = coding_categories + category;
+
+               if (this->id < 0)
                  {
-                   if (category == coding_category_utf_16_auto)
+                   /* No coding system of this category is defined.  */
+                   detect_info.rejected |= (1 << category);
+                 }
+               else if (category >= coding_category_raw_text)
+                 continue;
+               else if (detect_info.checked & (1 << category))
+                 {
+                   if (highest
+                       && (detect_info.found & (1 << category)))
+                     break;
+                 }
+               else
+                 {
+                   if ((*(this->detector)) (&coding, &detect_info)
+                       && highest
+                       && (detect_info.found & (1 << category)))
                      {
-                       if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
-                         category = coding_category_utf_16_le;
-                       else
-                         category = coding_category_utf_16_be;
+                       if (category == coding_category_utf_16_auto)
+                         {
+                           if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
+                             category = coding_category_utf_16_le;
+                           else
+                             category = coding_category_utf_16_be;
+                         }
+                       break;
                      }
-                   break;
                  }
              }
-         }
+       }
 
       if (detect_info.rejected == CATEGORY_MASK_ANY)
        {
@@ -7127,7 +7254,6 @@ detect_coding_system (src, src_chars, src_bytes, highest, multibytep,
     {
       if (detect_coding_utf_16 (&coding, &detect_info))
        {
-         enum coding_category category;
          struct coding_system *this;
 
          if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
@@ -7412,7 +7538,7 @@ DEFUN ("find-coding-systems-region-internal",
        }
     }
 
-  safe_codings = Qnil;
+  safe_codings = list2 (Qraw_text, Qno_conversion);
   for (tail = coding_attrs_list; CONSP (tail); tail = XCDR (tail))
     if (! NILP (XCAR (tail)))
       safe_codings = Fcons (CODING_ATTR_BASE_NAME (XCAR (tail)), safe_codings);
@@ -8772,7 +8898,7 @@ DEFUN ("coding-system-put", Fcoding_system_put, Scoding_system_put,
   (coding_system, prop, val)
      Lisp_Object coding_system, prop, val;
 {
-  Lisp_Object spec, attrs, plist;
+  Lisp_Object spec, attrs;
 
   CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
   attrs = AREF (spec, 0);
@@ -9503,3 +9629,6 @@ emacs_strerror (error_number)
 }
 
 #endif /* emacs */
+
+/* arch-tag: 3a3a2b01-5ff6-4071-9afe-f5b808d9229d
+   (do not change this comment) */