Commit b843d1ae authored by Kenichi Handa's avatar Kenichi Handa
Browse files

(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.
parent 600f9d03
No preview for this file type
...@@ -411,6 +411,12 @@ Lisp_Object Vcharset_revision_alist; ...@@ -411,6 +411,12 @@ Lisp_Object Vcharset_revision_alist;
/* Default coding systems used for process I/O. */ /* Default coding systems used for process I/O. */
Lisp_Object Vdefault_process_coding_system; 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 ***/ /*** 2. Emacs internal format (emacs-mule) handlers ***/
...@@ -2941,8 +2947,14 @@ setup_coding_system (coding_system, coding) ...@@ -2941,8 +2947,14 @@ setup_coding_system (coding_system, coding)
`post-read-conversion', `pre-write-conversion', `post-read-conversion', `pre-write-conversion',
`translation-table-for-decode', `translation-table-for-encode'. */ `translation-table-for-decode', `translation-table-for-encode'. */
plist = XVECTOR (coding_spec)->contents[3]; plist = XVECTOR (coding_spec)->contents[3];
coding->post_read_conversion = Fplist_get (plist, Qpost_read_conversion); /* Pre & post conversion functions should be disabled if
coding->pre_write_conversion = Fplist_get (plist, Qpre_write_conversion); 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); val = Fplist_get (plist, Qtranslation_table_for_decode);
if (SYMBOLP (val)) if (SYMBOLP (val))
val = Fget (val, Qtranslation_table_for_decode); val = Fget (val, Qtranslation_table_for_decode);
...@@ -4221,6 +4233,14 @@ static int shrink_conversion_region_threshhold = 1024; ...@@ -4221,6 +4233,14 @@ static int shrink_conversion_region_threshhold = 1024;
} \ } \
} while (0) } 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 /* 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 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 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) ...@@ -4345,9 +4365,18 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
new buffer. */ new buffer. */
struct buffer *prev = current_buffer; struct buffer *prev = current_buffer;
Lisp_Object new; 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, call2 (coding->pre_write_conversion,
make_number (from), make_number (to)); make_number (from), make_number (to));
inhibit_pre_post_conversion = 0;
/* Discard the unwind protect. */
specpdl_ptr--;
if (current_buffer != prev) if (current_buffer != prev)
{ {
len = ZV - BEGV; len = ZV - BEGV;
...@@ -4626,11 +4655,19 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) ...@@ -4626,11 +4655,19 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
if (! encodep && ! NILP (coding->post_read_conversion)) if (! encodep && ! NILP (coding->post_read_conversion))
{ {
Lisp_Object val; Lisp_Object val;
int count = specpdl_ptr - specpdl;
if (from != PT) if (from != PT)
TEMP_SET_PT_BOTH (from, from_byte); TEMP_SET_PT_BOTH (from, from_byte);
prev_Z = Z; 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)); val = call1 (coding->post_read_conversion, make_number (inserted));
inhibit_pre_post_conversion = 0;
/* Discard the unwind protect. */
specpdl_ptr--;
CHECK_NUMBER (val, 0); CHECK_NUMBER (val, 0);
inserted += Z - prev_Z; inserted += Z - prev_Z;
} }
...@@ -4671,34 +4708,34 @@ code_convert_string (str, coding, encodep, nocopy) ...@@ -4671,34 +4708,34 @@ code_convert_string (str, coding, encodep, nocopy)
int result; int result;
saved_coding_symbol = Qnil; saved_coding_symbol = Qnil;
if (encodep && !NILP (coding->pre_write_conversion) if ((encodep && !NILP (coding->pre_write_conversion)
|| !encodep && !NILP (coding->post_read_conversion)) || !encodep && !NILP (coding->post_read_conversion)))
{ {
/* Since we have to call Lisp functions which assume target text /* Since we have to call Lisp functions which assume target text
is in a buffer, after setting a temporary buffer, call is in a buffer, after setting a temporary buffer, call
code_convert_region. */ code_convert_region. */
int count = specpdl_ptr - specpdl; int count = specpdl_ptr - specpdl;
struct buffer *prev = current_buffer; struct buffer *prev = current_buffer;
int multibyte = STRING_MULTIBYTE (str);
record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); 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*"); temp_output_buffer_setup (" *code-converting-work*");
set_buffer_internal (XBUFFER (Vstandard_output)); set_buffer_internal (XBUFFER (Vstandard_output));
if (encodep) /* We must insert the contents of STR as is without
insert_from_string (str, 0, 0, to, to_byte, 0); unibyte<->multibyte conversion. For that, we adjust the
else multibyteness of the working buffer to that of STR. */
{ Ferase_buffer (); /* for safety */
/* We must insert the contents of STR as is without current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil;
unibyte<->multibyte conversion. */ insert_from_string (str, 0, 0, to, to_byte, 0);
current_buffer->enable_multibyte_characters = Qnil; UNGCPRO;
insert_from_string (str, 0, 0, to_byte, to_byte, 0);
current_buffer->enable_multibyte_characters = Qt;
}
code_convert_region (BEGV, BEGV_BYTE, ZV, ZV_BYTE, coding, encodep, 1); code_convert_region (BEGV, BEGV_BYTE, ZV, ZV_BYTE, coding, encodep, 1);
if (encodep) /* Make a unibyte string if we are encoding, otherwise make a
/* We must return the buffer contents as unibyte string. */ multibyte string. */
current_buffer->enable_multibyte_characters = Qnil; Fset_buffer_multibyte (encodep ? Qnil : Qt);
str = make_buffer_string (BEGV, ZV, 0); str = make_buffer_string (BEGV, ZV, 0);
set_buffer_internal (prev);
return unbind_to (count, str); return unbind_to (count, str);
} }
...@@ -5493,6 +5530,8 @@ init_coding_once () ...@@ -5493,6 +5530,8 @@ init_coding_once ()
#else #else
system_eol_type = CODING_EOL_LF; system_eol_type = CODING_EOL_LF;
#endif #endif
inhibit_pre_post_conversion = 0;
} }
#ifdef emacs #ifdef emacs
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment