*** empty log message ***
[m17n/m17n-lib.git] / src / plist.c
index 8926952..6c74c56 100644 (file)
@@ -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
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
@@ -129,7 +129,8 @@ free_plist (void *object)
   do {
     MPlist *next = plist->next;
 
-    if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key)
+    if (MPLIST_KEY (plist) != Mnil
+       && MPLIST_KEY (plist)->managing_key)
       M17N_OBJECT_UNREF (MPLIST_VAL (plist));
     M17N_OBJECT_UNREGISTER (plist_table, plist);
     free (plist);
@@ -613,11 +614,17 @@ write_element (MText *mt, MPlist *plist, int indent)
       sprintf (buf, "%d", num);
       PUTS (mt, buf);
     }
-  else if (MPLIST_PLIST_P (plist))
+  else if (MPLIST_PLIST_P (plist)
+          || MPLIST_NESTED_P (plist))
     {
       MPlist *pl;
       int newline = 0;
 
+      if (MPLIST_NESTED_P (plist))
+       {
+         write_symbol (mt, MPLIST_KEY (plist));
+         PUTC (mt, ':');
+       }
       plist = MPLIST_PLIST (plist);
       PUTC (mt, '(');
       if (indent >= 0)
@@ -714,17 +721,12 @@ write_element (MText *mt, MPlist *plist, int indent)
     }
   else 
     {
+      char buf[128];
+
       write_symbol (mt, MPLIST_KEY (plist));
       PUTC (mt, ':');
-      if (MPLIST_NESTED_P (plist))
-       write_element (mt, plist, indent + 1);
-      else
-       {
-         char buf[128];
-
-         sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
-         PUTS (mt, buf);
-       }
+      sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
+      PUTS (mt, buf);
     }
 }
 
@@ -791,6 +793,8 @@ mplist__from_plist (MPlist *plist)
       type = MPLIST_KEY (plist);
       if (type->managing_key && MPLIST_VAL (plist))
        M17N_OBJECT_REF (MPLIST_VAL (plist));
+      if (type == Mplist)
+       MPLIST_SET_NESTED_P (p);
       MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
       plist = MPLIST_NEXT (plist);
     }
@@ -819,6 +823,7 @@ mplist__from_alist (MPlist *plist)
       elt = MPLIST_PLIST (plist);
       if (! MPLIST_SYMBOL_P (elt))
        MERROR (MERROR_PLIST, NULL);
+      MPLIST_SET_NESTED_P (p);
       MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
       M17N_OBJECT_REF (MPLIST_NEXT (elt));
     }
@@ -924,8 +929,10 @@ mplist__conc (MPlist *plist, MPlist *tail)
   MPLIST_DO (pl, plist);
   MPLIST_KEY (pl) = MPLIST_KEY (tail);
   MPLIST_VAL (pl) = MPLIST_VAL (tail);
-  if (MPLIST_KEY (pl)->managing_key)
+  if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
     M17N_OBJECT_REF (MPLIST_VAL (pl));
+  if (MPLIST_NESTED_P (tail))
+    MPLIST_SET_NESTED_P (pl);
   tail = MPLIST_NEXT (tail);
   MPLIST_NEXT (pl) = tail;
   M17N_OBJECT_REF (tail);
@@ -1103,7 +1110,11 @@ mplist_copy (MPlist *plist)
   MPlist *copy = mplist (), *pl = copy;
 
   MPLIST_DO (plist, plist)
-    pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
+    {
+      if (MPLIST_NESTED_P (plist))
+       MPLIST_SET_NESTED_P (pl);
+      pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
+    }
   return copy;
 }
 
@@ -1166,10 +1177,10 @@ mplist_put (MPlist *plist, MSymbol key, void *val)
 /***en
     @brief Get the value of a property in a property list.
 
-    The mplist_get () function searches property list $PLIST
-    from the beginning for a property whose key is $KEY.  If such a
-    property is found, a pointer to its value is returned as the type
-    of <tt>(void *)</tt>.  If not found, @c NULL is returned.
+    The mplist_get () function searches property list $PLIST from the
+    beginning for a property whose key is $KEY.  If such a property is
+    found, its value is returned as the type of <tt>(void *)</tt>.  If
+    not found, @c NULL is returned.
 
     When @c NULL is returned, there are two possibilities: one is the
     case where no property is found (see above); the other is the case
@@ -1179,8 +1190,8 @@ mplist_put (MPlist *plist, MSymbol key, void *val)
 /***ja
     @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
 
-    ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼¤¬
-    $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤؤΥݥ¤¥ó¥¿¤ò
+    ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼
+    ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
     <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
 
     @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ­¤¬¤¢¤ë: 
@@ -1202,6 +1213,67 @@ mplist_get (MPlist *plist, MSymbol key)
 /*=*/
 
 /***en
+    @brief Set the value (function pointer) of a property in a property list.
+
+    The mplist_put_func () function is similar to mplist_put () but for
+    setting function pointer $FUNC in property list $PLIST for key
+    $KEY.  $KEY must not be a managing key.  */
+
+/***ja
+    @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
+
+    ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () Æ±ÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
+    Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
+    $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥­¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£  */
+
+
+/***
+    @seealso
+    mplist_put (), M17N_FUNC ()  */
+
+MPlist *
+mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
+{
+  if (key == Mnil || key->managing_key)
+    MERROR (MERROR_PLIST, NULL);
+  MPLIST_FIND (plist, key);
+  MPLIST_KEY (plist) = key;
+  MPLIST_FUNC (plist) = func;
+  MPLIST_SET_VAL_FUNC_P (plist);
+  if (! plist->next)
+    MPLIST_NEW ((plist)->next);
+  return plist;
+}
+
+/*=*/
+
+/***en
+    @brief Get the value (function pointer) of a property in a property list.
+
+    The mplist_get_func () function is similar to mplist_get () but for
+    getting a function pointer from property list $PLIST by key $KEY.  */
+
+/***ja
+    @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
+
+    ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
+    ¥¹¥È $PLIST Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
+    ¤òÆÀ¤ë¡£ */
+
+
+/***
+    @seealso
+    mplist_get () */
+M17NFunc
+mplist_get_func (MPlist *plist, MSymbol key)
+{
+  MPLIST_FIND (plist, key);
+  return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
+}
+
+/*=*/
+
+/***en
     @brief Add a property at the end of a property list.
 
     The mplist_add () function appends at the end of property list
@@ -1279,6 +1351,8 @@ mplist_push (MPlist *plist, MSymbol key, void *val)
   MPLIST_NEW (pl);
   MPLIST_KEY (pl) = MPLIST_KEY (plist);
   MPLIST_VAL (pl) = MPLIST_VAL (plist);
+  if (MPLIST_NESTED_P (plist))
+    MPLIST_SET_NESTED_P (pl);
   MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
   plist->next = pl;
   if (val && key->managing_key)
@@ -1295,7 +1369,7 @@ mplist_push (MPlist *plist, MSymbol key, void *val)
 
     The mplist_pop () function removes a property at the beginning of
     property list $PLIST.  As a result, the second key and value of
-    the original $PLIST become the first of those of the new $PLIST.
+    the $PLIST become the first ones.
 
     @return
     If the operation was successful, this function return the value of
@@ -1303,9 +1377,8 @@ mplist_push (MPlist *plist, MSymbol key, void *val)
 /***ja
     @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
 
-    ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST 
-    ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î $PLIST ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬¡¢¿·¤·¤¤ 
-    $PLIST ¤ÎÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣
+    ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
+    ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬ÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣
 
     @return 
     ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð