/* Flag to inhibit code conversion of end-of-line format. */
int inhibit_eol_conversion;
+/* Flag to make buffer-file-coding-system inherit from process-coding. */
+int inherit_process_coding_system;
+
/* Coding system to be used to encode text for terminal display. */
struct coding_system terminal_coding;
"coding-category-binary"
};
-/* Table pointers to coding systems corresponding to each coding
+/* Table of pointers to coding systems corresponding to each coding
categories. */
struct coding_system *coding_system_table[CODING_CATEGORY_IDX_MAX];
-/* Flag to tell if we look up unification table on character code
+/* Table of coding category masks. Nth element is a mask for a coding
+ cateogry of which priority is Nth. */
+static
+int coding_priorities[CODING_CATEGORY_IDX_MAX];
+
+/* Flag to tell if we look up translation table on character code
conversion. */
-Lisp_Object Venable_character_unification;
-/* Standard unification table to look up on decoding (reading). */
-Lisp_Object Vstandard_character_unification_table_for_decode;
-/* Standard unification table to look up on encoding (writing). */
-Lisp_Object Vstandard_character_unification_table_for_encode;
+Lisp_Object Venable_character_translation;
+/* Standard translation table to look up on decoding (reading). */
+Lisp_Object Vstandard_translation_table_for_decode;
+/* Standard translation table to look up on encoding (writing). */
+Lisp_Object Vstandard_translation_table_for_encode;
-Lisp_Object Qcharacter_unification_table;
-Lisp_Object Qcharacter_unification_table_for_decode;
-Lisp_Object Qcharacter_unification_table_for_encode;
+Lisp_Object Qtranslation_table;
+Lisp_Object Qtranslation_table_id;
+Lisp_Object Qtranslation_table_for_decode;
+Lisp_Object Qtranslation_table_for_encode;
/* Alist of charsets vs revision number. */
Lisp_Object Vcharset_revision_alist;
enum iso_code_class_type iso_code_class[256];
-#define CHARSET_OK(idx, charset) \
- (CODING_SPEC_ISO_REQUESTED_DESIGNATION \
- (coding_system_table[idx], charset) \
- != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION)
+#define CHARSET_OK(idx, charset) \
+ (coding_system_table[idx]->safe_charsets[charset] \
+ || (CODING_SPEC_ISO_REQUESTED_DESIGNATION \
+ (coding_system_table[idx], charset) \
+ != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))
#define SHIFT_OUT_OK(idx) \
(CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0)
c2 = ' '; \
} \
} \
- if (!NILP (unification_table) \
- && ((c_alt = unify_char (unification_table, \
- -1, (charset), c1, c2)) >= 0)) \
+ if (!NILP (translation_table) \
+ && ((c_alt = translate_char (translation_table, \
+ -1, (charset), c1, c2)) >= 0)) \
SPLIT_CHAR (c_alt, charset_alt, c1, c2); \
} \
if (charset_alt == CHARSET_ASCII || charset_alt < 0) \
make_number (chars), \
make_number (final_char)); \
if (charset >= 0 \
- && CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) == reg) \
+ && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) == reg \
+ || coding->safe_charsets[charset])) \
{ \
if (coding->spec.iso2022.last_invalid_designation_register == 0 \
&& reg == 0 \
Else, if it contains only valid codes, return 0.
Else return the length of the composing sequence. */
-int check_composing_code (coding, src, src_end)
+int
+check_composing_code (coding, src, src_end)
struct coding_system *coding;
unsigned char *src, *src_end;
{
c1 = *src++;
if ((c1 < ' ' || c1 >= 0x80)
|| (charset = iso_charset_table[dim][c >= ','][c1]) < 0
+ || ! coding->safe_charsets[charset]
|| (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
== CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))
invalid_code_found = 1;
invalid_code_found = 1;
}
}
- return ((coding->mode & CODING_MODE_LAST_BLOCK) ? src_end - src_start : -1);
+ return (invalid_code_found
+ ? src - src_start
+ : (coding->mode & CODING_MODE_LAST_BLOCK ? 0 : -1));
}
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */
/* Charsets invoked to graphic plane 0 and 1 respectively. */
int charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
int charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);
- Lisp_Object unification_table
- = coding->character_unification_table_for_decode;
+ Lisp_Object translation_table
+ = coding->translation_table_for_decode;
int result = CODING_FINISH_NORMAL;
- if (!NILP (Venable_character_unification) && NILP (unification_table))
- unification_table = Vstandard_character_unification_table_for_decode;
+ if (!NILP (Venable_character_translation) && NILP (translation_table))
+ translation_table = Vstandard_translation_table_for_decode;
coding->produced_char = 0;
coding->fake_multibyte = 0;
result1 = check_composing_code (coding, src, src_end);
if (result1 == 0)
- coding->composing = (c1 == '0'
- ? COMPOSING_NO_RULE_HEAD
- : COMPOSING_WITH_RULE_HEAD);
+ {
+ coding->composing = (c1 == '0'
+ ? COMPOSING_NO_RULE_HEAD
+ : COMPOSING_WITH_RULE_HEAD);
+ coding->produced_char++;
+ }
else if (result1 > 0)
{
if (result1 + 2 < (dst_bytes ? dst_end : src_base) - dst)
case '1': /* end composing */
coding->composing = COMPOSING_NO;
- coding->produced_char++;
break;
case '[': /* specification of direction */
dst = encode_invocation_designation (charset, coding, dst); \
} while (1)
-#define ENCODE_ISO_CHARACTER(charset, c1, c2) \
- do { \
- int c_alt, charset_alt; \
- if (!NILP (unification_table) \
- && ((c_alt = unify_char (unification_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++; \
- } while (0)
+#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++; \
+ } while (0)
/* Produce designation and invocation codes at a place pointed by DST
to use CHARSET. The element `spec.iso2022' of *CODING is updated.
If the current block ends before any end-of-line, we may fail to
find all the necessary designations. */
+void
encode_designation_at_bol (coding, table, src, src_end, dstp)
struct coding_system *coding;
Lisp_Object table;
unsigned char c1, c2;
SPLIT_STRING(src, bytes, charset, c1, c2);
- if ((c_alt = unify_char (table, -1, charset, c1, c2)) >= 0)
+ if ((c_alt = translate_char (table, -1, charset, c1, c2)) >= 0)
charset = CHAR_CHARSET (c_alt);
}
from DST_END to assure overflow checking is necessary only at the
head of loop. */
unsigned char *adjusted_dst_end = dst_end - 19;
- Lisp_Object unification_table
- = coding->character_unification_table_for_encode;
+ Lisp_Object translation_table
+ = coding->translation_table_for_encode;
int result = CODING_FINISH_NORMAL;
- if (!NILP (Venable_character_unification) && NILP (unification_table))
- unification_table = Vstandard_character_unification_table_for_encode;
+ if (!NILP (Venable_character_translation) && NILP (translation_table))
+ translation_table = Vstandard_translation_table_for_encode;
coding->consumed_char = 0;
coding->fake_multibyte = 0;
&& CODING_SPEC_ISO_BOL (coding))
{
/* We have to produce designation sequences if any now. */
- encode_designation_at_bol (coding, unification_table,
+ encode_designation_at_bol (coding, translation_table,
src, src_end, &dst);
CODING_SPEC_ISO_BOL (coding) = 0;
}
{
/* invalid sequence */
*dst++ = c1;
- *dst++ = c2;
- coding->consumed_char += 2;
+ src--;
+ coding->consumed_char++;
}
else
ENCODE_ISO_CHARACTER (c1, c2, /* dummy */ c3);
{
/* invalid sequence */
*dst++ = c1;
- *dst++ = c2;
- *dst++ = c3;
- coding->consumed_char += 3;
+ src -= 2;
+ coding->consumed_char++;
}
else if (c1 < LEADING_CODE_PRIVATE_11)
ENCODE_ISO_CHARACTER (c1, c2, c3);
{
/* invalid sequence */
*dst++ = c1;
- *dst++ = c2;
- *dst++ = c3;
- *dst++ = c4;
- coding->consumed_char += 4;
+ src -= 3;
+ coding->consumed_char++;
}
else
ENCODE_ISO_CHARACTER (c2, c3, c4);
{
/* invalid sequence */
*dst++ = c1;
- *dst++ = c2;
- coding->consumed_char += 2;
+ src--;
+ coding->consumed_char++;
}
else if (c2 == 0xFF)
{
break;
}
- if (src < src_end)
+ if (src < src_end && result == CODING_FINISH_NORMAL)
+ result = CODING_FINISH_INSUFFICIENT_DST;
+
+ /* If this is the last block of the text to be encoded, we must
+ reset graphic planes and registers to the initial state, and
+ flush out the carryover if any. */
+ if (coding->mode & CODING_MODE_LAST_BLOCK)
{
- if (result == CODING_FINISH_NORMAL)
- result = CODING_FINISH_INSUFFICIENT_DST;
- else
- /* If this is the last block of the text to be encoded, we
- must reset graphic planes and registers to the initial
- state, and flush out the carryover if any. */
- if (coding->mode & CODING_MODE_LAST_BLOCK)
- ENCODE_RESET_PLANE_AND_REGISTER;
+ ENCODE_RESET_PLANE_AND_REGISTER;
+ if (COMPOSING_P (coding->composing))
+ ENCODE_COMPOSITION_END;
}
-
coding->consumed = src - source;
coding->produced = coding->produced_char = dst - destination;
return result;
#define DECODE_SJIS_BIG5_CHARACTER(charset, c1, c2) \
do { \
int c_alt, charset_alt = (charset); \
- if (!NILP (unification_table) \
- && ((c_alt = unify_char (unification_table, \
- -1, (charset), c1, c2)) >= 0)) \
+ if (!NILP (translation_table) \
+ && ((c_alt = translate_char (translation_table, \
+ -1, (charset), c1, c2)) >= 0)) \
SPLIT_CHAR (c_alt, charset_alt, c1, c2); \
if (charset_alt == CHARSET_ASCII || charset_alt < 0) \
DECODE_CHARACTER_ASCII (c1); \
DECODE_CHARACTER_DIMENSION2 (charset_alt, c1, c2); \
} while (0)
-#define ENCODE_SJIS_BIG5_CHARACTER(charset, c1, c2) \
- do { \
- int c_alt, charset_alt; \
- if (!NILP (unification_table) \
- && ((c_alt = unify_char (unification_table, -1, charset, c1, c2)) \
- >= 0)) \
- SPLIT_CHAR (c_alt, charset_alt, c1, c2); \
- else \
- charset_alt = charset; \
- if (charset_alt == charset_ascii) \
- *dst++ = c1; \
- else if (CHARSET_DIMENSION (charset_alt) == 1) \
- { \
- if (sjis_p && charset_alt == charset_katakana_jisx0201) \
- *dst++ = c1; \
- else \
- { \
- *dst++ = charset_alt, *dst++ = c1; \
- coding->fake_multibyte = 1; \
- } \
- } \
- else \
- { \
- c1 &= 0x7F, c2 &= 0x7F; \
- if (sjis_p && charset_alt == charset_jisx0208) \
- { \
- unsigned char s1, s2; \
- \
- ENCODE_SJIS (c1, c2, s1, s2); \
- *dst++ = s1, *dst++ = s2; \
- coding->fake_multibyte = 1; \
- } \
- else if (!sjis_p \
- && (charset_alt == charset_big5_1 \
- || charset_alt == charset_big5_2)) \
- { \
- unsigned char b1, b2; \
- \
- ENCODE_BIG5 (charset_alt, c1, c2, b1, b2); \
- *dst++ = b1, *dst++ = b2; \
- } \
- else \
- { \
- *dst++ = charset_alt, *dst++ = c1, *dst++ = c2; \
- coding->fake_multibyte = 1; \
- } \
- } \
- coding->consumed_char++; \
+#define ENCODE_SJIS_BIG5_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_alt == charset_ascii) \
+ *dst++ = c1; \
+ else if (CHARSET_DIMENSION (charset_alt) == 1) \
+ { \
+ if (sjis_p && charset_alt == charset_katakana_jisx0201) \
+ *dst++ = c1; \
+ else \
+ { \
+ *dst++ = charset_alt, *dst++ = c1; \
+ coding->fake_multibyte = 1; \
+ } \
+ } \
+ else \
+ { \
+ c1 &= 0x7F, c2 &= 0x7F; \
+ if (sjis_p && charset_alt == charset_jisx0208) \
+ { \
+ unsigned char s1, s2; \
+ \
+ ENCODE_SJIS (c1, c2, s1, s2); \
+ *dst++ = s1, *dst++ = s2; \
+ coding->fake_multibyte = 1; \
+ } \
+ else if (!sjis_p \
+ && (charset_alt == charset_big5_1 \
+ || charset_alt == charset_big5_2)) \
+ { \
+ unsigned char b1, b2; \
+ \
+ ENCODE_BIG5 (charset_alt, c1, c2, b1, b2); \
+ *dst++ = b1, *dst++ = b2; \
+ } \
+ else \
+ { \
+ *dst++ = charset_alt, *dst++ = c1, *dst++ = c2; \
+ coding->fake_multibyte = 1; \
+ } \
+ } \
+ coding->consumed_char++; \
} while (0);
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
from DST_END to assure overflow checking is necessary only at the
head of loop. */
unsigned char *adjusted_dst_end = dst_end - 3;
- Lisp_Object unification_table
- = coding->character_unification_table_for_decode;
+ Lisp_Object translation_table
+ = coding->translation_table_for_decode;
int result = CODING_FINISH_NORMAL;
- if (!NILP (Venable_character_unification) && NILP (unification_table))
- unification_table = Vstandard_character_unification_table_for_decode;
+ if (!NILP (Venable_character_translation) && NILP (translation_table))
+ translation_table = Vstandard_translation_table_for_decode;
coding->produced_char = 0;
coding->fake_multibyte = 0;
from DST_END to assure overflow checking is necessary only at the
head of loop. */
unsigned char *adjusted_dst_end = dst_end - 1;
- Lisp_Object unification_table
- = coding->character_unification_table_for_encode;
+ Lisp_Object translation_table
+ = coding->translation_table_for_encode;
int result = CODING_FINISH_NORMAL;
- if (!NILP (Venable_character_unification) && NILP (unification_table))
- unification_table = Vstandard_character_unification_table_for_encode;
+ if (!NILP (Venable_character_translation) && NILP (translation_table))
+ translation_table = Vstandard_translation_table_for_encode;
coding->consumed_char = 0;
coding->fake_multibyte = 0;
This function is called only when `coding->eol_type' is
CODING_EOL_CRLF or CODING_EOL_CR. */
+int
decode_eol (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
unsigned char *source, *destination;
`coding->mode & CODING_MODE_SELECTIVE_DISPLAY' is nonzero, code
'\r' in source text also means end-of-line. */
+int
encode_eol (coding, source, destination, src_bytes, dst_bytes)
struct coding_system *coding;
unsigned char *source, *destination;
/* Initialize remaining fields. */
coding->composing = 0;
- coding->character_unification_table_for_decode = Qnil;
- coding->character_unification_table_for_encode = Qnil;
+ coding->translation_table_for_decode = Qnil;
+ coding->translation_table_for_encode = Qnil;
/* Get values of coding system properties:
`post-read-conversion', `pre-write-conversion',
- `character-unification-table-for-decode',
- `character-unification-table-for-encode'. */
+ `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);
- val = Fplist_get (plist, Qcharacter_unification_table_for_decode);
+ val = Fplist_get (plist, Qtranslation_table_for_decode);
if (SYMBOLP (val))
- val = Fget (val, Qcharacter_unification_table_for_decode);
- coding->character_unification_table_for_decode
- = CHAR_TABLE_P (val) ? val : Qnil;
- val = Fplist_get (plist, Qcharacter_unification_table_for_encode);
+ val = Fget (val, Qtranslation_table_for_decode);
+ coding->translation_table_for_decode = CHAR_TABLE_P (val) ? val : Qnil;
+ val = Fplist_get (plist, Qtranslation_table_for_encode);
if (SYMBOLP (val))
- val = Fget (val, Qcharacter_unification_table_for_encode);
- coding->character_unification_table_for_encode
- = CHAR_TABLE_P (val) ? val : Qnil;
+ val = Fget (val, Qtranslation_table_for_encode);
+ coding->translation_table_for_encode = CHAR_TABLE_P (val) ? val : Qnil;
val = Fplist_get (plist, Qcoding_category);
if (!NILP (val))
{
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
{
Lisp_Object val = XVECTOR (coding_spec)->contents[4];
+ Lisp_Object decoder, encoder;
+
if (CONSP (val)
- && VECTORP (XCONS (val)->car)
- && VECTORP (XCONS (val)->cdr))
+ && 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), XCONS (val)->car);
- setup_ccl_program (&(coding->spec.ccl.encoder), XCONS (val)->cdr);
+ setup_ccl_program (&(coding->spec.ccl.decoder), decoder);
+ setup_ccl_program (&(coding->spec.ccl.encoder), encoder);
}
else
goto label_invalid_coding_system;
*/
+static
+int ascii_skip_code[256];
+
/* Detect how a text of length SRC_BYTES pointed by SOURCE is encoded.
If it detects possible coding systems, return an integer in which
appropriate flag bits are set. Flag bits are defined by macros
{
register unsigned char c;
unsigned char *src = source, *src_end = source + src_bytes;
- unsigned int mask = (CODING_CATEGORY_MASK_ISO_7BIT
- | CODING_CATEGORY_MASK_ISO_SHIFT);
+ unsigned int mask;
int i;
/* At first, skip all ASCII characters and control characters except
for three ISO2022 specific control characters. */
+ ascii_skip_code[ISO_CODE_SO] = 0;
+ ascii_skip_code[ISO_CODE_SI] = 0;
+ ascii_skip_code[ISO_CODE_ESC] = 0;
+
label_loop_detect_coding:
- while (src < src_end)
- {
- c = *src;
- if (c >= 0x80
- || ((mask & CODING_CATEGORY_MASK_ISO_7BIT)
- && c == ISO_CODE_ESC)
- || ((mask & CODING_CATEGORY_MASK_ISO_SHIFT)
- && (c == ISO_CODE_SI || c == ISO_CODE_SO)))
- break;
- src++;
- }
+ while (src < src_end && ascii_skip_code[*src]) src++;
*skip = src - source;
if (src >= src_end)
{
/* No valid ISO2022 code follows C. Try again. */
src++;
- mask = (c != ISO_CODE_ESC
- ? CODING_CATEGORY_MASK_ISO_7BIT
- : CODING_CATEGORY_MASK_ISO_SHIFT);
+ if (c == ISO_CODE_ESC)
+ ascii_skip_code[ISO_CODE_ESC] = 1;
+ else
+ ascii_skip_code[ISO_CODE_SO] = ascii_skip_code[ISO_CODE_SI] = 1;
goto label_loop_detect_coding;
}
if (priorities)
{
for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)
{
- priorities[i] &= try;
- if (priorities[i] & CODING_CATEGORY_MASK_ISO)
+ if (priorities[i] & try & CODING_CATEGORY_MASK_ISO)
mask = detect_coding_iso2022 (src, src_end);
- else if (priorities[i] & CODING_CATEGORY_MASK_SJIS)
+ else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS)
mask = detect_coding_sjis (src, src_end);
- else if (priorities[i] & CODING_CATEGORY_MASK_BIG5)
+ else if (priorities[i] & try & CODING_CATEGORY_MASK_BIG5)
mask = detect_coding_big5 (src, src_end);
- else if (priorities[i] & CODING_CATEGORY_MASK_EMACS_MULE)
+ else if (priorities[i] & try & CODING_CATEGORY_MASK_EMACS_MULE)
mask = detect_coding_emacs_mule (src, src_end);
+ else if (priorities[i] & CODING_CATEGORY_MASK_RAW_TEXT)
+ mask = CODING_CATEGORY_MASK_RAW_TEXT;
+ else if (priorities[i] & CODING_CATEGORY_MASK_BINARY)
+ mask = CODING_CATEGORY_MASK_BINARY;
if (mask)
goto label_return_highest_only;
}
if (try & CODING_CATEGORY_MASK_EMACS_MULE)
mask |= detect_coding_emacs_mule (src, src_end);
}
- return (mask | CODING_CATEGORY_MASK_RAW_TEXT);
+ return (mask | CODING_CATEGORY_MASK_RAW_TEXT | CODING_CATEGORY_MASK_BINARY);
label_return_highest_only:
for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)
{
unsigned int idx;
int skip, mask, i;
- int priorities[CODING_CATEGORY_IDX_MAX];
Lisp_Object val = Vcoding_category_list;
- i = 0;
- while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX)
- {
- if (! SYMBOLP (XCONS (val)->car))
- break;
- idx = XFASTINT (Fget (XCONS (val)->car, Qcoding_category_index));
- if (idx >= CODING_CATEGORY_IDX_MAX)
- break;
- priorities[i++] = (1 << idx);
- val = XCONS (val)->cdr;
- }
- /* If coding-category-list is valid and contains all coding
- categories, `i' should be CODING_CATEGORY_IDX_MAX now. If not,
- the following code saves Emacs from craching. */
- while (i < CODING_CATEGORY_IDX_MAX)
- priorities[i++] = CODING_CATEGORY_MASK_RAW_TEXT;
-
- mask = detect_coding_mask (src, src_bytes, priorities, &skip);
+ mask = detect_coding_mask (src, src_bytes, coding_priorities, &skip);
coding->heading_ascii = skip;
if (!mask) return;
return;
}
- if (coding->heading_ascii >= 0)
+ eol_conversion = (coding->eol_type != CODING_EOL_LF);
+
+ if ((! eol_conversion) && (coding->heading_ascii >= 0))
/* Detection routine has already found how much we can skip at the
head. */
*beg += coding->heading_ascii;
endp_orig = endp = begp + *end - *beg;
}
- eol_conversion = (coding->eol_type != CODING_EOL_LF);
-
switch (coding->type)
{
case coding_type_emacs_mule:
{
if (coding->heading_ascii < 0)
while (begp < endp && *begp != '\r' && *begp < 0x80) begp++;
- while (begp < endp && *(endp - 1) != '\r' && *(endp - 1) < 0x80)
+ while (begp < endp && endp[-1] != '\r' && endp[-1] < 0x80)
endp--;
+ /* Do not consider LF as ascii if preceded by CR, since that
+ confuses eol decoding. */
+ if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
+ endp++;
}
else
begp = endp;
if (coding->heading_ascii < 0)
{
if (eol_conversion)
- while (begp < endp && *begp < 0x80 && *begp != '\n') begp++;
+ while (begp < endp && *begp < 0x80 && *begp != '\r') begp++;
else
while (begp < endp && *begp < 0x80) begp++;
}
/* We can skip all ASCII characters at the tail except for the
second byte of SJIS or BIG5 code. */
if (eol_conversion)
- while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\n') endp--;
+ while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\r') endp--;
else
while (begp < endp && endp[-1] < 0x80) endp--;
+ /* Do not consider LF as ascii if preceded by CR, since that
+ confuses eol decoding. */
+ if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
+ endp++;
if (begp < endp && endp < endp_orig && endp[-1] >= 0x80)
endp++;
break;
case CODING_CATEGORY_IDX_ISO_8_2:
/* We can skip all ASCII characters at the tail. */
if (eol_conversion)
- while (begp < endp && (c = endp[-1]) < 0x80 && c != '\n') endp--;
+ while (begp < endp && (c = endp[-1]) < 0x80 && c != '\r') endp--;
else
while (begp < endp && endp[-1] < 0x80) endp--;
+ /* Do not consider LF as ascii if preceded by CR, since that
+ confuses eol decoding. */
+ if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
+ endp++;
break;
case CODING_CATEGORY_IDX_ISO_7:
the following 2-byte at the tail. */
if (eol_conversion)
while (begp < endp
- && (c = endp[-1]) < 0x80 && c != ISO_CODE_ESC && c != '\n')
+ && (c = endp[-1]) < 0x80 && c != ISO_CODE_ESC && c != '\r')
endp--;
else
while (begp < endp
&& (c = endp[-1]) < 0x80 && c != ISO_CODE_ESC)
endp--;
+ /* Do not consider LF as ascii if preceded by CR, since that
+ confuses eol decoding. */
+ if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
+ endp++;
if (begp < endp && endp[-1] == ISO_CODE_ESC)
{
if (endp + 1 < endp_orig && end[0] == '(' && end[1] == 'B')
characters (and bytes) are recorded in members of the structure
CODING.
- If ADJUST is nonzero, we do various things as if the original text
+ If REPLACE is nonzero, we do various things as if the original text
is deleted and a new text is inserted. See the comments in
- replace_range (insdel.c) to know what we are doing.
-
- ADJUST nonzero also means that post-read-conversion or
- pre-write-conversion functions (if any) should be processed. */
+ replace_range (insdel.c) to know what we are doing. */
int
-code_convert_region (from, from_byte, to, to_byte, coding, encodep, adjust)
- int from, from_byte, to, to_byte, encodep, adjust;
+code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
+ int from, from_byte, to, to_byte, encodep, replace;
struct coding_system *coding;
{
int len = to - from, len_byte = to_byte - from_byte;
int require, inserted, inserted_byte;
- int from_byte_orig, to_byte_orig;
+ int head_skip, tail_skip, total_skip;
Lisp_Object saved_coding_symbol = Qnil;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
int first = 1;
int fake_multibyte = 0;
unsigned char *src, *dst;
- int combined_before_bytes = 0, combined_after_bytes = 0;
+ Lisp_Object deletion = Qnil;
+
+ if (from < PT && PT < to)
+ SET_PT_BOTH (from, from_byte);
- if (adjust)
+ if (replace)
{
int saved_from = from;
if (! encodep && CODING_REQUIRE_DETECTION (coding))
{
- /* We must detect encoding of text and eol. Even if detection
- routines can't decide the encoding, we should not let them
- undecided because the deeper decoding routine (decode_coding)
- tries to detect the encodings in vain in that case. */
+ /* We must detect encoding of text and eol format. */
if (from < GPT && to > GPT)
move_gap_both (from, from_byte);
{
detect_coding (coding, BYTE_POS_ADDR (from_byte), len_byte);
if (coding->type == coding_type_undecided)
+ /* It seems that the text contains only ASCII, but we
+ should not left it undecided because the deeper
+ decoding routine (decode_coding) tries to detect the
+ encodings again in vain. */
coding->type = coding_type_emacs_mule;
}
if (coding->eol_type == CODING_EOL_UNDECIDED)
: ! CODING_REQUIRE_DECODING (coding))
{
coding->produced = len_byte;
- if (multibyte)
+ if (multibyte
+ && ! replace
+ /* See the comment of the member heading_ascii in coding.h. */
+ && coding->heading_ascii < len_byte)
{
- if (GPT < from || GPT > to)
- move_gap_both (from, from_byte);
- coding->produced_char
- = multibyte_chars_in_text (BYTE_POS_ADDR (from_byte), len_byte);
+ /* We still may have to combine byte at the head and the
+ tail of the text in the region. */
+ if (from < GPT && GPT < to)
+ move_gap_both (to, to_byte);
+ len = multibyte_chars_in_text (BYTE_POS_ADDR (from_byte), len_byte);
+ adjust_after_insert (from, from_byte, to, to_byte, len);
+ coding->produced_char = len;
}
else
- coding->produced_char = len_byte;
+ {
+ if (!replace)
+ adjust_after_insert (from, from_byte, to, to_byte, len_byte);
+ coding->produced_char = len_byte;
+ }
return 0;
}
new buffer. */
struct buffer *prev = current_buffer, *new;
- call2 (coding->pre_write_conversion, from, to);
+ call2 (coding->pre_write_conversion,
+ make_number (from), make_number (to));
if (current_buffer != prev)
{
len = ZV - BEGV;
}
}
+ if (replace)
+ deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
+
/* Try to skip the heading and tailing ASCIIs. */
- from_byte_orig = from_byte; to_byte_orig = to_byte;
- if (from < GPT && GPT < to)
- move_gap (from);
- if (encodep)
- shrink_encoding_region (&from_byte, &to_byte, coding, NULL);
- else
- shrink_decoding_region (&from_byte, &to_byte, coding, NULL);
- if (from_byte == to_byte)
- {
- coding->produced = len_byte;
- coding->produced_char = multibyte ? len : len_byte;
- return 0;
- }
+ {
+ int from_byte_orig = from_byte, to_byte_orig = to_byte;
+
+ if (from < GPT && GPT < to)
+ move_gap_both (from, from_byte);
+ if (encodep)
+ shrink_encoding_region (&from_byte, &to_byte, coding, NULL);
+ else
+ shrink_decoding_region (&from_byte, &to_byte, coding, NULL);
+ if (from_byte == to_byte)
+ {
+ coding->produced = len_byte;
+ coding->produced_char = multibyte ? len : len_byte;
+ if (!replace)
+ /* We must record and adjust for this new text now. */
+ adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
+ return 0;
+ }
- /* Here, the excluded region by shrinking contains only ASCIIs. */
- from += (from_byte - from_byte_orig);
- to += (to_byte - to_byte_orig);
- len = to - from;
- len_byte = to_byte - from_byte;
+ head_skip = from_byte - from_byte_orig;
+ tail_skip = to_byte_orig - to_byte;
+ total_skip = head_skip + tail_skip;
+ from += head_skip;
+ to -= tail_skip;
+ len -= total_skip; len_byte -= total_skip;
+ }
/* For converion, we must put the gap before the text in addition to
making the gap larger for efficient decoding. The required gap
make_gap (require - GAP_SIZE);
move_gap_both (from, from_byte);
- if (adjust)
- adjust_before_replace (from, from_byte, to, to_byte);
-
if (GPT - BEG < beg_unchanged)
beg_unchanged = GPT - BEG;
if (Z - GPT < end_unchanged)
inserted += len_byte;
inserted_byte += len_byte;
while (len_byte--)
- *src++ = *dst++;
+ *dst++ = *src++;
fake_multibyte = 1;
break;
}
REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
Here, we are sure that NEW >= ORIG. */
- require = (len_byte * (coding->produced - coding->consumed)
- / coding->consumed);
+ float ratio = coding->produced - coding->consumed;
+ ratio /= coding->consumed;
+ require = len_byte * ratio;
first = 0;
}
if ((src - dst) < (require + 2000))
if (src - dst > 0) *dst = 0; /* Put an anchor. */
if (multibyte
- && (fake_multibyte || !encodep && (to - from) != (to_byte - from_byte)))
+ && (fake_multibyte
+ || !encodep && (to - from) != (to_byte - from_byte)))
inserted = multibyte_chars_in_text (GPT_ADDR, inserted_byte);
- adjust_after_replace (from, from_byte, to, to_byte,
- inserted, inserted_byte);
- if (from_byte_orig == from_byte)
- from_byte_orig = from_byte = PT_BYTE;
+ /* If we have shrinked the conversion area, adjust it now. */
+ if (total_skip > 0)
+ {
+ if (tail_skip > 0)
+ safe_bcopy (GAP_END_ADDR, GPT_ADDR + inserted_byte, tail_skip);
+ inserted += total_skip; inserted_byte += total_skip;
+ GAP_SIZE += total_skip;
+ GPT -= head_skip; GPT_BYTE -= head_skip;
+ ZV -= total_skip; ZV_BYTE -= total_skip;
+ Z -= total_skip; Z_BYTE -= total_skip;
+ from -= head_skip; from_byte -= head_skip;
+ to += tail_skip; to_byte += tail_skip;
+ }
+
+ adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte);
if (! encodep && ! NILP (coding->post_read_conversion))
{
signal_after_change (from, to - from, inserted);
{
- int skip = (to_byte_orig - to_byte) + (from_byte - from_byte_orig);
-
- coding->consumed = to_byte_orig - from_byte_orig;
- coding->consumed_char = skip + (to - from);
- coding->produced = skip + inserted_byte;
- coding->produced_char = skip + inserted;
+ coding->consumed = to_byte - from_byte;
+ coding->consumed_char = to - from;
+ coding->produced = inserted_byte;
+ coding->produced_char = inserted;
}
return 0;
{
int len;
char *buf;
- int from = 0, to = XSTRING (str)->size, to_byte = XSTRING (str)->size_byte;
+ int from = 0, to = XSTRING (str)->size;
+ int to_byte = STRING_BYTES (XSTRING (str));
struct gcpro gcpro1;
Lisp_Object saved_coding_symbol = Qnil;
int result;
len = encoding_buffer_size (coding, to_byte - from);
else
len = decoding_buffer_size (coding, to_byte - from);
- len += from + XSTRING (str)->size_byte - to_byte;
+ len += from + STRING_BYTES (XSTRING (str)) - to_byte;
GCPRO1 (str);
buf = get_conversion_buffer (len);
UNGCPRO;
? encode_coding (coding, XSTRING (str)->data + from,
buf + from, to_byte - from, len)
: decode_coding (coding, XSTRING (str)->data + from,
- buf + from, to - from, len));
+ buf + from, to_byte - from, len));
if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL)
{
/* We simple try to decode the whole string again but without
}
bcopy (XSTRING (str)->data + to_byte, buf + from + coding->produced,
- XSTRING (str)->size_byte - to_byte);
+ STRING_BYTES (XSTRING (str)) - to_byte);
- len = from + XSTRING (str)->size_byte - to_byte;
+ len = from + STRING_BYTES (XSTRING (str)) - to_byte;
if (encodep)
str = make_unibyte_string (buf, len + coding->produced);
else
- str = make_multibyte_string (buf, len + coding->produced_char,
- len + coding->produced);
+ str = make_string_from_bytes (buf, len + coding->produced_char,
+ len + coding->produced);
return str;
}
if (!highest)
val = Fnreverse (val);
- /* Then, substitute the elements by subsidiary coding systems. */
+ /* Then, replace the elements with subsidiary coding systems. */
for (tmp = val; !NILP (tmp); tmp = XCONS (tmp)->cdr)
{
- if (eol_type != CODING_EOL_UNDECIDED)
+ if (eol_type != CODING_EOL_UNDECIDED
+ && eol_type != CODING_EOL_INCONSISTENT)
{
Lisp_Object eol;
eol = Fget (XCONS (tmp)->car, Qeol_type);
CHECK_STRING (string, 0);
return detect_coding_system (XSTRING (string)->data,
- XSTRING (string)->size_byte,
+ STRING_BYTES (XSTRING (string)),
!NILP (highest));
}
coding.mode |= CODING_MODE_LAST_BLOCK;
code_convert_region (from, CHAR_TO_BYTE (from), to, CHAR_TO_BYTE (to),
&coding, encodep, 1);
+ Vlast_coding_system_used = coding.symbol;
return make_number (coding.produced_char);
}
"Decode the current region by specified coding system.\n\
When called from a program, takes three arguments:\n\
START, END, and CODING-SYSTEM. START and END are buffer positions.\n\
-Return length of decoded text.")
+This function sets `last-coding-system-used' to the precise coding system\n\
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
+not fully specified.)\n\
+It returns the length of the decoded text.")
(start, end, coding_system)
Lisp_Object start, end, coding_system;
{
"Encode the current region by specified coding system.\n\
When called from a program, takes three arguments:\n\
START, END, and CODING-SYSTEM. START and END are buffer positions.\n\
-Return length of encoded text.")
+This function sets `last-coding-system-used' to the precise coding system\n\
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
+not fully specified.)\n\
+It returns the length of the encoded text.")
(start, end, coding_system)
Lisp_Object start, end, coding_system;
{
error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data);
coding.mode |= CODING_MODE_LAST_BLOCK;
+ Vlast_coding_system_used = coding.symbol;
return code_convert_string (string, &coding, encodep, !NILP (nocopy));
}
2, 3, 0,
"Decode STRING which is encoded in CODING-SYSTEM, and return the result.\n\
Optional arg NOCOPY non-nil means it is ok to return STRING itself\n\
-if the decoding operation is trivial.")
+if the decoding operation is trivial.\n\
+This function sets `last-coding-system-used' to the precise coding system\n\
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
+not fully specified.)")
(string, coding_system, nocopy)
Lisp_Object string, coding_system, nocopy;
{
- return code_convert_string1(string, coding_system, nocopy, 0);
+ return code_convert_string1 (string, coding_system, nocopy, 0);
}
DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
2, 3, 0,
"Encode STRING to CODING-SYSTEM, and return the result.\n\
Optional arg NOCOPY non-nil means it is ok to return STRING itself\n\
-if the encoding operation is trivial.")
+if the encoding operation is trivial.\n\
+This function sets `last-coding-system-used' to the precise coding system\n\
+used (which may be different from CODING-SYSTEM if CODING-SYSTEM is\n\
+not fully specified.)")
(string, coding_system, nocopy)
Lisp_Object string, coding_system, nocopy;
{
- return code_convert_string1(string, coding_system, nocopy, 1);
+ return code_convert_string1 (string, coding_system, nocopy, 1);
}
\f
return Qnil;
}
+DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal,
+ Sset_coding_priority_internal, 0, 0, 0,
+ "Update internal database for the current value of `coding-category-list'.\n\
+This function is internal use only.")
+ ()
+{
+ int i = 0, idx;
+ Lisp_Object val = Vcoding_category_list;
+
+ while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX)
+ {
+ if (! SYMBOLP (XCONS (val)->car))
+ break;
+ idx = XFASTINT (Fget (XCONS (val)->car, Qcoding_category_index));
+ if (idx >= CODING_CATEGORY_IDX_MAX)
+ break;
+ coding_priorities[i++] = (1 << idx);
+ val = XCONS (val)->cdr;
+ }
+ /* If coding-category-list is valid and contains all coding
+ categories, `i' should be CODING_CATEGORY_IDX_MAX now. If not,
+ the following code saves Emacs from craching. */
+ while (i < CODING_CATEGORY_IDX_MAX)
+ coding_priorities[i++] = CODING_CATEGORY_MASK_RAW_TEXT;
+
+ return Qnil;
+}
+
#endif /* emacs */
\f
/*** 8. Post-amble ***/
+void
init_coding_once ()
{
int i;
bzero (coding_system_table, sizeof coding_system_table);
+ bzero (ascii_skip_code, sizeof ascii_skip_code);
+ for (i = 0; i < 128; i++)
+ ascii_skip_code[i] = 1;
+
#if defined (MSDOS) || defined (WINDOWSNT)
system_eol_type = CODING_EOL_CRLF;
#else
#ifdef emacs
+void
syms_of_coding ()
{
Qtarget_idx = intern ("target-idx");
}
}
- Qcharacter_unification_table = intern ("character-unification-table");
- staticpro (&Qcharacter_unification_table);
- Fput (Qcharacter_unification_table, Qchar_table_extra_slots,
- make_number (0));
+ Qtranslation_table = intern ("translation-table");
+ staticpro (&Qtranslation_table);
+ Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (0));
+
+ Qtranslation_table_id = intern ("translation-table-id");
+ staticpro (&Qtranslation_table_id);
- Qcharacter_unification_table_for_decode
- = intern ("character-unification-table-for-decode");
- staticpro (&Qcharacter_unification_table_for_decode);
+ Qtranslation_table_for_decode = intern ("translation-table-for-decode");
+ staticpro (&Qtranslation_table_for_decode);
- Qcharacter_unification_table_for_encode
- = intern ("character-unification-table-for-encode");
- staticpro (&Qcharacter_unification_table_for_encode);
+ Qtranslation_table_for_encode = intern ("translation-table-for-encode");
+ staticpro (&Qtranslation_table_for_encode);
Qsafe_charsets = intern ("safe-charsets");
staticpro (&Qsafe_charsets);
defsubr (&Skeyboard_coding_system);
defsubr (&Sfind_operation_coding_system);
defsubr (&Supdate_iso_coding_systems);
+ defsubr (&Sset_coding_priority_internal);
DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,
"List of coding systems.\n\
"*Non-nil inhibit code conversion of end-of-line format in any cases.");
inhibit_eol_conversion = 0;
+ DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,
+ "Non-nil means process buffer inherits coding system of process output.\n\
+Bind it to t if the process output is to be treated as if it were a file\n\
+read from some filesystem.");
+ inherit_process_coding_system = 0;
+
DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
"Alist to decide a coding system to use for a file I/O operation.\n\
The format is ((PATTERN . VAL) ...),\n\
"Mnemonic character indicating end-of-line format is not yet decided.");
eol_mnemonic_undecided = ':';
- DEFVAR_LISP ("enable-character-unification", &Venable_character_unification,
- "Non-nil means ISO 2022 encoder/decoder do character unification.");
- Venable_character_unification = Qt;
+ DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,
+ "*Non-nil enables character translation while encoding and decoding.");
+ Venable_character_translation = Qt;
- DEFVAR_LISP ("standard-character-unification-table-for-decode",
- &Vstandard_character_unification_table_for_decode,
- "Table for unifying characters when reading.");
- Vstandard_character_unification_table_for_decode = Qnil;
+ DEFVAR_LISP ("standard-translation-table-for-decode",
+ &Vstandard_translation_table_for_decode,
+ "Table for translating characters while decoding.");
+ Vstandard_translation_table_for_decode = Qnil;
- DEFVAR_LISP ("standard-character-unification-table-for-encode",
- &Vstandard_character_unification_table_for_encode,
- "Table for unifying characters when writing.");
- Vstandard_character_unification_table_for_encode = Qnil;
+ DEFVAR_LISP ("standard-translation-table-for-encode",
+ &Vstandard_translation_table_for_encode,
+ "Table for translationg characters while encoding.");
+ Vstandard_translation_table_for_encode = Qnil;
DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,
"Alist of charsets vs revision numbers.\n\