X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fmule-charset.c;h=05d38ce8d59b017d53eaa306a42c683d56689a0a;hb=7b4b1b26bb371112bf3e18732864bc08584127b6;hp=e9131b031187d0dd12887a000cb48ca8a4e1c045;hpb=7be94d13ea93e1016ca5569b349618adacccda1b;p=chise%2Fxemacs-chise.git- diff --git a/src/mule-charset.c b/src/mule-charset.c index e9131b0..05d38ce 100644 --- a/src/mule-charset.c +++ b/src/mule-charset.c @@ -25,6 +25,9 @@ Boston, MA 02111-1307, USA. */ /* Rewritten by Ben Wing . */ #include +#ifdef UTF2000 +#include +#endif #include "lisp.h" #include "buffer.h" @@ -62,11 +65,15 @@ Lisp_Object Vcharset_chinese_cns11643_2; #ifdef UTF2000 Lisp_Object Vcharset_ucs; Lisp_Object Vcharset_ucs_bmp; +Lisp_Object Vcharset_ucs_cns; Lisp_Object Vcharset_latin_viscii; +Lisp_Object Vcharset_latin_tcvn5712; Lisp_Object Vcharset_latin_viscii_lower; Lisp_Object Vcharset_latin_viscii_upper; +Lisp_Object Vcharset_chinese_big5; Lisp_Object Vcharset_ideograph_daikanwa; Lisp_Object Vcharset_mojikyo; +Lisp_Object Vcharset_mojikyo_2022_1; Lisp_Object Vcharset_mojikyo_pj_1; Lisp_Object Vcharset_mojikyo_pj_2; Lisp_Object Vcharset_mojikyo_pj_3; @@ -110,7 +117,7 @@ static int composite_char_col_next; struct charset_lookup *chlook; static const struct lrecord_description charset_lookup_description_1[] = { - { XD_LISP_OBJECT, offsetof(struct charset_lookup, charset_by_leading_byte), + { XD_LISP_OBJECT_ARRAY, offsetof (struct charset_lookup, charset_by_leading_byte), #ifdef UTF2000 128+4*128 #else @@ -120,7 +127,7 @@ static const struct lrecord_description charset_lookup_description_1[] = { }; static const struct struct_description charset_lookup_description = { - sizeof(struct charset_lookup), + sizeof (struct charset_lookup), charset_lookup_description_1 }; @@ -158,263 +165,715 @@ const Bytecount rep_bytes_by_first_byte[0xA0] = #ifdef UTF2000 +#define BT_UINT8_MIN 0 +#define BT_UINT8_MAX (UCHAR_MAX - 3) +#define BT_UINT8_t (UCHAR_MAX - 2) +#define BT_UINT8_nil (UCHAR_MAX - 1) +#define BT_UINT8_unbound UCHAR_MAX + +INLINE_HEADER int INT_UINT8_P (Lisp_Object obj); +INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj); +INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj); +INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n); +INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n); + +INLINE_HEADER int +INT_UINT8_P (Lisp_Object obj) +{ + if (INTP (obj)) + { + int num = XINT (obj); + + return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX); + } + else + return 0; +} + +INLINE_HEADER int +UINT8_VALUE_P (Lisp_Object obj) +{ + return EQ (obj, Qunbound) + || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj); +} + +INLINE_HEADER unsigned char +UINT8_ENCODE (Lisp_Object obj) +{ + if (EQ (obj, Qunbound)) + return BT_UINT8_unbound; + else if (EQ (obj, Qnil)) + return BT_UINT8_nil; + else if (EQ (obj, Qt)) + return BT_UINT8_t; + else + return XINT (obj); +} + +INLINE_HEADER Lisp_Object +UINT8_DECODE (unsigned char n) +{ + if (n == BT_UINT8_unbound) + return Qunbound; + else if (n == BT_UINT8_nil) + return Qnil; + else if (n == BT_UINT8_t) + return Qt; + else + return make_int (n); +} + static Lisp_Object -mark_char_byte_table (Lisp_Object obj) +mark_uint8_byte_table (Lisp_Object obj) { - struct Lisp_Char_Byte_Table *cte = XCHAR_BYTE_TABLE (obj); + return Qnil; +} + +static void +print_uint8_byte_table (Lisp_Object obj, + Lisp_Object printcharfun, int escapeflag) +{ + Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj); int i; + struct gcpro gcpro1, gcpro2; + GCPRO2 (obj, printcharfun); + write_c_string ("\n#property[i]); + unsigned char n = bte->property[i]; + if ( (i & 15) == 0 ) + write_c_string ("\n ", printcharfun); + write_c_string (" ", printcharfun); + if (n == BT_UINT8_unbound) + write_c_string ("void", printcharfun); + else if (n == BT_UINT8_nil) + write_c_string ("nil", printcharfun); + else if (n == BT_UINT8_t) + write_c_string ("t", printcharfun); + else + { + char buf[4]; + + sprintf (buf, "%hd", n); + write_c_string (buf, printcharfun); + } } - return Qnil; + UNGCPRO; + write_c_string (">", printcharfun); } static int -char_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) +uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) { - struct Lisp_Char_Byte_Table *cte1 = XCHAR_BYTE_TABLE (obj1); - struct Lisp_Char_Byte_Table *cte2 = XCHAR_BYTE_TABLE (obj2); + Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1); + Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2); int i; for (i = 0; i < 256; i++) - if (CHAR_BYTE_TABLE_P (cte1->property[i])) - { - if (CHAR_BYTE_TABLE_P (cte2->property[i])) - { - if (!char_byte_table_equal (cte1->property[i], - cte2->property[i], depth + 1)) - return 0; - } - else - return 0; - } - else - if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1)) - return 0; + if (te1->property[i] != te2->property[i]) + return 0; return 1; } static unsigned long -char_byte_table_hash (Lisp_Object obj, int depth) +uint8_byte_table_hash (Lisp_Object obj, int depth) { - struct Lisp_Char_Byte_Table *cte = XCHAR_BYTE_TABLE (obj); + Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj); + int i; + hashcode_t hash = 0; - return internal_array_hash (cte->property, 256, depth); + for (i = 0; i < 256; i++) + hash = HASH2 (hash, te->property[i]); + return hash; } -static const struct lrecord_description char_byte_table_description[] = { - { XD_LISP_OBJECT, offsetof(struct Lisp_Char_Byte_Table, property), 256 }, - { XD_END } -}; - -DEFINE_LRECORD_IMPLEMENTATION ("char-byte-table", char_byte_table, - mark_char_byte_table, - internal_object_printer, - 0, char_byte_table_equal, - char_byte_table_hash, - char_byte_table_description, - struct Lisp_Char_Byte_Table); +DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table, + mark_uint8_byte_table, + print_uint8_byte_table, + 0, uint8_byte_table_equal, + uint8_byte_table_hash, + 0 /* uint8_byte_table_description */, + Lisp_Uint8_Byte_Table); static Lisp_Object -make_char_byte_table (Lisp_Object initval) +make_uint8_byte_table (unsigned char initval) { Lisp_Object obj; int i; - struct Lisp_Char_Byte_Table *cte = - alloc_lcrecord_type (struct Lisp_Char_Byte_Table, - &lrecord_char_byte_table); + Lisp_Uint8_Byte_Table *cte; + + cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table, + &lrecord_uint8_byte_table); for (i = 0; i < 256; i++) cte->property[i] = initval; - XSETCHAR_BYTE_TABLE (obj, cte); + XSETUINT8_BYTE_TABLE (obj, cte); return obj; } +static int +uint8_byte_table_same_value_p (Lisp_Object obj) +{ + Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj); + unsigned char v0 = bte->property[0]; + int i; + + for (i = 1; i < 256; i++) + { + if (bte->property[i] != v0) + return 0; + } + return -1; +} + + +#define BT_UINT16_MIN 0 +#define BT_UINT16_MAX (USHRT_MAX - 3) +#define BT_UINT16_t (USHRT_MAX - 2) +#define BT_UINT16_nil (USHRT_MAX - 1) +#define BT_UINT16_unbound USHRT_MAX + +INLINE_HEADER int INT_UINT16_P (Lisp_Object obj); +INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj); +INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj); +INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us); + +INLINE_HEADER int +INT_UINT16_P (Lisp_Object obj) +{ + if (INTP (obj)) + { + int num = XINT (obj); + + return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX); + } + else + return 0; +} + +INLINE_HEADER int +UINT16_VALUE_P (Lisp_Object obj) +{ + return EQ (obj, Qunbound) + || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj); +} + +INLINE_HEADER unsigned short +UINT16_ENCODE (Lisp_Object obj) +{ + if (EQ (obj, Qunbound)) + return BT_UINT16_unbound; + else if (EQ (obj, Qnil)) + return BT_UINT16_nil; + else if (EQ (obj, Qt)) + return BT_UINT16_t; + else + return XINT (obj); +} + +INLINE_HEADER Lisp_Object +UINT16_DECODE (unsigned short n) +{ + if (n == BT_UINT16_unbound) + return Qunbound; + else if (n == BT_UINT16_nil) + return Qnil; + else if (n == BT_UINT16_t) + return Qt; + else + return make_int (n); +} + +INLINE_HEADER unsigned short +UINT8_TO_UINT16 (unsigned char n) +{ + if (n == BT_UINT8_unbound) + return BT_UINT16_unbound; + else if (n == BT_UINT8_nil) + return BT_UINT16_nil; + else if (n == BT_UINT8_t) + return BT_UINT16_t; + else + return n; +} + static Lisp_Object -copy_char_byte_table (Lisp_Object entry) +mark_uint16_byte_table (Lisp_Object obj) { - struct Lisp_Char_Byte_Table *cte = XCHAR_BYTE_TABLE (entry); - Lisp_Object obj; + return Qnil; +} + +static void +print_uint16_byte_table (Lisp_Object obj, + Lisp_Object printcharfun, int escapeflag) +{ + Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj); int i; - struct Lisp_Char_Byte_Table *ctenew = - alloc_lcrecord_type (struct Lisp_Char_Byte_Table, - &lrecord_char_byte_table); + struct gcpro gcpro1, gcpro2; + GCPRO2 (obj, printcharfun); + write_c_string ("\n#property[i]; - if (CHAR_BYTE_TABLE_P (new)) - ctenew->property[i] = copy_char_byte_table (new); + unsigned short n = bte->property[i]; + if ( (i & 15) == 0 ) + write_c_string ("\n ", printcharfun); + write_c_string (" ", printcharfun); + if (n == BT_UINT16_unbound) + write_c_string ("void", printcharfun); + else if (n == BT_UINT16_nil) + write_c_string ("nil", printcharfun); + else if (n == BT_UINT16_t) + write_c_string ("t", printcharfun); else - ctenew->property[i] = new; + { + char buf[7]; + + sprintf (buf, "%hd", n); + write_c_string (buf, printcharfun); + } } + UNGCPRO; + write_c_string (">", printcharfun); +} + +static int +uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) +{ + Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1); + Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2); + int i; + + for (i = 0; i < 256; i++) + if (te1->property[i] != te2->property[i]) + return 0; + return 1; +} - XSETCHAR_BYTE_TABLE (obj, ctenew); +static unsigned long +uint16_byte_table_hash (Lisp_Object obj, int depth) +{ + Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj); + int i; + hashcode_t hash = 0; + + for (i = 0; i < 256; i++) + hash = HASH2 (hash, te->property[i]); + return hash; +} + +DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table, + mark_uint16_byte_table, + print_uint16_byte_table, + 0, uint16_byte_table_equal, + uint16_byte_table_hash, + 0 /* uint16_byte_table_description */, + Lisp_Uint16_Byte_Table); + +static Lisp_Object +make_uint16_byte_table (unsigned short initval) +{ + Lisp_Object obj; + int i; + Lisp_Uint16_Byte_Table *cte; + + cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table, + &lrecord_uint16_byte_table); + + for (i = 0; i < 256; i++) + cte->property[i] = initval; + + XSETUINT16_BYTE_TABLE (obj, cte); + return obj; +} + +static Lisp_Object +expand_uint8_byte_table_to_uint16 (Lisp_Object table) +{ + Lisp_Object obj; + int i; + Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table); + Lisp_Uint16_Byte_Table* cte; + + cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table, + &lrecord_uint16_byte_table); + for (i = 0; i < 256; i++) + { + cte->property[i] = UINT8_TO_UINT16 (bte->property[i]); + } + XSETUINT16_BYTE_TABLE (obj, cte); return obj; } +static int +uint16_byte_table_same_value_p (Lisp_Object obj) +{ + Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj); + unsigned short v0 = bte->property[0]; + int i; + + for (i = 1; i < 256; i++) + { + if (bte->property[i] != v0) + return 0; + } + return -1; +} + static Lisp_Object -mark_char_code_table (Lisp_Object obj) +mark_byte_table (Lisp_Object obj) { - struct Lisp_Char_Code_Table *cte = XCHAR_CODE_TABLE (obj); + Lisp_Byte_Table *cte = XBYTE_TABLE (obj); + int i; - return cte->table; + for (i = 0; i < 256; i++) + { + mark_object (cte->property[i]); + } + return Qnil; +} + +static void +print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) +{ + Lisp_Byte_Table *bte = XBYTE_TABLE (obj); + int i; + struct gcpro gcpro1, gcpro2; + GCPRO2 (obj, printcharfun); + + write_c_string ("\n#property[i]; + if ( (i & 15) == 0 ) + write_c_string ("\n ", printcharfun); + write_c_string (" ", printcharfun); + if (EQ (elt, Qunbound)) + write_c_string ("void", printcharfun); + else + print_internal (elt, printcharfun, escapeflag); + } + UNGCPRO; + write_c_string (">", printcharfun); } static int -char_code_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) +byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) { - struct Lisp_Char_Code_Table *cte1 = XCHAR_CODE_TABLE (obj1); - struct Lisp_Char_Code_Table *cte2 = XCHAR_CODE_TABLE (obj2); + Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1); + Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2); + int i; - return char_byte_table_equal (cte1->table, cte2->table, depth + 1); + for (i = 0; i < 256; i++) + if (BYTE_TABLE_P (cte1->property[i])) + { + if (BYTE_TABLE_P (cte2->property[i])) + { + if (!byte_table_equal (cte1->property[i], + cte2->property[i], depth + 1)) + return 0; + } + else + return 0; + } + else + if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1)) + return 0; + return 1; } static unsigned long -char_code_table_hash (Lisp_Object obj, int depth) +byte_table_hash (Lisp_Object obj, int depth) { - struct Lisp_Char_Code_Table *cte = XCHAR_CODE_TABLE (obj); + Lisp_Byte_Table *cte = XBYTE_TABLE (obj); - return char_code_table_hash (cte->table, depth + 1); + return internal_array_hash (cte->property, 256, depth); } -static const struct lrecord_description char_code_table_description[] = { - { XD_LISP_OBJECT, offsetof(struct Lisp_Char_Code_Table, table), 1 }, +static const struct lrecord_description byte_table_description[] = { + { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 }, { XD_END } }; -DEFINE_LRECORD_IMPLEMENTATION ("char-code-table", char_code_table, - mark_char_code_table, - internal_object_printer, - 0, char_code_table_equal, - char_code_table_hash, - char_code_table_description, - struct Lisp_Char_Code_Table); +DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table, + mark_byte_table, + print_byte_table, + 0, byte_table_equal, + byte_table_hash, + byte_table_description, + Lisp_Byte_Table); static Lisp_Object -make_char_code_table (Lisp_Object initval) +make_byte_table (Lisp_Object initval) { Lisp_Object obj; - struct Lisp_Char_Code_Table *cte = - alloc_lcrecord_type (struct Lisp_Char_Code_Table, - &lrecord_char_code_table); + int i; + Lisp_Byte_Table *cte; + + cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table); - cte->table = make_char_byte_table (initval); + for (i = 0; i < 256; i++) + cte->property[i] = initval; - XSETCHAR_CODE_TABLE (obj, cte); + XSETBYTE_TABLE (obj, cte); return obj; } -static Lisp_Object -copy_char_code_table (Lisp_Object entry) +static int +byte_table_same_value_p (Lisp_Object obj) { - struct Lisp_Char_Code_Table *cte = XCHAR_CODE_TABLE (entry); - Lisp_Object obj; - struct Lisp_Char_Code_Table *ctenew = - alloc_lcrecord_type (struct Lisp_Char_Code_Table, - &lrecord_char_code_table); + Lisp_Byte_Table *bte = XBYTE_TABLE (obj); + Lisp_Object v0 = bte->property[0]; + int i; - ctenew->table = copy_char_byte_table (cte->table); - XSETCHAR_CODE_TABLE (obj, ctenew); - return obj; + for (i = 1; i < 256; i++) + { + if (!internal_equal (bte->property[i], v0, 0)) + return 0; + } + return -1; } -Lisp_Object -get_char_code_table (Emchar ch, Lisp_Object table) -{ - unsigned int code = ch; - struct Lisp_Char_Byte_Table* cpt - = XCHAR_BYTE_TABLE (XCHAR_CODE_TABLE (table)->table); - Lisp_Object ret = cpt->property [(unsigned char)(code >> 24)]; - - if (CHAR_BYTE_TABLE_P (ret)) - cpt = XCHAR_BYTE_TABLE (ret); - else - return ret; - - ret = cpt->property [(unsigned char) (code >> 16)]; - if (CHAR_BYTE_TABLE_P (ret)) - cpt = XCHAR_BYTE_TABLE (ret); - else - return ret; +Lisp_Object get_byte_table (Lisp_Object table, unsigned char idx); +Lisp_Object put_byte_table (Lisp_Object table, unsigned char idx, + Lisp_Object value); - ret = cpt->property [(unsigned char) (code >> 8)]; - if (CHAR_BYTE_TABLE_P (ret)) - cpt = XCHAR_BYTE_TABLE (ret); +Lisp_Object +get_byte_table (Lisp_Object table, unsigned char idx) +{ + if (UINT8_BYTE_TABLE_P (table)) + return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]); + else if (UINT16_BYTE_TABLE_P (table)) + return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]); + else if (BYTE_TABLE_P (table)) + return XBYTE_TABLE(table)->property[idx]; else - return ret; - - return cpt->property [(unsigned char) code]; + return table; } -void -put_char_code_table (Emchar ch, Lisp_Object value, Lisp_Object table) +Lisp_Object +put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value) { - unsigned int code = ch; - struct Lisp_Char_Byte_Table* cpt1 - = XCHAR_BYTE_TABLE (XCHAR_CODE_TABLE (table)->table); - Lisp_Object ret = cpt1->property[(unsigned char)(code >> 24)]; + if (UINT8_BYTE_TABLE_P (table)) + { + if (UINT8_VALUE_P (value)) + { + XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value); + if (!UINT8_BYTE_TABLE_P (value) && + !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value) + && uint8_byte_table_same_value_p (table)) + { + return value; + } + } + else if (UINT16_VALUE_P (value)) + { + Lisp_Object new = expand_uint8_byte_table_to_uint16 (table); - if (CHAR_BYTE_TABLE_P (ret)) + XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value); + return new; + } + else + { + Lisp_Object new = make_byte_table (Qnil); + int i; + + for (i = 0; i < 256; i++) + { + XBYTE_TABLE(new)->property[i] + = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]); + } + XBYTE_TABLE(new)->property[idx] = value; + return new; + } + } + else if (UINT16_BYTE_TABLE_P (table)) { - struct Lisp_Char_Byte_Table* cpt2 = XCHAR_BYTE_TABLE (ret); - - ret = cpt2->property[(unsigned char)(code >> 16)]; - if (CHAR_BYTE_TABLE_P (ret)) + if (UINT16_VALUE_P (value)) { - struct Lisp_Char_Byte_Table* cpt3 = XCHAR_BYTE_TABLE (ret); - - ret = cpt3->property[(unsigned char)(code >> 8)]; - if (CHAR_BYTE_TABLE_P (ret)) + XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value); + if (!UINT8_BYTE_TABLE_P (value) && + !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value) + && uint16_byte_table_same_value_p (table)) { - struct Lisp_Char_Byte_Table* cpt4 - = XCHAR_BYTE_TABLE (ret); - - cpt4->property[(unsigned char)code] = value; + return value; } - else if (!EQ (ret, value)) + } + else + { + Lisp_Object new = make_byte_table (Qnil); + int i; + + for (i = 0; i < 256; i++) { - Lisp_Object cpt4 = make_char_byte_table (ret); - - XCHAR_BYTE_TABLE(cpt4)->property[(unsigned char)code] = value; - cpt3->property[(unsigned char)(code >> 8)] = cpt4; + XBYTE_TABLE(new)->property[i] + = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]); } + XBYTE_TABLE(new)->property[idx] = value; + return new; } - else if (!EQ (ret, value)) + } + else if (BYTE_TABLE_P (table)) + { + XBYTE_TABLE(table)->property[idx] = value; + if (!UINT8_BYTE_TABLE_P (value) && + !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value) + && byte_table_same_value_p (table)) { - Lisp_Object cpt3 = make_char_byte_table (ret); - Lisp_Object cpt4 = make_char_byte_table (ret); - - XCHAR_BYTE_TABLE(cpt4)->property[(unsigned char)code] = value; - XCHAR_BYTE_TABLE(cpt3)->property[(unsigned char)(code >> 8)] - = cpt4; - cpt2->property[(unsigned char)(code >> 16)] = cpt3; + return value; } } - else if (!EQ (ret, value)) + else if (!internal_equal (table, value, 0)) { - Lisp_Object cpt2 = make_char_byte_table (ret); - Lisp_Object cpt3 = make_char_byte_table (ret); - Lisp_Object cpt4 = make_char_byte_table (ret); - - XCHAR_BYTE_TABLE(cpt4)->property[(unsigned char)code] = value; - XCHAR_BYTE_TABLE(cpt3)->property[(unsigned char)(code >> 8)] = cpt4; - XCHAR_BYTE_TABLE(cpt2)->property[(unsigned char)(code >> 16)] = cpt3; - cpt1->property[(unsigned char)(code >> 24)] = cpt2; + if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value)) + { + table = make_uint8_byte_table (UINT8_ENCODE (table)); + XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value); + } + else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value)) + { + table = make_uint16_byte_table (UINT16_ENCODE (table)); + XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value); + } + else + { + table = make_byte_table (table); + XBYTE_TABLE(table)->property[idx] = value; + } } + return table; } +static Lisp_Object +mark_char_id_table (Lisp_Object obj) +{ + Lisp_Char_ID_Table *cte = XCHAR_ID_TABLE (obj); + + return cte->table; +} -Lisp_Object Vcharacter_attribute_table; +static void +print_char_id_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) +{ + Lisp_Object table = XCHAR_ID_TABLE (obj)->table; + int i; + struct gcpro gcpro1, gcpro2; + GCPRO2 (obj, printcharfun); + + write_c_string ("#", printcharfun); +} + +static int +char_id_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) +{ + Lisp_Object table1 = XCHAR_ID_TABLE (obj1)->table; + Lisp_Object table2 = XCHAR_ID_TABLE (obj2)->table; + int i; + + for (i = 0; i < 256; i++) + { + if (!internal_equal (get_byte_table (table1, i), + get_byte_table (table2, i), 0)) + return 0; + } + return -1; +} + +static unsigned long +char_id_table_hash (Lisp_Object obj, int depth) +{ + Lisp_Char_ID_Table *cte = XCHAR_ID_TABLE (obj); + + return char_id_table_hash (cte->table, depth + 1); +} + +static const struct lrecord_description char_id_table_description[] = { + { XD_LISP_OBJECT, offsetof(Lisp_Char_ID_Table, table) }, + { XD_END } +}; + +DEFINE_LRECORD_IMPLEMENTATION ("char-id-table", char_id_table, + mark_char_id_table, + print_char_id_table, + 0, char_id_table_equal, + char_id_table_hash, + char_id_table_description, + Lisp_Char_ID_Table); + +static Lisp_Object +make_char_id_table (Lisp_Object initval) +{ + Lisp_Object obj; + Lisp_Char_ID_Table *cte; + + cte = alloc_lcrecord_type (Lisp_Char_ID_Table, &lrecord_char_id_table); + + cte->table = make_byte_table (initval); + + XSETCHAR_ID_TABLE (obj, cte); + return obj; +} + + +Lisp_Object +get_char_id_table (Emchar ch, Lisp_Object table) +{ + unsigned int code = ch; + + return + get_byte_table + (get_byte_table + (get_byte_table + (get_byte_table + (XCHAR_ID_TABLE (table)->table, + (unsigned char)(code >> 24)), + (unsigned char) (code >> 16)), + (unsigned char) (code >> 8)), + (unsigned char) code); +} + +void put_char_id_table (Emchar ch, Lisp_Object value, Lisp_Object table); +void +put_char_id_table (Emchar ch, Lisp_Object value, Lisp_Object table) +{ + unsigned int code = ch; + Lisp_Object table1, table2, table3, table4; + + table1 = XCHAR_ID_TABLE (table)->table; + table2 = get_byte_table (table1, (unsigned char)(code >> 24)); + table3 = get_byte_table (table2, (unsigned char)(code >> 16)); + table4 = get_byte_table (table3, (unsigned char)(code >> 8)); + + table4 = put_byte_table (table4, (unsigned char)code, value); + table3 = put_byte_table (table3, (unsigned char)(code >> 8), table4); + table2 = put_byte_table (table2, (unsigned char)(code >> 16), table3); + XCHAR_ID_TABLE (table)->table + = put_byte_table (table1, (unsigned char)(code >> 24), table2); +} + + +Lisp_Object Vchar_attribute_hash_table; Lisp_Object Vcharacter_composition_table; Lisp_Object Vcharacter_variant_table; +Lisp_Object Qideograph_daikanwa; Lisp_Object Q_decomposition; +Lisp_Object Qucs; Lisp_Object Q_ucs; Lisp_Object Qcompat; Lisp_Object Qisolated; @@ -433,8 +892,14 @@ Lisp_Object Qnarrow; Lisp_Object Qsmall; Lisp_Object Qfont; +Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg); + +Lisp_Object put_char_ccs_code_point (Lisp_Object character, + Lisp_Object ccs, Lisp_Object value); +Lisp_Object remove_char_ccs (Lisp_Object character, Lisp_Object ccs); + Emchar -to_char_code (Lisp_Object v, char* err_msg, Lisp_Object err_arg) +to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg) { if (INTP (v)) return XINT (v); @@ -488,21 +953,21 @@ Return character corresponding with list. { Lisp_Object v = Fcar (rest); Lisp_Object ret; - Emchar c = to_char_code (v, "Invalid value for composition", list); + Emchar c = to_char_id (v, "Invalid value for composition", list); - ret = get_char_code_table (c, table); + ret = get_char_id_table (c, table); rest = Fcdr (rest); if (NILP (rest)) { - if (!CHAR_CODE_TABLE_P (ret)) + if (!CHAR_ID_TABLE_P (ret)) return ret; else return Qt; } else if (!CONSP (rest)) break; - else if (CHAR_CODE_TABLE_P (ret)) + else if (CHAR_ID_TABLE_P (ret)) table = ret; else signal_simple_error ("Invalid table is found with", list); @@ -516,96 +981,162 @@ Return variants of CHARACTER. (character)) { CHECK_CHAR (character); - return Fcopy_list (get_char_code_table (XCHAR (character), - Vcharacter_variant_table)); + return Fcopy_list (get_char_id_table (XCHAR (character), + Vcharacter_variant_table)); } -DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /* -Return the alist of attributes of CHARACTER. + +/* We store the char-attributes in hash tables with the names as the + key and the actual char-id-table object as the value. Occasionally + we need to use them in a list format. These routines provide us + with that. */ +struct char_attribute_list_closure +{ + Lisp_Object *char_attribute_list; +}; + +static int +add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value, + void *char_attribute_list_closure) +{ + /* This function can GC */ + struct char_attribute_list_closure *calcl + = (struct char_attribute_list_closure*) char_attribute_list_closure; + Lisp_Object *char_attribute_list = calcl->char_attribute_list; + + *char_attribute_list = Fcons (key, *char_attribute_list); + return 0; +} + +DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /* +Return the list of all existing character attributes except coded-charsets. */ - (character)) + ()) { - CHECK_CHAR (character); - return Fcopy_alist (get_char_code_table (XCHAR (character), - Vcharacter_attribute_table)); + Lisp_Object char_attribute_list = Qnil; + struct gcpro gcpro1; + struct char_attribute_list_closure char_attribute_list_closure; + + GCPRO1 (char_attribute_list); + char_attribute_list_closure.char_attribute_list = &char_attribute_list; + elisp_maphash (add_char_attribute_to_list_mapper, + Vchar_attribute_hash_table, + &char_attribute_list_closure); + UNGCPRO; + return char_attribute_list; } -DEFUN ("get-char-attribute", Fget_char_attribute, 2, 2, 0, /* -Return the value of CHARACTER's ATTRIBUTE. +DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /* +Return char-id-table corresponding to ATTRIBUTE. */ - (character, attribute)) + (attribute)) { - Lisp_Object ret; - Lisp_Object ccs; + return Fgethash (attribute, Vchar_attribute_hash_table, Qnil); +} - CHECK_CHAR (character); - ret = get_char_code_table (XCHAR (character), - Vcharacter_attribute_table); - if (EQ (ret, Qnil)) - return Qnil; - if (!NILP (ccs = Ffind_charset (attribute))) - attribute = ccs; +/* We store the char-id-tables in hash tables with the attributes as + the key and the actual char-id-table object as the value. Each + char-id-table stores values of an attribute corresponding with + characters. Occasionally we need to get attributes of a character + in a association-list format. These routines provide us with + that. */ +struct char_attribute_alist_closure +{ + Emchar char_id; + Lisp_Object *char_attribute_alist; +}; - return Fcdr (Fassq (attribute, ret)); +static int +add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value, + void *char_attribute_alist_closure) +{ + /* This function can GC */ + struct char_attribute_alist_closure *caacl = + (struct char_attribute_alist_closure*) char_attribute_alist_closure; + Lisp_Object ret = get_char_id_table (caacl->char_id, value); + if (!UNBOUNDP (ret)) + { + Lisp_Object *char_attribute_alist = caacl->char_attribute_alist; + *char_attribute_alist + = Fcons (Fcons (key, ret), *char_attribute_alist); + } + return 0; } -Lisp_Object -put_char_attribute (Lisp_Object character, Lisp_Object attribute, - Lisp_Object value) +DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /* +Return the alist of attributes of CHARACTER. +*/ + (character)) { - Emchar char_code = XCHAR (character); - Lisp_Object ret - = get_char_code_table (char_code, Vcharacter_attribute_table); - Lisp_Object cell; + Lisp_Object alist = Qnil; + int i; - cell = Fassq (attribute, ret); + CHECK_CHAR (character); + { + struct gcpro gcpro1; + struct char_attribute_alist_closure char_attribute_alist_closure; + + GCPRO1 (alist); + char_attribute_alist_closure.char_id = XCHAR (character); + char_attribute_alist_closure.char_attribute_alist = &alist; + elisp_maphash (add_char_attribute_alist_mapper, + Vchar_attribute_hash_table, + &char_attribute_alist_closure); + UNGCPRO; + } - if (NILP (cell)) - { - ret = Fcons (Fcons (attribute, value), ret); - } - else if (!EQ (Fcdr (cell), value)) + for (i = 0; i < countof (chlook->charset_by_leading_byte); i++) { - Fsetcdr (cell, value); + Lisp_Object ccs = chlook->charset_by_leading_byte[i]; + + if (!NILP (ccs)) + { + Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs); + Lisp_Object cpos; + + if ( CHAR_ID_TABLE_P (encoding_table) + && INTP (cpos = get_char_id_table (XCHAR (character), + encoding_table)) ) + { + alist = Fcons (Fcons (ccs, cpos), alist); + } + } } - put_char_code_table (char_code, ret, Vcharacter_attribute_table); - return ret; + return alist; } -Lisp_Object -remove_char_attribute (Lisp_Object character, Lisp_Object attribute) +DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /* +Return the value of CHARACTER's ATTRIBUTE. +Return DEFAULT-VALUE if the value is not exist. +*/ + (character, attribute, default_value)) { - Emchar char_code = XCHAR (character); - Lisp_Object alist - = get_char_code_table (char_code, Vcharacter_attribute_table); + Lisp_Object ccs; - if (EQ (attribute, Fcar (Fcar (alist)))) + CHECK_CHAR (character); + if (!NILP (ccs = Ffind_charset (attribute))) { - alist = Fcdr (alist); + Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs); + + if (CHAR_ID_TABLE_P (encoding_table)) + return get_char_id_table (XCHAR (character), encoding_table); } else { - Lisp_Object pr = alist; - Lisp_Object r = Fcdr (alist); - - while (!NILP (r)) + Lisp_Object table = Fgethash (attribute, + Vchar_attribute_hash_table, + Qunbound); + if (!UNBOUNDP (table)) { - if (EQ (attribute, Fcar (Fcar (r)))) - { - XCDR (pr) = Fcdr (r); - break; - } - pr = r; - r = Fcdr (r); + Lisp_Object ret = get_char_id_table (XCHAR (character), table); + if (!UNBOUNDP (ret)) + return ret; } } - put_char_code_table (char_code, alist, Vcharacter_attribute_table); - return alist; + return default_value; } -Lisp_Object Qucs; - DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /* Store CHARACTER's ATTRIBUTE with VALUE. */ @@ -617,145 +1148,74 @@ Store CHARACTER's ATTRIBUTE with VALUE. ccs = Ffind_charset (attribute); if (!NILP (ccs)) { - if (!EQ (XCHARSET_NAME (ccs), Qucs) - || (XCHAR (character) != XINT (value))) + return put_char_ccs_code_point (character, ccs, value); + } + else if (EQ (attribute, Q_decomposition)) + { + Lisp_Object seq; + + if (!CONSP (value)) + signal_simple_error ("Invalid value for ->decomposition", + value); + + if (CONSP (Fcdr (value))) { - Lisp_Object cpos, rest; - Lisp_Object v = XCHARSET_DECODING_TABLE (ccs); - Lisp_Object nv; - int i = -1; - int ccs_len; - int dim; - int code_point; - - /* ad-hoc method for `ascii' */ - if ((XCHARSET_CHARS (ccs) == 94) && - (XCHARSET_BYTE_OFFSET (ccs) != 33)) - ccs_len = 128 - XCHARSET_BYTE_OFFSET (ccs); - else - ccs_len = XCHARSET_CHARS (ccs); + Lisp_Object rest = value; + Lisp_Object table = Vcharacter_composition_table; + size_t len; + int i = 0; - if (CONSP (value)) + GET_EXTERNAL_LIST_LENGTH (rest, len); + seq = make_vector (len, Qnil); + + while (CONSP (rest)) { - Lisp_Object ret = Fcar (value); + Lisp_Object v = Fcar (rest); + Lisp_Object ntable; + Emchar c + = to_char_id (v, "Invalid value for ->decomposition", value); - if (!INTP (ret)) - signal_simple_error ("Invalid value for coded-charset", value); - code_point = XINT (ret); - if (XCHARSET_GRAPHIC (ccs) == 1) - code_point &= 0x7F; - rest = Fcdr (value); - while (!NILP (rest)) + if (c < 0) + XVECTOR_DATA(seq)[i++] = v; + else + XVECTOR_DATA(seq)[i++] = make_char (c); + rest = Fcdr (rest); + if (!CONSP (rest)) { - int i; - - if (!CONSP (rest)) - signal_simple_error ("Invalid value for coded-charset", - value); - ret = Fcar (rest); - if (!INTP (ret)) - signal_simple_error ("Invalid value for coded-charset", - value); - i = XINT (ret); - if (XCHARSET_GRAPHIC (ccs) == 1) - i &= 0x7F; - code_point = (code_point << 8) | i; - rest = Fcdr (rest); + put_char_id_table (c, character, table); + break; } - value = make_int (code_point); - } - else if (INTP (value)) - { - if (XCHARSET_GRAPHIC (ccs) == 1) - value = make_int (XINT (value) & 0x7F7F7F7F); - } - else - signal_simple_error ("Invalid value for coded-charset", value); - - attribute = ccs; - cpos = Fget_char_attribute (character, attribute); - if (VECTORP (v)) - { - if (!NILP (cpos)) + else { - dim = XCHARSET_DIMENSION (ccs); - code_point = XINT (cpos); - while (dim > 0) + ntable = get_char_id_table (c, table); + if (!CHAR_ID_TABLE_P (ntable)) { - dim--; - i = ((code_point >> (8 * dim)) & 255) - - XCHARSET_BYTE_OFFSET (ccs); - nv = XVECTOR_DATA(v)[i]; - if (!VECTORP (nv)) - break; - v = nv; + ntable = make_char_id_table (Qnil); + put_char_id_table (c, ntable, table); } - if (i >= 0) - XVECTOR_DATA(v)[i] = Qnil; - v = XCHARSET_DECODING_TABLE (ccs); - } - } - else - { - XCHARSET_DECODING_TABLE (ccs) = v = make_vector (ccs_len, Qnil); - } - - dim = XCHARSET_DIMENSION (ccs); - code_point = XINT (value); - i = -1; - while (dim > 0) - { - dim--; - i = ((code_point >> (8 * dim)) & 255) - - XCHARSET_BYTE_OFFSET (ccs); - nv = XVECTOR_DATA(v)[i]; - if (dim > 0) - { - if (!VECTORP (nv)) - nv = (XVECTOR_DATA(v)[i] = make_vector (ccs_len, Qnil)); - v = nv; + table = ntable; } - else - break; } - XVECTOR_DATA(v)[i] = character; } else - attribute = ccs; - } - else if (EQ (attribute, Q_decomposition)) - { - Lisp_Object rest = value; - Lisp_Object table = Vcharacter_composition_table; - - if (!CONSP (value)) - signal_simple_error ("Invalid value for ->decomposition", - value); - - while (CONSP (rest)) { - Lisp_Object v = Fcar (rest); - Lisp_Object ntable; - Emchar c - = to_char_code (v, "Invalid value for ->decomposition", value); + Lisp_Object v = Fcar (value); - rest = Fcdr (rest); - if (!CONSP (rest)) + if (INTP (v)) { - put_char_code_table (c, character, table); - break; - } - else - { - ntable = get_char_code_table (c, table); - if (!CHAR_CODE_TABLE_P (ntable)) + Emchar c = XINT (v); + Lisp_Object ret + = get_char_id_table (c, Vcharacter_variant_table); + + if (NILP (Fmemq (v, ret))) { - ntable = make_char_code_table (Qnil); - put_char_code_table (c, ntable, table); + put_char_id_table (c, Fcons (character, ret), + Vcharacter_variant_table); } - table = ntable; } + seq = make_vector (1, v); } + value = seq; } else if (EQ (attribute, Q_ucs)) { @@ -767,14 +1227,26 @@ Store CHARACTER's ATTRIBUTE with VALUE. c = XINT (value); - ret = get_char_code_table (c, Vcharacter_variant_table); + ret = get_char_id_table (c, Vcharacter_variant_table); if (NILP (Fmemq (character, ret))) { - put_char_code_table (c, Fcons (character, ret), - Vcharacter_variant_table); + put_char_id_table (c, Fcons (character, ret), + Vcharacter_variant_table); } } - return put_char_attribute (character, attribute, value); + { + Lisp_Object table = Fgethash (attribute, + Vchar_attribute_hash_table, + Qnil); + + if (NILP (table)) + { + table = make_char_id_table (Qunbound); + Fputhash (attribute, table, Vchar_attribute_hash_table); + } + put_char_id_table (XCHAR (character), value, table); + return value; + } } DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /* @@ -788,46 +1260,221 @@ Remove CHARACTER's ATTRIBUTE. ccs = Ffind_charset (attribute); if (!NILP (ccs)) { - Lisp_Object cpos; - Lisp_Object v = XCHARSET_DECODING_TABLE (ccs); + return remove_char_ccs (character, ccs); + } + else + { + Lisp_Object table = Fgethash (attribute, + Vchar_attribute_hash_table, + Qunbound); + if (!UNBOUNDP (table)) + { + put_char_id_table (XCHAR (character), Qunbound, table); + return Qt; + } + } + return Qnil; +} + +INLINE_HEADER int CHARSET_BYTE_SIZE (Lisp_Charset* cs); +INLINE_HEADER int +CHARSET_BYTE_SIZE (Lisp_Charset* cs) +{ + /* ad-hoc method for `ascii' */ + if ((CHARSET_CHARS (cs) == 94) && + (CHARSET_BYTE_OFFSET (cs) != 33)) + return 128 - CHARSET_BYTE_OFFSET (cs); + else + return CHARSET_CHARS (cs); +} + +#define XCHARSET_BYTE_SIZE(ccs) CHARSET_BYTE_SIZE (XCHARSET (ccs)) + +int decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len); +int +decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len) +{ + int i; + + if (XVECTOR_LENGTH (v) > ccs_len) + return -1; + + for (i = 0; i < XVECTOR_LENGTH (v); i++) + { + Lisp_Object c = XVECTOR_DATA(v)[i]; + + if (!NILP (c) && !CHARP (c)) + { + if (VECTORP (c)) + { + int ret = decoding_table_check_elements (c, dim - 1, ccs_len); + if (ret) + return ret; + } + else + return -2; + } + } + return 0; +} + +INLINE_HEADER void +decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset, + int code_point); +INLINE_HEADER void +decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset, + int code_point) +{ + int i = -1; + + while (dim > 0) + { Lisp_Object nv; - int i = -1; - int ccs_len; - int dim; + + dim--; + i = ((code_point >> (8 * dim)) & 255) - byte_offset; + nv = XVECTOR_DATA(v)[i]; + if (!VECTORP (nv)) + break; + v = nv; + } + if (i >= 0) + XVECTOR_DATA(v)[i] = Qnil; +} + +INLINE_HEADER void +decoding_table_put_char (Lisp_Object v, int dim, int byte_offset, + int code_point, Lisp_Object character); +INLINE_HEADER void +decoding_table_put_char (Lisp_Object v, int dim, int byte_offset, + int code_point, Lisp_Object character) +{ + int i = -1; + Lisp_Object nv; + int ccs_len = XVECTOR_LENGTH (v); + + while (dim > 0) + { + dim--; + i = ((code_point >> (8 * dim)) & 255) - byte_offset; + nv = XVECTOR_DATA(v)[i]; + if (dim > 0) + { + if (!VECTORP (nv)) + nv = (XVECTOR_DATA(v)[i] = make_older_vector (ccs_len, Qnil)); + v = nv; + } + else + break; + } + XVECTOR_DATA(v)[i] = character; +} + +Lisp_Object +put_char_ccs_code_point (Lisp_Object character, + Lisp_Object ccs, Lisp_Object value) +{ + Lisp_Object encoding_table; + + if (!EQ (XCHARSET_NAME (ccs), Qucs) + || (XCHAR (character) != XINT (value))) + { + Lisp_Object v = XCHARSET_DECODING_TABLE (ccs); + int dim = XCHARSET_DIMENSION (ccs); + int ccs_len = XCHARSET_BYTE_SIZE (ccs); + int byte_offset = XCHARSET_BYTE_OFFSET (ccs); int code_point; - - /* ad-hoc method for `ascii' */ - if ((XCHARSET_CHARS (ccs) == 94) && - (XCHARSET_BYTE_OFFSET (ccs) != 33)) - ccs_len = 128 - XCHARSET_BYTE_OFFSET (ccs); + + if (CONSP (value)) + { /* obsolete representation: value must be a list of bytes */ + Lisp_Object ret = Fcar (value); + Lisp_Object rest; + + if (!INTP (ret)) + signal_simple_error ("Invalid value for coded-charset", value); + code_point = XINT (ret); + if (XCHARSET_GRAPHIC (ccs) == 1) + code_point &= 0x7F; + rest = Fcdr (value); + while (!NILP (rest)) + { + int j; + + if (!CONSP (rest)) + signal_simple_error ("Invalid value for coded-charset", + value); + ret = Fcar (rest); + if (!INTP (ret)) + signal_simple_error ("Invalid value for coded-charset", + value); + j = XINT (ret); + if (XCHARSET_GRAPHIC (ccs) == 1) + j &= 0x7F; + code_point = (code_point << 8) | j; + rest = Fcdr (rest); + } + value = make_int (code_point); + } + else if (INTP (value)) + { + code_point = XINT (value); + if (XCHARSET_GRAPHIC (ccs) == 1) + { + code_point &= 0x7F7F7F7F; + value = make_int (code_point); + } + } else - ccs_len = XCHARSET_CHARS (ccs); + signal_simple_error ("Invalid value for coded-charset", value); - attribute = ccs; - cpos = Fget_char_attribute (character, attribute); if (VECTORP (v)) { + Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil); if (!NILP (cpos)) { - dim = XCHARSET_DIMENSION (ccs); - code_point = XINT (cpos); - while (dim > 0) - { - dim--; - i = ((code_point >> (8 * dim)) & 255) - - XCHARSET_BYTE_OFFSET (ccs); - nv = XVECTOR_DATA(v)[i]; - if (!VECTORP (nv)) - break; - v = nv; - } - if (i >= 0) - XVECTOR_DATA(v)[i] = Qnil; - v = XCHARSET_DECODING_TABLE (ccs); + decoding_table_remove_char (v, dim, byte_offset, XINT (cpos)); } } + else + { + XCHARSET_DECODING_TABLE (ccs) + = v = make_older_vector (ccs_len, Qnil); + } + + decoding_table_put_char (v, dim, byte_offset, code_point, character); + } + if (NILP (encoding_table = XCHARSET_ENCODING_TABLE (ccs))) + { + XCHARSET_ENCODING_TABLE (ccs) + = encoding_table = make_char_id_table (Qnil); + } + put_char_id_table (XCHAR (character), value, encoding_table); + return Qt; +} + +Lisp_Object +remove_char_ccs (Lisp_Object character, Lisp_Object ccs) +{ + Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs); + Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs); + + if (VECTORP (decoding_table)) + { + Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil); + + if (!NILP (cpos)) + { + decoding_table_remove_char (decoding_table, + XCHARSET_DIMENSION (ccs), + XCHARSET_BYTE_OFFSET (ccs), + XINT (cpos)); + } + } + if (CHAR_ID_TABLE_P (encoding_table)) + { + put_char_id_table (XCHAR (character), Qnil, encoding_table); } - return remove_char_attribute (character, attribute); + return Qt; } EXFUN (Fmake_char, 3); @@ -841,6 +1488,9 @@ Store character's ATTRIBUTES. Lisp_Object rest = attributes; Lisp_Object code = Fcdr (Fassq (Qucs, attributes)); Lisp_Object character; +#if 0 + Lisp_Object daikanwa = Qnil; +#endif if (NILP (code)) { @@ -884,14 +1534,39 @@ Store character's ATTRIBUTES. while (CONSP (rest)) { Lisp_Object cell = Fcar (rest); +#if 0 + Lisp_Object key = Fcar (cell); + Lisp_Object value = Fcdr (cell); +#endif if (!LISTP (cell)) signal_simple_error ("Invalid argument", attributes); + +#if 0 + if (EQ (key, Qmorohashi_daikanwa)) + { + size_t len; + GET_EXTERNAL_LIST_LENGTH (value, len); + + if (len == 1) + { + if (NILP (daikanwa)) + daikanwa = Fcdr (Fassq (Qideograph_daikanwa, rest)); + if (EQ (Fcar (value), daikanwa)) + goto ignored; + } + } + else if (EQ (key, Qideograph_daikanwa)) + daikanwa = value; +#endif + Fput_char_attribute (character, Fcar (cell), Fcdr (cell)); +#if 0 + ignored: +#endif rest = Fcdr (rest); } - return - get_char_code_table (XCHAR (character), Vcharacter_attribute_table); + return character; } Lisp_Object Vutf_2000_version; @@ -934,13 +1609,16 @@ Lisp_Object Qascii, Qchinese_cns11643_2, #ifdef UTF2000 Qucs_bmp, + Qucs_cns, Qlatin_viscii, + Qlatin_tcvn5712, Qlatin_viscii_lower, Qlatin_viscii_upper, Qvietnamese_viscii_lower, Qvietnamese_viscii_upper, - Qideograph_daikanwa, + Qchinese_big5, Qmojikyo, + Qmojikyo_2022_1, Qmojikyo_pj_1, Qmojikyo_pj_2, Qmojikyo_pj_3, @@ -972,13 +1650,6 @@ Lisp_Object Ql2r, Qr2l; Lisp_Object Vcharset_hash_table; -#ifdef UTF2000 -static Charset_ID next_allocated_leading_byte; -#else -static Charset_ID next_allocated_1_byte_leading_byte; -static Charset_ID next_allocated_2_byte_leading_byte; -#endif - /* Composite characters are characters constructed by overstriking two or more regular characters. @@ -1089,7 +1760,7 @@ non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c) Use the macro charptr_emchar() instead. */ Emchar -non_ascii_charptr_emchar (CONST Bufbyte *str) +non_ascii_charptr_emchar (const Bufbyte *str) { #ifdef UTF2000 Bufbyte b; @@ -1240,30 +1911,18 @@ non_ascii_valid_char_p (Emchar ch) /* Basic string functions */ /************************************************************************/ -/* Copy the character pointed to by PTR into STR, assuming it's - non-ASCII. Do not call this directly. Use the macro - charptr_copy_char() instead. */ +/* Copy the character pointed to by SRC into DST. Do not call this + directly. Use the macro charptr_copy_char() instead. + Return the number of bytes copied. */ Bytecount -non_ascii_charptr_copy_char (CONST Bufbyte *ptr, Bufbyte *str) +non_ascii_charptr_copy_char (const Bufbyte *src, Bufbyte *dst) { - Bufbyte *strptr = str; - *strptr = *ptr++; - switch (REP_BYTES_BY_FIRST_BYTE (*strptr)) - { - /* Notice fallthrough. */ -#ifdef UTF2000 - case 6: *++strptr = *ptr++; - case 5: *++strptr = *ptr++; -#endif - case 4: *++strptr = *ptr++; - case 3: *++strptr = *ptr++; - case 2: *++strptr = *ptr; - break; - default: - abort (); - } - return strptr + 1 - str; + unsigned int bytes = REP_BYTES_BY_FIRST_BYTE (*src); + unsigned int i; + for (i = bytes; i; i--, dst++, src++) + *dst = *src; + return bytes; } @@ -1280,36 +1939,15 @@ Lstream_get_emchar_1 (Lstream *stream, int ch) { Bufbyte str[MAX_EMCHAR_LEN]; Bufbyte *strptr = str; + unsigned int bytes; str[0] = (Bufbyte) ch; - switch (REP_BYTES_BY_FIRST_BYTE (ch)) + + for (bytes = REP_BYTES_BY_FIRST_BYTE (ch) - 1; bytes; bytes--) { - /* Notice fallthrough. */ -#ifdef UTF2000 - case 6: - ch = Lstream_getc (stream); - assert (ch >= 0); - *++strptr = (Bufbyte) ch; - case 5: - ch = Lstream_getc (stream); - assert (ch >= 0); - *++strptr = (Bufbyte) ch; -#endif - case 4: - ch = Lstream_getc (stream); - assert (ch >= 0); - *++strptr = (Bufbyte) ch; - case 3: - ch = Lstream_getc (stream); - assert (ch >= 0); - *++strptr = (Bufbyte) ch; - case 2: - ch = Lstream_getc (stream); - assert (ch >= 0); - *++strptr = (Bufbyte) ch; - break; - default: - abort (); + int c = Lstream_getc (stream); + bufpos_checking_assert (c >= 0); + *++strptr = (Bufbyte) c; } return charptr_emchar (str); } @@ -1338,7 +1976,7 @@ Lstream_funget_emchar (Lstream *stream, Emchar ch) static Lisp_Object mark_charset (Lisp_Object obj) { - struct Lisp_Charset *cs = XCHARSET (obj); + Lisp_Charset *cs = XCHARSET (obj); mark_object (cs->short_name); mark_object (cs->long_name); @@ -1346,7 +1984,8 @@ mark_charset (Lisp_Object obj) mark_object (cs->registry); mark_object (cs->ccl_program); #ifdef UTF2000 - mark_object (cs->decoding_table); + mark_object (cs->encoding_table); + /* mark_object (cs->decoding_table); */ #endif return cs->name; } @@ -1354,7 +1993,7 @@ mark_charset (Lisp_Object obj) static void print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) { - struct Lisp_Charset *cs = XCHARSET (obj); + Lisp_Charset *cs = XCHARSET (obj); char buf[200]; if (print_readably) @@ -1384,9 +2023,16 @@ print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) } static const struct lrecord_description charset_description[] = { - { XD_LISP_OBJECT, offsetof(struct Lisp_Charset, name), 7 }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) }, #ifdef UTF2000 - { XD_LISP_OBJECT, offsetof(struct Lisp_Charset, decoding_table), 2 }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) }, + { XD_LISP_OBJECT, offsetof (Lisp_Charset, encoding_table) }, #endif { XD_END } }; @@ -1394,9 +2040,10 @@ static const struct lrecord_description charset_description[] = { DEFINE_LRECORD_IMPLEMENTATION ("charset", charset, mark_charset, print_charset, 0, 0, 0, charset_description, - struct Lisp_Charset); -/* Make a new charset. */ + Lisp_Charset); +/* Make a new charset. */ +/* #### SJT Should generic properties be allowed? */ static Lisp_Object make_charset (Charset_ID id, Lisp_Object name, unsigned short chars, unsigned char dimension, @@ -1408,10 +2055,11 @@ make_charset (Charset_ID id, Lisp_Object name, Emchar ucs_min, Emchar ucs_max, Emchar code_offset, unsigned char byte_offset) { - unsigned char type = 0; Lisp_Object obj; - struct Lisp_Charset *cs = - alloc_lcrecord_type (struct Lisp_Charset, &lrecord_charset); + Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset); + + zero_lcrecord (cs); + XSETCHARSET (obj, cs); CHARSET_ID (cs) = id; @@ -1430,65 +2078,13 @@ make_charset (Charset_ID id, Lisp_Object name, CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil; #ifdef UTF2000 CHARSET_DECODING_TABLE(cs) = Qnil; + CHARSET_ENCODING_TABLE(cs) = Qnil; CHARSET_UCS_MIN(cs) = ucs_min; CHARSET_UCS_MAX(cs) = ucs_max; CHARSET_CODE_OFFSET(cs) = code_offset; CHARSET_BYTE_OFFSET(cs) = byte_offset; #endif - switch (CHARSET_CHARS (cs)) - { - case 94: - switch (CHARSET_DIMENSION (cs)) - { - case 1: - type = CHARSET_TYPE_94; - break; - case 2: - type = CHARSET_TYPE_94X94; - break; - } - break; - case 96: - switch (CHARSET_DIMENSION (cs)) - { - case 1: - type = CHARSET_TYPE_96; - break; - case 2: - type = CHARSET_TYPE_96X96; - break; - } - break; -#ifdef UTF2000 - case 128: - switch (CHARSET_DIMENSION (cs)) - { - case 1: - type = CHARSET_TYPE_128; - break; - case 2: - type = CHARSET_TYPE_128X128; - break; - } - break; - case 256: - switch (CHARSET_DIMENSION (cs)) - { - case 1: - type = CHARSET_TYPE_256; - break; - case 2: - type = CHARSET_TYPE_256X256; - break; - } - break; -#endif - } -#ifndef UTF2000 - CHARSET_TYPE (cs) = type; -#endif - #ifndef UTF2000 if (id == LEADING_BYTE_ASCII) CHARSET_REP_BYTES (cs) = 1; @@ -1503,15 +2099,18 @@ make_charset (Charset_ID id, Lisp_Object name, /* some charsets do not have final characters. This includes ASCII, Control-1, Composite, and the two faux private charsets. */ + unsigned char iso2022_type + = (dimension == 1 ? 0 : 2) + (chars == 94 ? 0 : 1); #if UTF2000 if (code_offset == 0) { - assert (NILP (chlook->charset_by_attributes[type][final])); - chlook->charset_by_attributes[type][final] = obj; + assert (NILP (chlook->charset_by_attributes[iso2022_type][final])); + chlook->charset_by_attributes[iso2022_type][final] = obj; } #else - assert (NILP (chlook->charset_by_attributes[type][final][direction])); - chlook->charset_by_attributes[type][final][direction] = obj; + assert (NILP + (chlook->charset_by_attributes[iso2022_type][final][direction])); + chlook->charset_by_attributes[iso2022_type][final][direction] = obj; #endif } @@ -1531,24 +2130,24 @@ get_unallocated_leading_byte (int dimension) Charset_ID lb; #ifdef UTF2000 - if (next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE) + if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE) lb = 0; else - lb = next_allocated_leading_byte++; + lb = chlook->next_allocated_leading_byte++; #else if (dimension == 1) { - if (next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1) + if (chlook->next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1) lb = 0; else - lb = next_allocated_1_byte_leading_byte++; + lb = chlook->next_allocated_1_byte_leading_byte++; } else { - if (next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2) + if (chlook->next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2) lb = 0; else - lb = next_allocated_2_byte_leading_byte++; + lb = chlook->next_allocated_2_byte_leading_byte++; } #endif @@ -1561,6 +2160,10 @@ get_unallocated_leading_byte (int dimension) } #ifdef UTF2000 +/* Number of Big5 characters which have the same code in 1st byte. */ + +#define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40) + Emchar make_builtin_char (Lisp_Object charset, int c1, int c2) { @@ -1596,6 +2199,25 @@ make_builtin_char (Lisp_Object charset, int c1, int c2) } else { + if (EQ (charset, Vcharset_chinese_big5)) + { + int B1 = c1, B2 = c2; + unsigned int I + = (B1 - 0xA1) * BIG5_SAME_ROW + + B2 - (B2 < 0x7F ? 0x40 : 0x62); + + if (B1 < 0xC9) + { + charset = Vcharset_chinese_big5_1; + } + else + { + charset = Vcharset_chinese_big5_2; + I -= (BIG5_SAME_ROW) * (0xC9 - 0xA1); + } + c1 = I / 94 + 33; + c2 = I % 94 + 33; + } switch (XCHARSET_CHARS (charset)) { case 94: @@ -1694,6 +2316,20 @@ range_charset_code_point (Lisp_Object charset, Emchar ch) return -1; } } + if (EQ (charset, Vcharset_mojikyo_2022_1) + && (MIN_CHAR_MOJIKYO < ch) && (ch < MIN_CHAR_MOJIKYO + 94 * 60 * 94)) + { + int m = ch - MIN_CHAR_MOJIKYO - 1; + int byte1 = m / (94 * 60) + 33; + int byte2 = (m % (94 * 60)) / 94; + int byte3 = m % 94 + 33; + + if (byte2 < 30) + byte2 += 16 + 32; + else + byte2 += 18 + 32; + return (byte1 << 16) | (byte2 << 8) | byte3; + } return -1; } @@ -1755,11 +2391,18 @@ encode_builtin_char_1 (Emchar c, Lisp_Object* charset) *charset = Vcharset_ucs; return c; } + /* else if (c <= MAX_CHAR_DAIKANWA) { *charset = Vcharset_ideograph_daikanwa; return c - MIN_CHAR_DAIKANWA; } + */ + else if (c <= MAX_CHAR_MOJIKYO) + { + *charset = Vcharset_mojikyo; + return c - MIN_CHAR_MOJIKYO; + } else if (c < MIN_CHAR_94) { *charset = Vcharset_ucs; @@ -1767,7 +2410,7 @@ encode_builtin_char_1 (Emchar c, Lisp_Object* charset) } else if (c <= MAX_CHAR_94) { - *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94, + *charset = CHARSET_BY_ATTRIBUTES (94, 1, ((c - MIN_CHAR_94) / 94) + '0', CHARSET_LEFT_TO_RIGHT); if (!NILP (*charset)) @@ -1780,7 +2423,7 @@ encode_builtin_char_1 (Emchar c, Lisp_Object* charset) } else if (c <= MAX_CHAR_96) { - *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96, + *charset = CHARSET_BY_ATTRIBUTES (96, 1, ((c - MIN_CHAR_96) / 96) + '0', CHARSET_LEFT_TO_RIGHT); if (!NILP (*charset)) @@ -1794,7 +2437,7 @@ encode_builtin_char_1 (Emchar c, Lisp_Object* charset) else if (c <= MAX_CHAR_94x94) { *charset - = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94X94, + = CHARSET_BY_ATTRIBUTES (94, 2, ((c - MIN_CHAR_94x94) / (94 * 94)) + '0', CHARSET_LEFT_TO_RIGHT); if (!NILP (*charset)) @@ -1809,7 +2452,7 @@ encode_builtin_char_1 (Emchar c, Lisp_Object* charset) else if (c <= MAX_CHAR_96x96) { *charset - = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96X96, + = CHARSET_BY_ATTRIBUTES (96, 2, ((c - MIN_CHAR_96x96) / (96 * 96)) + '0', CHARSET_LEFT_TO_RIGHT); if (!NILP (*charset)) @@ -1890,7 +2533,7 @@ add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value, (struct charset_list_closure*) charset_list_closure; Lisp_Object *charset_list = chcl->charset_list; - *charset_list = Fcons (XCHARSET_NAME (value), *charset_list); + *charset_list = Fcons (key /* XCHARSET_NAME (value) */, *charset_list); return 0; } @@ -1913,13 +2556,14 @@ Return a list of the names of all defined charsets. } DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /* -Return the name of the given charset. +Return the name of charset CHARSET. */ (charset)) { return XCHARSET_NAME (Fget_charset (charset)); } +/* #### SJT Should generic properties be allowed? */ DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /* Define a new character set. This function is for use with Mule support. @@ -1971,10 +2615,8 @@ character set. Recognized properties are: { int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1; int direction = CHARSET_LEFT_TO_RIGHT; - int type; Lisp_Object registry = Qnil; Lisp_Object charset; - Lisp_Object rest, keyword, value; Lisp_Object ccl_program = Qnil; Lisp_Object short_name = Qnil, long_name = Qnil; int byte_offset = -1; @@ -1987,89 +2629,94 @@ character set. Recognized properties are: if (!NILP (charset)) signal_simple_error ("Cannot redefine existing charset", name); - EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props) - { - if (EQ (keyword, Qshort_name)) - { - CHECK_STRING (value); - short_name = value; - } + { + EXTERNAL_PROPERTY_LIST_LOOP_3 (keyword, value, props) + { + if (EQ (keyword, Qshort_name)) + { + CHECK_STRING (value); + short_name = value; + } - if (EQ (keyword, Qlong_name)) - { - CHECK_STRING (value); - long_name = value; - } + if (EQ (keyword, Qlong_name)) + { + CHECK_STRING (value); + long_name = value; + } - else if (EQ (keyword, Qdimension)) - { - CHECK_INT (value); - dimension = XINT (value); - if (dimension < 1 || dimension > 2) - signal_simple_error ("Invalid value for 'dimension", value); - } + else if (EQ (keyword, Qdimension)) + { + CHECK_INT (value); + dimension = XINT (value); + if (dimension < 1 || dimension > 2) + signal_simple_error ("Invalid value for 'dimension", value); + } - else if (EQ (keyword, Qchars)) - { - CHECK_INT (value); - chars = XINT (value); - if (chars != 94 && chars != 96) - signal_simple_error ("Invalid value for 'chars", value); - } + else if (EQ (keyword, Qchars)) + { + CHECK_INT (value); + chars = XINT (value); + if (chars != 94 && chars != 96) + signal_simple_error ("Invalid value for 'chars", value); + } - else if (EQ (keyword, Qcolumns)) - { - CHECK_INT (value); - columns = XINT (value); - if (columns != 1 && columns != 2) - signal_simple_error ("Invalid value for 'columns", value); - } + else if (EQ (keyword, Qcolumns)) + { + CHECK_INT (value); + columns = XINT (value); + if (columns != 1 && columns != 2) + signal_simple_error ("Invalid value for 'columns", value); + } - else if (EQ (keyword, Qgraphic)) - { - CHECK_INT (value); - graphic = XINT (value); + else if (EQ (keyword, Qgraphic)) + { + CHECK_INT (value); + graphic = XINT (value); #ifdef UTF2000 - if (graphic < 0 || graphic > 2) + if (graphic < 0 || graphic > 2) #else - if (graphic < 0 || graphic > 1) + if (graphic < 0 || graphic > 1) #endif - signal_simple_error ("Invalid value for 'graphic", value); - } + signal_simple_error ("Invalid value for 'graphic", value); + } - else if (EQ (keyword, Qregistry)) - { - CHECK_STRING (value); - registry = value; - } + else if (EQ (keyword, Qregistry)) + { + CHECK_STRING (value); + registry = value; + } - else if (EQ (keyword, Qdirection)) - { - if (EQ (value, Ql2r)) - direction = CHARSET_LEFT_TO_RIGHT; - else if (EQ (value, Qr2l)) - direction = CHARSET_RIGHT_TO_LEFT; - else - signal_simple_error ("Invalid value for 'direction", value); - } + else if (EQ (keyword, Qdirection)) + { + if (EQ (value, Ql2r)) + direction = CHARSET_LEFT_TO_RIGHT; + else if (EQ (value, Qr2l)) + direction = CHARSET_RIGHT_TO_LEFT; + else + signal_simple_error ("Invalid value for 'direction", value); + } - else if (EQ (keyword, Qfinal)) - { - CHECK_CHAR_COERCE_INT (value); - final = XCHAR (value); - if (final < '0' || final > '~') - signal_simple_error ("Invalid value for 'final", value); - } + else if (EQ (keyword, Qfinal)) + { + CHECK_CHAR_COERCE_INT (value); + final = XCHAR (value); + if (final < '0' || final > '~') + signal_simple_error ("Invalid value for 'final", value); + } - else if (EQ (keyword, Qccl_program)) - { - CHECK_VECTOR (value); - ccl_program = value; - } + else if (EQ (keyword, Qccl_program)) + { + struct ccl_program test_ccl; - else - signal_simple_error ("Unrecognized property", keyword); - } + if (setup_ccl_program (&test_ccl, value) < 0) + signal_simple_error ("Invalid value for 'ccl-program", value); + ccl_program = value; + } + + else + signal_simple_error ("Unrecognized property", keyword); + } + } if (!final) error ("'final must be specified"); @@ -2078,13 +2725,10 @@ character set. Recognized properties are: ("Final must be in the range 0x30 - 0x5F for dimension == 2", make_char (final)); - if (dimension == 1) - type = (chars == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96; - else - type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96; - - if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) || - !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT))) + if (!NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final, + CHARSET_LEFT_TO_RIGHT)) || + !NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final, + CHARSET_RIGHT_TO_LEFT))) error ("Character set already defined for this DIMENSION/CHARS/FINAL combo"); @@ -2135,7 +2779,7 @@ NEW-NAME is the name of the new charset. Return the new charset. int id, chars, dimension, columns, graphic, final; int direction; Lisp_Object registry, doc_string, short_name, long_name; - struct Lisp_Charset *cs; + Lisp_Charset *cs; charset = Fget_charset (charset); if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset))) @@ -2217,7 +2861,6 @@ will be returned if character sets exist for both directions). (dimension, chars, final, direction)) { int dm, ch, fi, di = -1; - int type; Lisp_Object obj = Qnil; CHECK_INT (dimension); @@ -2246,19 +2889,14 @@ will be returned if character sets exist for both directions). signal_simple_error ("Final must be in the range 0x30 - 0x5F for dimension == 2", final); - if (dm == 1) - type = (ch == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96; - else - type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96; - - if (di == -1) + if (di == -1) { - obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT); + obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_LEFT_TO_RIGHT); if (NILP (obj)) - obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT); + obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_RIGHT_TO_LEFT); } else - obj = CHARSET_BY_ATTRIBUTES (type, fi, di); + obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, di); if (CHARSETP (obj)) return XCHARSET_NAME (obj); @@ -2298,13 +2936,13 @@ Return dimension of CHARSET. } DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /* -Return property PROP of CHARSET. +Return property PROP of CHARSET, a charset object or symbol naming a charset. Recognized properties are those listed in `make-charset', as well as 'name and 'doc-string. */ (charset, prop)) { - struct Lisp_Charset *cs; + Lisp_Charset *cs; charset = Fget_charset (charset); cs = XCHARSET (charset); @@ -2326,10 +2964,8 @@ Recognized properties are those listed in `make-charset', as well as if (EQ (prop, Qreverse_direction_charset)) { Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs); - if (NILP (obj)) - return Qnil; - else - return XCHARSET_NAME (obj); + /* #### Is this translation OK? If so, error checking sufficient? */ + return CHARSETP (obj) ? XCHARSET_NAME (obj) : obj; } signal_simple_error ("Unrecognized charset property name", prop); return Qnil; /* not reached */ @@ -2351,8 +2987,11 @@ Set the 'ccl-program property of CHARSET to CCL-PROGRAM. */ (charset, ccl_program)) { + struct ccl_program test_ccl; + charset = Fget_charset (charset); - CHECK_VECTOR (ccl_program); + if (setup_ccl_program (&test_ccl, ccl_program) < 0) + signal_simple_error ("Invalid ccl-program", ccl_program); XCHARSET_CCL_PROGRAM (charset) = ccl_program; return Qnil; } @@ -2399,39 +3038,42 @@ Set mapping-table of CHARSET to TABLE. (charset, table)) { struct Lisp_Charset *cs; - Lisp_Object old_table; size_t i; + int byte_offset; charset = Fget_charset (charset); cs = XCHARSET (charset); - if (EQ (table, Qnil)) + if (NILP (table)) { - CHARSET_DECODING_TABLE(cs) = table; + if (VECTORP (CHARSET_DECODING_TABLE(cs))) + make_vector_newer (CHARSET_DECODING_TABLE(cs)); + CHARSET_DECODING_TABLE(cs) = Qnil; return table; } else if (VECTORP (table)) { - int ccs_len; - - /* ad-hoc method for `ascii' */ - if ((CHARSET_CHARS (cs) == 94) && - (CHARSET_BYTE_OFFSET (cs) != 33)) - ccs_len = 128 - CHARSET_BYTE_OFFSET (cs); - else - ccs_len = CHARSET_CHARS (cs); - - if (XVECTOR_LENGTH (table) > ccs_len) - args_out_of_range (table, make_int (CHARSET_CHARS (cs))); - old_table = CHARSET_DECODING_TABLE(cs); - CHARSET_DECODING_TABLE(cs) = table; + int ccs_len = CHARSET_BYTE_SIZE (cs); + int ret = decoding_table_check_elements (table, + CHARSET_DIMENSION (cs), + ccs_len); + if (ret) + { + if (ret == -1) + signal_simple_error ("Too big table", table); + else if (ret == -2) + signal_simple_error ("Invalid element is found", table); + else + signal_simple_error ("Something wrong", table); + } + CHARSET_DECODING_TABLE(cs) = Qnil; } else signal_error (Qwrong_type_argument, list2 (build_translated_string ("vector-or-nil-p"), table)); - /* signal_simple_error ("Wrong type argument: vector-or-nil-p", table); */ + byte_offset = CHARSET_BYTE_OFFSET (cs); switch (CHARSET_DIMENSION (cs)) { case 1: @@ -2440,9 +3082,8 @@ Set mapping-table of CHARSET to TABLE. Lisp_Object c = XVECTOR_DATA(table)[i]; if (CHARP (c)) - put_char_attribute - (c, charset, - make_int (i + CHARSET_BYTE_OFFSET (cs))); + put_char_ccs_code_point (c, charset, + make_int (i + byte_offset)); } break; case 2: @@ -2454,25 +3095,21 @@ Set mapping-table of CHARSET to TABLE. { size_t j; - if (XVECTOR_LENGTH (v) > CHARSET_CHARS (cs)) - { - CHARSET_DECODING_TABLE(cs) = old_table; - args_out_of_range (v, make_int (CHARSET_CHARS (cs))); - } for (j = 0; j < XVECTOR_LENGTH (v); j++) { Lisp_Object c = XVECTOR_DATA(v)[j]; if (CHARP (c)) - put_char_attribute + put_char_ccs_code_point (c, charset, - make_int ( ((i + CHARSET_BYTE_OFFSET (cs)) << 8) - | (j + CHARSET_BYTE_OFFSET (cs)) )); + make_int ( ( (i + byte_offset) << 8 ) + | (j + byte_offset) + ) ); } } else if (CHARP (v)) - put_char_attribute (v, charset, - make_int (i + CHARSET_BYTE_OFFSET (cs))); + put_char_ccs_code_point (v, charset, + make_int (i + byte_offset)); } break; } @@ -2500,6 +3137,77 @@ Make a character from CHARSET and code-point CODE. c &= 0x7F7F7F7F; return make_char (DECODE_CHAR (charset, c)); } + +DEFUN ("decode-builtin-char", Fdecode_builtin_char, 2, 2, 0, /* +Make a builtin character from CHARSET and code-point CODE. +*/ + (charset, code)) +{ + int c; + int final; + + charset = Fget_charset (charset); + CHECK_INT (code); + c = XINT (code); + + if ((final = XCHARSET_FINAL (charset)) >= '0') + { + if (XCHARSET_DIMENSION (charset) == 1) + { + switch (XCHARSET_CHARS (charset)) + { + case 94: + return + make_char (MIN_CHAR_94 + (final - '0') * 94 + + ((c & 0x7F) - 33)); + case 96: + return + make_char (MIN_CHAR_96 + (final - '0') * 96 + + ((c & 0x7F) - 32)); + default: + return Fdecode_char (charset, code); + } + } + else + { + switch (XCHARSET_CHARS (charset)) + { + case 94: + return + make_char (MIN_CHAR_94x94 + + (final - '0') * 94 * 94 + + (((c >> 8) & 0x7F) - 33) * 94 + + ((c & 0x7F) - 33)); + case 96: + return + make_char (MIN_CHAR_96x96 + + (final - '0') * 96 * 96 + + (((c >> 8) & 0x7F) - 32) * 96 + + ((c & 0x7F) - 32)); + default: + return Fdecode_char (charset, code); + } + } + } + else if (XCHARSET_UCS_MAX (charset)) + { + Emchar cid + = (XCHARSET_DIMENSION (charset) == 1 + ? + c - XCHARSET_BYTE_OFFSET (charset) + : + ((c >> 8) - XCHARSET_BYTE_OFFSET (charset)) + * XCHARSET_CHARS (charset) + + (c & 0xFF) - XCHARSET_BYTE_OFFSET (charset)) + - XCHARSET_CODE_OFFSET (charset) + XCHARSET_UCS_MIN (charset); + if ((cid < XCHARSET_UCS_MIN (charset)) + || (XCHARSET_UCS_MAX (charset) < cid)) + return Fdecode_char (charset, code); + return make_char (cid); + } + else + return Fdecode_char (charset, code); +} #endif DEFUN ("make-char", Fmake_char, 2, 3, 0, /* @@ -2510,7 +3218,7 @@ character s with caron. */ (charset, arg1, arg2)) { - struct Lisp_Charset *cs; + Lisp_Charset *cs; int a1, a2; int lowlim, highlim; @@ -2527,7 +3235,7 @@ character s with caron. CHECK_INT (arg1); /* It is useful (and safe, according to Olivier Galibert) to strip - the 8th bit off ARG1 and ARG2 becaue it allows programmers to + the 8th bit off ARG1 and ARG2 because it allows programmers to write (make-char 'latin-iso8859-2 CODE) where code is the actual Latin 2 code of the character. */ #ifdef UTF2000 @@ -2563,27 +3271,27 @@ character s with caron. } DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /* -Return the character set of char CH. +Return the character set of CHARACTER. */ - (ch)) + (character)) { - CHECK_CHAR_COERCE_INT (ch); + CHECK_CHAR_COERCE_INT (character); - return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch))); + return XCHARSET_NAME (CHAR_CHARSET (XCHAR (character))); } DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /* -Return the octet numbered N (should be 0 or 1) of char CH. +Return the octet numbered N (should be 0 or 1) of CHARACTER. N defaults to 0 if omitted. */ - (ch, n)) + (character, n)) { Lisp_Object charset; int octet0, octet1; - CHECK_CHAR_COERCE_INT (ch); + CHECK_CHAR_COERCE_INT (character); - BREAKUP_CHAR (XCHAR (ch), charset, octet0, octet1); + BREAKUP_CHAR (XCHAR (character), charset, octet0, octet1); if (NILP (n) || EQ (n, Qzero)) return make_int (octet0); @@ -2594,7 +3302,7 @@ N defaults to 0 if omitted. } DEFUN ("split-char", Fsplit_char, 1, 1, 0, /* -Return list of charset and one or two position-codes of CHAR. +Return list of charset and one or two position-codes of CHARACTER. */ (character)) { @@ -2721,6 +3429,14 @@ Return a string of the characters comprising a composite character. void syms_of_mule_charset (void) { +#ifdef UTF2000 + INIT_LRECORD_IMPLEMENTATION (uint8_byte_table); + INIT_LRECORD_IMPLEMENTATION (uint16_byte_table); + INIT_LRECORD_IMPLEMENTATION (byte_table); + INIT_LRECORD_IMPLEMENTATION (char_id_table); +#endif + INIT_LRECORD_IMPLEMENTATION (charset); + DEFSUBR (Fcharsetp); DEFSUBR (Ffind_charset); DEFSUBR (Fget_charset); @@ -2740,6 +3456,8 @@ syms_of_mule_charset (void) DEFSUBR (Fset_charset_ccl_program); DEFSUBR (Fset_charset_registry); #ifdef UTF2000 + DEFSUBR (Fchar_attribute_list); + DEFSUBR (Ffind_char_attribute_table); DEFSUBR (Fchar_attribute_alist); DEFSUBR (Fget_char_attribute); DEFSUBR (Fput_char_attribute); @@ -2753,6 +3471,7 @@ syms_of_mule_charset (void) #ifdef UTF2000 DEFSUBR (Fdecode_char); + DEFSUBR (Fdecode_builtin_char); #endif DEFSUBR (Fmake_char); DEFSUBR (Fchar_charset); @@ -2821,13 +3540,17 @@ syms_of_mule_charset (void) defsymbol (&Qfont, "font"); defsymbol (&Qucs, "ucs"); defsymbol (&Qucs_bmp, "ucs-bmp"); + defsymbol (&Qucs_cns, "ucs-cns"); defsymbol (&Qlatin_viscii, "latin-viscii"); + defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712"); defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower"); defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper"); defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower"); defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper"); defsymbol (&Qideograph_daikanwa, "ideograph-daikanwa"); + defsymbol (&Qchinese_big5, "chinese-big5"); defsymbol (&Qmojikyo, "mojikyo"); + defsymbol (&Qmojikyo_2022_1, "mojikyo-2022-1"); defsymbol (&Qmojikyo_pj_1, "mojikyo-pj-1"); defsymbol (&Qmojikyo_pj_2, "mojikyo-pj-2"); defsymbol (&Qmojikyo_pj_3, "mojikyo-pj-3"); @@ -2886,10 +3609,10 @@ vars_of_mule_charset (void) #endif #ifdef UTF2000 - next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE; + chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE; #else - next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1; - next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2; + chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1; + chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2; #endif #ifndef UTF2000 @@ -2901,19 +3624,16 @@ Leading-code of private TYPE9N charset of column-width 1. #endif #ifdef UTF2000 - Vutf_2000_version = build_string("0.14 (Kawachi-Katakami)"); + Vutf_2000_version = build_string("0.17 (Hōryūji)"); DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /* Version number of UTF-2000. */ ); - staticpro (&Vcharacter_attribute_table); - Vcharacter_attribute_table = make_char_code_table (Qnil); - staticpro (&Vcharacter_composition_table); - Vcharacter_composition_table = make_char_code_table (Qnil); + Vcharacter_composition_table = make_char_id_table (Qnil); staticpro (&Vcharacter_variant_table); - Vcharacter_variant_table = make_char_code_table (Qnil); + Vcharacter_variant_table = make_char_id_table (Qnil); Vdefault_coded_charset_priority_list = Qnil; DEFVAR_LISP ("default-coded-charset-priority-list", @@ -2934,6 +3654,10 @@ complex_vars_of_mule_charset (void) ease of access. */ #ifdef UTF2000 + staticpro (&Vchar_attribute_hash_table); + Vchar_attribute_hash_table + = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); + staticpro (&Vcharset_ucs); Vcharset_ucs = make_charset (LEADING_BYTE_UCS, Qucs, 256, 4, @@ -2952,6 +3676,15 @@ complex_vars_of_mule_charset (void) build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"), build_string ("\\(ISO10646.*-1\\|UNICODE[23]?-0\\)"), Qnil, 0, 0xFFFF, 0, 0); + staticpro (&Vcharset_ucs_cns); + Vcharset_ucs_cns = + make_charset (LEADING_BYTE_UCS_CNS, Qucs_cns, 256, 4, + 1, 2, 0, CHARSET_LEFT_TO_RIGHT, + build_string ("UCS for CNS"), + build_string ("UCS for CNS 11643"), + build_string ("ISO/IEC 10646 for CNS 11643"), + build_string (""), + Qnil, 0, 0xFFFFFFF, 0, 0); #else # define MIN_CHAR_THAI 0 # define MAX_CHAR_THAI 0 @@ -3174,6 +3907,15 @@ complex_vars_of_mule_charset (void) build_string (CHINESE_CNS_PLANE_RE("2")), Qnil, 0, 0, 0, 33); #ifdef UTF2000 + staticpro (&Vcharset_latin_tcvn5712); + Vcharset_latin_tcvn5712 = + make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1, + 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT, + build_string ("TCVN 5712"), + build_string ("TCVN 5712 (VSCII-2)"), + build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"), + build_string ("tcvn5712-1"), + Qnil, 0, 0, 0, 32); staticpro (&Vcharset_latin_viscii_lower); Vcharset_latin_viscii_lower = make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1, @@ -3201,6 +3943,15 @@ complex_vars_of_mule_charset (void) build_string ("VISCII 1.1 (Vietnamese)"), build_string ("VISCII1\\.1"), Qnil, 0, 0, 0, 0); + staticpro (&Vcharset_chinese_big5); + Vcharset_chinese_big5 = + make_charset (LEADING_BYTE_CHINESE_BIG5, Qchinese_big5, 256, 2, + 2, 2, 0, CHARSET_LEFT_TO_RIGHT, + build_string ("Big5"), + build_string ("Big5"), + build_string ("Big5 Chinese traditional"), + build_string ("big5"), + Qnil, 0, 0, 0, 0); staticpro (&Vcharset_ideograph_daikanwa); Vcharset_ideograph_daikanwa = make_charset (LEADING_BYTE_DAIKANWA, Qideograph_daikanwa, 256, 2, @@ -3219,216 +3970,51 @@ complex_vars_of_mule_charset (void) build_string ("Konjaku-Mojikyo"), build_string (""), Qnil, MIN_CHAR_MOJIKYO, MAX_CHAR_MOJIKYO, 0, 0); - staticpro (&Vcharset_mojikyo_pj_1); - Vcharset_mojikyo_pj_1 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_1, Qmojikyo_pj_1, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-1"), - build_string ("Mojikyo (pseudo JIS encoding) part 1"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 1"), - build_string ("jisx0208\\.Mojikyo-1$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_2); - Vcharset_mojikyo_pj_2 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_2, Qmojikyo_pj_2, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-2"), - build_string ("Mojikyo (pseudo JIS encoding) part 2"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 2"), - build_string ("jisx0208\\.Mojikyo-2$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_3); - Vcharset_mojikyo_pj_3 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_3, Qmojikyo_pj_3, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-3"), - build_string ("Mojikyo (pseudo JIS encoding) part 3"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 3"), - build_string ("jisx0208\\.Mojikyo-3$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_4); - Vcharset_mojikyo_pj_4 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_4, Qmojikyo_pj_4, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-4"), - build_string ("Mojikyo (pseudo JIS encoding) part 4"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 4"), - build_string ("jisx0208\\.Mojikyo-4$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_5); - Vcharset_mojikyo_pj_5 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_5, Qmojikyo_pj_5, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-5"), - build_string ("Mojikyo (pseudo JIS encoding) part 5"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 5"), - build_string ("jisx0208\\.Mojikyo-5$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_6); - Vcharset_mojikyo_pj_6 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_6, Qmojikyo_pj_6, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-6"), - build_string ("Mojikyo (pseudo JIS encoding) part 6"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 6"), - build_string ("jisx0208\\.Mojikyo-6$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_7); - Vcharset_mojikyo_pj_7 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_7, Qmojikyo_pj_7, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-7"), - build_string ("Mojikyo (pseudo JIS encoding) part 7"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 7"), - build_string ("jisx0208\\.Mojikyo-7$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_8); - Vcharset_mojikyo_pj_8 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_8, Qmojikyo_pj_8, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-8"), - build_string ("Mojikyo (pseudo JIS encoding) part 8"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 8"), - build_string ("jisx0208\\.Mojikyo-8$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_9); - Vcharset_mojikyo_pj_9 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_9, Qmojikyo_pj_9, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-9"), - build_string ("Mojikyo (pseudo JIS encoding) part 9"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 9"), - build_string ("jisx0208\\.Mojikyo-9$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_10); - Vcharset_mojikyo_pj_10 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_10, Qmojikyo_pj_10, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-10"), - build_string ("Mojikyo (pseudo JIS encoding) part 10"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 10"), - build_string ("jisx0208\\.Mojikyo-10$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_11); - Vcharset_mojikyo_pj_11 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_11, Qmojikyo_pj_11, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-11"), - build_string ("Mojikyo (pseudo JIS encoding) part 11"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 11"), - build_string ("jisx0208\\.Mojikyo-11$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_12); - Vcharset_mojikyo_pj_12 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_12, Qmojikyo_pj_12, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-12"), - build_string ("Mojikyo (pseudo JIS encoding) part 12"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 12"), - build_string ("jisx0208\\.Mojikyo-12$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_13); - Vcharset_mojikyo_pj_13 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_13, Qmojikyo_pj_13, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-13"), - build_string ("Mojikyo (pseudo JIS encoding) part 13"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 13"), - build_string ("jisx0208\\.Mojikyo-13$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_14); - Vcharset_mojikyo_pj_14 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_14, Qmojikyo_pj_14, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-14"), - build_string ("Mojikyo (pseudo JIS encoding) part 14"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 14"), - build_string ("jisx0208\\.Mojikyo-14$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_15); - Vcharset_mojikyo_pj_15 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_15, Qmojikyo_pj_15, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-15"), - build_string ("Mojikyo (pseudo JIS encoding) part 15"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 15"), - build_string ("jisx0208\\.Mojikyo-15$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_16); - Vcharset_mojikyo_pj_16 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_16, Qmojikyo_pj_16, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-16"), - build_string ("Mojikyo (pseudo JIS encoding) part 16"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 16"), - build_string ("jisx0208\\.Mojikyo-16$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_17); - Vcharset_mojikyo_pj_17 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_17, Qmojikyo_pj_17, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-17"), - build_string ("Mojikyo (pseudo JIS encoding) part 17"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 17"), - build_string ("jisx0208\\.Mojikyo-17$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_18); - Vcharset_mojikyo_pj_18 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_18, Qmojikyo_pj_18, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-18"), - build_string ("Mojikyo (pseudo JIS encoding) part 18"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 18"), - build_string ("jisx0208\\.Mojikyo-18$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_19); - Vcharset_mojikyo_pj_19 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_19, Qmojikyo_pj_19, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-19"), - build_string ("Mojikyo (pseudo JIS encoding) part 19"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 19"), - build_string ("jisx0208\\.Mojikyo-19$"), - Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_20); - Vcharset_mojikyo_pj_20 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_20, Qmojikyo_pj_20, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-20"), - build_string ("Mojikyo (pseudo JIS encoding) part 20"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 20"), - build_string ("jisx0208\\.Mojikyo-20$"), + staticpro (&Vcharset_mojikyo_2022_1); + Vcharset_mojikyo_2022_1 = + make_charset (LEADING_BYTE_MOJIKYO_2022_1, Qmojikyo_2022_1, 94, 3, + 2, 2, ':', CHARSET_LEFT_TO_RIGHT, + build_string ("Mojikyo-2022-1"), + build_string ("Mojikyo ISO-2022 Part 1"), + build_string ("Konjaku-Mojikyo for ISO/IEC 2022 Part 1"), + build_string (""), Qnil, 0, 0, 0, 33); - staticpro (&Vcharset_mojikyo_pj_21); - Vcharset_mojikyo_pj_21 = - make_charset (LEADING_BYTE_MOJIKYO_PJ_21, Qmojikyo_pj_21, 94, 2, - 2, 0, 0, CHARSET_LEFT_TO_RIGHT, - build_string ("Mojikyo-PJ-21"), - build_string ("Mojikyo (pseudo JIS encoding) part 21"), - build_string - ("Konjaku-Mojikyo (pseudo JIS encoding) part 21"), - build_string ("jisx0208\\.Mojikyo-21$"), + +#define DEF_MOJIKYO_PJ(n) \ + staticpro (&Vcharset_mojikyo_pj_##n); \ + Vcharset_mojikyo_pj_##n = \ + make_charset (LEADING_BYTE_MOJIKYO_PJ_##n, Qmojikyo_pj_##n, 94, 2, \ + 2, 0, 0, CHARSET_LEFT_TO_RIGHT, \ + build_string ("Mojikyo-PJ-"#n), \ + build_string ("Mojikyo (pseudo JIS encoding) part "#n), \ + build_string \ + ("Konjaku-Mojikyo (pseudo JIS encoding) part "#n), \ + build_string \ + ("\\(MojikyoPJ-"#n "\\|jisx0208\\.Mojikyo-"#n "\\)$"), \ Qnil, 0, 0, 0, 33); + + DEF_MOJIKYO_PJ (1); + DEF_MOJIKYO_PJ (2); + DEF_MOJIKYO_PJ (3); + DEF_MOJIKYO_PJ (4); + DEF_MOJIKYO_PJ (5); + DEF_MOJIKYO_PJ (6); + DEF_MOJIKYO_PJ (7); + DEF_MOJIKYO_PJ (8); + DEF_MOJIKYO_PJ (9); + DEF_MOJIKYO_PJ (10); + DEF_MOJIKYO_PJ (11); + DEF_MOJIKYO_PJ (12); + DEF_MOJIKYO_PJ (13); + DEF_MOJIKYO_PJ (14); + DEF_MOJIKYO_PJ (15); + DEF_MOJIKYO_PJ (16); + DEF_MOJIKYO_PJ (17); + DEF_MOJIKYO_PJ (18); + DEF_MOJIKYO_PJ (19); + DEF_MOJIKYO_PJ (20); + DEF_MOJIKYO_PJ (21); + staticpro (&Vcharset_ethiopic_ucs); Vcharset_ethiopic_ucs = make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,