changeset 26067:f54ca66e2571

(code_convert_string): Add record_unwind_protect to assure setting inhibit_pre_post_conversion back to zero. Take care of the multibyteness of the working buffer. (inhibit_pre_post_conversion): New variable. (setup_coding_system): If inhibit_pre_post_conversion is nonzero, ignore post-read-conversion and pre-write-conversion property of the coding system. (code_convert_region_unwind): New function. (code_convert_region): Set inhibit_pre_post_conversion to 1 while running pre-write-conversion and post-read-conversion. (code_convert_string): Likewise.
author Kenichi Handa <handa@m17n.org>
date Mon, 18 Oct 1999 01:35:54 +0000
parents 7087c5dd25b6
children 3803a546186f
files src/coding.c
diffstat 1 files changed, 60 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/coding.c	Sun Oct 17 16:48:22 1999 +0000
+++ b/src/coding.c	Mon Oct 18 01:35:54 1999 +0000
@@ -411,6 +411,12 @@
 /* Default coding systems used for process I/O.  */
 Lisp_Object Vdefault_process_coding_system;
 
+/* Global flag to tell that we can't call post-read-conversion and
+   pre-write-conversion functions.  Usually the value is zero, but it
+   is set to 1 temporarily while such functions are running.  This is
+   to avoid infinite recursive call.  */
+static int inhibit_pre_post_conversion;
+
 
 /*** 2. Emacs internal format (emacs-mule) handlers ***/
 
@@ -2941,8 +2947,14 @@
      `post-read-conversion', `pre-write-conversion',
      `translation-table-for-decode', `translation-table-for-encode'.  */
   plist = XVECTOR (coding_spec)->contents[3];
-  coding->post_read_conversion = Fplist_get (plist, Qpost_read_conversion);
-  coding->pre_write_conversion = Fplist_get (plist, Qpre_write_conversion);
+  /* Pre & post conversion functions should be disabled if
+     inhibit_eol_conversion is nozero.  This is the case that a code
+     conversion function is called while those functions are running.  */
+  if (! inhibit_pre_post_conversion)
+    {
+      coding->post_read_conversion = Fplist_get (plist, Qpost_read_conversion);
+      coding->pre_write_conversion = Fplist_get (plist, Qpre_write_conversion);
+    }
   val = Fplist_get (plist, Qtranslation_table_for_decode);
   if (SYMBOLP (val))
     val = Fget (val, Qtranslation_table_for_decode);
@@ -4221,6 +4233,14 @@
       }									\
   } while (0)
 
+static Lisp_Object
+code_convert_region_unwind (dummy)
+     Lisp_Object dummy;
+{
+  inhibit_pre_post_conversion = 0;
+  return Qnil;
+}
+
 /* Decode (if ENCODEP is zero) or encode (if ENCODEP is nonzero) the
    text from FROM to TO (byte positions are FROM_BYTE and TO_BYTE) by
    coding system CODING, and return the status code of code conversion
@@ -4345,9 +4365,18 @@
          new buffer.  */
       struct buffer *prev = current_buffer;
       Lisp_Object new;
-
+      int count = specpdl_ptr - specpdl;
+
+      record_unwind_protect (code_convert_region_unwind, 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;
       call2 (coding->pre_write_conversion,
 	     make_number (from), make_number (to));
+      inhibit_pre_post_conversion = 0;
+      /* Discard the unwind protect.  */
+      specpdl_ptr--;
+
       if (current_buffer != prev)
 	{
 	  len = ZV - BEGV;
@@ -4626,11 +4655,19 @@
   if (! encodep && ! NILP (coding->post_read_conversion))
     {
       Lisp_Object val;
+      int count = specpdl_ptr - specpdl;
 
       if (from != PT)
 	TEMP_SET_PT_BOTH (from, from_byte);
       prev_Z = Z;
+      record_unwind_protect (code_convert_region_unwind, Qnil);
+      /* We should not call any more pre-write/post-read-conversion
+         functions while this post-read-conversion is running.  */
+      inhibit_pre_post_conversion = 1;
       val = call1 (coding->post_read_conversion, make_number (inserted));
+      inhibit_pre_post_conversion = 0;
+      /* Discard the unwind protect.  */
+      specpdl_ptr--;
       CHECK_NUMBER (val, 0);
       inserted += Z - prev_Z;
     }
@@ -4671,34 +4708,34 @@
   int result;
 
   saved_coding_symbol = Qnil;
-  if (encodep && !NILP (coding->pre_write_conversion)
-      || !encodep && !NILP (coding->post_read_conversion))
+  if ((encodep && !NILP (coding->pre_write_conversion)
+       || !encodep && !NILP (coding->post_read_conversion)))
     {
       /* Since we have to call Lisp functions which assume target text
-         is in a buffer, after setting a temporary buffer, call
-         code_convert_region.  */
+	 is in a buffer, after setting a temporary buffer, call
+	 code_convert_region.  */
       int count = specpdl_ptr - specpdl;
       struct buffer *prev = current_buffer;
+      int multibyte = STRING_MULTIBYTE (str);
 
       record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+      record_unwind_protect (code_convert_region_unwind, Qnil);
+      inhibit_pre_post_conversion = 1;
+      GCPRO1 (str);
       temp_output_buffer_setup (" *code-converting-work*");
       set_buffer_internal (XBUFFER (Vstandard_output));
-      if (encodep)
-	insert_from_string (str, 0, 0, to, to_byte, 0);
-      else
-	{
-	  /* We must insert the contents of STR as is without
-             unibyte<->multibyte conversion.  */
-	  current_buffer->enable_multibyte_characters = Qnil;
-	  insert_from_string (str, 0, 0, to_byte, to_byte, 0);
-	  current_buffer->enable_multibyte_characters = Qt;
-	}
+      /* 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.  */
+      Ferase_buffer ();		/* for safety */
+      current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil;
+      insert_from_string (str, 0, 0, to, to_byte, 0);
+      UNGCPRO;
       code_convert_region (BEGV, BEGV_BYTE, ZV, ZV_BYTE, coding, encodep, 1);
-      if (encodep)
-	/* We must return the buffer contents as unibyte string.  */
-	current_buffer->enable_multibyte_characters = Qnil;
+      /* Make a unibyte string if we are encoding, otherwise make a
+         multibyte string.  */
+      Fset_buffer_multibyte (encodep ? Qnil : Qt);
       str = make_buffer_string (BEGV, ZV, 0);
-      set_buffer_internal (prev);
       return unbind_to (count, str);
     }
 
@@ -5493,6 +5530,8 @@
 #else
   system_eol_type = CODING_EOL_LF;
 #endif
+
+  inhibit_pre_post_conversion = 0;
 }
 
 #ifdef emacs