update.
[chise/xemacs-chise.git.1] / src / chartab.c
index 3cf4c35..7c1408a 100644 (file)
@@ -4,7 +4,8 @@
    Copyright (C) 1995, 1996 Ben Wing.
    Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN.
    Licensed to the Free Software Foundation.
    Copyright (C) 1995, 1996 Ben Wing.
    Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN.
    Licensed to the Free Software Foundation.
-   Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006 MORIOKA Tomohiko
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008,
+     2010, 2011, 2012, 2013, 2015, 2016 MORIOKA Tomohiko
 
 This file is part of XEmacs.
 
 
 This file is part of XEmacs.
 
@@ -99,7 +100,7 @@ Lisp_Object Vchar_db_stingy_mode;
 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 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 */ Lisp_Object UINT8_DECODE (unsigned char n);
 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
 
 INLINE_HEADER int
 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
 
 INLINE_HEADER int
@@ -137,7 +138,7 @@ UINT8_ENCODE (Lisp_Object obj)
     return XINT (obj);
 }
 
     return XINT (obj);
 }
 
-INLINE_HEADER Lisp_Object
+/* INLINE_HEADER */ Lisp_Object
 UINT8_DECODE (unsigned char n)
 {
   if (n == BT_UINT8_unloaded)
 UINT8_DECODE (unsigned char n)
 {
   if (n == BT_UINT8_unloaded)
@@ -354,7 +355,7 @@ save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
     {
       if (ct->property[i] == BT_UINT8_unloaded)
        {
     {
       if (ct->property[i] == BT_UINT8_unloaded)
        {
-         c1 = c + unit;
+         c += unit;
        }
       else if (ct->property[i] != BT_UINT8_unbound)
        {
        }
       else if (ct->property[i] != BT_UINT8_unbound)
        {
@@ -391,7 +392,7 @@ save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
 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 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 */ Lisp_Object UINT16_DECODE (unsigned short us);
 
 INLINE_HEADER int
 INT_UINT16_P (Lisp_Object obj)
 
 INLINE_HEADER int
 INT_UINT16_P (Lisp_Object obj)
@@ -428,7 +429,7 @@ UINT16_ENCODE (Lisp_Object obj)
     return XINT (obj);
 }
 
     return XINT (obj);
 }
 
-INLINE_HEADER Lisp_Object
+/* INLINE_HEADER */ Lisp_Object
 UINT16_DECODE (unsigned short n)
 {
   if (n == BT_UINT16_unloaded)
 UINT16_DECODE (unsigned short n)
 {
   if (n == BT_UINT16_unloaded)
@@ -678,7 +679,7 @@ save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
     {
       if (ct->property[i] == BT_UINT16_unloaded)
        {
     {
       if (ct->property[i] == BT_UINT16_unloaded)
        {
-         c1 = c + unit;
+         c += unit;
        }
       else if (ct->property[i] != BT_UINT16_unbound)
        {
        }
       else if (ct->property[i] != BT_UINT16_unbound)
        {
@@ -1130,7 +1131,7 @@ make_char_id_table (Lisp_Object initval)
 
 
 Lisp_Object Qcomposition;
 
 
 Lisp_Object Qcomposition;
-Lisp_Object Qmap_decomposition;
+Lisp_Object Qrep_decomposition;
 Lisp_Object Qto_decomposition_at_superscript;
 Lisp_Object Qto_decomposition_at_circled;
 Lisp_Object Q_canonical;
 Lisp_Object Qto_decomposition_at_superscript;
 Lisp_Object Qto_decomposition_at_circled;
 Lisp_Object Q_canonical;
@@ -3269,6 +3270,43 @@ Return the alist of attributes of CHARACTER.
   return alist;
 }
 
   return alist;
 }
 
+DEFUN ("char-feature-base-name=", Fchar_feature_base_name_eq, 2, 2, 0, /*
+Return the alist of attributes of CHARACTER.
+*/
+       (base_name, feature_name))
+{
+  Lisp_String *bn, *fn;
+  Bytecount len_bn, len_fn, i;
+  Bufbyte *ptr_bn, *ptr_fn;
+
+  CHECK_SYMBOL (base_name);
+  CHECK_SYMBOL (feature_name);
+
+  bn = XSYMBOL (base_name)->name;
+  fn = XSYMBOL (feature_name)->name;
+  len_bn = string_length (bn);
+  len_fn = string_length (fn);
+
+  if ( len_bn > len_fn )
+    return Qnil;
+
+  ptr_bn = string_data (bn);
+  ptr_fn = string_data (fn);
+  for ( i = len_fn - 1; i >= 0; i-- )
+    {
+      if ( ptr_fn[i] == '*' )
+       return Qnil;
+      if ( ptr_fn[i] == '@' )
+       break;
+    }
+  if ( i < 0 )
+    i = len_fn;
+  if ( (len_bn == i) && (memcmp (ptr_bn, ptr_fn, len_bn) == 0) )
+    return Qt;
+  else
+    return Qnil;
+}
+
 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.
 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.
@@ -3302,6 +3340,7 @@ find_char_feature_in_family (Lisp_Object character,
 {
   Lisp_Object ancestors
     = Fget_char_attribute (character, con_feature, Qnil);
 {
   Lisp_Object ancestors
     = Fget_char_attribute (character, con_feature, Qnil);
+#if 0
 
   while (!NILP (ancestors))
     {
 
   while (!NILP (ancestors))
     {
@@ -3326,6 +3365,38 @@ find_char_feature_in_family (Lisp_Object character,
       if (!NILP (ret))
        ancestors = nconc2 (Fcopy_sequence (ancestors), ret);
     }
       if (!NILP (ret))
        ancestors = nconc2 (Fcopy_sequence (ancestors), ret);
     }
+#else
+  Lisp_Object ancestor;
+
+  if (CONSP (ancestors))
+    ancestor = XCAR (ancestors);
+  else
+    ancestor = ancestors;
+
+  if (!NILP (ancestor))
+    {
+      Lisp_Object ret;
+      Lisp_Object anc;
+
+      if (EQ (ancestor, character))
+       return Qunbound;
+
+      ret = Fchar_feature (ancestor, feature, Qunbound,
+                          Qnil, make_int (0));
+      if (!UNBOUNDP (ret))
+       return ret;
+
+      ret = find_char_feature_in_family (ancestor, Q_subsumptive_from,
+                                        feature, feature_rel_max);
+      if (!UNBOUNDP (ret))
+       return ret;
+
+      ret = find_char_feature_in_family (ancestor, Q_denotational_from,
+                                        feature, feature_rel_max);
+      if (!UNBOUNDP (ret))
+       return ret;
+    }
+#endif
   return Qunbound;
 }
 
   return Qunbound;
 }
 
@@ -3342,6 +3413,7 @@ Return DEFAULT-VALUE if the value is not exist.
   if (!UNBOUNDP (ret))
     return ret;
 
   if (!UNBOUNDP (ret))
     return ret;
 
+#if 0
   if (NILP (feature_rel_max)
       || (INTP (feature_rel_max) &&
          XINT (feature_rel_max) > 0))
   if (NILP (feature_rel_max)
       || (INTP (feature_rel_max) &&
          XINT (feature_rel_max) > 0))
@@ -3366,6 +3438,7 @@ Return DEFAULT-VALUE if the value is not exist.
            return ret;
        }
     }
            return ret;
        }
     }
+#endif
 
   if ( !(EQ (attribute, Q_identical)) &&
        !(EQ (attribute, Q_subsumptive_from)) &&
 
   if ( !(EQ (attribute, Q_identical)) &&
        !(EQ (attribute, Q_subsumptive_from)) &&
@@ -3374,11 +3447,13 @@ Return DEFAULT-VALUE if the value is not exist.
          || (INTP (char_rel_max) &&
              XINT (char_rel_max) > 0)) ) )
     {
          || (INTP (char_rel_max) &&
              XINT (char_rel_max) > 0)) ) )
     {
+#if 0
       Lisp_String* name = symbol_name (XSYMBOL (attribute));
       Bufbyte *name_str = string_data (name);
 
       if ( (name_str[0] != '=') || (name_str[1] == '>') )
        {
       Lisp_String* name = symbol_name (XSYMBOL (attribute));
       Bufbyte *name_str = string_data (name);
 
       if ( (name_str[0] != '=') || (name_str[1] == '>') )
        {
+#endif
          ret = find_char_feature_in_family (character, Q_identical,
                                             attribute, feature_rel_max);
          if (!UNBOUNDP (ret))
          ret = find_char_feature_in_family (character, Q_identical,
                                             attribute, feature_rel_max);
          if (!UNBOUNDP (ret))
@@ -3393,7 +3468,9 @@ Return DEFAULT-VALUE if the value is not exist.
                                             attribute, feature_rel_max);
          if (!UNBOUNDP (ret))
            return ret;
                                             attribute, feature_rel_max);
          if (!UNBOUNDP (ret))
            return ret;
+#if 0
        }
        }
+#endif
     }
   return default_value;
 }
     }
   return default_value;
 }
