(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.
This commit is contained in:
Kenichi Handa 1999-10-18 01:36:35 +00:00
parent 600f9d0390
commit b843d1aed4
2 changed files with 74 additions and 20 deletions

View file

@ -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