+ return ret;
+
+ ret = cpt->property [(unsigned char) (code >> 8)];
+ if (CHAR_BYTE_TABLE_P (ret))
+ cpt = XCHAR_BYTE_TABLE (ret);
+ else
+ return ret;
+
+ return cpt->property [(unsigned char) code];
+}
+
+void
+put_char_code_table (Emchar ch, Lisp_Object value, Lisp_Object table)
+{
+ 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 (CHAR_BYTE_TABLE_P (ret))
+ {
+ struct Lisp_Char_Byte_Table* cpt2 = XCHAR_BYTE_TABLE (ret);
+
+ ret = cpt2->property[(unsigned char)(code >> 16)];
+ if (CHAR_BYTE_TABLE_P (ret))
+ {
+ struct Lisp_Char_Byte_Table* cpt3 = XCHAR_BYTE_TABLE (ret);
+
+ ret = cpt3->property[(unsigned char)(code >> 8)];
+ if (CHAR_BYTE_TABLE_P (ret))
+ {
+ struct Lisp_Char_Byte_Table* cpt4
+ = XCHAR_BYTE_TABLE (ret);
+
+ cpt4->property[(unsigned char)code] = value;
+ }
+ else if (!EQ (ret, value))
+ {
+ Lisp_Object cpt4 = make_char_byte_table (ret);
+
+ XCHAR_BYTE_TABLE(cpt4)->property[(unsigned char)code] = value;
+ cpt3->property[(unsigned char)(code >> 8)] = cpt4;
+ }
+ }
+ else if (!EQ (ret, value))
+ {
+ 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;
+ }
+ }
+ else if (!EQ (ret, value))
+ {
+ 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;
+ }
+}
+
+
+Lisp_Object Vcharacter_attribute_table;
+Lisp_Object Vcharacter_composition_table;
+Lisp_Object Vcharacter_variant_table;
+
+Lisp_Object Q_decomposition;
+Lisp_Object Q_ucs;
+Lisp_Object Qwide;
+Lisp_Object Qnarrow;
+Lisp_Object Qcompat;
+Lisp_Object QnoBreak;
+Lisp_Object Qsuper;
+Lisp_Object Qfraction;
+
+Emchar
+to_char_code (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
+{
+ if (INTP (v))
+ return XINT (v);
+ if (CHARP (v))
+ return XCHAR (v);
+ else if (EQ (v, Qwide))
+ return -1;
+ else if (EQ (v, Qnarrow))
+ return -2;
+ else if (EQ (v, Qcompat))
+ return -3;
+ else if (EQ (v, QnoBreak))
+ return -4;
+ else if (EQ (v, Qsuper))
+ return -5;
+ else if (EQ (v, Qfraction))
+ return -6;
+ else
+ signal_simple_error (err_msg, err_arg);
+}
+
+DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
+Return character corresponding with list.
+*/
+ (list))
+{
+ Lisp_Object table = Vcharacter_composition_table;
+ Lisp_Object rest = list;
+
+ while (CONSP (rest))