(fc_decode_prop): Fix for the case of too large VAL.
[m17n/m17n-lib.git] / src / symbol.c
index ae11459..75ef4f1 100644 (file)
@@ -1,5 +1,5 @@
 /* symbol.c -- symbol 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
 
@@ -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
@@ -148,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)
@@ -170,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;
 }
@@ -211,13 +220,14 @@ msymbol__list (MSymbol prop)
        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.  */
@@ -260,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);
 }
 
@@ -469,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
@@ -634,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>
@@ -645,9 +735,10 @@ msymbol_get (MSymbol symbol, MSymbol key)
 /***en
     @brief Dump a symbol.
 
-    The mdebug_dump_symbol () function prints symbol $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.
@@ -657,8 +748,9 @@ msymbol_get (MSymbol symbol, MSymbol key)
 /***ja
     @brief ¥·¥ó¥Ü¥ë¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_symbol () ¤Ï¥·¥ó¥Ü¥ë $symbol ¤ò stderr 
-    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+    ´Ø¿ô mdebug_dump_symbol () ¤Ï¥·¥ó¥Ü¥ë $symbol ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷
+    ¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ
+    ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $SYMBOL ¤òÊÖ¤¹¡£ 
@@ -684,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;
@@ -697,8 +789,9 @@ 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.
@@ -708,8 +801,9 @@ mdebug_dump_symbol (MSymbol symbol, int indent)
 /***ja
     @brief ¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë̾¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_all_symbols () ¤Ï¡¢¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë¤Î̾Á°¤ò 
-    stderr ¤Ë°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+    ´Ø¿ô mdebug_dump_all_symbols () ¤Ï¡¢¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë¤Î̾Á°¤òɸ½à¥¨
+    ¥é¡¼½ÐÎϤ⤷¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë°õ
+    ºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï #Mnil ¤òÊÖ¤¹¡£ 
@@ -731,17 +825,17 @@ mdebug_dump_all_symbols (int indent)
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
-  fprintf (stderr, "(symbol-list");
+  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);
+       fprintf (mdebug__output, "\n%s  (%4d", prefix, i);
        for (; sym; sym = sym->next, n++)
-         fprintf (stderr, " '%s'", sym->name);
-       fprintf (stderr, ")");
+         fprintf (mdebug__output, " '%s'", sym->name);
+       fprintf (mdebug__output, ")");
       }
-  fprintf (stderr, "\n%s  (total %d)", prefix, n);
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, "\n%s  (total %d)", prefix, n);
+  fprintf (mdebug__output, ")");
   return Mnil;
 }