Update copyright years
[m17n/m17n-lib.git] / src / symbol.c
index 3e7258c..36a544c 100644 (file)
@@ -1,5 +1,5 @@
 /* symbol.c -- symbol module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
      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
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
@@ -29,8 +29,8 @@
     identifiers.  Symbols are similar to atoms in the X library, but a
     symbol can have zero or more @e symbol @e properties.  A symbol
     property consists of a @e key and a @e value, where key is also a
-    symbol and value is anything that can be cast to <tt>(void
-    *)</tt>.  "The symbol property that belongs to the symbol S and
+    symbol and value is anything that can be cast to <tt>(void *)</tt>.  
+    "The symbol property that belongs to the symbol S and
     whose key is K" may be shortened to "K property of S".
 
     Symbols are used mainly in the following three ways.
     value of a property whose key is a managing key must be a @e
     managed @e object.  See @ref m17nObject for the detail.
 */
-
 /***ja
     @addtogroup m17nSymbol ¥·¥ó¥Ü¥ë
 
-    @brief ¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API
+    @brief ¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
 
-    m17n ¥é¥¤¥Ö¥é¥ê¤Ï°ì°Õ¤Ë·è¤Þ¤ëµ­½Ò»Ò¤È¤·¤Æ @e ¥·¥ó¥Ü¥ë ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§
-    ¥¯¥È¤òÍѤ¤¤ë¡£¥·¥ó¥Ü¥ë¤Ï X ¥é¥¤¥Ö¥é¥ê¤Î¥¢¥È¥à¤È»÷¤Æ¤¤¤ë¤¬¡¢0 ¸Ä°Ê
-    ¾å¤Î @e ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ëÅÀ¤Ç¡¢¥¢¥È¥à¤è¤ê¹âµ¡
-    Ç½¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¤½
-    ¤ì¼«ÂÎ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤϠ<tt>(void *)</tt> ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â
-    ¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£¡Ö¥·¥ó¥Ü¥ë S ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼
-    ¤¬ K ¤Î¤â¤Î¡×¤ò´Êñ¤Ë¡ÖS ¤Î K ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
+    m17n ¥é¥¤¥Ö¥é¥ê¤Ï°ì°Õ¤Ë·è¤Þ¤ë¼±Ê̻ҤȤ·¤Æ @e ¥·¥ó¥Ü¥ë 
+    ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤òÍѤ¤¤ë¡£¥·¥ó¥Ü¥ë¤Ï X ¥é¥¤¥Ö¥é¥ê¤Î¥¢¥È¥à¤È»÷¤Æ¤¤¤ë¤¬¡¢
+    0 ¸Ä°Ê¾å¤Î @e ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ï
+    @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¤½¤ì¼«ÂÎ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤϠ
+    <tt>(void *)</tt> ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£¡Ö¥·¥ó¥Ü¥ë 
+    S ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ K ¤Î¤â¤Î¡×¤ò´Êñ¤Ë¡ÖS ¤Î K 
+    ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
 
     ¥·¥ó¥Ü¥ë¤ÎÍÑÅӤϼç¤Ë°Ê²¼¤Î3Ä̤ê¤Ç¤¢¤ë¡£
 
-    @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ (¤ª¤è¤Ó¾¤Î¥×¥í¥Ñ¥Æ¥£) ¤Î¥­¡¼¤òɽ¤ï¤¹¡£
+    @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ª¤è¤Ó¾¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òɽ¤¹¡£
 
-    @li Ê¸»ú¥»¥Ã¥È¡¢¥³¡¼¥É·Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ê¤É¤Î³Æ¼ï¥ª¥Ö¥¸¥§¥¯¥È¤òɽ
-    ¤ï¤¹¡£
+    @li Ê¸»ú¥»¥Ã¥È¡¢¥³¡¼¥É·Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ê¤É¤Î³Æ¼ï¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¡£
 
     @li m17n ¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Î°ú¿ô¤È¤Ê¤ê¡¢´Ø¿ô¤ÎµóÆ°¤òÀ©¸æ¤¹¤ë¡£
 
-    ¥­¡¼¤¬ @c Mmanaging_key ¤ÇÃͤ¬ @c NULL °Ê³°¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò
-    »ý¤Ä¥·¥ó¥Ü¥ë¤Ï¡¢@e ´ÉÍý¥­¡¼ ¤È¸Æ¤Ð¤ì¤ë¡£¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
-    ¤¬´ÉÍý¥­¡¼¤Î¾ì¹ç¡¢¤½¤ÎÃͤϠ@e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
-    ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤Î¾Ï¤ò»²¾È
-    ¤Î¤³¤È¡£
-
-    ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤ÏÃͤÎÂå¤ê¤Ë @e ¥×¥í¥Ð¥¤¥À´Ø¿ô ¤ò»ý¤¿¤»¤ë¤³¤È
-    ¤â¤Ç¤­¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤Ï¤½¤Î¥­¡¼¤ÎÃͤòÆÀ¤è¤¦¤È¤¹¤ë»þ¤Ë¸Æ¤Ð¤ì¡¢¤½
-    ¤ÎÊÖ¤êÃͤ¬µá¤á¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤʤ롣¤³¤Î»ÅÁȤߤˤè¤Ã¤Æ¥·
-    ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÙ±äɾ²Á¤¬²Äǽ¤Ë¤Ê¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤ÏÃͤòÊÖ¤¹¤È
-    Æ±»þ¤ËÃͤòÀßÄꤹ¤ë¤³¤È¤â¤Ç¤­¡¢¤³¤Î¾ì¹ç¤Ë¤Ï¡¢¥×¥í¥Ð¥¤¥À´Ø¿ô¼«ÂΤÏÃÍ
-    ¤ÎÀßÄê°Ê¹ß¤Ï̵¸ú¤È¤Ê¤ë¡£  */
+    @e ´ÉÍý¥­¡¼ ¤È¸Æ¤Ð¤ì¤ëÆÃÊ̤ʥ·¥ó¥Ü¥ë¤¬¤¢¤ê¡¢´ÉÍý¥­¡¼¤ò¥­¡¼¤È¤·¤Æ»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏ
+    @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ï @ref m17nObject »²¾È¡£
+*/
 
 /*=*/
 