@@ -3496,7 +3573,7 @@ put_char_composition (Lisp_Object character, Lisp_Object value)
        }
 #endif
     }
        }
 #endif
     }
-  return Qmap_decomposition;
+  return Qrep_decomposition;
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
@@ -3530,17 +3607,35 @@ Store CHARACTER's ATTRIBUTE with VALUE.
 
   if (!NILP (ccs))
     {
 
   if (!NILP (ccs))
     {
-      value = put_char_ccs_code_point (character, ccs, value);
+      if ( !NILP (value) )
+       value = put_char_ccs_code_point (character, ccs, value);
       attribute = XCHARSET_NAME (ccs);
     }
       attribute = XCHARSET_NAME (ccs);
     }
-  else if ( EQ (attribute, Qmap_decomposition) ||
-           EQ (attribute, Q_decomposition) )
+  else if (
+#if 0
+           EQ (attribute, Qrep_decomposition) ||
+#else
+           !NILP (Fchar_feature_base_name_eq (Qrep_decomposition,
+                                              attribute)) ||
+#endif
+           EQ (attribute, Q_decomposition) /* || */
+#if 0
+           !NILP (Fstring_match (build_string ("^=decomposition@[^*]+$"),
+                                 Fsymbol_name (attribute),
+                                 Qnil, Qnil))
+#endif
+           )
     {
     {
+      Lisp_Object ret;
+
       value = Fcopy_sequence (Fchar_refs_simplify_char_specs (value));
       value = Fcopy_sequence (Fchar_refs_simplify_char_specs (value));
-      attribute = put_char_composition (character, value);
-      if ( !EQ (attribute, Qmap_decomposition) &&
+      ret = put_char_composition (character, value);
+      if ( !EQ (ret, Qrep_decomposition) &&
           SYMBOLP (XCAR (value)) )
           SYMBOLP (XCAR (value)) )
-       value = XCDR (value);
+       {
+         attribute = ret;
+         value = XCDR (value);
+       }
     }
   else if (EQ (attribute, Qto_ucs))
     {
     }
   else if (EQ (attribute, Qto_ucs))
     {
@@ -3715,22 +3810,43 @@ open_chise_data_source_maybe ()
 {
   if (default_chise_data_source == NULL)
     {
 {
   if (default_chise_data_source == NULL)
     {
-      Lisp_Object db_dir = Vdata_directory;
       int modemask = 0755;             /* rwxr-xr-x */
       int modemask = 0755;             /* rwxr-xr-x */
+      char* db_dir_name;
+      size_t len;
 
 
-      if (NILP (db_dir))
-       db_dir = build_string ("../etc");
-      db_dir = Fexpand_file_name (build_string ("chise-db"), db_dir);
+      if (STRINGP (Vdata_directory))
+       {
+         char* dir_name = XSTRING_DATA (Vdata_directory);
+
+         len = strlen (dir_name) + 8;
+         db_dir_name = alloca (len + 1);
+         strncpy (db_dir_name, dir_name, len);
+       }
+      else
+       {
+         if (STRINGP (current_buffer->directory))
+           {
+             char* dir_name = XSTRING_DATA (current_buffer->directory);
+
+             len = strlen (dir_name) + 7 + 8;
+             db_dir_name = alloca (len + 1);
+             strncpy (db_dir_name, dir_name, len);
+             strncat(db_dir_name, "../etc/", 15);
+           }
+         else
+           {
+             len = 7 + 8;
+             db_dir_name = alloca (len + 1);
+             strncpy (db_dir_name, "../etc/", len);
+           }
+       }
+      strncat(db_dir_name, "chise-db", 8);
 
 
-      default_chise_data_source
-       = CHISE_DS_open (CHISE_DS_Berkeley_DB, XSTRING_DATA (db_dir),
-                        0 /* DB_HASH */, modemask);
+      default_chise_data_source = CHISE_DS_open (CHISE_DS_Berkeley_DB,
+                                                db_dir_name,
+                                                0 /* DB_HASH */, modemask);
       if (default_chise_data_source == NULL)
        return -1;
       if (default_chise_data_source == NULL)
        return -1;
-#if 0
-      chise_ds_set_make_string_function (default_chise_data_source,
-                                        &make_string);
-#endif
     }
   return 0;
 }
     }
   return 0;
 }
@@ -3806,13 +3922,8 @@ char_table_get_db (Lisp_Char_Table* cit, Emchar ch)
 
   if (!status)
     {
 
   if (!status)
     {
-#if 0
-      val = Fread (make_string (chise_value_data (&value),
-                               chise_value_size (&value) ));
-#else
       val = read_from_c_string (chise_value_data (&value),
                                chise_value_size (&value) );
       val = read_from_c_string (chise_value_data (&value),
                                chise_value_size (&value) );
-#endif
     }
   else
     val = Qunbound;
     }
   else
     val = Qunbound;
@@ -3827,6 +3938,17 @@ char_table_get_db (Lisp_Char_Table* cit, Emchar ch)
   return val;
 }
 
   return val;
 }
 
