From b843d1aed4ea675ca01d63df16958e206a911d19 Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Mon, 18 Oct 1999 01:36:35 +0000 Subject: [PATCH] (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. --- src/ChangeLog | 15 ++++++++++ src/coding.c | 79 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4ce465572b..e664129af3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +1999-10-08 Kenichi Handa + + * coding.c (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. + + * coding.c (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. + 1999-10-17 Miles Bader * editfns.c: Doc fix. diff --git a/src/coding.c b/src/coding.c index 5a4a4c8c9a..4bf0b2aea8 100644 --- a/src/coding.c +++ b/src/coding.c @@ -411,6 +411,12 @@ Lisp_Object Vcharset_revision_alist; /* 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 @@ setup_coding_system (coding_system, coding) `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 @@ static int shrink_conversion_region_threshhold = 1024; } \ } 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 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) 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 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) 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 @@ code_convert_string (str, coding, encodep, nocopy) 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 @@ init_coding_once () #else system_eol_type = CODING_EOL_LF; #endif + + inhibit_pre_post_conversion = 0; } #ifdef emacs -- 2.20.1