@@ -159,17 +148,26 @@ void
 msymbol__fini ()
 {
   int i;
-  MSymbol sym, next;
-  int freed_symbols = 0;
+  MSymbol sym;
 
   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
     for (sym = symbol_table[i]; sym; sym = sym->next)
       if (! MPLIST_TAIL_P (&sym->plist))
        {
          if (sym->plist.key->managing_key)
-           M17N_OBJECT_UNREF (sym->plist.val);
+           M17N_OBJECT_UNREF (MPLIST_VAL (&sym->plist));
          M17N_OBJECT_UNREF (sym->plist.next);
+         sym->plist.key = Mnil;
        }
+}
+
+void
+msymbol__free_table ()
+{
+  int i;
+  MSymbol sym, next;
+  int freed_symbols = 0;
+
   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
     {
       for (sym = symbol_table[i]; sym; sym = next)
@@ -181,8 +179,8 @@ msymbol__fini ()
        }
       symbol_table[i] = NULL;
     }
-  if (mdebug__flag & MDEBUG_FINI)
-    fprintf (stderr, "%16s %7d %7d %7d\n", "Symbol",
+  if (mdebug__flags[MDEBUG_FINI])
+    fprintf (mdebug__output, "%16s %7d %7d %7d\n", "Symbol",
             num_symbols, freed_symbols, num_symbols - freed_symbols);
   num_symbols = 0;
 }
@@ -198,19 +196,38 @@ msymbol__with_len (const char *name, int len)
   return msymbol (p);
 }
 