+#ifdef USE_CONCORD_OBJECT_SYSTEM
+COS_object
+char_table_get_db_cos (Lisp_Char_Table* cit, Emchar ch)
+{
+  return
+    concord_object_get_attribute
+    (cos_make_char (ch),
+     cos_intern (XSTRING_DATA (Fsymbol_name (cit->name))));
+}
+#endif
+
 #ifndef HAVE_LIBCHISE
 Lisp_Object
 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
 #ifndef HAVE_LIBCHISE
 Lisp_Object
 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
@@ -4097,6 +4219,27 @@ load_char_attribute_maybe (Lisp_Char_Table* cit, Emchar ch)
   return Qunbound;
 }
 
   return Qunbound;
 }
 
+#ifdef USE_CONCORD_OBJECT_SYSTEM
+COS_object
+load_char_attribute_maybe_cos (Lisp_Char_Table* cit, Emchar ch)
+{
+  Lisp_Object attribute = CHAR_TABLE_NAME (cit);
+
+  if (!NILP (attribute))
+    {
+      COS_object val;
+
+      if (char_table_open_db_maybe (cit))
+       return NULL;
+
+      val = char_table_get_db_cos (cit, ch);
+
+      return val;
+    }
+  return NULL;
+}
+#endif
+
 Lisp_Char_Table* char_attribute_table_to_load;
 
 #ifdef HAVE_LIBCHISE
 Lisp_Char_Table* char_attribute_table_to_load;
 
 #ifdef HAVE_LIBCHISE
