]> code.delx.au - gnu-emacs/blobdiff - src/coding.c
*** empty log message ***
[gnu-emacs] / src / coding.c
index 4ae1a25e8f02117d8a2fb8417c1e31c52cb56973..bd96b5cc068a5fec9b7b08dd62d2caa6cdb39f34 100644 (file)
@@ -1,7 +1,9 @@
 /* Coding system handler (conversion, detection, and etc).
-   Copyright (C) 1995,97,1998,2002,2003  Electrotechnical Laboratory, JAPAN.
-   Licensed to the Free Software Foundation.
-   Copyright (C) 2001,2002,2003  Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005,
+                 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1997, 1998, 2002, 2003, 2004, 2005
+     National Institute of Advanced Industrial Science and Technology (AIST)
+     Registration Number H14PRO021
 
 This file is part of GNU Emacs.
 
@@ -17,8 +19,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /*** TABLE OF CONTENTS ***
 
@@ -363,7 +365,7 @@ Lisp_Object Qsafe_chars;
 Lisp_Object Qvalid_codes;
 
 extern Lisp_Object Qinsert_file_contents, Qwrite_region;
-Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;
+Lisp_Object Qcall_process, Qcall_process_region;
 Lisp_Object Qstart_process, Qopen_network_stream;
 Lisp_Object Qtarget_idx;
 
@@ -733,7 +735,7 @@ detect_coding_emacs_mule (src, src_end, multibytep)
          c = -1;                                               \
        else                                                    \
          {                                                     \
-           c -= 0xA0;                                          \
+           c -= 0x80;                                          \
            *p++ = c;                                           \
          }                                                     \
       }                                                                \
@@ -871,7 +873,7 @@ decode_composition_emacs_mule (coding, src, src_end,
          component[ncomponent] = c;
        }
     }
-  else
+  else if (c >= 0x80)
     {
       /* This may be an old Emacs 20 style format.  See the comment at
         the section 2 of this file.  */
@@ -923,6 +925,8 @@ decode_composition_emacs_mule (coding, src, src_end,
       else
        return 0;
     }
+  else
+    return 0;
 
   if (buf == bufp || dst + (bufp - buf) <= (dst_bytes ? dst_end : src))
     {
@@ -3603,6 +3607,8 @@ setup_coding_system (coding_system, coding)
     {
       coding->eol_type = CODING_EOL_UNDECIDED;
       coding->common_flags = CODING_REQUIRE_DETECTION_MASK;
+      if (system_eol_type != CODING_EOL_LF)
+       coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
     }
   else if (XFASTINT (eol_type) == 1)
     {
@@ -3918,9 +3924,12 @@ setup_coding_system (coding_system, coding)
   coding->type = coding_type_no_conversion;
   coding->category_idx = CODING_CATEGORY_IDX_BINARY;
   coding->common_flags = 0;
-  coding->eol_type = CODING_EOL_LF;
+  coding->eol_type = NILP (coding_system) ? system_eol_type : CODING_EOL_LF;
+  if (coding->eol_type != CODING_EOL_LF)
+    coding->common_flags
+      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
   coding->pre_write_conversion = coding->post_read_conversion = Qnil;
-  return -1;
+  return NILP (coding_system) ? 0 : -1;
 }
 
 /* Free memory blocks allocated for storing composition information.  */
@@ -4994,6 +5003,8 @@ encode_coding (coding, source, destination, src_bytes, dst_bytes)
   coding->consumed = coding->consumed_char = 0;
   coding->errors = 0;
   coding->result = CODING_FINISH_NORMAL;
+  if (coding->eol_type == CODING_EOL_UNDECIDED)
+    coding->eol_type = system_eol_type;
 
   switch (coding->type)
     {
@@ -5250,6 +5261,8 @@ shrink_encoding_region (beg, end, coding, str)
   if (coding->type == coding_type_ccl
       || coding->eol_type == CODING_EOL_CRLF
       || coding->eol_type == CODING_EOL_CR
+      || (coding->eol_type == CODING_EOL_UNDECIDED
+         && system_eol_type != CODING_EOL_LF)
       || (coding->cmp_data && coding->cmp_data->used > 0))
     {
       /* We can't skip any data.  */
@@ -5353,12 +5366,22 @@ static int shrink_conversion_region_threshhold = 1024;
       }                                                                        \
   } while (0)
 
+/* ARG is (CODING BUFFER ...) where CODING is what to be set in
+   Vlast_coding_system_used and the remaining elements are buffers to
+   kill.  */
 static Lisp_Object
 code_convert_region_unwind (arg)
      Lisp_Object arg;
 {
+  struct gcpro gcpro1;
+  GCPRO1 (arg);
+
   inhibit_pre_post_conversion = 0;
-  Vlast_coding_system_used = arg;
+  Vlast_coding_system_used = XCAR (arg);
+  for (arg = XCDR (arg); ! NILP (arg); arg = XCDR (arg))
+    Fkill_buffer (XCAR (arg));
+
+  UNGCPRO;
   return Qnil;
 }
 
@@ -5611,7 +5634,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
       Lisp_Object new;
 
       record_unwind_protect (code_convert_region_unwind,
-                            Vlast_coding_system_used);
+                            Fcons (Vlast_coding_system_used, Qnil));
       /* We should not call any more pre-write/post-read-conversion
          functions while this pre-write-conversion is running.  */
       inhibit_pre_post_conversion = 1;