+/** Return a plist of symbols that has non-NULL property PROP.  If
+    PROP is Mnil, return a plist of all symbols.  Values of the plist
+    is NULL.  */
+
+MPlist *
+msymbol__list (MSymbol prop)
+{
+  MPlist *plist = mplist ();
+  int i;
+  MSymbol sym;
+
+  for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
+    for (sym = symbol_table[i]; sym; sym = sym->next)
+      if (prop == Mnil || msymbol_get (sym, prop))
+       mplist_push (plist, sym, NULL);
+  return plist;
+}
+
 
 /** Canonicalize the name of SYM, and return a symbol of the
     canonicalized name.  Canonicalization is done by this rule:
        o convert all uppercase characters to lowercase.
        o remove all non alpha-numeric characters.
        o change the leading "ibm" to "cp".
-       o change the leading "cp" to "ibm"
+       o change the leading "windows-" to "cp".
+       o change the leading "cp" to "ibm".
        o remove the leading "iso".
     For instance:
        "ISO-8859-2" -> "88592"
        "euc-JP" -> "eucjp"
        "IBM851" -> "cp851"
-       "CP1250" -> "ibm1250"
+       "windows-1250" -> "cp250"
 
     This function is used to canonicalize charset and coding system
     names.  */
@@ -253,7 +270,15 @@ msymbol__canonicalize (MSymbol sym)
       canon[1] = 'b';
       canon[2] = 'm';
     }
-
+  else if (canon[0] == 'w' && p - canon > 7
+          && memcmp (canon + 1, "indows", 6) == 0
+          && isdigit (canon[7]))
+    {
+      /* Change "windowsXXX" to "cpXXX" */
+      canon += 5;
+      canon[0] = 'c';
+      canon[1] = 'p';
+    }
   return msymbol (canon);
 }
 
@@ -276,12 +301,13 @@ MTextPropDeserializeFunc msymbol__deserializer = deserialize_symbol;
     The symbol #Mnil has the name <tt>"nil"</tt> and, in general,
     represents @e false or @e no.  When coerced to "int", its value is
     zero.  #Mnil can't have any symbol property.  */
-
 /***ja
-    @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mnil
+    @brief "nil" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
 
-    ¥·¥ó¥Ü¥ë #Mnil ¤Ï <tt>"nil"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡×
-    ¤ò°ÕÌ£¤¹¤ë¡£#Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£  */
+    ¥·¥ó¥Ü¥ë #Mnil ¤Ï <tt>"nil"</tt> 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡×¤Þ¤¿¤Ï¡ÖÈÝÄê¡×¤ò°ÕÌ£¤¹¤ë¡£
+    "int" ¤ËÊÑ´¹¤µ¤ì¤¿¾ì¹ç¡¢ÃͤϠ0 ¤Ç¤¢¤ë¡£
+    #Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£  */
 
 MSymbol Mnil;
 
@@ -292,12 +318,10 @@ MSymbol Mnil;
 
     The symbol #Mt has the name <tt>"t"</tt> and, in general,
     represents @e true or @e yes.  */
-
 /***ja
-    @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mt
+    @brief "t" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
 
-    ¥·¥ó¥Ü¥ë #Mt ¤Ï <tt>"t"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤ò°Õ
-    Ì£¤¹¤ë¡£  */
+    ¥·¥ó¥Ü¥ë #Mt ¤Ï <tt>"t"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤Þ¤¿¤Ï¡Ö¹ÎÄê¡×¤ò°ÕÌ£¤¹¤ë¡£  */
 
 MSymbol Mt;
 
@@ -309,12 +333,11 @@ MSymbol Mt;
     The symbol #Mstring has the name <tt>"string"</tt> and is used
     as an argument of the functions mchar_define_property (),
     etc.  */
-
 /***ja
-    @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
+    @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
 
-    ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mstring ¤Ï <tt>"string"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
-    ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
+    ¥·¥ó¥Ü¥ë #Mstring ¤Ï <tt>"string"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢´Ø¿ô 
+    mchar_define_property () ¤Ê¤É¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
 
 MSymbol Mstring;
 
@@ -326,12 +349,11 @@ MSymbol Mstring;
     The symbol #Msymbol has the name <tt>"symbol"</tt> and is used
     as an argument of the functions mchar_define_property (),
     etc.  */
-
 /***ja
-    @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
+    @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
 
-    ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï <tt>"symbol"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
-    ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
+    ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï <tt>"symbol"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢´Ø¿ô
+    mchar_define_property () ¤Ê¤É¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
 
 MSymbol Msymbol;
 
@@ -352,12 +374,19 @@ MSymbol Msymbol;
 
     @errors
     This function never fails.  */