@@ -4232,13 +4375,27 @@ implementation does not coalesce ranges all of whose values are the same.
   return slarg.retval;
 }
 
   return slarg.retval;
 }
 
+static Lisp_Object
+allocate_character ()
+{
+  int cid = XINT (Vnext_defined_char_id);
+
+  if (cid <= 0xE00000)
+    {
+      Vnext_defined_char_id = make_int (cid + 1);
+      return make_char (cid);
+    }
+  else
+    return Qnil;
+}
+
 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
 Store character's ATTRIBUTES.
 */
        (attributes))
 {
   Lisp_Object rest;
 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
 Store character's ATTRIBUTES.
 */
        (attributes))
 {
   Lisp_Object rest;
-  Lisp_Object code = Fcdr (Fassq (Qmap_ucs, attributes));
+  Lisp_Object code = Fcdr (Fassq (Qrep_ucs, attributes));
   Lisp_Object character;
 
   if (NILP (code))
   Lisp_Object character;
 
   if (NILP (code))
@@ -4280,7 +4437,7 @@ Store character's ATTRIBUTES.
            }
          rest = Fcdr (rest);
        }
            }
          rest = Fcdr (rest);
        }
-#if 1
+#if 0
       {
        int cid = XINT (Vnext_defined_char_id);
 
       {
        int cid = XINT (Vnext_defined_char_id);
 
@@ -4292,16 +4449,9 @@ Store character's ATTRIBUTES.
          }
       }
 #else
          }
       }
 #else
