Update copyright years
[m17n/m17n-lib.git] / src / symbol.c
1 /* symbol.c -- symbol module.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5
6    This file is part of the m17n library.
7
8    The m17n library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    The m17n library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with the m17n library; if not, write to the Free
20    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    02111-1307, USA.  */
22
23 /***en
24     @addtogroup m17nSymbol
25
26     @brief Symbol objects and API for them.
27
28     The m17n library uses objects called @e symbols as unambiguous
29     identifiers.  Symbols are similar to atoms in the X library, but a
30     symbol can have zero or more @e symbol @e properties.  A symbol
31     property consists of a @e key and a @e value, where key is also a
32     symbol and value is anything that can be cast to <tt>(void *)</tt>.  
33     "The symbol property that belongs to the symbol S and
34     whose key is K" may be shortened to "K property of S".
35
36     Symbols are used mainly in the following three ways.
37
38     @li As keys of symbol properties and other properties.
39
40     @li To represent various objects, e.g. charsets, coding systems,
41     fontsets.
42
43     @li As arguments of the m17n library functions to control
44     their behavior.
45
46     There is a special kind of symbol, a @e managing @e key.  The
47     value of a property whose key is a managing key must be a @e
48     managed @e object.  See @ref m17nObject for the detail.
49 */
50 /***ja
51     @addtogroup m17nSymbol ¥·¥ó¥Ü¥ë
52
53     @brief ¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
54
55     m17n ¥é¥¤¥Ö¥é¥ê¤Ï°ì°Õ¤Ë·è¤Þ¤ë¼±Ê̻ҤȤ·¤Æ @e ¥·¥ó¥Ü¥ë 
56     ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤òÍѤ¤¤ë¡£¥·¥ó¥Ü¥ë¤Ï X ¥é¥¤¥Ö¥é¥ê¤Î¥¢¥È¥à¤È»÷¤Æ¤¤¤ë¤¬¡¢
57     0 ¸Ä°Ê¾å¤Î @e ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ï
58     @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¤½¤ì¼«ÂÎ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤϠ
59     <tt>(void *)</tt> ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£¡Ö¥·¥ó¥Ü¥ë 
60     S ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ K ¤Î¤â¤Î¡×¤ò´Êñ¤Ë¡ÖS ¤Î K 
61     ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
62
63     ¥·¥ó¥Ü¥ë¤ÎÍÑÅӤϼç¤Ë°Ê²¼¤Î3Ä̤ê¤Ç¤¢¤ë¡£
64
65     @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ª¤è¤Ó¾¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òɽ¤¹¡£
66
67     @li Ê¸»ú¥»¥Ã¥È¡¢¥³¡¼¥É·Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ê¤É¤Î³Æ¼ï¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¡£
68
69     @li m17n ¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Î°ú¿ô¤È¤Ê¤ê¡¢´Ø¿ô¤ÎµóÆ°¤òÀ©¸æ¤¹¤ë¡£
70
71     @e ´ÉÍý¥­¡¼ ¤È¸Æ¤Ð¤ì¤ëÆÃÊ̤ʥ·¥ó¥Ü¥ë¤¬¤¢¤ê¡¢´ÉÍý¥­¡¼¤ò¥­¡¼¤È¤·¤Æ»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏ
72     @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ï @ref m17nObject »²¾È¡£
73 */
74
75 /*=*/
76
77 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
78 /*** @addtogroup m17nInternal
79      @{ */
80
81 #include <config.h>
82 #include <stdlib.h>
83 #include <string.h>
84 #include <ctype.h>
85
86 #include "m17n.h"
87 #include "m17n-misc.h"
88 #include "internal.h"
89 #include "symbol.h"
90 #include "character.h"
91 #include "mtext.h"
92 #include "plist.h"
93
94 static int num_symbols;
95
96 #define SYMBOL_TABLE_SIZE 1024
97
98 static MSymbol symbol_table[SYMBOL_TABLE_SIZE];
99
100 static unsigned
101 hash_string (const char *str, int len)
102 {
103   unsigned hash = 0;
104   const char *end = str + len;
105   unsigned c;
106
107   while (str < end)
108     {
109       c = *((unsigned char *) str++);
110       if (c >= 0140)
111         c -= 40;
112       hash = ((hash << 3) + (hash >> 28) + c);
113     }
114   return hash & (SYMBOL_TABLE_SIZE - 1);
115 }
116
117
118 static MPlist *
119 serialize_symbol (void *val)
120 {
121   MPlist *plist = mplist ();
122
123   mplist_add (plist, Msymbol, val);
124   return plist;
125 }
126
127 static void *
128 deserialize_symbol (MPlist *plist)
129 {
130   return (MPLIST_SYMBOL_P (plist) ? MPLIST_SYMBOL (plist) : Mnil);
131 }
132
133 \f
134 /* Internal API */
135
136 int
137 msymbol__init ()
138 {
139   num_symbols = 0;
140   Mnil = (MSymbol) 0;
141   Mt = msymbol ("t");
142   Msymbol = msymbol ("symbol");
143   Mstring = msymbol ("string");
144   return 0;
145 }
146
147 void
148 msymbol__fini ()
149 {
150   int i;
151   MSymbol sym;
152
153   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
154     for (sym = symbol_table[i]; sym; sym = sym->next)
155       if (! MPLIST_TAIL_P (&sym->plist))
156         {
157           if (sym->plist.key->managing_key)
158             M17N_OBJECT_UNREF (MPLIST_VAL (&sym->plist));
159           M17N_OBJECT_UNREF (sym->plist.next);
160           sym->plist.key = Mnil;
161         }
162 }
163
164 void
165 msymbol__free_table ()
166 {
167   int i;
168   MSymbol sym, next;
169   int freed_symbols = 0;
170
171   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
172     {
173       for (sym = symbol_table[i]; sym; sym = next)
174         {
175           next = sym->next;
176           free (sym->name);
177           free (sym);
178           freed_symbols++;
179         }
180       symbol_table[i] = NULL;
181     }
182   if (mdebug__flags[MDEBUG_FINI])
183     fprintf (mdebug__output, "%16s %7d %7d %7d\n", "Symbol",
184              num_symbols, freed_symbols, num_symbols - freed_symbols);
185   num_symbols = 0;
186 }
187
188
189 MSymbol
190 msymbol__with_len (const char *name, int len)
191 {
192   char *p = alloca (len + 1);
193
194   memcpy (p, name, len);
195   p[len] = '\0';
196   return msymbol (p);
197 }
198
199 /** Return a plist of symbols that has non-NULL property PROP.  If
200     PROP is Mnil, return a plist of all symbols.  Values of the plist
201     is NULL.  */
202
203 MPlist *
204 msymbol__list (MSymbol prop)
205 {
206   MPlist *plist = mplist ();
207   int i;
208   MSymbol sym;
209
210   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
211     for (sym = symbol_table[i]; sym; sym = sym->next)
212       if (prop == Mnil || msymbol_get (sym, prop))
213         mplist_push (plist, sym, NULL);
214   return plist;
215 }
216
217
218 /** Canonicalize the name of SYM, and return a symbol of the
219     canonicalized name.  Canonicalization is done by this rule:
220         o convert all uppercase characters to lowercase.
221         o remove all non alpha-numeric characters.
222         o change the leading "ibm" to "cp".
223         o change the leading "windows-" to "cp".
224         o change the leading "cp" to "ibm".
225         o remove the leading "iso".
226     For instance:
227         "ISO-8859-2" -> "88592"
228         "euc-JP" -> "eucjp"
229         "IBM851" -> "cp851"
230         "windows-1250" -> "cp250"
231
232     This function is used to canonicalize charset and coding system
233     names.  */
234
235 MSymbol
236 msymbol__canonicalize (MSymbol sym)
237 {
238   char *name = sym->name;
239   /* Extra 2 bytes are for changing "cpXXX" to "ibmXXX" and
240      terminating '\0'.  */
241   char *canon = (char *) alloca (strlen (name) + 2);
242   char *p = canon;
243
244   for (; *name; name++)
245     if (ISALNUM (*name))
246       *p++ = TOLOWER (*name);
247   *p = '\0';
248   if (p - canon > 3 && canon[0] == 'i')
249     {
250       if (canon[1] == 'b' && canon[2] == 'm' && isdigit (canon[3]))
251         {
252           /* Change "ibmXXX" to "cpXXX".  */
253           canon++;
254           canon[0] = 'c';
255           canon[1] = 'p';
256         }
257       else if (canon[1] == 's' && canon[2] == 'o')
258         {
259           /* Change "isoXXX" to "XXX".  */
260           canon += 3;
261         }
262     }
263   else if (p - canon > 2
264            && canon[0] == 'c' && canon[1] == 'p' && isdigit (canon[2]))
265     {
266       /* Change "cpXXX" to "ibmXXX".  */
267       for (; p >= canon + 2; p--)
268         p[1] = p[0];
269       canon[0] = 'i';
270       canon[1] = 'b';
271       canon[2] = 'm';
272     }
273   else if (canon[0] == 'w' && p - canon > 7
274            && memcmp (canon + 1, "indows", 6) == 0
275            && isdigit (canon[7]))
276     {
277       /* Change "windowsXXX" to "cpXXX" */
278       canon += 5;
279       canon[0] = 'c';
280       canon[1] = 'p';
281     }
282   return msymbol (canon);
283 }
284
285 MTextPropSerializeFunc msymbol__serializer = serialize_symbol;
286 MTextPropDeserializeFunc msymbol__deserializer = deserialize_symbol;
287
288 /*** @} */
289 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
290
291 \f
292 /* External API */
293
294 /*** @addtogroup m17nSymbol */
295 /*** @{ */
296
297 /*=*/
298 /***en
299     @brief Symbol whose name is "nil".
300
301     The symbol #Mnil has the name <tt>"nil"</tt> and, in general,
302     represents @e false or @e no.  When coerced to "int", its value is
303     zero.  #Mnil can't have any symbol property.  */
304 /***ja
305     @brief "nil" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
306
307     ¥·¥ó¥Ü¥ë #Mnil ¤Ï <tt>"nil"</tt> 
308     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡×¤Þ¤¿¤Ï¡ÖÈÝÄê¡×¤ò°ÕÌ£¤¹¤ë¡£
309     "int" ¤ËÊÑ´¹¤µ¤ì¤¿¾ì¹ç¡¢ÃͤϠ0 ¤Ç¤¢¤ë¡£
310     #Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£  */
311
312 MSymbol Mnil;
313
314 /*=*/
315
316 /***en
317     @brief Symbol whose name is "t".
318
319     The symbol #Mt has the name <tt>"t"</tt> and, in general,
320     represents @e true or @e yes.  */
321 /***ja
322     @brief "t" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
323
324     ¥·¥ó¥Ü¥ë #Mt ¤Ï <tt>"t"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤Þ¤¿¤Ï¡Ö¹ÎÄê¡×¤ò°ÕÌ£¤¹¤ë¡£  */
325
326 MSymbol Mt;
327
328 /*=*/
329
330 /***en
331     @brief Symbol whose name is "string".
332
333     The symbol #Mstring has the name <tt>"string"</tt> and is used
334     as an argument of the functions mchar_define_property (),
335     etc.  */
336 /***ja
337     @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
338
339     ¥·¥ó¥Ü¥ë #Mstring ¤Ï <tt>"string"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢´Ø¿ô 
340     mchar_define_property () ¤Ê¤É¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
341
342 MSymbol Mstring;
343
344 /*=*/
345
346 /***en
347     @brief Symbol whose name is "symbol".
348
349     The symbol #Msymbol has the name <tt>"symbol"</tt> and is used
350     as an argument of the functions mchar_define_property (),
351     etc.  */
352 /***ja
353     @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
354
355     ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï <tt>"symbol"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢´Ø¿ô
356     mchar_define_property () ¤Ê¤É¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
357
358 MSymbol Msymbol;
359
360 /*=*/
361
362 /***en
363     @brief Get a symbol.
364
365     The msymbol () function returns the canonical symbol whose name is
366     $NAME.  If there is none, one is created.  The created one is not
367     a managing key.
368
369     Symbols whose name starts by two spaces are reserved by the m17n
370     library, and are used by the library only internally.
371
372     @return
373     This function returns the found or created symbol.
374
375     @errors
376     This function never fails.  */
377 /***ja
378     @brief ¥·¥ó¥Ü¥ë¤òÆÀ¤ë.
379
380     ´Ø¿ô msymbol () ¤Ï $NAME 
381     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤ÄÀµµ¬²½¤µ¤ì¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢À¸À®¤¹¤ë¡£À¸À®¤µ¤ì¤¿¥·¥ó¥Ü¥ë¤Ï´ÉÍý¥­¡¼¤Ç¤Ï¤Ê¤¤¡£
382
383     ¶õÇòʸ»úÆó¤Ä¤Ç»Ï¤Þ¤ë¥·¥ó¥Ü¥ë¤Ï m17n ¥é¥¤¥Ö¥é¥êÍѤǤ¢¤ê¡¢ÆâÉôŪ¤Ë¤Î¤ßÍѤ¤¤é¤ì¤ë¡£
384
385     @return
386     ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤±¤¿¤«À¸À®¤·¤¿¤«¤·¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£
387
388     @errors
389     ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£
390
391     @latexonly \IPAlabel{msymbol} @endlatexonly  */
392
393 /***
394     @seealso
395     msymbol_as_managing_key (), msymbol_name (), msymbol_exist ()  */
396
397 MSymbol
398 msymbol (const char *name)
399 {
400   MSymbol sym;
401   int len;
402   unsigned hash;
403
404   len = strlen (name);
405   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
406     return Mnil;
407   hash = hash_string (name, len);
408   len++;
409   for (sym = symbol_table[hash]; sym; sym = sym->next)
410     if (len == sym->length
411         && *name == *(sym->name)
412         && ! memcmp (name, sym->name, len))
413       return sym;
414
415   num_symbols++;
416   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
417   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
418   memcpy (sym->name, name, len);
419   sym->length = len;
420   sym->next = symbol_table[hash];
421   symbol_table[hash] = sym;
422   return sym;
423 }
424
425 /***en
426     @brief Create a managing key.
427
428     The msymbol_as_managing_key () function returns a newly created
429     managing key whose name is $NAME.  It there already exists a
430     symbol of name $NAME, it returns #Mnil.
431
432     Symbols whose name starts by two spaces are reserved by the m17n
433     library, and are used by the library only internally.
434
435     @return
436     If the operation was successful, this function returns the created
437     symbol.  Otherwise, it returns #Mnil.  */
438 /***ja
439     @brief ´ÉÍý¥­¡¼¤òºî¤ë.
440
441     ´Ø¿ô msymbol_as_managing_key () ¤Ï̾Á° $NAME 
442     ¤ò»ý¤Ä¿·¤·¤¯ºî¤é¤ì¤¿´ÉÍý¥­¡¼¤òÊÖ¤¹¡£¤¹¤Ç¤Ë̾Á° $NAME ¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤¬¤¢¤ì¤Ð¡¢
443     #Mnil ¤òÊÖ¤¹¡£
444
445     ¶õÇòʸ»úÆó¤Ä¤Ç»Ï¤Þ¤ë¥·¥ó¥Ü¥ë¤Ï m17n ¥é¥¤¥Ö¥é¥êÍѤǤ¢¤ê¡¢ÆâÉôŪ¤Ë¤Î¤ßÍѤ¤¤é¤ì¤ë¡£
446
447     @return
448     ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤ÏÀ¸À®¤·¤¿¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
449     #Mnil ¤òÊÖ¤¹¡£   */
450
451 /***
452     @errors
453     MERROR_SYMBOL
454
455     @seealso
456     msymbol (), msymbol_exist ()  */
457
458 MSymbol
459 msymbol_as_managing_key (const char *name)
460 {
461   MSymbol sym;
462   int len;
463   unsigned hash;
464
465   len = strlen (name);
466   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
467     MERROR (MERROR_SYMBOL, Mnil);
468   hash = hash_string (name, len);
469   len++;
470   for (sym = symbol_table[hash]; sym; sym = sym->next)
471     if (len == sym->length
472         && *name == *(sym->name)
473         && ! memcmp (name, sym->name, len))
474       MERROR (MERROR_SYMBOL, Mnil);
475
476   num_symbols++;
477   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
478   sym->managing_key = 1;
479   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
480   memcpy (sym->name, name, len);
481   sym->length = len;
482   sym->next = symbol_table[hash];
483   symbol_table[hash] = sym;
484   return sym;
485 }
486
487 /*=*/
488
489 /***en
490     @brief Check if a symbol is a managing key.
491
492     The msymbol_is_managing_key () function checks if the symbol
493     $SYMBOL is a managing key or not.
494
495     @return 
496     Return 1 if the symbol is a managing key.  Otherwise,
497     return 0.  */
498
499 int
500 msymbol_is_managing_key (MSymbol symbol)
501 {
502   return (symbol->managing_key == 1);
503 }
504
505 /*=*/
506
507 /***en
508     @brief Search for a symbol that has a specified name.
509
510     The msymbol_exist () function searches for the symbol whose name
511     is $NAME.
512
513     @return
514     If such a symbol exists, msymbol_exist () returns that symbol.
515     Otherwise it returns the predefined symbol #Mnil.
516
517     @errors
518     This function never fails.  */
519 /***ja
520     @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹.
521
522     ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹¡£
523
524     @return
525     ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë
526     #Mnil ¤òÊÖ¤¹¡£  
527
528     @errors
529     ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£     */
530
531 /***@seealso
532     msymbol_name (), msymbol ()  */
533
534 MSymbol
535 msymbol_exist (const char *name)
536 {
537   MSymbol sym;
538   int len;
539   unsigned hash;
540
541   len = strlen (name);
542   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
543     return Mnil;
544   hash = hash_string (name, len);
545   len++;
546   for (sym = symbol_table[hash]; sym; sym = sym->next)
547     if (len == sym->length
548         && *name == *(sym->name)
549         && ! memcmp (name, sym->name, len))
550       return sym;
551   return Mnil;
552 }
553
554 /*=*/
555
556 /***en
557     @brief Get symbol name.
558
559     The msymbol_name () function returns a pointer to a string
560     containing the name of $SYMBOL.
561
562     @errors
563     This function never fails.  */
564 /***ja
565     @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÆÀ¤ë.
566
567     ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL 
568     ¤Î̾Á°¤ò´Þ¤àʸ»úÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
569
570     @errors
571     ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£     */
572
573 /***@seealso
574     msymbol (), msymbol_exist ()  */
575
576 char *
577 msymbol_name (MSymbol symbol)
578 {
579   return (symbol == Mnil ? "nil" : symbol->name);
580 }
581
582 /*=*/
583 /***en
584     @brief Set the value of a symbol property.
585
586     The msymbol_put () function assigns $VAL to the value of the
587     symbol property that belongs to $SYMBOL and whose key is $KEY.  If
588     the symbol property already has a value, $VAL overwrites the old
589     one.  Both $SYMBOL and $KEY must not be #Mnil.
590
591     If $KEY is a managing key, $VAL must be a managed object.  In this
592     case, the reference count of the old value, if not @c NULL, is
593     decremented by one, and that of $VAL is incremented by one.
594
595     @return
596     If the operation was successful, msymbol_put () returns 0.
597     Otherwise it returns -1 and assigns an error code to the external
598     variable #merror_code.  */
599 /***ja
600     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
601
602     ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò
603     $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£
604     $SYMBOL, $KEY ¤È¤â #Mnil ¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
605
606     $KEY ¤¬´ÉÍý¥­¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
607     @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
608
609     @return
610     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 
611     ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
612
613 /***
614     @errors
615     @c MERROR_SYMBOL
616
617     @seealso
618     msymbol_get () */
619
620 int
621 msymbol_put (MSymbol symbol, MSymbol key, void *val)
622 {
623   if (symbol == Mnil || key == Mnil)
624     MERROR (MERROR_SYMBOL, -1);
625   mplist_put (&symbol->plist, key, val);
626   return 0;
627 }
628
629 /*=*/
630
631 /***en
632     @brief Get the value of a symbol property.
633
634     The msymbol_get () function searches for the value of the symbol
635     property that belongs to $SYMBOL and whose key is $KEY.  If
636     $SYMBOL has such a symbol property, its value is returned.
637     Otherwise @c NULL is returned.
638
639     @return
640     If an error is detected, msymbol_get () returns @c NULL and
641     assigns an error code to the external variable #merror_code.  */
642 /***ja
643     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
644
645     ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL 
646     ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY 
647     ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
648     @c NULL ¤òÊÖ¤¹¡£
649
650     @return 
651     ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¡¢msymbol_get () ¤Ï @c NULL 
652     ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
653
654 /***
655     @errors
656     @c MERROR_SYMBOL
657
658     @seealso
659     msymbol_put () */
660
661 void *
662 msymbol_get (MSymbol symbol, MSymbol key)
663 {
664   MPlist *plist;
665
666   if (symbol == Mnil || key == Mnil)
667     return NULL;
668   plist = &symbol->plist;
669   MPLIST_FIND (plist, key);
670   return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
671 }
672
673 /*=*/
674 /***en
675     @brief Set the value (function pointer) of a symbol property.
676
677     The msymbol_put_func () function is similar to msymbol_put () but for
678     setting function pointer $FUNC as the property value of $SYMBOL for
679     key $KEY.  */
680
681 /***ja
682     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ(´Ø¿ô¥Ý¥¤¥ó¥¿)¤òÀßÄꤹ¤ë.
683
684     ´Ø¿ô msymbol_put_func () ¤Ï¡¢´Ø¿ô msymbol_put () ¤ÈƱÍͤˡ¢¥·¥ó¥Ü¥ë
685     $SYMBOL ¤Î¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë¡£Ã¢¤·
686     ¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿ $FUNC ¤Ç¤¢¤ë¡£ */
687
688 /***
689     @seealso
690      msymbol_put (), M17N_FUNC ()  */
691 int
692 msymbol_put_func (MSymbol symbol, MSymbol key, M17NFunc func)
693 {
694   if (symbol == Mnil || key == Mnil)
695     MERROR (MERROR_SYMBOL, -1);
696   mplist_put_func (&symbol->plist, key, func);
697   return 0;
698 }
699
700 /*=*/
701
702 /***en
703     @brief Get the value (function pointer) of a symbol property.
704
705     The msymbol_get_func () function is similar to msymbol_get () but for
706     getting a function pointer form the property of symbol $SYMBOL.  */
707
708 /***ja
709     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ (´Ø¿ô¥Ý¥¤¥ó¥¿) ¤òÆÀ¤ë.
710
711     ´Ø¿ô msymbol_get_func () ¤Ï¡¢´Ø¿ô msymbol_get () ¤ÈƱÍͤˡ¢¥·¥ó¥Ü¥ë
712     $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òÆÀ¤ë¡£Ã¢¤·
713     ¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿¤ò¤Ç¤¢¤ë¡£    */
714
715 /***
716     @seealso
717     msymbol_get ()  */
718
719 M17NFunc
720 msymbol_get_func (MSymbol symbol, MSymbol key)
721 {
722   if (symbol == Mnil || key == Mnil)
723     return NULL;
724   return mplist_get_func (&symbol->plist, key);
725 }
726
727 /*** @} */
728
729 #include <stdio.h>
730
731 /*** @addtogroup m17nDebug */
732 /*=*/
733 /*** @{ */
734
735 /***en
736     @brief Dump a symbol.
737
738     The mdebug_dump_symbol () function prints symbol $SYMBOL in a
739     human readable way to the stderr or to what specified by the
740     environment variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how
741     many columns to indent the lines but the first one.
742
743     @return
744     This function returns $SYMBOL.
745
746     @errors
747     MERROR_DEBUG  */
748 /***ja
749     @brief ¥·¥ó¥Ü¥ë¤ò¥À¥ó¥×¤¹¤ë.
750
751     ´Ø¿ô mdebug_dump_symbol () ¤Ï¥·¥ó¥Ü¥ë $symbol ¤òɸ½à¥¨¥é¡¼½ÐÎϤ⤷
752     ¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ
753     ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
754
755     @return
756     ¤³¤Î´Ø¿ô¤Ï $SYMBOL ¤òÊÖ¤¹¡£ 
757
758     @errors
759     MERROR_DEBUG  */
760
761 MSymbol
762 mdebug_dump_symbol (MSymbol symbol, int indent)
763 {
764   char *prefix;
765   MPlist *plist;
766   char *name;
767
768   if (indent < 0)
769     MERROR (MERROR_DEBUG, Mnil);
770   prefix = (char *) alloca (indent + 1);
771   memset (prefix, 32, indent);
772   prefix[indent] = 0;
773
774   if (symbol == Mnil)
775     plist = NULL, name = "nil";
776   else
777     plist = &symbol->plist, name = symbol->name;
778
779   fprintf (mdebug__output, "%s%s", prefix, name);
780   while (plist && MPLIST_KEY (plist) != Mnil)
781     {
782       fprintf (mdebug__output, ":%s", MPLIST_KEY (plist)->name);
783       plist = MPLIST_NEXT (plist);
784     }
785   return symbol;
786 }
787
788 /***en
789     @brief Dump all symbol names.
790
791     The mdebug_dump_all_symbols () function prints names of all
792     symbols to the stderr or to what specified by the environment
793     variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how many columns
794     to indent the lines but the first one.
795
796     @return
797     This function returns #Mnil.
798
799     @errors
800     MERROR_DEBUG  */
801 /***ja
802     @brief ¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë̾¤ò¥À¥ó¥×¤¹¤ë.
803
804     ´Ø¿ô mdebug_dump_all_symbols () ¤Ï¡¢¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë¤Î̾Á°¤òɸ½à¥¨
805     ¥é¡¼½ÐÎϤ⤷¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë°õ
806     ºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
807
808     @return
809     ¤³¤Î´Ø¿ô¤Ï #Mnil ¤òÊÖ¤¹¡£ 
810
811     @errors
812     MERROR_DEBUG  */
813
814
815 MSymbol
816 mdebug_dump_all_symbols (int indent)
817 {
818   char *prefix;
819   int i, n;
820   MSymbol sym;
821
822   if (indent < 0)
823     MERROR (MERROR_DEBUG, Mnil);
824   prefix = (char *) alloca (indent + 1);
825   memset (prefix, 32, indent);
826   prefix[indent] = 0;
827
828   fprintf (mdebug__output, "(symbol-list");
829   for (i = n = 0; i < SYMBOL_TABLE_SIZE; i++)
830     if ((sym = symbol_table[i]))
831       {
832         fprintf (mdebug__output, "\n%s  (%4d", prefix, i);
833         for (; sym; sym = sym->next, n++)
834           fprintf (mdebug__output, " '%s'", sym->name);
835         fprintf (mdebug__output, ")");
836       }
837   fprintf (mdebug__output, "\n%s  (total %d)", prefix, n);
838   fprintf (mdebug__output, ")");
839   return Mnil;
840 }
841
842 /*** @} */ 
843
844 /*
845   Local Variables:
846   coding: euc-japan
847   End:
848 */