# HG changeset patch # User Kenichi Handa # Date 1022066085 0 # Node ID 74b74f59bc09b9db14d7f36f7bafc642f7a77ac6 # Parent 235ee9d10206d171df4f7f74f0a140aa5a9b453d (decode_coding_charset): Adjusted for the change of Fdefine_coding_system_internal. (Fdefine_coding_system_internal): For a coding system of `charset' type, store a list of charset IDs in `charset_attr_charset_valids' element of coding attributes. diff -r 235ee9d10206 -r 74b74f59bc09 src/coding.c --- a/src/coding.c Wed May 22 11:14:25 2002 +0000 +++ b/src/coding.c Wed May 22 11:14:45 2002 +0000 @@ -4320,6 +4320,8 @@ ONE_MORE_BYTE (c); if (c == '\r') { + /* Here we assume that no charset maps '\r' to something + else. */ if (EQ (eol_type, Qdos)) { if (src < src_end @@ -4333,28 +4335,70 @@ { Lisp_Object val; struct charset *charset; + int dim; + unsigned code; int c1; val = AREF (valids, c); if (NILP (val)) goto invalid_code; - charset = CHARSET_FROM_ID (XFASTINT (val)); - if (CHARSET_DIMENSION (charset) > 1) + if (INTEGERP (val)) { - ONE_MORE_BYTE (c1); - c = (c << 8) | c1; - if (CHARSET_DIMENSION (charset) > 2) + charset = CHARSET_FROM_ID (XFASTINT (val)); + dim = CHARSET_DIMENSION (charset); + code = c; + if (dim > 1) { ONE_MORE_BYTE (c1); - c = (c << 8) | c1; - if (CHARSET_DIMENSION (charset) > 3) + code = (code << 8) | c1; + if (dim > 2) { ONE_MORE_BYTE (c1); - c = (c << 8) | c1; + code = (code << 8) | c1; + if (dim > 3) + { + ONE_MORE_BYTE (c1); + code = (c << 8) | c1; + } } } + CODING_DECODE_CHAR (coding, src, src_base, src_end, + charset, code, c); } - CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c); + else + { + /* VAL is a list of charset IDs. It is assured that the + list is sorted by charset dimensions (smaller one + comes first). */ + int b[4]; + int len = 1; + + b[0] = c; + /* VAL is a list of charset IDs. */ + while (CONSP (val)) + { + charset = CHARSET_FROM_ID (XFASTINT (XCAR (val))); + dim = CHARSET_DIMENSION (charset); + while (len < dim) + { + ONE_MORE_BYTE (c1); + b[len++] = c1; + } + if (dim == 1) + code = b[0]; + else if (dim == 2) + code = (b[0] << 8) | b[1]; + else if (dim == 3) + code = (b[0] << 16) | (b[1] << 8) | b[2]; + else + code = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; + CODING_DECODE_CHAR (coding, src, src_base, + src_end, charset, code, c); + if (c >= 0) + break; + val = XCDR (val); + } + } if (c < 0) goto invalid_code; } @@ -7366,20 +7410,61 @@ if (EQ (coding_type, Qcharset)) { + /* Generate a lisp vector of 256 elements. Each element is nil, + integer, or a list of charset IDs. + + If Nth element is nil, the byte code N is invalid in this + coding system. + + If Nth element is a number NUM, N is the first byte of a + charset whose ID is NUM. + + If Nth element is a list of charset IDs, N is the first byte + of one of them. The list is sorted by dimensions of the + charsets. A charset of smaller dimension comes firtst. + */ val = Fmake_vector (make_number (256), Qnil); for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) { - struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (tail))); - int idx = (CHARSET_DIMENSION (charset) - 1) * 4; - + struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail))); + int dim = CHARSET_DIMENSION (charset); + int idx = (dim - 1) * 4; + for (i = charset->code_space[idx]; i <= charset->code_space[idx + 1]; i++) { - if (NILP (AREF (val, i))) - ASET (val, i, XCAR (tail)); + Lisp_Object tmp, tmp2; + int dim2; + + tmp = AREF (val, i); + if (NILP (tmp)) + tmp = XCAR (tail); + else if (NUMBERP (tmp)) + { + dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp))); + if (dim < dim2) + tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil)); + else + tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil)); + } else - error ("Charsets conflicts in the first byte"); + { + for (tmp2 = tmp; CONSP (tmp2); tmp2 = XCDR (tmp2)) + { + dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (XCAR (tmp2)))); + if (dim < dim2) + break; + } + if (NILP (tmp2)) + tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil)); + else + { + XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2))); + XSETCAR (tmp2, XCAR (tail)); + } + } + ASET (val, i, tmp); } } ASET (attrs, coding_attr_charset_valids, val);