-      if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
-       {
-         if (!INTP (code))
-           signal_simple_error ("Invalid argument", attributes);
-         else
-           character = make_char (XINT (code) + 0x100000);
-         goto setup_attributes;
-       }
+      if ( NILP (character = allocate_character ()) )
 #endif
 #endif
-      return Qnil;
+       return Qnil;
     }
   else if (!INTP (code))
     signal_simple_error ("Invalid argument", attributes);
     }
   else if (!INTP (code))
     signal_simple_error ("Invalid argument", attributes);
@@ -4362,6 +4512,62 @@ Retrieve the character of the given ATTRIBUTES.
 
 \f
 /************************************************************************/
 
 \f
 /************************************************************************/
+/*                      Character Feature Property                      */
+/************************************************************************/
+
+#ifdef HAVE_LIBCHISE
+DEFUN ("char-feature-property", Fchar_feature_property, 2, 3, 0, /*
+Return the value of FEATURE's PROPERTY.
+Return DEFAULT-VALUE if the value is not exist.
+*/
+       (feature, property, default_value))
+{
+  unsigned char* feature_name;
+  unsigned char* property_name;
+  CHISE_Value value;
+  int status;
+
+  feature_name = XSTRING_DATA (Fsymbol_name (feature));
+  property_name = XSTRING_DATA (Fsymbol_name (property));
+  status
+    = chise_feature_load_property_value (chise_ds_get_feature
+                                        (default_chise_data_source,
+                                         feature_name),
+                                        chise_ds_get_property
+                                        (default_chise_data_source,
+                                         property_name),
+                                        &value);
+  if (!status)
+    return read_from_c_string (chise_value_data (&value),
+                              chise_value_size (&value) );
+  else
+    return default_value;
+}
+
+DEFUN ("put-char-feature-property", Fput_char_feature_property, 3, 3, 0, /*
+Store FEATURE's PROPERTY with VALUE.
+*/
+       (feature, property, value))
+{
+  unsigned char* feature_name;
+  unsigned char* property_name;
+  CHISE_Property prop;
+
+  feature_name = XSTRING_DATA (Fsymbol_name (feature));
+  property_name = XSTRING_DATA (Fsymbol_name (property));
+  prop = chise_ds_get_property (default_chise_data_source,
+                               property_name);
+  chise_feature_set_property_value
+    (chise_ds_get_feature (default_chise_data_source, feature_name),
+     prop, XSTRING_DATA (Fprin1_to_string
+                        (value, Qnil)));
+  chise_property_sync (prop);
+  return Qnil;
+}
+#endif
+
+\f
+/************************************************************************/
 /*                         Char table read syntax                       */
 /************************************************************************/
 
 /*                         Char table read syntax                       */
 /************************************************************************/
 