@@ -5979,7 +6002,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
        TEMP_SET_PT_BOTH (from, from_byte);
       prev_Z = Z;
       record_unwind_protect (code_convert_region_unwind,
-                            Vlast_coding_system_used);
+                            Fcons (Vlast_coding_system_used, Qnil));
       saved_coding_system = Vlast_coding_system_used;
       Vlast_coding_system_used = coding->symbol;
       /* We should not call any more pre-write/post-read-conversion
@@ -6025,17 +6048,31 @@ static Lisp_Object Vcode_conversion_workbuf_name;
 
 /* Set the current buffer to the working buffer prepared for
    code-conversion.  MULTIBYTE specifies the multibyteness of the
-   buffer.  */
+   buffer.  Return the buffer we set if it must be killed after use.
+   Otherwise return Qnil.  */
 
-static struct buffer *
+static Lisp_Object
 set_conversion_work_buffer (multibyte)
      int multibyte;
 {
-  Lisp_Object buffer;
+  Lisp_Object buffer, buffer_to_kill;
   struct buffer *buf;
 
   buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
   buf = XBUFFER (buffer);
+  if (buf == current_buffer)
+    {
+      /* As we are already in the work buffer, we must generate a new
+        buffer for the work.  */
+      Lisp_Object name;
+       
+      name = Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
+      buffer = buffer_to_kill = Fget_buffer_create (name);
+      buf = XBUFFER (buffer);
+    }
+  else
+    buffer_to_kill = Qnil;
+
   delete_all_overlays (buf);
   buf->directory = current_buffer->directory;
   buf->read_only = Qnil;
@@ -6048,7 +6085,7 @@ set_conversion_work_buffer (multibyte)
     Fwiden ();
   del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
   buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
-  return buf;
+  return buffer_to_kill;
 }
 
 Lisp_Object
@@ -6060,12 +6097,11 @@ run_pre_post_conversion_on_str (str, coding, encodep)
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2;
   int multibyte = STRING_MULTIBYTE (str);
-  struct buffer *buf;
   Lisp_Object old_deactivate_mark;
+  Lisp_Object buffer_to_kill;
+  Lisp_Object unwind_arg;
 
   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-  record_unwind_protect (code_convert_region_unwind,
-                        Vlast_coding_system_used);
   /* It is not crucial to specbind this.  */
   old_deactivate_mark = Vdeactivate_mark;
   GCPRO2 (str, old_deactivate_mark);
@@ -6073,14 +6109,26 @@ run_pre_post_conversion_on_str (str, coding, encodep)
   /* We must insert the contents of STR as is without
      unibyte<->multibyte conversion.  For that, we adjust the
      multibyteness of the working buffer to that of STR.  */
