X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ftext-coding.c;h=6ac6ae034e6d8db141c50374c7be05d7817d7d07;hb=5de20b74ae1be7bdf3a3a362d8a782168713665a;hp=7ba047ee61064a1b16af7acd426507508a6233a8;hpb=17154b8643a42a405158c07a3dbabeb83144c438;p=chise%2Fxemacs-chise.git diff --git a/src/text-coding.c b/src/text-coding.c index 7ba047e..6ac6ae0 100644 --- a/src/text-coding.c +++ b/src/text-coding.c @@ -46,18 +46,20 @@ Lisp_Object Vcoding_system_for_read; Lisp_Object Vcoding_system_for_write; Lisp_Object Vfile_name_coding_system; +Lisp_Object Vcoded_charset_entity_reference_alist; + /* Table of symbols identifying each coding category. */ -Lisp_Object coding_category_symbol[CODING_CATEGORY_LAST + 1]; +Lisp_Object coding_category_symbol[CODING_CATEGORY_LAST]; struct file_coding_dump { /* Coding system currently associated with each coding category. */ - Lisp_Object coding_category_system[CODING_CATEGORY_LAST + 1]; + Lisp_Object coding_category_system[CODING_CATEGORY_LAST]; /* Table of all coding categories in decreasing order of priority. This describes a permutation of the possible coding categories. */ - int coding_category_by_priority[CODING_CATEGORY_LAST + 1]; + int coding_category_by_priority[CODING_CATEGORY_LAST]; #if defined(MULE) && !defined(UTF2000) Lisp_Object ucs_to_mule_table[65536]; @@ -65,7 +67,7 @@ struct file_coding_dump { } *fcd; static const struct lrecord_description fcd_description_1[] = { - { XD_LISP_OBJECT_ARRAY, offsetof (struct file_coding_dump, coding_category_system), CODING_CATEGORY_LAST + 1 }, + { XD_LISP_OBJECT_ARRAY, offsetof (struct file_coding_dump, coding_category_system), CODING_CATEGORY_LAST }, #if defined(MULE) && !defined(UTF2000) { XD_LISP_OBJECT_ARRAY, offsetof (struct file_coding_dump, ucs_to_mule_table), countof (fcd->ucs_to_mule_table) }, #endif @@ -103,6 +105,8 @@ Lisp_Object Qshort, Qno_ascii_eol, Qno_ascii_cntl, Qseven, Qlock_shift; #endif #ifdef UTF2000 Lisp_Object Qdisable_composition; +Lisp_Object Quse_entity_reference; +Lisp_Object Qd, Qx, QX; #endif Lisp_Object Qencode, Qdecode; @@ -197,8 +201,10 @@ static int detect_coding_big5 (struct detection_state *st, const Extbyte *src, size_t n); static void decode_coding_big5 (Lstream *decoding, const Extbyte *src, unsigned_char_dynarr *dst, size_t n); -static void encode_coding_big5 (Lstream *encoding, const Bufbyte *src, - unsigned_char_dynarr *dst, size_t n); +void char_encode_big5 (struct encoding_stream *str, Emchar c, + unsigned_char_dynarr *dst, unsigned int *flags); +void char_finish_big5 (struct encoding_stream *str, + unsigned_char_dynarr *dst, unsigned int *flags); static int detect_coding_ucs4 (struct detection_state *st, const Extbyte *src, size_t n); @@ -327,6 +333,9 @@ static const struct lrecord_description coding_system_description[] = { { XD_STRUCT_PTR, offsetof (Lisp_Coding_System, iso2022.output_conv), 1, &ccsd_description }, { XD_LISP_OBJECT, offsetof (Lisp_Coding_System, ccl.decode) }, { XD_LISP_OBJECT, offsetof (Lisp_Coding_System, ccl.encode) }, +#ifdef UTF2000 + { XD_LISP_OBJECT, offsetof (Lisp_Coding_System, ccs_priority_list) }, +#endif #endif { XD_END } }; @@ -377,6 +386,13 @@ mark_coding_system (Lisp_Object obj) } } break; +#ifdef UTF2000 + + case CODESYS_BIG5: + mark_object (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 0)); + mark_object (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 1)); + break; +#endif case CODESYS_CCL: mark_object (CODING_SYSTEM_CCL_DECODE (codesys)); @@ -388,6 +404,9 @@ mark_coding_system (Lisp_Object obj) } mark_object (CODING_SYSTEM_PRE_WRITE_CONVERSION (codesys)); +#ifdef UTF2000 + mark_object (CODING_SYSTEM_CCS_PRIORITY_LIST (codesys)); +#endif return CODING_SYSTEM_POST_READ_CONVERSION (codesys); } @@ -636,12 +655,28 @@ allocate_coding_system (enum coding_system_type type, Lisp_Object name) CODING_SYSTEM_TYPE (codesys) = type; CODING_SYSTEM_MNEMONIC (codesys) = Qnil; #ifdef MULE +#ifdef UTF2000 + CODING_SYSTEM_CCS_PRIORITY_LIST (codesys) = Qnil; +#endif if (type == CODESYS_ISO2022) { int i; for (i = 0; i < 4; i++) CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i) = Qnil; } +#ifdef UTF2000 + if (type == CODESYS_BIG5) + { + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 0) + = Vcharset_ascii; + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 1) + = Vcharset_chinese_big5; + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 2) + = Qnil; + CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, 3) + = Qnil; + } +#endif else if (type == CODESYS_CCL) { CODING_SYSTEM_CCL_DECODE (codesys) = Qnil; @@ -792,6 +827,9 @@ character set. Recognized properties are: If non-nil, composition/decomposition for combining characters are disabled. +'use-entity-reference + If non-nil, SGML style entity-reference is used for non-system-characters. + 'post-read-conversion Function called after a file has been read in, to perform the decoding. Called with two arguments, START and END, denoting @@ -943,6 +981,8 @@ if TYPE is 'ccl: #ifdef UTF2000 else if (EQ (key, Qdisable_composition)) CODING_SYSTEM_DISABLE_COMPOSITION (codesys) = !NILP (value); + else if (EQ (key, Quse_entity_reference)) + CODING_SYSTEM_USE_ENTITY_REFERENCE (codesys) = !NILP (value); #endif #ifdef MULE else if (ty == CODESYS_ISO2022) @@ -992,6 +1032,15 @@ if TYPE is 'ccl: else signal_simple_error ("Unrecognized property", key); } +#ifdef UTF2000 + else if (ty == CODESYS_BIG5) + { + if (EQ (key, Qcharset_g0)) FROB_INITIAL_CHARSET (0); + else if (EQ (key, Qcharset_g1)) FROB_INITIAL_CHARSET (1); + else + signal_simple_error ("Unrecognized property", key); + } +#endif else if (EQ (type, Qccl)) { Lisp_Object sym; @@ -1396,6 +1445,12 @@ Return the PROP property of CODING-SYSTEM. else if (EQ (prop, Qpre_write_conversion)) return XCODING_SYSTEM_PRE_WRITE_CONVERSION (coding_system); #ifdef MULE +#ifdef UTF2000 + else if (EQ (prop, Qdisable_composition)) + return XCODING_SYSTEM_DISABLE_COMPOSITION (coding_system) ? Qt : Qnil; + else if (EQ (prop, Quse_entity_reference)) + return XCODING_SYSTEM_USE_ENTITY_REFERENCE (coding_system) ? Qt : Qnil; +#endif else if (type == CODESYS_ISO2022) { if (EQ (prop, Qcharset_g0)) @@ -1465,7 +1520,7 @@ decode_coding_category (Lisp_Object symbol) int i; CHECK_SYMBOL (symbol); - for (i = 0; i <= CODING_CATEGORY_LAST; i++) + for (i = 0; i < CODING_CATEGORY_LAST; i++) if (EQ (coding_category_symbol[i], symbol)) return i; @@ -1481,7 +1536,7 @@ Return a list of all recognized coding categories. int i; Lisp_Object list = Qnil; - for (i = CODING_CATEGORY_LAST; i >= 0; i--) + for (i = CODING_CATEGORY_LAST - 1; i >= 0; i--) list = Fcons (coding_category_symbol[i], list); return list; } @@ -1495,13 +1550,13 @@ previously. */ (list)) { - int category_to_priority[CODING_CATEGORY_LAST + 1]; + int category_to_priority[CODING_CATEGORY_LAST]; int i, j; Lisp_Object rest; /* First generate a list that maps coding categories to priorities. */ - for (i = 0; i <= CODING_CATEGORY_LAST; i++) + for (i = 0; i < CODING_CATEGORY_LAST; i++) category_to_priority[i] = -1; /* Highest priority comes from the specified list. */ @@ -1518,7 +1573,7 @@ previously. /* Now go through the existing categories by priority to retrieve the categories not yet specified and preserve their priority order. */ - for (j = 0; j <= CODING_CATEGORY_LAST; j++) + for (j = 0; j < CODING_CATEGORY_LAST; j++) { int cat = fcd->coding_category_by_priority[j]; if (category_to_priority[cat] < 0) @@ -1528,7 +1583,7 @@ previously. /* Now we need to construct the inverse of the mapping we just constructed. */ - for (i = 0; i <= CODING_CATEGORY_LAST; i++) + for (i = 0; i < CODING_CATEGORY_LAST; i++) fcd->coding_category_by_priority[category_to_priority[i]] = i; /* Phew! That was confusing. */ @@ -1543,7 +1598,7 @@ Return a list of coding categories in descending order of priority. int i; Lisp_Object list = Qnil; - for (i = CODING_CATEGORY_LAST; i >= 0; i--) + for (i = CODING_CATEGORY_LAST - 1; i >= 0; i--) list = Fcons (coding_category_symbol[fcd->coding_category_by_priority[i]], list); return list; @@ -1793,7 +1848,7 @@ coding_system_from_mask (int mask) #endif /* Look through the coding categories by priority and find the first one that is allowed. */ - for (i = 0; i <= CODING_CATEGORY_LAST; i++) + for (i = 0; i < CODING_CATEGORY_LAST; i++) { cat = fcd->coding_category_by_priority[i]; if ((mask & (1 << cat)) && @@ -1991,7 +2046,7 @@ type. Optional arg BUFFER defaults to the current buffer. #ifdef MULE decst.mask = postprocess_iso2022_mask (decst.mask); #endif - for (i = CODING_CATEGORY_LAST; i >= 0; i--) + for (i = CODING_CATEGORY_LAST - 1; i >= 0; i--) { int sys = fcd->coding_category_by_priority[i]; if (decst.mask & (1 << sys)) @@ -2193,6 +2248,9 @@ struct decoding_stream unsigned char counter; #endif #ifdef UTF2000 + unsigned char er_counter; + unsigned char er_buf[16]; + unsigned combined_char_count; Emchar combined_chars[16]; Lisp_Object combining_table; @@ -2224,10 +2282,11 @@ COMPOSE_ADD_CHAR(struct decoding_stream *str, { if (CODING_SYSTEM_DISABLE_COMPOSITION (str->codesys)) DECODE_ADD_UCS_CHAR (character, dst); - else if (!CHAR_ID_TABLE_P (str->combining_table)) + else if (!CHAR_TABLEP (str->combining_table)) { Lisp_Object ret - = get_char_id_table (character, Vcharacter_composition_table); + = get_char_id_table (XCHAR_TABLE(Vcharacter_composition_table), + character); if (NILP (ret)) DECODE_ADD_UCS_CHAR (character, dst); @@ -2241,12 +2300,15 @@ COMPOSE_ADD_CHAR(struct decoding_stream *str, else { Lisp_Object ret - = get_char_id_table (character, str->combining_table); + = get_char_id_table (XCHAR_TABLE(str->combining_table), + character); if (CHARP (ret)) { Emchar char2 = XCHARVAL (ret); - ret = get_char_id_table (char2, Vcharacter_composition_table); + ret = + get_char_id_table (XCHAR_TABLE(Vcharacter_composition_table), + char2); if (NILP (ret)) { DECODE_ADD_UCS_CHAR (char2, dst); @@ -2260,7 +2322,7 @@ COMPOSE_ADD_CHAR(struct decoding_stream *str, str->combining_table = ret; } } - else if (CHAR_ID_TABLE_P (ret)) + else if (CHAR_TABLEP (ret)) { str->combined_chars[str->combined_char_count++] = character; str->combining_table = ret; @@ -2411,6 +2473,7 @@ reset_decoding_stream (struct decoding_stream *str) str->counter = 0; #endif /* MULE */ #ifdef UTF2000 + str->er_counter = 0; str->combined_char_count = 0; str->combining_table = Qnil; #endif @@ -2901,6 +2964,10 @@ reset_encoding_stream (struct encoding_stream *str) str->encode_char = &char_encode_shift_jis; str->finish = &char_finish_shift_jis; break; + case CODESYS_BIG5: + str->encode_char = &char_encode_big5; + str->finish = &char_finish_big5; + break; default: break; } @@ -3016,9 +3083,6 @@ mule_encode (Lstream *encoding, const Bufbyte *src, encode_coding_no_conversion (encoding, src, dst, n); break; #ifdef MULE - case CODESYS_BIG5: - encode_coding_big5 (encoding, src, dst, n); - break; case CODESYS_CCL: str->ccl.last_block = str->flags & CODING_STATE_END; /* When applying ccl program to stream, MUST NOT set NULL @@ -3572,6 +3636,11 @@ decode_coding_big5 (Lstream *decoding, const Extbyte *src, unsigned int flags = str->flags; unsigned int cpos = str->cpos; eol_type_t eol_type = str->eol_type; +#ifdef UTF2000 + Lisp_Object ccs + = CODING_SYSTEM_ISO2022_INITIAL_CHARSET (DECODING_STREAM_DATA + (decoding)->codesys, 1); +#endif while (n--) { @@ -3582,9 +3651,12 @@ decode_coding_big5 (Lstream *decoding, const Extbyte *src, if (BYTE_BIG5_TWO_BYTE_2_P (c)) { #ifdef UTF2000 - DECODE_ADD_UCS_CHAR - (DECODE_CHAR (Vcharset_chinese_big5, (cpos << 8) | c), - dst); + int code_point = (cpos << 8) | c; + Emchar char_id = DECODE_DEFINED_CHAR (ccs, code_point); + + if (char_id < 0) + char_id = DECODE_CHAR (Vcharset_chinese_big5, code_point); + DECODE_ADD_UCS_CHAR (char_id, dst); #else unsigned char b1, b2, b3; DECODE_BIG5 (cpos, c, b1, b2, b3); @@ -3619,66 +3691,78 @@ decode_coding_big5 (Lstream *decoding, const Extbyte *src, /* Convert internally-formatted data to Big5. */ -static void -encode_coding_big5 (Lstream *encoding, const Bufbyte *src, - unsigned_char_dynarr *dst, size_t n) +void +char_encode_big5 (struct encoding_stream *str, Emchar ch, + unsigned_char_dynarr *dst, unsigned int *flags) { -#ifndef UTF2000 - unsigned char c; - struct encoding_stream *str = ENCODING_STREAM_DATA (encoding); - unsigned int flags = str->flags; - unsigned int ch = str->ch; eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys); - while (n--) + if (ch == '\n') { - c = *src++; - if (c == '\n') + if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) + Dynarr_add (dst, '\r'); + if (eol_type != EOL_CR) + Dynarr_add (dst, ch); + } + else + { +#ifdef UTF2000 + int code_point; + Lisp_Object ccs + = CODING_SYSTEM_ISO2022_INITIAL_CHARSET (str->codesys, 1); + + if ((code_point = charset_code_point (Vcharset_ascii, ch)) >= 0) + Dynarr_add (dst, code_point); + else if ((code_point = charset_code_point (ccs, ch)) >= 0) { - if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT) - Dynarr_add (dst, '\r'); - if (eol_type != EOL_CR) - Dynarr_add (dst, '\n'); + Dynarr_add (dst, code_point >> 8); + Dynarr_add (dst, code_point & 0xFF); } - else if (BYTE_ASCII_P (c)) + else if ((code_point + = charset_code_point (Vcharset_chinese_big5, ch)) >= 0) { - /* ASCII. */ - Dynarr_add (dst, c); + Dynarr_add (dst, code_point >> 8); + Dynarr_add (dst, code_point & 0xFF); } - else if (BUFBYTE_LEADING_BYTE_P (c)) - { - if (c == LEADING_BYTE_CHINESE_BIG5_1 || - c == LEADING_BYTE_CHINESE_BIG5_2) - { - /* A recognized leading byte. */ - ch = c; - continue; /* not done with this character. */ - } - /* otherwise just ignore this character. */ - } - else if (ch == LEADING_BYTE_CHINESE_BIG5_1 || - ch == LEADING_BYTE_CHINESE_BIG5_2) + else if ((code_point + = charset_code_point (Vcharset_chinese_big5_1, ch)) >= 0) { - /* Previous char was a recognized leading byte. */ - ch = (ch << 8) | c; - continue; /* not done with this character. */ + unsigned int I + = ((code_point >> 8) - 33) * (0xFF - 0xA1) + + ((code_point & 0xFF) - 33); + unsigned char b1 = I / BIG5_SAME_ROW + 0xA1; + unsigned char b2 = I % BIG5_SAME_ROW; + + b2 += b2 < 0x3F ? 0x40 : 0x62; + Dynarr_add (dst, b1); + Dynarr_add (dst, b2); } - else if (ch) + else if ((code_point + = charset_code_point (Vcharset_chinese_big5_2, ch)) >= 0) { - /* Encountering second byte of a Big5 character. */ + unsigned int I + = ((code_point >> 8) - 33) * (0xFF - 0xA1) + + ((code_point & 0xFF) - 33); unsigned char b1, b2; - ENCODE_BIG5 (ch >> 8, ch & 0xFF, c, b1, b2); + I += BIG5_SAME_ROW * (0xC9 - 0xA1); + b1 = I / BIG5_SAME_ROW + 0xA1; + b2 = I % BIG5_SAME_ROW; + b2 += b2 < 0x3F ? 0x40 : 0x62; Dynarr_add (dst, b1); Dynarr_add (dst, b2); } - - ch = 0; + else + Dynarr_add (dst, '?'); +#else +#endif } +} - str->flags = flags; - str->ch = ch; -#endif +void +char_finish_big5 (struct encoding_stream *str, unsigned_char_dynarr *dst, + unsigned int *flags) +{ } @@ -3949,6 +4033,7 @@ decode_coding_utf8 (Lstream *decoding, const Extbyte *src, unsigned int cpos = str->cpos; eol_type_t eol_type = str->eol_type; unsigned char counter = str->counter; + unsigned char er_counter = str->er_counter; while (n--) { @@ -3957,33 +4042,149 @@ decode_coding_utf8 (Lstream *decoding, const Extbyte *src, { if ( c < 0xC0 ) { - DECODE_HANDLE_EOL_TYPE (eol_type, c, flags, dst); - DECODE_ADD_UCS_CHAR (c, dst); - } - else if ( c < 0xE0 ) - { - cpos = c & 0x1f; - counter = 1; - } - else if ( c < 0xF0 ) - { - cpos = c & 0x0f; - counter = 2; - } - else if ( c < 0xF8 ) - { - cpos = c & 0x07; - counter = 3; - } - else if ( c < 0xFC ) - { - cpos = c & 0x03; - counter = 4; + if (!CODING_SYSTEM_USE_ENTITY_REFERENCE (str->codesys)) + { + DECODE_HANDLE_EOL_TYPE (eol_type, c, flags, dst); + DECODE_ADD_UCS_CHAR (c, dst); + } + else if (er_counter == 0) + { + if (c == '&') + { + str->er_buf[0] = '&'; + er_counter++; + } + else + { + DECODE_HANDLE_EOL_TYPE (eol_type, c, flags, dst); + DECODE_ADD_UCS_CHAR (c, dst); + } + } + else if (c == ';') + { + Lisp_Object string = make_string (str->er_buf, er_counter); + Lisp_Object rest = Vcoded_charset_entity_reference_alist; + Lisp_Object cell; + Lisp_Object ret; + Lisp_Object pat; + Lisp_Object ccs; + int base; + + while (!NILP (rest)) + { + cell = Fcar (rest); + ccs = Fcar (cell); + if (NILP (ccs = Ffind_charset (ccs))) + continue; + + cell = Fcdr (cell); + ret = Fcar (cell); + if (STRINGP (ret)) + pat = ret; + else + continue; + + cell = Fcdr (cell); + cell = Fcdr (cell); + ret = Fcar (cell); + if (EQ (ret, Qd)) + { + pat = concat3 (build_string ("^&"), + pat, build_string ("\\([0-9]+\\)$")); + base = 10; + } + else if (EQ (ret, Qx)) + { + pat = concat3 (build_string ("^&"), + pat, + build_string ("\\([0-9a-f]+\\)$")); + base = 16; + } + else if (EQ (ret, QX)) + { + pat = concat3 (build_string ("^&"), + pat, + build_string ("\\([0-9A-F]+\\)$")); + base = 16; + } + else + continue; + + if (!NILP (Fstring_match (pat, string, Qnil, Qnil))) + { + int code + = XINT (Fstring_to_number + (Fsubstring (string, + Fmatch_beginning + (make_int (1)), + Fmatch_end (make_int (1))), + make_int (base))); + + DECODE_ADD_UCS_CHAR (DECODE_CHAR (ccs, code), dst); + goto decoded; + } + rest = Fcdr (rest); + } + if (!NILP (Fstring_match + (build_string ("^&MCS-\\([0-9A-F]+\\)$"), + string, Qnil, Qnil))) + { + int code + = XINT (Fstring_to_number + (Fsubstring (string, + Fmatch_beginning + (make_int (1)), + Fmatch_end (make_int (1))), + make_int (16))); + + DECODE_ADD_UCS_CHAR (code, dst); + } + else + { + Dynarr_add_many (dst, str->er_buf, er_counter); + Dynarr_add (dst, ';'); + } + decoded: + er_counter = 0; + } + else if ( (er_counter >= 16) || (c <= ' ') || (c >= 0x7F) ) + { + Dynarr_add_many (dst, str->er_buf, er_counter); + er_counter = 0; + DECODE_ADD_UCS_CHAR (c, dst); + } + else + str->er_buf[er_counter++] = c; } else { - cpos = c & 0x01; - counter = 5; + Dynarr_add_many (dst, str->er_buf, er_counter); + er_counter = 0; + if ( c < 0xE0 ) + { + cpos = c & 0x1f; + counter = 1; + } + else if ( c < 0xF0 ) + { + cpos = c & 0x0f; + counter = 2; + } + else if ( c < 0xF8 ) + { + cpos = c & 0x07; + counter = 3; + } + else if ( c < 0xFC ) + { + cpos = c & 0x03; + counter = 4; + } + else + { + cpos = c & 0x01; + counter = 5; + } } } else if ( (c & 0xC0) == 0x80 ) @@ -4009,15 +4210,23 @@ decode_coding_utf8 (Lstream *decoding, const Extbyte *src, } if (flags & CODING_STATE_END) - if (counter > 0) - { - decode_output_utf8_partial_char (counter, cpos, dst); - cpos = 0; - counter = 0; - } + { + if (counter > 0) + { + decode_output_utf8_partial_char (counter, cpos, dst); + cpos = 0; + counter = 0; + } + else if ( er_counter > 0) + { + Dynarr_add_many (dst, str->er_buf, er_counter); + er_counter = 0; + } + } str->flags = flags; str->cpos = cpos; str->counter = counter; + str->er_counter = er_counter; } void @@ -4037,40 +4246,117 @@ char_encode_utf8 (struct encoding_stream *str, Emchar ch, { Dynarr_add (dst, ch); } - else if (ch <= 0x7ff) - { - Dynarr_add (dst, (ch >> 6) | 0xc0); - Dynarr_add (dst, (ch & 0x3f) | 0x80); - } - else if (ch <= 0xffff) - { - Dynarr_add (dst, (ch >> 12) | 0xe0); - Dynarr_add (dst, ((ch >> 6) & 0x3f) | 0x80); - Dynarr_add (dst, (ch & 0x3f) | 0x80); - } - else if (ch <= 0x1fffff) - { - Dynarr_add (dst, (ch >> 18) | 0xf0); - Dynarr_add (dst, ((ch >> 12) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 6) & 0x3f) | 0x80); - Dynarr_add (dst, (ch & 0x3f) | 0x80); - } - else if (ch <= 0x3ffffff) - { - Dynarr_add (dst, (ch >> 24) | 0xf8); - Dynarr_add (dst, ((ch >> 18) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 12) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 6) & 0x3f) | 0x80); - Dynarr_add (dst, (ch & 0x3f) | 0x80); - } else { - Dynarr_add (dst, (ch >> 30) | 0xfc); - Dynarr_add (dst, ((ch >> 24) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 18) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 12) & 0x3f) | 0x80); - Dynarr_add (dst, ((ch >> 6) & 0x3f) | 0x80); - Dynarr_add (dst, (ch & 0x3f) | 0x80); + int code_point = charset_code_point (Vcharset_ucs, ch); + + if ( (code_point < 0) || (code_point > 0x10FFFF) ) + { + if (CODING_SYSTEM_USE_ENTITY_REFERENCE (str->codesys)) + { + Lisp_Object rest = Vcoded_charset_entity_reference_alist; + Lisp_Object cell; + Lisp_Object ret; + Lisp_Object ccs; + int format_columns, idx; + char buf[16], format[16]; + + while (!NILP (rest)) + { + cell = Fcar (rest); + ccs = Fcar (cell); + if (!NILP (ccs = Ffind_charset (ccs))) + { + if ( (code_point + = charset_code_point (ccs, ch)) >= 0 ) + { + cell = Fcdr (cell); + ret = Fcar (cell); + if (STRINGP (ret) + && ((idx =XSTRING_LENGTH (ret)) <= 6)) + { + strncpy (format, XSTRING_DATA (ret), idx); + } + else + continue; + + cell = Fcdr (cell); + ret = Fcar (cell); + if (INTP (ret)) + { + format [idx++] = '%'; + format_columns = XINT (ret); + if ( (2 <= format_columns) + && (format_columns <= 8) ) + { + format [idx++] = '0'; + format [idx++] = '0' + format_columns; + } + } + + cell = Fcdr (cell); + ret = Fcar (cell); + if (EQ (ret, Qd)) + format [idx++] = 'd'; + else if (EQ (ret, Qx)) + format [idx++] = 'x'; + else if (EQ (ret, QX)) + format [idx++] = 'X'; + else + continue; + format [idx++] = 0; + + sprintf (buf, format, code_point); + Dynarr_add (dst, '&'); + Dynarr_add_many (dst, buf, strlen (buf)); + Dynarr_add (dst, ';'); + return; + } + } + rest = Fcdr (rest); + } + sprintf (buf, "&MCS-%08X;", ch); + Dynarr_add_many (dst, buf, strlen (buf)); + return; + } + else + code_point = ch; + } + if (code_point <= 0x7ff) + { + Dynarr_add (dst, (code_point >> 6) | 0xc0); + Dynarr_add (dst, (code_point & 0x3f) | 0x80); + } + else if (code_point <= 0xffff) + { + Dynarr_add (dst, (code_point >> 12) | 0xe0); + Dynarr_add (dst, ((code_point >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (code_point & 0x3f) | 0x80); + } + else if (code_point <= 0x1fffff) + { + Dynarr_add (dst, (code_point >> 18) | 0xf0); + Dynarr_add (dst, ((code_point >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (code_point & 0x3f) | 0x80); + } + else if (code_point <= 0x3ffffff) + { + Dynarr_add (dst, (code_point >> 24) | 0xf8); + Dynarr_add (dst, ((code_point >> 18) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (code_point & 0x3f) | 0x80); + } + else + { + Dynarr_add (dst, (code_point >> 30) | 0xfc); + Dynarr_add (dst, ((code_point >> 24) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 18) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 12) & 0x3f) | 0x80); + Dynarr_add (dst, ((code_point >> 6) & 0x3f) | 0x80); + Dynarr_add (dst, (code_point & 0x3f) | 0x80); + } } } @@ -5733,6 +6019,10 @@ syms_of_file_coding (void) #endif /* MULE */ #ifdef UTF2000 defsymbol (&Qdisable_composition, "disable-composition"); + defsymbol (&Quse_entity_reference, "use-entity-reference"); + defsymbol (&Qd, "d"); + defsymbol (&Qx, "x"); + defsymbol (&QX, "X"); #endif defsymbol (&Qencode, "encode"); defsymbol (&Qdecode, "decode"); @@ -5787,10 +6077,10 @@ vars_of_file_coding (void) int i; fcd = xnew (struct file_coding_dump); - dumpstruct (&fcd, &fcd_description); + dump_add_root_struct_ptr (&fcd, &fcd_description); /* Initialize to something reasonable ... */ - for (i = 0; i <= CODING_CATEGORY_LAST; i++) + for (i = 0; i < CODING_CATEGORY_LAST; i++) { fcd->coding_category_system[i] = Qnil; fcd->coding_category_by_priority[i] = i; @@ -5836,6 +6126,17 @@ Coding system used to convert pathnames when accessing files. */ ); Vfile_name_coding_system = Qnil; + DEFVAR_LISP ("coded-charset-entity-reference-alist", + &Vcoded_charset_entity_reference_alist /* +Alist of coded-charset vs corresponding entity-reference. +Each element looks like (CCS PREFIX CODE-COLUMNS CODE-TYPE). +CCS is coded-charset. +CODE-COLUMNS is columns of code-point of entity-reference. +CODE-TYPE is format type of code-point of entity-reference. +`d' means decimal value and `x' means hexadecimal value. +*/ ); + Vcoded_charset_entity_reference_alist = Qnil; + DEFVAR_BOOL ("enable-multibyte-characters", &enable_multibyte_characters /* Non-nil means the buffer contents are regarded as multi-byte form of characters, not a binary code. This affects the display, file I/O, @@ -5854,7 +6155,7 @@ complex_vars_of_file_coding (void) make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); the_codesys_prop_dynarr = Dynarr_new (codesys_prop); - dumpstruct (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description); + dump_add_root_struct_ptr (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description); #define DEFINE_CODESYS_PROP(Prop_Type, Sym) do \ { \ @@ -5892,6 +6193,10 @@ complex_vars_of_file_coding (void) DEFINE_CODESYS_PROP (CODESYS_PROP_CCL, Qencode); DEFINE_CODESYS_PROP (CODESYS_PROP_CCL, Qdecode); +#ifdef UTF2000 + DEFINE_CODESYS_PROP (CODESYS_PROP_ALL_OK, Qdisable_composition); + DEFINE_CODESYS_PROP (CODESYS_PROP_ALL_OK, Quse_entity_reference); +#endif #endif /* MULE */ /* Need to create this here or we're really screwed. */ Fmake_coding_system @@ -5930,7 +6235,7 @@ complex_vars_of_file_coding (void) #if defined(MULE) && !defined(UTF2000) { - unsigned int i; + size_t i; for (i = 0; i < countof (fcd->ucs_to_mule_table); i++) fcd->ucs_to_mule_table[i] = Qnil;