-
 /***ja
-    @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÊÖ¤¹
+    @brief ¥·¥ó¥Ü¥ë¤òÆÀ¤ë.
+
+    ´Ø¿ô msymbol () ¤Ï $NAME 
+    ¤È¤¤¤¦Ì¾Á°¤ò»ý¤ÄÀµµ¬²½¤µ¤ì¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢À¸À®¤¹¤ë¡£À¸À®¤µ¤ì¤¿¥·¥ó¥Ü¥ë¤Ï´ÉÍý¥­¡¼¤Ç¤Ï¤Ê¤¤¡£
+
+    ¶õÇòʸ»úÆó¤Ä¤Ç»Ï¤Þ¤ë¥·¥ó¥Ü¥ë¤Ï m17n ¥é¥¤¥Ö¥é¥êÍѤǤ¢¤ê¡¢ÆâÉôŪ¤Ë¤Î¤ßÍѤ¤¤é¤ì¤ë¡£
 
-    ´Ø¿ô msymbol () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥·
-    ¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¿·¤·¤¤¥·¥ó¥Ü¥ë¤¬¼«Æ°Åª¤Ëºî¤é¤ì¤ë¡£
+    @return
+    ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤±¤¿¤«À¸À®¤·¤¿¤«¤·¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£
+
+    @errors
+    ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£
 
     @latexonly \IPAlabel{msymbol} @endlatexonly  */
 
@@ -406,6 +435,18 @@ msymbol (const char *name)
     @return
     If the operation was successful, this function returns the created
     symbol.  Otherwise, it returns #Mnil.  */
+/***ja
+    @brief ´ÉÍý¥­¡¼¤òºî¤ë.
+
+    ´Ø¿ô msymbol_as_managing_key () ¤Ï̾Á° $NAME 
+    ¤ò»ý¤Ä¿·¤·¤¯ºî¤é¤ì¤¿´ÉÍý¥­¡¼¤òÊÖ¤¹¡£¤¹¤Ç¤Ë̾Á° $NAME ¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤¬¤¢¤ì¤Ð¡¢
+    #Mnil ¤òÊÖ¤¹¡£
+
+    ¶õÇòʸ»úÆó¤Ä¤Ç»Ï¤Þ¤ë¥·¥ó¥Ü¥ë¤Ï m17n ¥é¥¤¥Ö¥é¥êÍѤǤ¢¤ê¡¢ÆâÉôŪ¤Ë¤Î¤ßÍѤ¤¤é¤ì¤ë¡£
+
+    @return
+    ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤ÏÀ¸À®¤·¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
+    #Mnil ¤òÊÖ¤¹¡£   */
 
 /***
     @errors
@@ -446,6 +487,24 @@ msymbol_as_managing_key (const char *name)
 /*=*/
 
 /***en
+    @brief Check if a symbol is a managing key.
+
+    The msymbol_is_managing_key () function checks if the symbol
+    $SYMBOL is a managing key or not.
+
+    @return 
+    Return 1 if the symbol is a managing key.  Otherwise,
+    return 0.  */
+
+int
+msymbol_is_managing_key (MSymbol symbol)
+{
+  return (symbol->managing_key == 1);
+}
+
+/*=*/
+
+/***en
     @brief Search for a symbol that has a specified name.
 
     The msymbol_exist () function searches for the symbol whose name
@@ -457,15 +516,17 @@ msymbol_as_managing_key (const char *name)
 
     @errors
     This function never fails.  */
-
 /***ja
-    @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹
+    @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹.
 
-    ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òõ¤¹¡£
+    ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹¡£
 
     @return
-    ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê
-    ¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mnil ¤òÊÖ¤¹¡£  */
+    ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë
+    #Mnil ¤òÊÖ¤¹¡£  
+
+    @errors
+    ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£     */
 
 /***@seealso
     msymbol_name (), msymbol ()  */
@@ -498,15 +559,16 @@ msymbol_exist (const char *name)
     The msymbol_name () function returns a pointer to a string
     containing the name of $SYMBOL.
 
-    @return
-    Name of the specified symbol.
-
     @errors
     This function never fails.  */
 /***ja
-    @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÊÖ¤¹
+    @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÆÀ¤ë.
 
-    ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL ¤Î̾Á°¤òÊÖ¤¹¡£  */
+    ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL 
+    ¤Î̾Á°¤ò´Þ¤àʸ»úÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
+
+    @errors
+    ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£     */
 
 /***@seealso
     msymbol (), msymbol_exist ()  */