-  set_conversion_work_buffer (multibyte);
+  buffer_to_kill = set_conversion_work_buffer (multibyte);
+  if (NILP (buffer_to_kill))
+    unwind_arg = Fcons (Vlast_coding_system_used, Qnil);
+  else
+    unwind_arg = list2 (Vlast_coding_system_used, buffer_to_kill);
+  record_unwind_protect (code_convert_region_unwind, unwind_arg);
 
   insert_from_string (str, 0, 0,
                      SCHARS (str), SBYTES (str), 0);
   UNGCPRO;
   inhibit_pre_post_conversion = 1;
   if (encodep)
-    call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));
+    {
+      struct buffer *prev = current_buffer;
+
+      call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));
+      if (prev != current_buffer)
+       /* We must kill the current buffer too.  */
+       Fsetcdr (unwind_arg, Fcons (Fcurrent_buffer (), XCDR (unwind_arg)));
+    }
   else
     {
       Vlast_coding_system_used = coding->symbol;
@@ -6114,8 +6162,10 @@ run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
 {
   struct gcpro gcpro1, gcpro2;
   struct buffer *cur = current_buffer;
+  struct buffer *prev;
   Lisp_Object old_deactivate_mark, old_last_coding_system_used;
   Lisp_Object args[3];
+  Lisp_Object buffer_to_kill;
 
   /* It is not crucial to specbind this.  */
   old_deactivate_mark = Vdeactivate_mark;
@@ -6125,10 +6175,11 @@ run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
   /* We must insert the contents of STR as is without
      unibyte<->multibyte conversion.  For that, we adjust the
      multibyteness of the working buffer to that of STR.  */
-  set_conversion_work_buffer (coding->src_multibyte);
+  buffer_to_kill = set_conversion_work_buffer (coding->src_multibyte);
   insert_1_both (*str, nchars, nbytes, 0, 0, 0);
   UNGCPRO;
   inhibit_pre_post_conversion = 1;
+  prev = current_buffer;
   args[0] = coding->pre_write_conversion;
   args[1] = make_number (BEG);
   args[2] = make_number (Z);
@@ -6148,7 +6199,11 @@ run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
   bcopy (BEG_ADDR, *str, coding->produced);
   coding->src_multibyte
     = ! NILP (current_buffer->enable_multibyte_characters);
+  if (prev != current_buffer)
+    Fkill_buffer (Fcurrent_buffer ());
   set_buffer_internal (cur);
+  if (! NILP (buffer_to_kill))
+    Fkill_buffer (buffer_to_kill);
 }
 
 
@@ -6260,6 +6315,7 @@ decode_coding_string (str, coding, nocopy)
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
+         || result == CODING_FINISH_INTERRUPT
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
@@ -6675,7 +6731,7 @@ highest priority.  */)
                               STRING_MULTIBYTE (string));
 }
 
-/*  Subroutine for Fsafe_coding_systems_region_internal.
+/*  Subroutine for Ffind_coding_systems_region_internal.
 
     Return a list of coding systems that safely encode the multibyte
     text between P and PEND.  SAFE_CODINGS, if non-nil, is an alist of
@@ -7062,7 +7118,7 @@ code_convert_region1 (start, end, coding_system, encodep)
   from = XFASTINT (start);
   to = XFASTINT (end);
 
-  if (NILP (coding_system))
+  if (NILP (coding_system) && system_eol_type == CODING_EOL_LF)
     return make_number (to - from);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
@@ -7117,7 +7173,7 @@ code_convert_string1 (string, coding_system, nocopy, encodep)
   CHECK_STRING (string);
   CHECK_SYMBOL (coding_system);
 
-  if (NILP (coding_system))
+  if (NILP (coding_system) && system_eol_type == CODING_EOL_LF)
     return (NILP (nocopy) ? Fcopy_sequence (string) : string);
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
@@ -7176,7 +7232,7 @@ code_convert_string_norecord (string, coding_system, encodep)
   CHECK_STRING (string);
   CHECK_SYMBOL (coding_system);
 
-  if (NILP (coding_system))
+  if (NILP (coding_system) && system_eol_type == CODING_EOL_LF)
     return string;
 
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)