*** empty log message ***
[m17n/m17n-lib.git] / src / textprop.c
index 42a026a..4a39e9b 100644 (file)
@@ -1,5 +1,5 @@
 /* textprop.c -- text property module.
 /* textprop.c -- text property module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
    02111-1307, USA.  */
 
 /***en
@@ -32,8 +32,8 @@
     application programs can be simple.
 
     A text property consists of a @e key and @e values, where key is a
     application programs can be simple.
 
     A text property consists of a @e key and @e values, where key is a
-    symbol and values are anything that can be cast to <tt>(void
-    *)</tt>.  Unlike other types of properties, a text property can
+    symbol and values are anything that can be cast to <tt>(void *)
+    </tt>.  Unlike other types of properties, a text property can
     have multiple values.  "The text property whose key is K" may be
     shortened to "K property".  */
 
     have multiple values.  "The text property whose key is K" may be
     shortened to "K property".  */
 
@@ -512,7 +512,7 @@ adjust_intervals (MInterval *head, MInterval *tail, int diff)
 
   if (diff < 0)
     {
 
   if (diff < 0)
     {
-      /* Adjust end poistions of properties starting before HEAD.  */
+      /* Adjust end positions of properties starting before HEAD.  */
       for (i = 0; i < head->nprops; i++)
        {
          prop = head->stack[i];
       for (i = 0; i < head->nprops; i++)
        {
          prop = head->stack[i];
@@ -1021,20 +1021,19 @@ pop_all_properties (MTextPlist *plist, int from, int to)
 }
 
 
 }
 
 
-/* Delete volatile text properties between FROM and TO.  If KEY is
-   Mnil, we are going to delete text, thus both strongly and weakly
-   volatile properties must be deleted.  Otherwise we are going to
-   modify a text property KEY, thus only strongly volatile properties
-   whose key is not KEY must be deleted.  */
+/* Delete volatile text properties between FROM and TO.  If DELETING
+   is nonzero, we are going to delete text, thus both strongly and
+   weakly volatile properties must be deleted.  Otherwise we are going
+   to modify a text property KEY, thus only strongly volatile
+   properties whose key is not KEY must be deleted.  */
 
 static void
 
 static void
-prepare_to_modify (MText *mt, int from, int to, MSymbol key)
+prepare_to_modify (MText *mt, int from, int to, MSymbol key, int deleting)
 {
   MTextPlist *plist = mt->plist, *prev = NULL;
   int mask_bits = MTEXTPROP_VOLATILE_STRONG;
 {
   MTextPlist *plist = mt->plist, *prev = NULL;
   int mask_bits = MTEXTPROP_VOLATILE_STRONG;
-  int deleting = (key == Mnil) && (from < to);
 
 
-  if (key == Mnil)
+  if (deleting)
     mask_bits |= MTEXTPROP_VOLATILE_WEAK;
   while (plist)
     {
     mask_bits |= MTEXTPROP_VOLATILE_WEAK;
   while (plist)
     {
@@ -1128,16 +1127,16 @@ dump_interval (MInterval *interval, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
-  fprintf (stderr, "(interval %d-%d (%d)", interval->start, interval->end,
-          interval->nprops);
+  fprintf (mdebug__output, "(interval %d-%d (%d)",
+          interval->start, interval->end, interval->nprops);
   for (i = 0; i < interval->nprops; i++)
   for (i = 0; i < interval->nprops; i++)
-    fprintf (stderr, "\n%s (%d %d/%d %d-%d 0x%x)",
+    fprintf (mdebug__output, "\n%s (%d %d/%d %d-%d 0x%x)",
             prefix, i,
             interval->stack[i]->control.ref_count,
             interval->stack[i]->attach_count,
             interval->stack[i]->start, interval->stack[i]->end,
             (unsigned) interval->stack[i]->val);
             prefix, i,
             interval->stack[i]->control.ref_count,
             interval->stack[i]->attach_count,
             interval->stack[i]->start, interval->stack[i]->end,
             (unsigned) interval->stack[i]->val);
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, ")");
 }
 
 void
 }
 
 void
@@ -1148,31 +1147,33 @@ dump_textplist (MTextPlist *plist, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
-  fprintf (stderr, "(properties");
+  fprintf (mdebug__output, "(properties");
   if (! plist)
   if (! plist)
-    fprintf (stderr, ")\n");
+    fprintf (mdebug__output, ")\n");
   else
     {
   else
     {
-      fprintf (stderr, "\n");
+      fprintf (mdebug__output, "\n");
       while (plist)
        {
          MInterval *interval = plist->head;
 
       while (plist)
        {
          MInterval *interval = plist->head;
 
-         fprintf (stderr, "%s (%s", prefix, msymbol_name (plist->key));
+         fprintf (mdebug__output, "%s (%s", prefix, msymbol_name (plist->key));
          while (interval)
            {
          while (interval)
            {
-             fprintf (stderr, " (%d %d", interval->start, interval->end);
+             fprintf (mdebug__output, " (%d %d",
+                      interval->start, interval->end);
              if (interval->nprops > 0)
                {
                  int i;
 
                  for (i = 0; i < interval->nprops; i++)
              if (interval->nprops > 0)
                {
                  int i;
 
                  for (i = 0; i < interval->nprops; i++)
-                   fprintf (stderr, " 0x%x", (int) interval->stack[i]->val);
+                   fprintf (mdebug__output, " 0x%x",
+                            (int) interval->stack[i]->val);
                }
                }
-             fprintf (stderr, ")");
+             fprintf (mdebug__output, ")");
              interval = interval->next;
            }
              interval = interval->next;
            }
-         fprintf (stderr, ")\n");
+         fprintf (mdebug__output, ")\n");
          xassert (check_plist (plist, 0) == 0);
          plist = plist->next;
        }
          xassert (check_plist (plist, 0) == 0);
          plist = plist->next;
        }
@@ -1185,7 +1186,7 @@ dump_textplist (MTextPlist *plist, int indent)
 int
 mtext__prop_init ()
 {
 int
 mtext__prop_init ()
 {
-  text_property_table.count = 0;
+  M17N_OBJECT_ADD_ARRAY (text_property_table, "Text property");
   Mtext_prop_serializer = msymbol ("text-prop-serializer");
   Mtext_prop_deserializer = msymbol ("text-prop-deserializer");
   return 0;
   Mtext_prop_serializer = msymbol ("text-prop-serializer");
   Mtext_prop_deserializer = msymbol ("text-prop-deserializer");
   return 0;
@@ -1203,7 +1204,6 @@ mtext__prop_fini ()
       pool = next;
     }
   interval_pool_root.next = NULL;  
       pool = next;
     }
   interval_pool_root.next = NULL;  
-  mdebug__report_object ("Text property", &text_property_table);
 }
 
 
 }
 
 
@@ -1260,7 +1260,7 @@ mtext__adjust_plist_for_delete (MText *mt, int pos, int len)
     }      
 
   to = pos + len;
     }      
 
   to = pos + len;
-  prepare_to_modify (mt, pos, to, Mnil);
+  prepare_to_modify (mt, pos, to, Mnil, 1);
   for (plist = mt->plist; plist; plist = plist->next)
     {
       MInterval *interval = pop_all_properties (plist, pos, to);
   for (plist = mt->plist; plist; plist = plist->next)
     {
       MInterval *interval = pop_all_properties (plist, pos, to);
@@ -1300,7 +1300,7 @@ mtext__adjust_plist_for_insert (MText *mt, int pos, int nchars,
       return;
     }
   if (pos > 0 && pos < mtext_nchars (mt))
       return;
     }
   if (pos > 0 && pos < mtext_nchars (mt))
-    prepare_to_modify (mt, pos, pos, Mnil);
+    prepare_to_modify (mt, pos, pos, Mnil, 0);
 
   for (pl_last = NULL, pl = mt->plist; pl; pl_last = pl, pl = pl->next)
     {
 
   for (pl_last = NULL, pl = mt->plist; pl; pl_last = pl, pl = pl->next)
     {
@@ -1429,6 +1429,56 @@ mtext__adjust_plist_for_insert (MText *mt, int pos, int nchars,
     }
 }
 
     }
 }
 
+/* len1 > 0 && len2 > 0 */
+
+void
+mtext__adjust_plist_for_change (MText *mt, int pos, int len1, int len2)
+{
+  int pos2 = pos + len1;
+
+  prepare_to_modify (mt, pos, pos2, Mnil, 0);
+
+  if (len1 < len2)
+    {
+      int diff = len2 - len1;
+      MTextPlist *plist;
+
+      for (plist = mt->plist; plist; plist = plist->next)
+       {
+         MInterval *head = find_interval (plist, pos2);
+         MInterval *tail = plist->tail;
+         MTextProperty *prop;
+         int i;
+
+         if (head)
+           {
+             if (head->start == pos2)
+               head = head->prev;
+             while (tail != head)
+               {
+                 for (i = 0; i < tail->nprops; i++)
+                   {
+                     prop = tail->stack[i];
+                     if (prop->start == tail->start)
+                       prop->start += diff, prop->end += diff;
+                   }
+                 tail->start += diff;
+                 tail->end += diff;
+                 tail = tail->prev;
+               }
+           }
+         for (i = 0; i < tail->nprops; i++)
+           tail->stack[i]->end += diff;
+         tail->end += diff;
+       }
+    }
+  else if (len1 > len2)
+    {
+      mtext__adjust_plist_for_delete (mt, pos + len2, len1 - len2);
+    }
+}
+
+
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
@@ -1519,7 +1569,7 @@ mtext_get_prop (MText *mt, int pos, MSymbol key)
 /*=*/
 
 /***en
 /*=*/
 
 /***en
-    @brief Get multiple values of a text property
+    @brief Get multiple values of a text property.
 
     The mtext_get_prop_values () function searches the character at
     $POS in M-text $MT for the property whose key is $KEY.  If such
 
     The mtext_get_prop_values () function searches the character at
     $POS in M-text $MT for the property whose key is $KEY.  If such
@@ -1597,7 +1647,7 @@ mtext_get_prop_values (MText *mt, int pos, MSymbol key,
 /*=*/
 
 /***en
 /*=*/
 
 /***en
-    @brief Get list of text property keys at a position of an M-text.
+    @brief Get a list of text property keys at a position of an M-text.
 
     The mtext_get_prop_keys () function creates an array whose
     elements are the keys of text properties found at position $POS in
 
     The mtext_get_prop_keys () function creates an array whose
     elements are the keys of text properties found at position $POS in
@@ -1733,7 +1783,7 @@ mtext_put_prop (MText *mt, int from, int to, MSymbol key, void *val)
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
-  prepare_to_modify (mt, from, to, key);
+  prepare_to_modify (mt, from, to, key, 0);
   plist = get_plist_create (mt, key, 1);
   interval = pop_all_properties (plist, from, to);
   prop = new_text_property (mt, from, to, key, val, 0);
   plist = get_plist_create (mt, key, 1);
   interval = pop_all_properties (plist, from, to);
   prop = new_text_property (mt, from, to, key, val, 0);
@@ -1794,7 +1844,7 @@ mtext_put_prop_values (MText *mt, int from, int to,
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
-  prepare_to_modify (mt, from, to, key);
+  prepare_to_modify (mt, from, to, key, 0);
   plist = get_plist_create (mt, key, 1);
   interval = pop_all_properties (plist, from, to);
   if (num > 0)
   plist = get_plist_create (mt, key, 1);
   interval = pop_all_properties (plist, from, to);
   if (num > 0)
@@ -1823,7 +1873,8 @@ mtext_put_prop_values (MText *mt, int from, int to,
 
     The mtext_push_prop () function pushes a text property whose key
     is $KEY and value is $VAL to the characters between $FROM
 
     The mtext_push_prop () function pushes a text property whose key
     is $KEY and value is $VAL to the characters between $FROM
-    (inclusive) and $TO (exclusive) in $MT.  With this functio,
+    (inclusive) and $TO (exclusive) in M-text $MT.  With this
+    function,
 
 @verbatim
                     FROM                    TO
 
 @verbatim
                     FROM                    TO
@@ -1891,7 +1942,7 @@ mtext_push_prop (MText *mt, int from, int to,
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
 
   M_CHECK_RANGE (mt, from, to, -1, 0);
 
-  prepare_to_modify (mt, from, to, key);
+  prepare_to_modify (mt, from, to, key, 0);
   plist = get_plist_create (mt, key, 1);
 
   /* Find an interval that covers the position FROM.  */
   plist = get_plist_create (mt, key, 1);
 
   /* Find an interval that covers the position FROM.  */
@@ -1970,7 +2021,7 @@ mtext_push_prop (MText *mt, int from, int to,
 /*=*/
 
 /***en
 /*=*/
 
 /***en
-    @brief Pop a text property
+    @brief Pop a text property.
 
     The mtext_pop_prop () function removes the topmost text property
     whose key is $KEY from the characters between $FROM (inclusive)
 
     The mtext_pop_prop () function removes the topmost text property
     whose key is $KEY from the characters between $FROM (inclusive)
@@ -2056,7 +2107,7 @@ mtext_pop_prop (MText *mt, int from, int to, MSymbol key)
     /* No property to pop.  */
     return 0;
 
     /* No property to pop.  */
     return 0;
 
-  prepare_to_modify (mt, from, to, key);
+  prepare_to_modify (mt, from, to, key, 0);
 
   /* If the found interval starts before FROM and has value(s), divide
      it at FROM.  */
 
   /* If the found interval starts before FROM and has value(s), divide
      it at FROM.  */
@@ -2140,7 +2191,7 @@ mtext_pop_prop (MText *mt, int from, int to, MSymbol key)
 
     ´Ø¿ô mtext_prop_range () ¤Ï¡¢»ØÄꤷ¤¿¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬Æ±¤¸
     ¤Ç¤¢¤ëϢ³¤·¤¿Ê¸»ú¤ÎÈϰϤòÄ´¤Ù¤ë¡£¤Þ¤º M-text $MT ¤Î $POS ¤Î°ÌÃÖ¤Ë
 
     ´Ø¿ô mtext_prop_range () ¤Ï¡¢»ØÄꤷ¤¿¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬Æ±¤¸
     ¤Ç¤¢¤ëϢ³¤·¤¿Ê¸»ú¤ÎÈϰϤòÄ´¤Ù¤ë¡£¤Þ¤º M-text $MT ¤Î $POS ¤Î°ÌÃÖ¤Ë
-    ¤¢¤ëʸ»ú¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼ $KEY ¤Ç»ØÄꤵ¤ì¤¿¤â¤Î¤ÎÃͤò¸«¤Ä¤±
+    ¤¢¤ëʸ»ú¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼ $KEY ¤Ç»ØÄꤵ¤ì¤¿¤â¤ÎÃͤò¸«¤Ä¤±
     ¤ë¡£¤½¤·¤ÆÁ°¸å¤Îʸ»ú¤â $KEY ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬Æ±¤¸¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò
     Ä´¤Ù¤ë¡£¸«¤Ä¤±¤¿ÈϰϤκǽé¤ÈºÇ¸å¤ò¡¢¤½¤ì¤¾¤ì $FROM ¤È $TO ¤Ë¥Ý¥¤¥ó
     ¥È¤µ¤ì¤ëÊÑ¿ô¤ËÊݸ¤¹¤ë¡£$FROM ¤ËÊݸ¤µ¤ì¤ëʸ»ú¤Î°ÌÃ֤ϸ«¤Ä¤±¤¿ÈÏ°Ï
     ¤ë¡£¤½¤·¤ÆÁ°¸å¤Îʸ»ú¤â $KEY ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬Æ±¤¸¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò
     Ä´¤Ù¤ë¡£¸«¤Ä¤±¤¿ÈϰϤκǽé¤ÈºÇ¸å¤ò¡¢¤½¤ì¤¾¤ì $FROM ¤È $TO ¤Ë¥Ý¥¤¥ó
     ¥È¤µ¤ì¤ëÊÑ¿ô¤ËÊݸ¤¹¤ë¡£$FROM ¤ËÊݸ¤µ¤ì¤ëʸ»ú¤Î°ÌÃ֤ϸ«¤Ä¤±¤¿ÈÏ°Ï
@@ -2235,6 +2286,7 @@ mtext_prop_range (MText *mt, MSymbol key, int pos,
 
     $CONTROL_BITS must be 0 or logical OR of @c enum @c
     MTextPropertyControl.  */
 
     $CONTROL_BITS must be 0 or logical OR of @c enum @c
     MTextPropertyControl.  */
+
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÀ¸À®¤¹¤ë.
 
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÀ¸À®¤¹¤ë.
 
@@ -2257,6 +2309,7 @@ mtext_property (MSymbol key, void *val, int control_bits)
     The mtext_property_mtext () function returns the M-text to which
     text property $PROP is attached.  If $PROP is currently detached,
     NULL is returned.  */
     The mtext_property_mtext () function returns the M-text to which
     text property $PROP is attached.  If $PROP is currently detached,
     NULL is returned.  */
+
 /***ja
     @brief ¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä M-text ¤òÊÖ¤¹.
 
 /***ja
     @brief ¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä M-text ¤òÊÖ¤¹.
 
@@ -2275,6 +2328,7 @@ mtext_property_mtext (MTextProperty *prop)
 
     The mtext_property_key () function returns the key (symbol) of
     text property $PROP.  */
 
     The mtext_property_key () function returns the key (symbol) of
     text property $PROP.  */
+
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÊÖ¤¹.
 
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÊÖ¤¹.
 
@@ -2292,6 +2346,7 @@ mtext_property_key (MTextProperty *prop)
 
     The mtext_property_value () function returns the value of text
     property $PROP.  */
 
     The mtext_property_value () function returns the value of text
     property $PROP.  */
+
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
 
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
 
@@ -2311,6 +2366,7 @@ mtext_property_value (MTextProperty *prop)
     text property $PROP.  The start position is a character position
     of an M-text where $PROP begins.  If $PROP is detached, it returns
     -1.  */
     text property $PROP.  The start position is a character position
     of an M-text where $PROP begins.  If $PROP is detached, it returns
     -1.  */
+
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î³«»Ï°ÌÃÖ¤òÊÖ¤¹.
 
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î³«»Ï°ÌÃÖ¤òÊÖ¤¹.
 
@@ -2331,6 +2387,7 @@ mtext_property_start (MTextProperty *prop)
     text property $PROP.  The end position is a character position of
     an M-text where $PROP ends.  If $PROP is detached, it returns
     -1.  */
     text property $PROP.  The end position is a character position of
     an M-text where $PROP ends.  If $PROP is detached, it returns
     -1.  */
+
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î½ªÎ»°ÌÃÖ¤òÊÖ¤¹.
 
 /***ja
     @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î½ªÎ»°ÌÃÖ¤òÊÖ¤¹.
 
@@ -2358,6 +2415,7 @@ mtext_property_end (MTextProperty *prop)
 
     If an error is detected, mtext_get_property () returns @c NULL and
     assigns an error code to the external variable #merror_code.  */
 
     If an error is detected, mtext_get_property () returns @c NULL and
     assigns an error code to the external variable #merror_code.  */
+
 /***ja
     @brief °ìÈÖ¾å¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÆÀ¤ë.
 
 /***ja
     @brief °ìÈÖ¾å¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÆÀ¤ë.
 
@@ -2405,6 +2463,7 @@ mtext_get_property (MText *mt, int pos, MSymbol key)
     $POS does not have a property whose key is $KEY, the return value
     is 0. If an error is detected, mtext_get_properties () returns -1
     and assigns an error code to the external variable #merror_code.  */
     $POS does not have a property whose key is $KEY, the return value
     is 0. If an error is detected, mtext_get_properties () returns -1
     and assigns an error code to the external variable #merror_code.  */
+
 /***ja
     @brief Ê£¿ô¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÆÀ¤ë.
 
 /***ja
     @brief Ê£¿ô¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÆÀ¤ë.
 
@@ -2468,6 +2527,7 @@ mtext_get_properties (MText *mt, int pos, MSymbol key,
     If the operation was successful, mtext_attach_property () returns
     0.  Otherwise it returns -1 and assigns an error code to the
     external variable #merror_code.  */
     If the operation was successful, mtext_attach_property () returns
     0.  Otherwise it returns -1 and assigns an error code to the
     external variable #merror_code.  */
+
 /***ja
     @brief  M-text¤Ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÉղ乤ë.
 
 /***ja
     @brief  M-text¤Ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÉղ乤ë.
 
@@ -2480,6 +2540,7 @@ mtext_get_properties (MText *mt, int pos, MSymbol key,
     ¤ì¤Ð -1 ¤òÊÖ¤·¤Æ³°ÉôÊÑ¿ô#merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£      */
 
 
     ¤ì¤Ð -1 ¤òÊÖ¤·¤Æ³°ÉôÊÑ¿ô#merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£      */
 
 
+int
 mtext_attach_property (MText *mt, int from, int to, MTextProperty *prop)
 {     
   MTextPlist *plist;
 mtext_attach_property (MText *mt, int from, int to, MTextProperty *prop)
 {     
   MTextPlist *plist;
@@ -2490,7 +2551,7 @@ mtext_attach_property (MText *mt, int from, int to, MTextProperty *prop)
   M17N_OBJECT_REF (prop);
   if (prop->mt)
     mtext_detach_property (prop);
   M17N_OBJECT_REF (prop);
   if (prop->mt)
     mtext_detach_property (prop);
-  prepare_to_modify (mt, from, to, prop->key);
+  prepare_to_modify (mt, from, to, prop->key, 0);
   plist = get_plist_create (mt, prop->key, 1);
   xassert (check_plist (plist, 0) == 0);
   interval = pop_all_properties (plist, from, to);
   plist = get_plist_create (mt, prop->key, 1);
   xassert (check_plist (plist, 0) == 0);
   interval = pop_all_properties (plist, from, to);
@@ -2517,8 +2578,9 @@ mtext_attach_property (MText *mt, int from, int to, MTextProperty *prop)
 
     @return
     This function always returns 0.  */
 
     @return
     This function always returns 0.  */
+
 /***ja
 /***ja
-    @brief  M-text ¤«¤é¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òʬΥ¤¹¤ë¡£
+    @brief  M-text ¤«¤é¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òʬΥ¤¹¤ë.
 
     ´Ø¿ô mtext_detach_property () ¤Ï¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ $PROP ¤òʬΥ¤¹¤ë¡£
 
 
     ´Ø¿ô mtext_detach_property () ¤Ï¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ $PROP ¤òʬΥ¤¹¤ë¡£
 
@@ -2533,7 +2595,7 @@ mtext_detach_property (MTextProperty *prop)
 
   if (! prop->mt)
     return 0;
 
   if (! prop->mt)
     return 0;
-  prepare_to_modify (prop->mt, start, end, prop->key);
+  prepare_to_modify (prop->mt, start, end, prop->key, 0);
   plist = get_plist_create (prop->mt, prop->key, 0);
   xassert (plist);
   detach_property (plist, prop, NULL);
   plist = get_plist_create (prop->mt, prop->key, 0);
   xassert (plist);
   detach_property (plist, prop, NULL);
@@ -2543,18 +2605,21 @@ mtext_detach_property (MTextProperty *prop)
 /***en
     @brief Push a text property onto an M-text.
 
 /***en
     @brief Push a text property onto an M-text.
 
-    The mtext_push_property () function attaches text property $PROP on
-    M-text $MT by the "push" manner.
+    The mtext_push_property () function pushes text property $PROP to
+    the characters between $FROM (inclusive) and $TO (exclusive) in
+    M-text $MT.
 
     @return
     If the operation was successful, mtext_push_property () returns
     0.  Otherwise it returns -1 and assigns an error code to the
     external variable #merror_code.  */
 
     @return
     If the operation was successful, mtext_push_property () returns
     0.  Otherwise it returns -1 and assigns an error code to the
     external variable #merror_code.  */
+
 /***ja
     @brief M-text ¤Ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥×¥Ã¥·¥å¤¹¤ë.
 
 /***ja
     @brief M-text ¤Ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥×¥Ã¥·¥å¤¹¤ë.
 
-    ´Ø¿ô mtext_push_property () ¤Ï¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ $PROP ¤òM-text
-    $MT ¤Ë¥×¥Ã¥·¥å¤·¤ÆÉղ乤롣
+    ´Ø¿ô mtext_push_property () ¤Ï¡¢¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ $PROP ¤ò¡¢
+    M-text $MT Ãæ¤Î $FROM ¡Ê´Þ¤Þ¤ì¤ë¡Ë¤«¤é $TO ¡Ê´Þ¤Þ¤ì¤Ê¤¤¡Ë¤ÎÈϰϤÎ
+    Ê¸»ú¤Ë¥×¥Ã¥·¥å¤¹¤ë¡£
 
     @return
     ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢mtext_push_property () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±
 
     @return
     ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢mtext_push_property () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±
@@ -2573,7 +2638,7 @@ mtext_push_property (MText *mt, int from, int to, MTextProperty *prop)
   M17N_OBJECT_REF (prop);
   if (prop->mt)
     mtext_detach_property (prop);
   M17N_OBJECT_REF (prop);
   if (prop->mt)
     mtext_detach_property (prop);
-  prepare_to_modify (mt, from, to, prop->key);
+  prepare_to_modify (mt, from, to, prop->key, 0);
   plist = get_plist_create (mt, prop->key, 1);
   prop->mt = mt;
   prop->start = from;
   plist = get_plist_create (mt, prop->key, 1);
   prop->mt = mt;
   prop->start = from;
@@ -2657,17 +2722,20 @@ mtext_push_property (MText *mt, int from, int to, MTextProperty *prop)
     property whose key is #Mtext_prop_serializer and value is a
     pointer to an appropriate serializer function.
 
     property whose key is #Mtext_prop_serializer and value is a
     pointer to an appropriate serializer function.
 
-    @seealso Mtext_prop_serializer (), MTextPropSerializeFunc
+    @seealso
+    mtext_serialize (), #MTextPropSerializeFunc
   */
   */
+
 /***ja
     @brief ¥·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤ò»ØÄꤹ¤ë¥·¥ó¥Ü¥ë.
 
 /***ja
     @brief ¥·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤ò»ØÄꤹ¤ë¥·¥ó¥Ü¥ë.
 
-    ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¤¿¤á¤Ë¡¢¥æ¡¼¥¶¤Ï¥Æ¥­¥¹¥È¥×¥í¥Ñ
+    ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¤½¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ
     ¥Æ¥£ÍѤΥ·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤òÍ¿¤¨¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¶ñÂÎŪ¤Ë¤Ï¡¢
     #Mtext_prop_serializer ¤ò¥­¡¼¤È¤·¡¢Å¬Àڤʥ·¥ê¥¢¥é¥¤¥º´Ø¿ô¤Ø¤Î¥Ý¥¤
     ¥Æ¥£ÍѤΥ·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤òÍ¿¤¨¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¶ñÂÎŪ¤Ë¤Ï¡¢
     #Mtext_prop_serializer ¤ò¥­¡¼¤È¤·¡¢Å¬Àڤʥ·¥ê¥¢¥é¥¤¥º´Ø¿ô¤Ø¤Î¥Ý¥¤
-    ¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¤ò»ØÄꤹ¤ë¡£
+    ¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¡£
 
 
-    @seealso Mtext_prop_serializer (), MTextPropSerializeFunc
+    @seealso
+    mtext_serialize (), #MTextPropSerializeFunc
   */
 MSymbol Mtext_prop_serializer;
 
   */
 MSymbol Mtext_prop_serializer;
 
@@ -2679,17 +2747,20 @@ MSymbol Mtext_prop_serializer;
     property whose key is #Mtext_prop_deserializer and value is a
     pointer to an appropriate deserializer function.
 
     property whose key is #Mtext_prop_deserializer and value is a
     pointer to an appropriate deserializer function.
 
-    @seealso Mtext_prop_serializer (), MTextPropSerializeFunc
+    @seealso
+    mtext_deserialize (), #MTextPropSerializeFunc
   */
   */
+
 /***ja
     @brief ¥Ç¥·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤ò»ØÄꤹ¤ë¥·¥ó¥Ü¥ë.
 
 /***ja
     @brief ¥Ç¥·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤ò»ØÄꤹ¤ë¥·¥ó¥Ü¥ë.
 
-    ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¤¿¤á¤Ë¡¢¥æ¡¼¥¶¤Ï¥Æ¥­¥¹¥È¥×¥í
+    ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¤½¤Î¥Æ¥­¥¹¥È¥×¥í
     ¥Ñ¥Æ¥£ÍѤΥǥ·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤òÍ¿¤¨¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¶ñÂÎŪ¤Ë¤Ï¡¢
     #Mtext_prop_deserializer ¤ò¥­¡¼¤È¤·¡¢Å¬Àڤʥǥ·¥ê¥¢¥é¥¤¥º´Ø¿ô¤Ø¤Î
     ¥Ñ¥Æ¥£ÍѤΥǥ·¥ê¥¢¥é¥¤¥¶´Ø¿ô¤òÍ¿¤¨¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¶ñÂÎŪ¤Ë¤Ï¡¢
     #Mtext_prop_deserializer ¤ò¥­¡¼¤È¤·¡¢Å¬Àڤʥǥ·¥ê¥¢¥é¥¤¥º´Ø¿ô¤Ø¤Î
-    ¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¤ò»ØÄꤹ¤ë¡£
+    ¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¡£
 
 
-    @seealso Mtext_prop_serializer (), MTextPropSerializeFunc
+    @seealso
+    mtext_deserialize (), #MTextPropSerializeFunc
   */
 MSymbol Mtext_prop_deserializer;
 
   */
 MSymbol Mtext_prop_deserializer;
 
@@ -2697,14 +2768,15 @@ MSymbol Mtext_prop_deserializer;
     @brief Serialize text properties in an M-text.
 
     The mtext_serialize () function serializes the text between $FROM
     @brief Serialize text properties in an M-text.
 
     The mtext_serialize () function serializes the text between $FROM
-    and $TO in M-text $MT.  The serialized result is an M-text in the
+    and $TO in M-text $MT.  The serialized result is an M-text in a
     form of XML.  $PROPERTY_LIST limits the text properties to be
     form of XML.  $PROPERTY_LIST limits the text properties to be
-    serialized.  If a symbol 
-    @li appears as the value of an element in $PROPERTY_LIST (the key must be @c Mt ), and 
-    @li has the symbol    property #Mtext_prop_serializer, 
-    
-    a text property having that symbol as its key is turned into the
-    "property" element in the resulting XML representation.
+    serialized. Only those text properties whose key 
+
+    @li appears as the value of an element in $PROPERTY_LIST, and
+    @li has the symbol property #Mtext_prop_serializer
+
+    are serialized as a "property" element in the resulting XML
+    representation.
 
     The DTD of the generated XML is as follows:
 
 
     The DTD of the generated XML is as follows:
 
@@ -2730,19 +2802,21 @@ MSymbol Mtext_prop_deserializer;
     error code to the external variable #merror_code.
 
     @seealso
     error code to the external variable #merror_code.
 
     @seealso
-    mtext_deserialize (), Mtext_prop_serializer  */
+    mtext_deserialize (), #Mtext_prop_serializer  */
+
 /***ja
     @brief M-text Ãæ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
 
     ´Ø¿ô mtext_serialize () ¤Ï M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­
 /***ja
     @brief M-text Ãæ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
 
     ´Ø¿ô mtext_serialize () ¤Ï M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­
-    ¥¹¥È¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¡£¥·¥ê¥¢¥é¥¤¥º¤·¤¿·ë²Ì XML ·Á¼°¤Î M-text ¤Ç
+    ¥¹¥È¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë¡£¥·¥ê¥¢¥é¥¤¥º¤·¤¿·ë²Ì¤Ï XML ·Á¼°¤Î M-text ¤Ç
     ¤¢¤ë¡£ $PROPERTY_LIST ¤Ï¥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¸ÂÄê
     ¤¢¤ë¡£ $PROPERTY_LIST ¤Ï¥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¸ÂÄê
-    ¤¹¤ë¡£¥·¥ó¥Ü¥ë¤¬
-    @li $PROPERTY_LIST (¥­¡¼¤Ï @c Mt) ¤ÎÍ×ÁǤÎÃͤȤ·¤Æ¸½¤ï¤ì¡¢
-    @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ #Mtext_prop_serializer ¤ò»ý¤Ä¤Ê¤é¤Ð¡¢
+    ¤¹¤ë¡£ÂоݤȤʤë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¡¢¤½¤Î¥­¡¼¤¬
+
+    @li $PROPERTY_LIST ¤ÎÍ×ÁǤÎÃͤȤ·¤Æ¸½¤ï¤ì¡¢¤«¤Ä
+    @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ #Mtext_prop_serializer ¤ò»ý¤Ä
     
     
-    ¤³¤Î¥·¥ó¥Ü¥ë¤ò¥­¡¼¤È¤¹¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¡¢À¸À®¤µ¤ì¤ë XML É½¸½
-    Ãæ¤Ç "property" Í×ÁǤËÊÑ´¹¤µ¤ì¤ë¡£
+    ¤â¤Î¤Î¤ß¤Ç¤¢¤ë¡£¤³¤Î¾ò·ï¤òËþ¤¿¤¹¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¡¢À¸À®¤µ¤ì¤ë 
+    XML É½¸½Ãæ¤Ç "property" Í×ÁǤ˥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¡£
 
     À¸À®¤µ¤ì¤ë XML ¤Î DTD ¤Ï°Ê²¼¤ÎÄ̤ê:
 
 
     À¸À®¤µ¤ì¤ë XML ¤Î DTD ¤Ï°Ê²¼¤ÎÄ̤ê:
 
@@ -2768,7 +2842,7 @@ MSymbol Mtext_prop_deserializer;
     ¤òÀßÄꤹ¤ë¡£
 
     @seealso
     ¤òÀßÄꤹ¤ë¡£
 
     @seealso
-    mtext_deserialize (), Mtext_prop_serializer  */
+    mtext_deserialize (), #Mtext_prop_serializer  */
 
 MText *
 mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
 
 MText *
 mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
@@ -2783,6 +2857,11 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
   int n;
 
   M_CHECK_RANGE (mt, from, to, NULL, NULL);
   int n;
 
   M_CHECK_RANGE (mt, from, to, NULL, NULL);
+  if (mt->format != MTEXT_FORMAT_US_ASCII
+      && mt->format != MTEXT_FORMAT_UTF_8)
+    mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
+  if (MTEXT_DATA (mt)[mtext_nbytes (mt)] != 0)
+    MTEXT_DATA (mt)[mtext_nbytes (mt)] = 0;
   doc = xmlParseMemory (XML_TEMPLATE, strlen (XML_TEMPLATE) + 1);
   node = xmlDocGetRootElement (doc);
 
   doc = xmlParseMemory (XML_TEMPLATE, strlen (XML_TEMPLATE) + 1);
   node = xmlDocGetRootElement (doc);
 
@@ -2791,7 +2870,8 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
     {
       MSymbol key = MPLIST_VAL (pl);
 
     {
       MSymbol key = MPLIST_VAL (pl);
 
-      func = (MTextPropSerializeFunc) msymbol_get (key, Mtext_prop_serializer);
+      func = ((MTextPropSerializeFunc)
+             msymbol_get_func (key, Mtext_prop_serializer));
       if (func)
        extract_text_properties (mt, from, to, key, plist);
     }
       if (func)
        extract_text_properties (mt, from, to, key, plist);
     }
@@ -2804,13 +2884,13 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
       MPlist *serialized_plist;
       xmlNodePtr child;
 
       MPlist *serialized_plist;
       xmlNodePtr child;
 
-      func = (MTextPropSerializeFunc) msymbol_get (prop->key,
-                                                  Mtext_prop_serializer);
+      func = ((MTextPropSerializeFunc)
+             msymbol_get_func (prop->key, Mtext_prop_serializer));
       serialized_plist = (func) (prop->val);
       if (! serialized_plist)
        continue;
       mtext_reset (work);
       serialized_plist = (func) (prop->val);
       if (! serialized_plist)
        continue;
       mtext_reset (work);
-      mplist__serialize (work, serialized_plist);
+      mplist__serialize (work, serialized_plist, 0);
       child = xmlNewChild (node, NULL, (xmlChar *) "property", NULL);
       xmlSetProp (child, (xmlChar *) "key",
                  (xmlChar *) MSYMBOL_NAME (prop->key));
       child = xmlNewChild (node, NULL, (xmlChar *) "property", NULL);
       xmlSetProp (child, (xmlChar *) "key",
                  (xmlChar *) MSYMBOL_NAME (prop->key));
@@ -2857,7 +2937,7 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
     @brief Deserialize text properties in an M-text.
 
     The mtext_deserialize () function deserializes M-text $MT.  $MT
     @brief Deserialize text properties in an M-text.
 
     The mtext_deserialize () function deserializes M-text $MT.  $MT
-    must be an XML having the followng DTD.
+    must be an XML having the following DTD.
 
 @verbatim
 <!DOCTYPE mtext [
 
 @verbatim
 <!DOCTYPE mtext [
@@ -2881,7 +2961,8 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
     code to the external variable #merror_code.
 
     @seealso
     code to the external variable #merror_code.
 
     @seealso
-    mtext_serialize (), Mtext_prop_deserializer  */
+    mtext_serialize (), #Mtext_prop_deserializer  */
+
 /***ja
     @brief M-text Ãæ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
 
 /***ja
     @brief M-text Ãæ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
 
@@ -2910,7 +2991,7 @@ mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
     ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @seealso
     ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @seealso
-    mtext_serialize (), Mtext_prop_deserializer  */
+    mtext_serialize (), #Mtext_prop_deserializer  */
 
 MText *
 mtext_deserialize (MText *mt)
 
 MText *
 mtext_deserialize (MText *mt)
@@ -2985,7 +3066,7 @@ mtext_deserialize (MText *mt)
 
        key = msymbol ((char *) key_str);
        func = ((MTextPropDeserializeFunc)
 
        key = msymbol ((char *) key_str);
        func = ((MTextPropDeserializeFunc)
-               msymbol_get (key, Mtext_prop_deserializer));
+               msymbol_get_func (key, Mtext_prop_deserializer));
        if (! func)
          continue;
        plist = mplist__from_string (val_str, strlen ((char *) val_str));
        if (! func)
          continue;
        plist = mplist__from_string (val_str, strlen ((char *) val_str));