} \
else \
{ \
- *dst++ = (c); \
+ /* If ASCII charset is invoked to GR, \
+ we must reset MSB now. */ \
+ *dst++ = (c) & 0x7F; \
coding->produced_char++; \
- if ((c) >= 0x80) \
- coding->fake_multibyte = 1; \
} \
} while (0)
/* 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;
+
\f
/*** 2. Emacs internal format (emacs-mule) handlers ***/
dst = encode_invocation_designation (charset, coding, dst); \
} while (1)
-#define ENCODE_ISO_CHARACTER(charset, c1, c2) \
- do { \
- int c_alt, charset_alt; \
- if (!NILP (translation_table) \
- && ((c_alt = translate_char (translation_table, -1, \
- charset, c1, c2)) \
- >= 0)) \
- SPLIT_CHAR (c_alt, charset_alt, c1, c2); \
- else \
- charset_alt = charset; \
- if (CHARSET_DIMENSION (charset_alt) == 1) \
- { \
- if (charset == CHARSET_ASCII \
- && coding->flags & CODING_FLAG_ISO_USE_ROMAN) \
- charset_alt = charset_latin_jisx0201; \
- ENCODE_ISO_CHARACTER_DIMENSION1 (charset_alt, c1); \
- } \
- else \
- { \
- if (charset == charset_jisx0208 \
- && coding->flags & CODING_FLAG_ISO_USE_OLDJIS) \
- charset_alt = charset_jisx0208_1978; \
- ENCODE_ISO_CHARACTER_DIMENSION2 (charset_alt, c1, c2); \
- } \
- if (! COMPOSING_P (coding->composing)) \
- coding->consumed_char++; \
+#define ENCODE_ISO_CHARACTER(charset, c1, c2) \
+ do { \
+ int c_alt, charset_alt; \
+ if (!NILP (translation_table) \
+ && ((c_alt = translate_char (translation_table, -1, \
+ charset, c1, c2)) \
+ >= 0)) \
+ SPLIT_CHAR (c_alt, charset_alt, c1, c2); \
+ else \
+ charset_alt = charset; \
+ if (CHARSET_DEFINED_P (charset_alt)) \
+ { \
+ if (CHARSET_DIMENSION (charset_alt) == 1) \
+ { \
+ if (charset == CHARSET_ASCII \
+ && coding->flags & CODING_FLAG_ISO_USE_ROMAN) \
+ charset_alt = charset_latin_jisx0201; \
+ ENCODE_ISO_CHARACTER_DIMENSION1 (charset_alt, c1); \
+ } \
+ else \
+ { \
+ if (charset == charset_jisx0208 \
+ && coding->flags & CODING_FLAG_ISO_USE_OLDJIS) \
+ charset_alt = charset_jisx0208_1978; \
+ ENCODE_ISO_CHARACTER_DIMENSION2 (charset_alt, c1, c2); \
+ } \
+ } \
+ else \
+ { \
+ if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS) \
+ { \
+ *dst++ = charset & 0x7f; \
+ *dst++ = c1 & 0x7f; \
+ if (c2) \
+ *dst++ = c2 & 0x7f; \
+ } \
+ else \
+ { \
+ *dst++ = charset; \
+ *dst++ = c1; \
+ if (c2) \
+ *dst++ = c2; \
+ } \
+ } \
+ if (! COMPOSING_P (coding->composing)) \
+ coding->consumed_char++; \
} while (0)
/* Produce designation and invocation codes at a place pointed by DST
switch (emacs_code_class[c1])
{
case EMACS_ascii_code:
+ c2 = 0;
ENCODE_ISO_CHARACTER (CHARSET_ASCII, c1, /* dummy */ c2);
break;
case EMACS_leading_code_2:
ONE_MORE_BYTE (c2);
+ c3 = 0;
if (c2 < 0xA0)
{
/* invalid sequence */
case EMACS_leading_code_3:
TWO_MORE_BYTES (c2, c3);
+ c4 = 0;
if (c2 < 0xA0 || c3 < 0xA0)
{
/* invalid sequence */
{ \
if (sjis_p && charset_alt == charset_katakana_jisx0201) \
*dst++ = c1; \
+ else if (sjis_p && charset_alt == charset_latin_jisx0201) \
+ *dst++ = c1 & 0x7F; \
else \
{ \
*dst++ = charset_alt, *dst++ = c1; \
else \
{ \
c1 &= 0x7F, c2 &= 0x7F; \
- if (sjis_p && charset_alt == charset_jisx0208) \
+ if (sjis_p && (charset_alt == charset_jisx0208 \
+ || charset_alt == charset_jisx0208_1978))\
{ \
unsigned char s1, s2; \
\
coding->produced_char++;
}
else if (c1 < 0x80)
- DECODE_SJIS_BIG5_CHARACTER (charset_ascii, c1, /* dummy */ c2);
+ {
+ c2 = 0; /* avoid warning */
+ DECODE_SJIS_BIG5_CHARACTER (charset_ascii, c1, /* dummy */ c2);
+ }
else
{
if (sjis_p)
}
else if (c1 < 0xE0)
/* SJIS -> JISX0201-Kana */
- DECODE_SJIS_BIG5_CHARACTER (charset_katakana_jisx0201, c1,
- /* dummy */ c2);
+ {
+ c2 = 0; /* avoid warning */
+ DECODE_SJIS_BIG5_CHARACTER (charset_katakana_jisx0201, c1,
+ /* dummy */ c2);
+ }
else
goto label_invalid_code_1;
}
coding->fake_multibyte = 0;
if (src_bytes <= 0)
- return result;
+ {
+ coding->produced = coding->produced_char = 0;
+ coding->consumed = coding->consumed_char = 0;
+ return result;
+ }
switch (coding->eol_type)
{
`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);
bzero (coding->safe_charsets, MAX_CHARSET + 1);
while (CONSP (val))
{
- if ((i = get_charset_id (XCONS (val)->car)) >= 0)
+ if ((i = get_charset_id (XCAR (val))) >= 0)
coding->safe_charsets[i] = 1;
- val = XCONS (val)->cdr;
+ val = XCDR (val);
}
}
val = Vcharset_revision_alist;
while (CONSP (val))
{
- charset = get_charset_id (Fcar_safe (XCONS (val)->car));
+ charset = get_charset_id (Fcar_safe (XCAR (val)));
if (charset >= 0
- && (temp = Fcdr_safe (XCONS (val)->car), INTEGERP (temp))
+ && (temp = Fcdr_safe (XCAR (val)), INTEGERP (temp))
&& (i = XINT (temp), (i >= 0 && (i + '@') < 128)))
CODING_SPEC_ISO_REVISION_NUMBER (coding, charset) = i;
- val = XCONS (val)->cdr;
+ val = XCDR (val);
}
/* Checks FLAGS[REG] (REG = 0, 1, 2 3) and decide designations.
tail = flags[i];
coding->flags |= CODING_FLAG_ISO_DESIGNATION;
- if (INTEGERP (XCONS (tail)->car)
- && (charset = XINT (XCONS (tail)->car),
+ if (INTEGERP (XCAR (tail))
+ && (charset = XINT (XCAR (tail)),
CHARSET_VALID_P (charset))
- || (charset = get_charset_id (XCONS (tail)->car)) >= 0)
+ || (charset = get_charset_id (XCAR (tail))) >= 0)
{
CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) =i;
}
else
CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
- tail = XCONS (tail)->cdr;
+ tail = XCDR (tail);
while (CONSP (tail))
{
- if (INTEGERP (XCONS (tail)->car)
- && (charset = XINT (XCONS (tail)->car),
+ if (INTEGERP (XCAR (tail))
+ && (charset = XINT (XCAR (tail)),
CHARSET_VALID_P (charset))
- || (charset = get_charset_id (XCONS (tail)->car)) >= 0)
+ || (charset = get_charset_id (XCAR (tail))) >= 0)
CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
= i;
- else if (EQ (XCONS (tail)->car, Qt))
+ else if (EQ (XCAR (tail), Qt))
reg_bits |= 1 << i;
- tail = XCONS (tail)->cdr;
+ tail = XCDR (tail);
}
}
else
coding->common_flags
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
{
- Lisp_Object val;
- Lisp_Object decoder, encoder;
-
val = XVECTOR (coding_spec)->contents[4];
- if (CONSP (val)
- && SYMBOLP (XCONS (val)->car)
- && !NILP (decoder = Fget (XCONS (val)->car, Qccl_program_idx))
- && !NILP (decoder = Fcdr (Faref (Vccl_program_table, decoder)))
- && SYMBOLP (XCONS (val)->cdr)
- && !NILP (encoder = Fget (XCONS (val)->cdr, Qccl_program_idx))
- && !NILP (encoder = Fcdr (Faref (Vccl_program_table, encoder))))
- {
- setup_ccl_program (&(coding->spec.ccl.decoder), decoder);
- setup_ccl_program (&(coding->spec.ccl.encoder), encoder);
- }
- else
+ if (! CONSP (val)
+ || setup_ccl_program (&(coding->spec.ccl.decoder),
+ XCAR (val)) < 0
+ || setup_ccl_program (&(coding->spec.ccl.encoder),
+ XCDR (val)) < 0)
goto label_invalid_coding_system;
bzero (coding->spec.ccl.valid_codes, 256);
{
Lisp_Object this;
- for (; CONSP (val); val = XCONS (val)->cdr)
+ for (; CONSP (val); val = XCDR (val))
{
- this = XCONS (val)->car;
+ this = XCAR (val);
if (INTEGERP (this)
&& XINT (this) >= 0 && XINT (this) < 256)
coding->spec.ccl.valid_codes[XINT (this)] = 1;
else if (CONSP (this)
- && INTEGERP (XCONS (this)->car)
- && INTEGERP (XCONS (this)->cdr))
+ && INTEGERP (XCAR (this))
+ && INTEGERP (XCDR (this)))
{
- int start = XINT (XCONS (this)->car);
- int end = XINT (XCONS (this)->cdr);
+ int start = XINT (XCAR (this));
+ int end = XINT (XCDR (this));
if (start >= 0 && start <= end && end < 256)
while (start <= end)
coding->symbol
= XVECTOR (subsidiaries)->contents[coding->eol_type];
}
+ setup_coding_system (coding->symbol, coding);
}
return;
}
/* See "GENERAL NOTES about `decode_coding_XXX ()' functions". Before
decoding, it may detect coding system and format of end-of-line if
- those are not yet decided. */
+ those are not yet decided.
+
+ This function does not make full use of DESTINATION buffer. For
+ instance, if coding->type is coding_type_iso2022, it uses only
+ (DST_BYTES - 7) bytes of DESTINATION buffer. In the case that
+ DST_BYTES is decided by the function decoding_buffer_size, it
+ contains extra 256 bytes (defined by CONVERSION_BUFFER_EXTRA_ROOM).
+ So, this function can decode the full SOURCE. But, in the other
+ case, if you want to avoid carry over, you must supply at least 7
+ bytes more area in DESTINATION buffer than expected maximum bytes
+ that will be produced by this function. */
int
decode_coding (coding, source, destination, src_bytes, dst_bytes)
return result;
}
-/* See "GENERAL NOTES about `encode_coding_XXX ()' functions". */
+/* See "GENERAL NOTES about `encode_coding_XXX ()' functions".
+
+ This function does not make full use of DESTINATION buffer. For
+ instance, if coding->type is coding_type_iso2022, it uses only
+ (DST_BYTES - 20) bytes of DESTINATION buffer. In the case that
+ DST_BYTES is decided by the function encoding_buffer_size, it
+ contains extra 256 bytes (defined by CONVERSION_BUFFER_EXTRA_ROOM).
+ So, this function can encode the full SOURCE. But, in the other
+ case, if you want to avoid carry over, you must supply at least 20
+ bytes more area in DESTINATION buffer than expected maximum bytes
+ that will be produced by this function. */
int
encode_coding (coding, source, destination, src_bytes, dst_bytes)
} \
} 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
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;
ZV_BYTE -= len_byte;
Z_BYTE -= len_byte;
- if (GPT - BEG < beg_unchanged)
- beg_unchanged = GPT - BEG;
- if (Z - GPT < end_unchanged)
- end_unchanged = Z - GPT;
+ if (GPT - BEG < BEG_UNCHANGED)
+ BEG_UNCHANGED = GPT - BEG;
+ if (Z - GPT < END_UNCHANGED)
+ END_UNCHANGED = Z - GPT;
for (;;)
{
if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL)
{
unsigned char *pend = dst, *p = pend - inserted_byte;
+ Lisp_Object eol_type;
/* Encode LFs back to the original eol format (CR or CRLF). */
if (coding->eol_type == CODING_EOL_CR)
while (p < pend) if (*p++ == '\n') count++;
if (src - dst < count)
{
- /* We don't have sufficient room for putting LFs
+ /* We don't have sufficient room for encoding LFs
back to CRLF. We must record converted and
not-yet-converted text back to the buffer
content, enlarge the gap, then record them out of
/* Suppress eol-format conversion in the further conversion. */
coding->eol_type = CODING_EOL_LF;
- /* Restore the original symbol. */
- coding->symbol = saved_coding_symbol;
+ /* Set the coding system symbol to that for Unix-like EOL. */
+ eol_type = Fget (saved_coding_symbol, Qeol_type);
+ if (VECTORP (eol_type)
+ && XVECTOR (eol_type)->size == 3
+ && SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF]))
+ coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];
+ else
+ coding->symbol = saved_coding_symbol;
continue;
}
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;
}
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);
}
/* At first, gather possible coding systems in VAL. */
val = Qnil;
- for (tmp = Vcoding_category_list; !NILP (tmp); tmp = XCONS (tmp)->cdr)
+ for (tmp = Vcoding_category_list; !NILP (tmp); tmp = XCDR (tmp))
{
int idx
- = XFASTINT (Fget (XCONS (tmp)->car, Qcoding_category_index));
+ = XFASTINT (Fget (XCAR (tmp), Qcoding_category_index));
if (coding_mask & (1 << idx))
{
- val = Fcons (Fsymbol_value (XCONS (tmp)->car), val);
+ val = Fcons (Fsymbol_value (XCAR (tmp)), val);
if (highest)
break;
}
val = Fnreverse (val);
/* Then, replace the elements with subsidiary coding systems. */
- for (tmp = val; !NILP (tmp); tmp = XCONS (tmp)->cdr)
+ for (tmp = val; !NILP (tmp); tmp = XCDR (tmp))
{
if (eol_type != CODING_EOL_UNDECIDED
&& eol_type != CODING_EOL_INCONSISTENT)
{
Lisp_Object eol;
- eol = Fget (XCONS (tmp)->car, Qeol_type);
+ eol = Fget (XCAR (tmp), Qeol_type);
if (VECTORP (eol))
- XCONS (tmp)->car = XVECTOR (eol)->contents[eol_type];
+ XCAR (tmp) = XVECTOR (eol)->contents[eol_type];
}
}
- return (highest ? XCONS (val)->car : val);
+ return (highest ? XCAR (val) : val);
}
DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,
if (NILP (chain))
return Qnil;
- for (; CONSP (chain); chain = XCONS (chain)->cdr)
+ for (; CONSP (chain); chain = XCDR (chain))
{
Lisp_Object elt;
- elt = XCONS (chain)->car;
+ elt = XCAR (chain);
if (CONSP (elt)
&& ((STRINGP (target)
- && STRINGP (XCONS (elt)->car)
- && fast_string_match (XCONS (elt)->car, target) >= 0)
- || (INTEGERP (target) && EQ (target, XCONS (elt)->car))))
+ && STRINGP (XCAR (elt))
+ && fast_string_match (XCAR (elt), target) >= 0)
+ || (INTEGERP (target) && EQ (target, XCAR (elt)))))
{
- val = XCONS (elt)->cdr;
+ val = XCDR (elt);
/* Here, if VAL is both a valid coding system and a valid
function symbol, we return VAL as a coding system. */
if (CONSP (val))
while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX)
{
- if (! SYMBOLP (XCONS (val)->car))
+ if (! SYMBOLP (XCAR (val)))
break;
- idx = XFASTINT (Fget (XCONS (val)->car, Qcoding_category_index));
+ idx = XFASTINT (Fget (XCAR (val), Qcoding_category_index));
if (idx >= CODING_CATEGORY_IDX_MAX)
break;
coding_priorities[i++] = (1 << idx);
- val = XCONS (val)->cdr;
+ val = XCDR (val);
}
/* If coding-category-list is valid and contains all coding
categories, `i' should be CODING_CATEGORY_IDX_MAX now. If not,
#else
system_eol_type = CODING_EOL_LF;
#endif
+
+ inhibit_pre_post_conversion = 0;
}
#ifdef emacs
DEFVAR_LISP ("coding-system-for-write", &Vcoding_system_for_write,
"Specify the coding system for write operations.\n\
-It is useful to bind this variable with `let', but do not set it globally.\n\
-If the value is a coding system, it is used for encoding on write operation.\n\
-If not, an appropriate element is used from one of the coding system alists:\n\
+Programs bind this variable with `let', but you should not set it globally.\n\
+If the value is a coding system, it is used for encoding of output,\n\
+when writing it to a file and when sending it to a file or subprocess.\n\
+\n\
+If this does not specify a coding system, an appropriate element\n\
+is used from one of the coding system alists:\n\
There are three such tables, `file-coding-system-alist',\n\
-`process-coding-system-alist', and `network-coding-system-alist'.");
+`process-coding-system-alist', and `network-coding-system-alist'.\n\
+For output to files, if the above procedure does not specify a coding system,\n\
+the value of `buffer-file-coding-system' is used.");
Vcoding_system_for_write = Qnil;
DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,