@@ -534,18 +596,19 @@ msymbol_name (MSymbol symbol)
     If the operation was successful, msymbol_put () returns 0.
     Otherwise it returns -1 and assigns an error code to the external
     variable #merror_code.  */
-
 /***ja
-    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë
+    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
+
+    ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò
+    $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£
+    $SYMBOL, $KEY ¤È¤â #Mnil ¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
 
-    ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·
-    ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹
-    ¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£$SYMBOL, $KEY ¤È¤â´û¤ËÀ¸À®¤µ¤ì¤¿¥·¥ó¥Ü
-    ¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    $KEY ¤¬´ÉÍý¥­¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
+    @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
 
     @return
-    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤ò
-    ÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 
+    ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 /***
     @errors
@@ -573,23 +636,20 @@ msymbol_put (MSymbol symbol, MSymbol key, void *val)
     $SYMBOL has such a symbol property, its value is returned.
     Otherwise @c NULL is returned.
 
-
     @return
     If an error is detected, msymbol_get () returns @c NULL and
     assigns an error code to the external variable #merror_code.  */
-
 /***ja
-    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòõ¤¹
+    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
 
-    ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
-    ¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
-    ¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß
-    ¤»¤º¡¢¤«¤Ä $KEY ¤ËÂФ¹¤ë¥×¥í¥Ð¥¤¥À´Ø¿ô¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤Î´Ø¿ô¤ò¸Æ¤ó
-    ¤Ç¤½¤ÎÌá¤êÃͤòÊÖ¤¹¡£³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â¥×¥í¥Ð¥¤¥À´Ø¿ô¤â¸
-    ºß¤·¤Ê¤¤¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c NULL ¤òÊÖ¤¹¡£
+    ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL 
+    ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY 
+    ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
+    @c NULL ¤òÊÖ¤¹¡£
 
-    ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
-    #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
+    @return 
+    ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¡¢msymbol_get () ¤Ï @c NULL 
+    ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
 
 /***
     @errors
@@ -610,6 +670,60 @@ msymbol_get (MSymbol symbol, MSymbol key)
   return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
 }
 
+/*=*/
+/***en
+    @brief Set the value (function pointer) of a symbol property.
+
+    The msymbol_put_func () function is similar to msymbol_put () but for
+    setting function pointer $FUNC as the property value of $SYMBOL for
+    key $KEY.  */
+
+/***ja
+    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ(´Ø¿ô¥Ý¥¤¥ó¥¿)¤òÀßÄꤹ¤ë.
+
+    ´Ø¿ô msymbol_put_func () ¤Ï¡¢´Ø¿ô msymbol_put () ¤ÈƱÍͤˡ¢¥·¥ó¥Ü¥ë
+    $SYMBOL ¤Î¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë¡£Ã¢¤·
+    ¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿ $FUNC ¤Ç¤¢¤ë¡£ */
+
+/***
+    @seealso
+     msymbol_put (), M17N_FUNC ()  */
+int
+msymbol_put_func (MSymbol symbol, MSymbol key, M17NFunc func)
+{
+  if (symbol == Mnil || key == Mnil)
+    MERROR (MERROR_SYMBOL, -1);
+  mplist_put_func (&symbol->plist, key, func);
+  return 0;
+}
+
+/*=*/
+
+/***en
+    @brief Get the value (function pointer) of a symbol property.
+
+    The msymbol_get_func () function is similar to msymbol_get () but for
+    getting a function pointer form the property of symbol $SYMBOL.  */
+
+/***ja
+    @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ (´Ø¿ô¥Ý¥¤¥ó¥¿) ¤òÆÀ¤ë.
+
+    ´Ø¿ô msymbol_get_func () ¤Ï¡¢´Ø¿ô msymbol_get () ¤ÈƱÍͤˡ¢¥·¥ó¥Ü¥ë
+    $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òÆÀ¤ë¡£Ã¢¤·
+    ¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿¤ò¤Ç¤¢¤ë¡£    */
+
+/***
+    @seealso
+    msymbol_get ()  */
+
+M17NFunc
+msymbol_get_func (MSymbol symbol, MSymbol key)
+{
+  if (symbol == Mnil || key == Mnil)
+    return NULL;
+  return mplist_get_func (&symbol->plist, key);
+}
+
 /*** @} */
 
 #include <stdio.h>
