Change /***ja to /***oldja
[m17n/m17n-lib.git] / src / symbol.c
1 /* symbol.c -- symbol module.
2    Copyright (C) 2003, 2004
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., 59 Temple Place, Suite 330, Boston, MA
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
33     *)</tt>.  "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
51 /***oldja
52     @addtogroup m17nSymbol ¥·¥ó¥Ü¥ë
53
54     @brief ¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API
55
56     m17n ¥é¥¤¥Ö¥é¥ê¤Ï°ì°Õ¤Ë·è¤Þ¤ëµ­½Ò»Ò¤È¤·¤Æ @e ¥·¥ó¥Ü¥ë ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§
57     ¥¯¥È¤òÍѤ¤¤ë¡£¥·¥ó¥Ü¥ë¤Ï X ¥é¥¤¥Ö¥é¥ê¤Î¥¢¥È¥à¤È»÷¤Æ¤¤¤ë¤¬¡¢0 ¸Ä°Ê
58     ¾å¤Î @e ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ëÅÀ¤Ç¡¢¥¢¥È¥à¤è¤ê¹âµ¡
59     Ç½¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¤½
60     ¤ì¼«ÂÎ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃͤϠ<tt>(void *)</tt> ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â
61     ¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£¡Ö¥·¥ó¥Ü¥ë S ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼
62     ¤¬ K ¤Î¤â¤Î¡×¤ò´Êñ¤Ë¡ÖS ¤Î K ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
63
64     ¥·¥ó¥Ü¥ë¤ÎÍÑÅӤϼç¤Ë°Ê²¼¤Î3Ä̤ê¤Ç¤¢¤ë¡£
65
66     @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ (¤ª¤è¤Ó¾¤Î¥×¥í¥Ñ¥Æ¥£) ¤Î¥­¡¼¤òɽ¤ï¤¹¡£
67
68     @li Ê¸»ú¥»¥Ã¥È¡¢¥³¡¼¥É·Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ê¤É¤Î³Æ¼ï¥ª¥Ö¥¸¥§¥¯¥È¤òɽ
69     ¤ï¤¹¡£
70
71     @li m17n ¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Î°ú¿ô¤È¤Ê¤ê¡¢´Ø¿ô¤ÎµóÆ°¤òÀ©¸æ¤¹¤ë¡£
72
73     ¥­¡¼¤¬ @c Mmanaging_key ¤ÇÃͤ¬ @c NULL °Ê³°¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò
74     »ý¤Ä¥·¥ó¥Ü¥ë¤Ï¡¢@e ´ÉÍý¥­¡¼ ¤È¸Æ¤Ð¤ì¤ë¡£¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼
75     ¤¬´ÉÍý¥­¡¼¤Î¾ì¹ç¡¢¤½¤ÎÃͤϠ@e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
76     ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤Î¾Ï¤ò»²¾È
77     ¤Î¤³¤È¡£
78
79     ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤ÏÃͤÎÂå¤ê¤Ë @e ¥×¥í¥Ð¥¤¥À´Ø¿ô ¤ò»ý¤¿¤»¤ë¤³¤È
80     ¤â¤Ç¤­¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤Ï¤½¤Î¥­¡¼¤ÎÃͤòÆÀ¤è¤¦¤È¤¹¤ë»þ¤Ë¸Æ¤Ð¤ì¡¢¤½
81     ¤ÎÊÖ¤êÃͤ¬µá¤á¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤʤ롣¤³¤Î»ÅÁȤߤˤè¤Ã¤Æ¥·
82     ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÙ±äɾ²Á¤¬²Äǽ¤Ë¤Ê¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤ÏÃͤòÊÖ¤¹¤È
83     Æ±»þ¤ËÃͤòÀßÄꤹ¤ë¤³¤È¤â¤Ç¤­¡¢¤³¤Î¾ì¹ç¤Ë¤Ï¡¢¥×¥í¥Ð¥¤¥À´Ø¿ô¼«ÂΤÏÃÍ
84     ¤ÎÀßÄê°Ê¹ß¤Ï̵¸ú¤È¤Ê¤ë¡£  */
85
86 /*=*/
87
88 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
89 /*** @addtogroup m17nInternal
90      @{ */
91
92 #include <config.h>
93 #include <stdlib.h>
94 #include <string.h>
95 #include <ctype.h>
96
97 #include "m17n.h"
98 #include "m17n-misc.h"
99 #include "internal.h"
100 #include "symbol.h"
101 #include "character.h"
102 #include "mtext.h"
103 #include "plist.h"
104
105 static int num_symbols;
106
107 #define SYMBOL_TABLE_SIZE 1024
108
109 static MSymbol symbol_table[SYMBOL_TABLE_SIZE];
110
111 static unsigned
112 hash_string (const char *str, int len)
113 {
114   unsigned hash = 0;
115   const char *end = str + len;
116   unsigned c;
117
118   while (str < end)
119     {
120       c = *((unsigned char *) str++);
121       if (c >= 0140)
122         c -= 40;
123       hash = ((hash << 3) + (hash >> 28) + c);
124     }
125   return hash & (SYMBOL_TABLE_SIZE - 1);
126 }
127
128
129 static MPlist *
130 serialize_symbol (void *val)
131 {
132   MPlist *plist = mplist ();
133
134   mplist_add (plist, Msymbol, val);
135   return plist;
136 }
137
138 static void *
139 deserialize_symbol (MPlist *plist)
140 {
141   return (MPLIST_SYMBOL_P (plist) ? MPLIST_SYMBOL (plist) : Mnil);
142 }
143
144 \f
145 /* Internal API */
146
147 int
148 msymbol__init ()
149 {
150   num_symbols = 0;
151   Mnil = (MSymbol) 0;
152   Mt = msymbol ("t");
153   Msymbol = msymbol ("symbol");
154   Mstring = msymbol ("string");
155   return 0;
156 }
157
158 void
159 msymbol__fini ()
160 {
161   int i;
162   MSymbol sym, next;
163   int freed_symbols = 0;
164
165   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
166     for (sym = symbol_table[i]; sym; sym = sym->next)
167       if (! MPLIST_TAIL_P (&sym->plist))
168         {
169           if (sym->plist.key->managing_key)
170             M17N_OBJECT_UNREF (sym->plist.val);
171           M17N_OBJECT_UNREF (sym->plist.next);
172         }
173   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
174     {
175       for (sym = symbol_table[i]; sym; sym = next)
176         {
177           next = sym->next;
178           free (sym->name);
179           free (sym);
180           freed_symbols++;
181         }
182       symbol_table[i] = NULL;
183     }
184   if (mdebug__flag & MDEBUG_FINI)
185     fprintf (stderr, "%16s %7d %7d %7d\n", "Symbol",
186              num_symbols, freed_symbols, num_symbols - freed_symbols);
187   num_symbols = 0;
188 }
189
190
191 MSymbol
192 msymbol__with_len (const char *name, int len)
193 {
194   char *p = alloca (len + 1);
195
196   memcpy (p, name, len);
197   p[len] = '\0';
198   return msymbol (p);
199 }
200
201
202 /** Canonicalize the name of SYM, and return a symbol of the
203     canonicalized name.  Canonicalization is done by this rule:
204         o convert all uppercase characters to lowercase.
205         o remove all non alpha-numeric characters.
206         o change the leading "ibm" to "cp".
207         o change the leading "cp" to "ibm"
208         o remove the leading "iso".
209     For instance:
210         "ISO-8859-2" -> "88592"
211         "euc-JP" -> "eucjp"
212         "IBM851" -> "cp851"
213         "CP1250" -> "ibm1250"
214
215     This function is used to canonicalize charset and coding system
216     names.  */
217
218 MSymbol
219 msymbol__canonicalize (MSymbol sym)
220 {
221   char *name = sym->name;
222   /* Extra 2 bytes are for changing "cpXXX" to "ibmXXX" and
223      terminating '\0'.  */
224   char *canon = (char *) alloca (strlen (name) + 2);
225   char *p = canon;
226
227   for (; *name; name++)
228     if (ISALNUM (*name))
229       *p++ = TOLOWER (*name);
230   *p = '\0';
231   if (p - canon > 3 && canon[0] == 'i')
232     {
233       if (canon[1] == 'b' && canon[2] == 'm' && isdigit (canon[3]))
234         {
235           /* Change "ibmXXX" to "cpXXX".  */
236           canon++;
237           canon[0] = 'c';
238           canon[1] = 'p';
239         }
240       else if (canon[1] == 's' && canon[2] == 'o')
241         {
242           /* Change "isoXXX" to "XXX".  */
243           canon += 3;
244         }
245     }
246   else if (p - canon > 2
247            && canon[0] == 'c' && canon[1] == 'p' && isdigit (canon[2]))
248     {
249       /* Change "cpXXX" to "ibmXXX".  */
250       for (; p >= canon + 2; p--)
251         p[1] = p[0];
252       canon[0] = 'i';
253       canon[1] = 'b';
254       canon[2] = 'm';
255     }
256
257   return msymbol (canon);
258 }
259
260 MTextPropSerializeFunc msymbol__serializer = serialize_symbol;
261 MTextPropDeserializeFunc msymbol__deserializer = deserialize_symbol;
262
263 /*** @} */
264 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
265
266 \f
267 /* External API */
268
269 /*** @addtogroup m17nSymbol */
270 /*** @{ */
271
272 /*=*/
273 /***en
274     @brief Symbol whose name is "nil".
275
276     The symbol #Mnil has the name <tt>"nil"</tt> and, in general,
277     represents @e false or @e no.  When coerced to "int", its value is
278     zero.  #Mnil can't have any symbol property.  */
279
280 /***oldja
281     @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mnil
282
283     ¥·¥ó¥Ü¥ë #Mnil ¤Ï <tt>"nil"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡×
284     ¤ò°ÕÌ£¤¹¤ë¡£#Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£  */
285
286 MSymbol Mnil;
287
288 /*=*/
289
290 /***en
291     @brief Symbol whose name is "t".
292
293     The symbol #Mt has the name <tt>"t"</tt> and, in general,
294     represents @e true or @e yes.  */
295
296 /***oldja
297     @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mt
298
299     ¥·¥ó¥Ü¥ë #Mt ¤Ï <tt>"t"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤ò°Õ
300     Ì£¤¹¤ë¡£  */
301
302 MSymbol Mt;
303
304 /*=*/
305
306 /***en
307     @brief Symbol whose name is "string".
308
309     The symbol #Mstring has the name <tt>"string"</tt> and is used
310     as an argument of the functions mchar_define_property (),
311     etc.  */
312
313 /***oldja
314     @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
315
316     ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mstring ¤Ï <tt>"string"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
317     ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
318
319 MSymbol Mstring;
320
321 /*=*/
322
323 /***en
324     @brief Symbol whose name is "symbol".
325
326     The symbol #Msymbol has the name <tt>"symbol"</tt> and is used
327     as an argument of the functions mchar_define_property (),
328     etc.  */
329
330 /***oldja
331     @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
332
333     ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï <tt>"symbol"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
334     ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
335
336 MSymbol Msymbol;
337
338 /*=*/
339
340 /***en
341     @brief Get a symbol.
342
343     The msymbol () function returns the canonical symbol whose name is
344     $NAME.  If there is none, one is created.  The created one is not
345     a managing key.
346
347     Symbols whose name starts by two spaces are reserved by the m17n
348     library, and are used by the library only internally.
349
350     @return
351     This function returns the found or created symbol.
352
353     @errors
354     This function never fails.  */
355
356 /***oldja
357     @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÊÖ¤¹
358
359     ´Ø¿ô msymbol () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥·
360     ¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¿·¤·¤¤¥·¥ó¥Ü¥ë¤¬¼«Æ°Åª¤Ëºî¤é¤ì¤ë¡£
361
362     @latexonly \IPAlabel{msymbol} @endlatexonly  */
363
364 /***
365     @seealso
366     msymbol_as_managing_key (), msymbol_name (), msymbol_exist ()  */
367
368 MSymbol
369 msymbol (const char *name)
370 {
371   MSymbol sym;
372   int len;
373   unsigned hash;
374
375   len = strlen (name);
376   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
377     return Mnil;
378   hash = hash_string (name, len);
379   len++;
380   for (sym = symbol_table[hash]; sym; sym = sym->next)
381     if (len == sym->length
382         && *name == *(sym->name)
383         && ! memcmp (name, sym->name, len))
384       return sym;
385
386   num_symbols++;
387   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
388   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
389   memcpy (sym->name, name, len);
390   sym->length = len;
391   sym->next = symbol_table[hash];
392   symbol_table[hash] = sym;
393   return sym;
394 }
395
396 /***en
397     @brief Create a managing key.
398
399     The msymbol_as_managing_key () function returns a newly created
400     managing key whose name is $NAME.  It there already exists a
401     symbol of name $NAME, it returns #Mnil.
402
403     Symbols whose name starts by two spaces are reserved by the m17n
404     library, and are used by the library only internally.
405
406     @return
407     If the operation was successful, this function returns the created
408     symbol.  Otherwise, it returns #Mnil.  */
409
410 /***
411     @errors
412     MERROR_SYMBOL
413
414     @seealso
415     msymbol (), msymbol_exist ()  */
416
417 MSymbol
418 msymbol_as_managing_key (const char *name)
419 {
420   MSymbol sym;
421   int len;
422   unsigned hash;
423
424   len = strlen (name);
425   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
426     MERROR (MERROR_SYMBOL, Mnil);
427   hash = hash_string (name, len);
428   len++;
429   for (sym = symbol_table[hash]; sym; sym = sym->next)
430     if (len == sym->length
431         && *name == *(sym->name)
432         && ! memcmp (name, sym->name, len))
433       MERROR (MERROR_SYMBOL, Mnil);
434
435   num_symbols++;
436   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
437   sym->managing_key = 1;
438   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
439   memcpy (sym->name, name, len);
440   sym->length = len;
441   sym->next = symbol_table[hash];
442   symbol_table[hash] = sym;
443   return sym;
444 }
445
446 /*=*/
447
448 /***en
449     @brief Search for a symbol that has a specified name.
450
451     The msymbol_exist () function searches for the symbol whose name
452     is $NAME.
453
454     @return
455     If such a symbol exists, msymbol_exist () returns that symbol.
456     Otherwise it returns the predefined symbol #Mnil.
457
458     @errors
459     This function never fails.  */
460
461 /***oldja
462     @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹
463
464     ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òõ¤¹¡£
465
466     @return
467     ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê
468     ¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mnil ¤òÊÖ¤¹¡£  */
469
470 /***@seealso
471     msymbol_name (), msymbol ()  */
472
473 MSymbol
474 msymbol_exist (const char *name)
475 {
476   MSymbol sym;
477   int len;
478   unsigned hash;
479
480   len = strlen (name);
481   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
482     return Mnil;
483   hash = hash_string (name, len);
484   len++;
485   for (sym = symbol_table[hash]; sym; sym = sym->next)
486     if (len == sym->length
487         && *name == *(sym->name)
488         && ! memcmp (name, sym->name, len))
489       return sym;
490   return Mnil;
491 }
492
493 /*=*/
494
495 /***en
496     @brief Get symbol name.
497
498     The msymbol_name () function returns a pointer to a string
499     containing the name of $SYMBOL.
500
501     @return
502     Name of the specified symbol.
503
504     @errors
505     This function never fails.  */
506 /***oldja
507     @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÊÖ¤¹
508
509     ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL ¤Î̾Á°¤òÊÖ¤¹¡£  */
510
511 /***@seealso
512     msymbol (), msymbol_exist ()  */
513
514 char *
515 msymbol_name (MSymbol symbol)
516 {
517   return (symbol == Mnil ? "nil" : symbol->name);
518 }
519
520 /*=*/
521 /***en
522     @brief Set the value of a symbol property.
523
524     The msymbol_put () function assigns $VAL to the value of the
525     symbol property that belongs to $SYMBOL and whose key is $KEY.  If
526     the symbol property already has a value, $VAL overwrites the old
527     one.  Both $SYMBOL and $KEY must not be #Mnil.
528
529     If $KEY is a managing key, $VAL must be a managed object.  In this
530     case, the reference count of the old value, if not @c NULL, is
531     decremented by one, and that of $VAL is incremented by one.
532
533     @return
534     If the operation was successful, msymbol_put () returns 0.
535     Otherwise it returns -1 and assigns an error code to the external
536     variable #merror_code.  */
537
538 /***oldja
539     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë
540
541     ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·
542     ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹
543     ¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£$SYMBOL, $KEY ¤È¤â´û¤ËÀ¸À®¤µ¤ì¤¿¥·¥ó¥Ü
544     ¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
545
546     @return
547     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤ò
548     ÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
549
550 /***
551     @errors
552     @c MERROR_SYMBOL
553
554     @seealso
555     msymbol_get () */
556
557 int
558 msymbol_put (MSymbol symbol, MSymbol key, void *val)
559 {
560   if (symbol == Mnil || key == Mnil)
561     MERROR (MERROR_SYMBOL, -1);
562   mplist_put (&symbol->plist, key, val);
563   return 0;
564 }
565
566 /*=*/
567
568 /***en
569     @brief Get the value of a symbol property.
570
571     The msymbol_get () function searches for the value of the symbol
572     property that belongs to $SYMBOL and whose key is $KEY.  If
573     $SYMBOL has such a symbol property, its value is returned.
574     Otherwise @c NULL is returned.
575
576
577     @return
578     If an error is detected, msymbol_get () returns @c NULL and
579     assigns an error code to the external variable #merror_code.  */
580
581 /***oldja
582     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòõ¤¹
583
584     ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
585     ¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
586     ¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß
587     ¤»¤º¡¢¤«¤Ä $KEY ¤ËÂФ¹¤ë¥×¥í¥Ð¥¤¥À´Ø¿ô¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤Î´Ø¿ô¤ò¸Æ¤ó
588     ¤Ç¤½¤ÎÌá¤êÃͤòÊÖ¤¹¡£³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â¥×¥í¥Ð¥¤¥À´Ø¿ô¤â¸
589     ºß¤·¤Ê¤¤¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c NULL ¤òÊÖ¤¹¡£
590
591     ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
592     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
593
594 /***
595     @errors
596     @c MERROR_SYMBOL
597
598     @seealso
599     msymbol_put () */
600
601 void *
602 msymbol_get (MSymbol symbol, MSymbol key)
603 {
604   MPlist *plist;
605
606   if (symbol == Mnil || key == Mnil)
607     return NULL;
608   plist = &symbol->plist;
609   MPLIST_FIND (plist, key);
610   return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
611 }
612
613 /*** @} */
614
615 #include <stdio.h>
616
617 /*** @addtogroup m17nDebug */
618 /*=*/
619 /*** @{ */
620
621 /***en
622     @brief Dump a symbol.
623
624     The mdebug_dump_symbol () function prints $SYMBOL in a human
625     readable way to the stderr.  $INDENT specifies how many columns to
626     indent the lines but the first one.
627
628     @return
629     This function returns $SYMBOL.
630
631     @errors
632     MERROR_DEBUG  */
633
634 MSymbol
635 mdebug_dump_symbol (MSymbol symbol, int indent)
636 {
637   char *prefix;
638   MPlist *plist;
639   char *name;
640
641   if (indent < 0)
642     MERROR (MERROR_DEBUG, Mnil);
643   prefix = (char *) alloca (indent + 1);
644   memset (prefix, 32, indent);
645   prefix[indent] = 0;
646
647   if (symbol == Mnil)
648     plist = NULL, name = "nil";
649   else
650     plist = &symbol->plist, name = symbol->name;
651
652   fprintf (stderr, "%s%s", prefix, name);
653   while (plist && MPLIST_KEY (plist) != Mnil)
654     {
655       fprintf (stderr, ":%s", MPLIST_KEY (plist)->name);
656       plist = MPLIST_NEXT (plist);
657     }
658   return symbol;
659 }
660
661 /***en
662     @brief Dump all symbol names.
663
664     The mdebug_dump_all_symbols () function prints names of all
665     symbols to the stderr.  $INDENT specifies how many columns to
666     indent the lines but the first one.
667
668     @return
669     This function returns #Mnil.
670
671     @errors
672     MERROR_DEBUG  */
673
674
675 MSymbol
676 mdebug_dump_all_symbols (int indent)
677 {
678   char *prefix;
679   int i;
680   MSymbol sym;
681
682   if (indent < 0)
683     MERROR (MERROR_DEBUG, Mnil);
684   prefix = (char *) alloca (indent + 1);
685   memset (prefix, 32, indent);
686   prefix[indent] = 0;
687
688   fprintf (stderr, "(symbol-list");
689   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
690     if ((sym = symbol_table[i]))
691       {
692         fprintf (stderr, "\n%s  (%4d", prefix, i);
693         for (; sym; sym = sym->next)
694           fprintf (stderr, " '%s'", sym->name);
695         fprintf (stderr, ")");
696       }
697   fprintf (stderr, ")");
698   return Mnil;
699 }
700
701 /*** @} */ 
702
703 /*
704   Local Variables:
705   coding: euc-japan
706   End:
707 */