@@ -4699,6 +4905,12 @@ word_boundary_p (Emchar c1, Emchar c2)
 void
 syms_of_chartab (void)
 {
 void
 syms_of_chartab (void)
 {
+#if defined(UTF2000) || defined(HAVE_CONCORD)
+  defsymbol (&Q_subsumptive,           "->subsumptive");
+  defsymbol (&Q_subsumptive_from,      "<-subsumptive");
+  defsymbol (&Q_denotational,          "->denotational");
+  defsymbol (&Q_denotational_from,     "<-denotational");
+#endif
 #ifdef UTF2000
   INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
   INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
 #ifdef UTF2000
   INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
   INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
@@ -4706,16 +4918,12 @@ syms_of_chartab (void)
 
   defsymbol (&Qto_ucs,                 "=>ucs");
   defsymbol (&Q_ucs_unified,           "->ucs-unified");
 
   defsymbol (&Qto_ucs,                 "=>ucs");
   defsymbol (&Q_ucs_unified,           "->ucs-unified");
-  defsymbol (&Q_subsumptive,           "->subsumptive");
-  defsymbol (&Q_subsumptive_from,      "<-subsumptive");
-  defsymbol (&Q_denotational,          "->denotational");
-  defsymbol (&Q_denotational_from,     "<-denotational");
   defsymbol (&Q_identical,             "->identical");
   defsymbol (&Q_identical_from,                "<-identical");
   defsymbol (&Q_component,             "->ideographic-component-forms");
   defsymbol (&Q_component_of,          "<-ideographic-component-forms");
   defsymbol (&Qcomposition,            "composition");
   defsymbol (&Q_identical,             "->identical");
   defsymbol (&Q_identical_from,                "<-identical");
   defsymbol (&Q_component,             "->ideographic-component-forms");
   defsymbol (&Q_component_of,          "<-ideographic-component-forms");
   defsymbol (&Qcomposition,            "composition");
-  defsymbol (&Qmap_decomposition,      "=decomposition");
+  defsymbol (&Qrep_decomposition,      "=decomposition");
   defsymbol (&Qto_decomposition_at_superscript,
             "=>decomposition@superscript");
   defsymbol (&Qto_decomposition_at_circled, "=>decomposition@circled");
   defsymbol (&Qto_decomposition_at_superscript,
             "=>decomposition@superscript");
   defsymbol (&Qto_decomposition_at_circled, "=>decomposition@circled");
@@ -4759,6 +4967,7 @@ syms_of_chartab (void)
 #endif
   DEFSUBR (Fload_char_attribute_table);
 #endif
 #endif
   DEFSUBR (Fload_char_attribute_table);
 #endif
+  DEFSUBR (Fchar_feature_base_name_eq);
   DEFSUBR (Fchar_feature);
   DEFSUBR (Fchar_attribute_alist);
   DEFSUBR (Fget_char_attribute);
   DEFSUBR (Fchar_feature);
   DEFSUBR (Fchar_attribute_alist);
   DEFSUBR (Fget_char_attribute);
@@ -4770,6 +4979,10 @@ syms_of_chartab (void)
   DEFSUBR (Fchar_variants);
 
   DEFSUBR (Fget_composite_char);
   DEFSUBR (Fchar_variants);
 
   DEFSUBR (Fget_composite_char);
+#ifdef HAVE_LIBCHISE
+  DEFSUBR (Fchar_feature_property);
+  DEFSUBR (Fput_char_feature_property);
+#endif /* HAVE_LIBCHISE */
 #endif
 
   INIT_LRECORD_IMPLEMENTATION (char_table);
 #endif
 
   INIT_LRECORD_IMPLEMENTATION (char_table);