@@ -621,15 +735,28 @@ msymbol_get (MSymbol symbol, MSymbol key)
 /***en
     @brief Dump a symbol.
 
-    The mdebug_dump_symbol () function prints $SYMBOL in a human
-    readable way to the stderr.  $INDENT specifies how many columns to
-    indent the lines but the first one.
+    The mdebug_dump_symbol () function prints symbol $SYMBOL in a
+    human readable way to the stderr or to what specified by the
+    environment variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how
+    many columns to indent the lines but the first one.
 
     @return
     This function returns $SYMBOL.
 
     @errors
     MERROR_DEBUG  */
+/***ja
+    @brief ¥·¥ó¥Ü¥ë¤ò¥À¥ó¥×¤¹¤ë.
+
+    ´Ø¿ô mdebug_dump_symbol () ¤Ï¥·¥ó¥Ü¥ë $symbol ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷
+    ¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ
+    ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+
+    @return
+    ¤³¤Î´Ø¿ô¤Ï $SYMBOL ¤òÊÖ¤¹¡£ 
+
+    @errors
+    MERROR_DEBUG  */
 
 MSymbol
 mdebug_dump_symbol (MSymbol symbol, int indent)
@@ -649,10 +776,10 @@ mdebug_dump_symbol (MSymbol symbol, int indent)
   else
     plist = &symbol->plist, name = symbol->name;
 
-  fprintf (stderr, "%s%s", prefix, name);
+  fprintf (mdebug__output, "%s%s", prefix, name);
   while (plist && MPLIST_KEY (plist) != Mnil)
     {
-      fprintf (stderr, ":%s", MPLIST_KEY (plist)->name);
+      fprintf (mdebug__output, ":%s", MPLIST_KEY (plist)->name);
       plist = MPLIST_NEXT (plist);
     }
   return symbol;
@@ -662,21 +789,34 @@ mdebug_dump_symbol (MSymbol symbol, int indent)
     @brief Dump all symbol names.
 
     The mdebug_dump_all_symbols () function prints names of all
-    symbols to the stderr.  $INDENT specifies how many columns to
-    indent the lines but the first one.
+    symbols to the stderr or to what specified by the environment
+    variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how many columns
+    to indent the lines but the first one.
 
     @return
     This function returns #Mnil.
 
     @errors
     MERROR_DEBUG  */
+/***ja
+    @brief ¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë̾¤ò¥À¥ó¥×¤¹¤ë.
+
+    ´Ø¿ô mdebug_dump_all_symbols () ¤Ï¡¢¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë¤Î̾Á°¤òɸ½à¥¨
+    ¥é¡¼½ÐÎϤ⤷¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë°õ
+    ºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+
+    @return
+    ¤³¤Î´Ø¿ô¤Ï #Mnil ¤òÊÖ¤¹¡£ 
+
+    @errors
+    MERROR_DEBUG  */
 
 
 MSymbol
 mdebug_dump_all_symbols (int indent)
 {
   char *prefix;
-  int i;
+  int i, n;
   MSymbol sym;
 
   if (indent < 0)
@@ -685,16 +825,17 @@ mdebug_dump_all_symbols (int indent)
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
-  fprintf (stderr, "(symbol-list");
-  for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
+  fprintf (mdebug__output, "(symbol-list");
+  for (i = n = 0; i < SYMBOL_TABLE_SIZE; i++)
     if ((sym = symbol_table[i]))
       {
-       fprintf (stderr, "\n%s  (%4d", prefix, i);
-       for (; sym; sym = sym->next)
-         fprintf (stderr, " '%s'", sym->name);
-       fprintf (stderr, ")");
+       fprintf (mdebug__output, "\n%s  (%4d", prefix, i);
+       for (; sym; sym = sym->next, n++)
+         fprintf (mdebug__output, " '%s'", sym->name);
+       fprintf (mdebug__output, ")");
       }
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, "\n%s  (total %d)", prefix, n);
+  fprintf (mdebug__output, ")");
   return Mnil;
 }