+
+DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
+Store CHARACTER's ATTRIBUTE with VALUE.
+*/
+ (character, attribute, value))
+{
+ Lisp_Object ccs;
+
+ CHECK_CHAR (character);
+ ccs = Ffind_charset (attribute);
+ if (!NILP (ccs))
+ {
+ Lisp_Object rest;
+ Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
+ Lisp_Object nv;
+ int i = -1;
+ int ccs_len;
+
+ /* 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);
+
+ if (!CONSP (value))
+ signal_simple_error ("Invalid value for coded-charset",
+ value);
+
+ attribute = ccs;
+ rest = Fget_char_attribute (character, attribute);
+ if (VECTORP (v))
+ {
+ if (!NILP (rest))
+ {
+ while (!NILP (rest))
+ {
+ Lisp_Object ei = Fcar (rest);
+
+ i = XINT (ei) - XCHARSET_BYTE_OFFSET (ccs);
+ nv = XVECTOR_DATA(v)[i];
+ if (!VECTORP (nv))
+ break;
+ v = nv;
+ rest = Fcdr (rest);
+ }
+ if (i >= 0)
+ XVECTOR_DATA(v)[i] = Qnil;
+ v = XCHARSET_DECODING_TABLE (ccs);
+ }
+ }
+ else
+ {
+ XCHARSET_DECODING_TABLE (ccs) = v = make_vector (ccs_len, Qnil);
+ }
+
+ if (XCHARSET_GRAPHIC (ccs) == 1)
+ value = Fcopy_list (value);
+ rest = value;
+ i = -1;
+ while (CONSP (rest))
+ {
+ Lisp_Object ei = Fcar (rest);
+
+ if (!INTP (ei))
+ signal_simple_error ("Invalid value for coded-charset", value);
+ i = XINT (ei);
+ if ((i < 0) || (255 < i))
+ signal_simple_error ("Invalid value for coded-charset", value);
+ if (XCHARSET_GRAPHIC (ccs) == 1)
+ {
+ i &= 0x7F;
+ Fsetcar (rest, make_int (i));
+ }
+ i -= XCHARSET_BYTE_OFFSET (ccs);
+ nv = XVECTOR_DATA(v)[i];
+ rest = Fcdr (rest);
+ if (CONSP (rest))
+ {
+ if (!VECTORP (nv))
+ {
+ nv = (XVECTOR_DATA(v)[i] = make_vector (ccs_len, Qnil));
+ }
+ v = nv;
+ }
+ else
+ break;
+ }
+ XVECTOR_DATA(v)[i] = character;
+ }
+ 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);
+
+ rest = Fcdr (rest);
+ if (!CONSP (rest))
+ {
+ put_char_code_table (c, character, table);
+ break;
+ }
+ else
+ {
+ ntable = get_char_code_table (c, table);
+ if (!CHAR_CODE_TABLE_P (ntable))
+ {
+ ntable = make_char_code_table (Qnil);
+ put_char_code_table (c, ntable, table);
+ }
+ table = ntable;
+ }
+ }
+ }
+ else if (EQ (attribute, Q_ucs))
+ {
+ Lisp_Object ret;
+ Emchar c;
+
+ if (!INTP (value))
+ signal_simple_error ("Invalid value for ->ucs", value);
+
+ c = XINT (value);
+
+ ret = get_char_code_table (c, Vcharacter_variant_table);
+ if (NILP (Fmemq (character, ret)))
+ {
+ put_char_code_table (c, Fcons (character, ret),
+ Vcharacter_variant_table);
+ }
+ }
+ return put_char_attribute (character, attribute, value);
+}
+
+Lisp_Object Qucs;
+
+EXFUN (Fmake_char, 3);
+
+DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
+Store character's ATTRIBUTES.
+*/
+ (attributes))
+{
+ Lisp_Object rest = attributes;
+ Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
+ Lisp_Object character;
+
+ if (NILP (code))
+ {
+ while (CONSP (rest))
+ {
+ Lisp_Object cell = Fcar (rest);
+ Lisp_Object ccs;