Merge from emacs--devo--0
[bpt/emacs.git] / src / coding.c
index 3efce13..d3a82ae 100644 (file)
@@ -1,7 +1,8 @@
 /* Coding system handler (conversion, detection, etc).
    Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                 2006 Free Software Foundation, Inc.
-   Copyright (C) 1995, 1997, 1998, 2002, 2003, 2004, 2005
+                 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+     2005, 2006, 2007
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H14PRO021
    Copyright (C) 2003
@@ -877,7 +878,7 @@ 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));
+                                           EMACS_INT, EMACS_INT));
 static unsigned char *alloc_destination P_ ((struct coding_system *,
                                             EMACS_INT, unsigned char *));
 static void setup_iso_safe_charsets P_ ((Lisp_Object));
@@ -1033,18 +1034,20 @@ coding_alloc_by_realloc (coding, bytes)
 }
 
 static void
-coding_alloc_by_making_gap (coding, bytes)
+coding_alloc_by_making_gap (coding, offset, bytes)
      struct coding_system *coding;
-     EMACS_INT bytes;
+     EMACS_INT offset, bytes;
 {
   if (BUFFERP (coding->dst_object)
       && EQ (coding->src_object, coding->dst_object))
     {
-      EMACS_INT add = coding->src_bytes - coding->consumed;
+      EMACS_INT add = offset + (coding->src_bytes - coding->consumed);
 
+      GPT += offset, GPT_BYTE += offset;
       GAP_SIZE -= add; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
       make_gap (bytes);
       GAP_SIZE += add; ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
+      GPT -= offset, GPT_BYTE -= offset;
     }
   else
     {
@@ -1067,7 +1070,7 @@ alloc_destination (coding, nbytes, dst)
   EMACS_INT offset = dst - coding->destination;
 
   if (BUFFERP (coding->dst_object))
-    coding_alloc_by_making_gap (coding, nbytes);
+    coding_alloc_by_making_gap (coding, offset, nbytes);
   else
     coding_alloc_by_realloc (coding, nbytes);
   record_conversion_result (coding, CODING_RESULT_SUCCESS);
@@ -2948,6 +2951,9 @@ decode_coding_iso_2022 (coding)
 
   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 = (char *) SDATA (CODING_ATTR_SAFE_CHARSETS(attrs));
 
   while (1)
     {
@@ -3806,7 +3812,7 @@ encode_coding_iso_2022 (coding)
 
   setup_iso_safe_charsets (attrs);
   /* Charset list may have been changed.  */
-  charset_list = CODING_ATTR_CHARSET_LIST (attrs);             \
+  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   coding->safe_charsets = (char *) SDATA (CODING_ATTR_SAFE_CHARSETS(attrs));
 
   ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
@@ -4731,6 +4737,7 @@ detect_coding_charset (coding, detect_info)
   int consumed_chars = 0;
   Lisp_Object attrs, valids;
   int found = 0;
+  int head_ascii = coding->head_ascii;
 
   detect_info->checked |= CATEGORY_MASK_CHARSET;
 
@@ -4739,21 +4746,68 @@ detect_coding_charset (coding, detect_info)
   valids = AREF (attrs, coding_attr_charset_valids);
 
   if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
-    src += coding->head_ascii;
+    src += head_ascii;
 
   while (1)
     {
       int c;
+      Lisp_Object val;
+      struct charset *charset;
+      int dim, idx;
 
       src_base = src;
       ONE_MORE_BYTE (c);
       if (c < 0)
        continue;
-      if (NILP (AREF (valids, c)))
+      val = AREF (valids, c);
+      if (NILP (val))
        break;
       if (c >= 0x80)
        found = CATEGORY_MASK_CHARSET;
+      if (INTEGERP (val))
+       {
+         charset = CHARSET_FROM_ID (XFASTINT (val));
+         dim = CHARSET_DIMENSION (charset);
+         for (idx = 1; idx < dim; idx++)
+           {
+             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])
+               break;
+           }
+         if (idx < dim)
+           break;
+       }
+      else
+       {
+         idx = 1;
+         for (; CONSP (val); val = XCDR (val))
+           {
+             charset = CHARSET_FROM_ID (XFASTINT (XCAR (val)));
+             dim = CHARSET_DIMENSION (charset);
+             while (idx < dim)
+               {
+                 if (src == src_end)
+                   goto too_short;
+                 ONE_MORE_BYTE (c);
+                 if (c < charset->code_space[(dim - 1 - idx) * 4]
+                     || c > charset->code_space[(dim - 1 - idx) * 4 + 1])
+                   break;
+                 idx++;
+               }
+             if (idx == dim)
+               {
+                 val = Qnil;
+                 break;
+               }
+           }
+         if (CONSP (val))
+           break;
+       }
     }
+ too_short:
   detect_info->rejected |= CATEGORY_MASK_CHARSET;
   return 0;
 
@@ -6707,7 +6761,9 @@ decode_coding_gap (coding, chars, bytes)
     detect_coding (coding);
 
   coding->mode |= CODING_MODE_LAST_BLOCK;
+  current_buffer->text->inhibit_shrinking = 1;
   decode_coding (coding);
+  current_buffer->text->inhibit_shrinking = 0;
 
   attrs = CODING_ID_ATTRS (coding->id);
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
@@ -8136,7 +8192,7 @@ Return the corresponding character.  */)
 
 
 DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,
-       doc: /* Encode a Japanese character CHAR to shift_jis encoding.
+       doc: /* Encode a Japanese character CH to shift_jis encoding.
 Return the corresponding code in SJIS.  */)
      (ch)
     Lisp_Object ch;
@@ -8204,7 +8260,7 @@ Return the corresponding character.  */)
 }
 
 DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,
-       doc: /* Encode the Big5 character CHAR to BIG5 coding system.
+       doc: /* Encode the Big5 character CH to BIG5 coding system.
 Return the corresponding character code in Big5.  */)
      (ch)
      Lisp_Object ch;