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