*** 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
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 /***ja
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
164   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
165     for (sym = symbol_table[i]; sym; sym = sym->next)
166       if (! MPLIST_TAIL_P (&sym->plist))
167         {
168           if (sym->plist.key->managing_key)
169             M17N_OBJECT_UNREF (sym->plist.val);
170           M17N_OBJECT_UNREF (sym->plist.next);
171         }
172   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
173     for (sym = symbol_table[i]; sym; sym = next)
174       {
175         next = sym->next;
176         free (sym->name);
177         free (sym);
178       }
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 ÄêµÁºÑ¥·¥ó¥Ü¥ë Mnil
273
274     ¥·¥ó¥Ü¥ë #Mnil ¤Ï <tt>"nil"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡×
275     ¤ò°ÕÌ£¤¹¤ë¡£#Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£  */
276
277 MSymbol Mnil;
278
279 /*=*/
280
281 /***en
282     @brief Symbol whose name is "t".
283
284     The symbol #Mt has the name <tt>"t"</tt> and, in general,
285     represents @e true or @e yes.  */
286
287 /***ja
288     @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mt
289
290     ¥·¥ó¥Ü¥ë #Mt ¤Ï <tt>"t"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤ò°Õ
291     Ì£¤¹¤ë¡£  */
292
293 MSymbol Mt;
294
295 /*=*/
296
297 /***en
298     @brief Symbol whose name is "string".
299
300     The symbol #Mstring has the name <tt>"string"</tt> and is used
301     as an argument of the functions mchar_define_property (),
302     etc.  */
303
304 /***ja
305     @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
306
307     ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mstring ¤Ï <tt>"string"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
308     ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
309
310 MSymbol Mstring;
311
312 /*=*/
313
314 /***en
315     @brief Symbol whose name is "symbol".
316
317     The symbol #Msymbol has the name <tt>"symbol"</tt> and is used
318     as an argument of the functions mchar_define_property (),
319     etc.  */
320
321 /***ja
322     @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
323
324     ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï <tt>"symbol"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
325     ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
326
327 MSymbol Msymbol;
328
329 /*=*/
330
331 /***en
332     @brief Get a symbol.
333
334     The msymbol () function returns the canonical symbol whose name is
335     $NAME.  If there is none, one is created.  The created one is not
336     a managing key.
337
338     Symbols whose name starts by two spaces are reserved by the m17n
339     library, and are used by the library only internally.
340
341     @return
342     This function returns the found or created symbol.
343
344     @errors
345     This function never fails.  */
346
347 /***ja
348     @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÊÖ¤¹
349
350     ´Ø¿ô msymbol () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥·
351     ¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¿·¤·¤¤¥·¥ó¥Ü¥ë¤¬¼«Æ°Åª¤Ëºî¤é¤ì¤ë¡£
352
353     @latexonly \IPAlabel{msymbol} @endlatexonly  */
354
355 /***
356     @seealso
357     msymbol_as_managing_key (), msymbol_name (), msymbol_exist ()  */
358
359 MSymbol
360 msymbol (const char *name)
361 {
362   MSymbol sym;
363   int len;
364   unsigned hash;
365
366   len = strlen (name);
367   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
368     return Mnil;
369   hash = hash_string (name, len);
370   len++;
371   for (sym = symbol_table[hash]; sym; sym = sym->next)
372     if (len == sym->length
373         && *name == *(sym->name)
374         && ! memcmp (name, sym->name, len))
375       return sym;
376
377   num_symbols++;
378   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
379   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
380   memcpy (sym->name, name, len);
381   sym->length = len;
382   sym->next = symbol_table[hash];
383   symbol_table[hash] = sym;
384   return sym;
385 }
386
387 /***en
388     @brief Create a managing key.
389
390     The msymbol_as_managing_key () function returns a newly created
391     managing key whose name is $NAME.  It there already exists a
392     symbol of name $NAME, it returns #Mnil.
393
394     Symbols whose name starts by two spaces are reserved by the m17n
395     library, and are used by the library only internally.
396
397     @return
398     If the operation was successful, this function returns the created
399     symbol.  Otherwise, it returns #Mnil.  */
400
401 /***
402     @errors
403     MERROR_SYMBOL
404
405     @seealso
406     msymbol (), msymbol_exist ()  */
407
408 MSymbol
409 msymbol_as_managing_key (const char *name)
410 {
411   MSymbol sym;
412   int len;
413   unsigned hash;
414
415   len = strlen (name);
416   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
417     MERROR (MERROR_SYMBOL, Mnil);
418   hash = hash_string (name, len);
419   len++;
420   for (sym = symbol_table[hash]; sym; sym = sym->next)
421     if (len == sym->length
422         && *name == *(sym->name)
423         && ! memcmp (name, sym->name, len))
424       MERROR (MERROR_SYMBOL, Mnil);
425
426   num_symbols++;
427   MTABLE_CALLOC (sym, 1, MERROR_SYMBOL);
428   sym->managing_key = 1;
429   MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL);
430   memcpy (sym->name, name, len);
431   sym->length = len;
432   sym->next = symbol_table[hash];
433   symbol_table[hash] = sym;
434   return sym;
435 }
436
437 /*=*/
438
439 /***en
440     @brief Search for a symbol that has a specified name.
441
442     The msymbol_exist () function searches for the symbol whose name
443     is $NAME.
444
445     @return
446     If such a symbol exists, msymbol_exist () returns that symbol.
447     Otherwise it returns the predefined symbol #Mnil.
448
449     @errors
450     This function never fails.  */
451
452 /***ja
453     @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹
454
455     ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òõ¤¹¡£
456
457     @return
458     ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê
459     ¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mnil ¤òÊÖ¤¹¡£  */
460
461 /***@seealso
462     msymbol_name (), msymbol ()  */
463
464 MSymbol
465 msymbol_exist (const char *name)
466 {
467   MSymbol sym;
468   int len;
469   unsigned hash;
470
471   len = strlen (name);
472   if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l')
473     return Mnil;
474   hash = hash_string (name, len);
475   len++;
476   for (sym = symbol_table[hash]; sym; sym = sym->next)
477     if (len == sym->length
478         && *name == *(sym->name)
479         && ! memcmp (name, sym->name, len))
480       return sym;
481   return Mnil;
482 }
483
484 /*=*/
485
486 /***en
487     @brief Get symbol name.
488
489     The msymbol_name () function returns a pointer to a string
490     containing the name of $SYMBOL.
491
492     @return
493     Name of the specified symbol.
494
495     @errors
496     This function never fails.  */
497 /***ja
498     @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÊÖ¤¹
499
500     ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL ¤Î̾Á°¤òÊÖ¤¹¡£  */
501
502 /***@seealso
503     msymbol (), msymbol_exist ()  */
504
505 char *
506 msymbol_name (MSymbol symbol)
507 {
508   return (symbol == Mnil ? "nil" : symbol->name);
509 }
510
511 /*=*/
512 /***en
513     @brief Set the value of a symbol property.
514
515     The msymbol_put () function assigns $VAL to the value of the
516     symbol property that belongs to $SYMBOL and whose key is $KEY.  If
517     the symbol property already has a value, $VAL overwrites the old
518     one.  Both $SYMBOL and $KEY must not be #Mnil.
519
520     If $KEY is a managing key, $VAL must be a managed object.  In this
521     case, the reference count of the old value, if not @c NULL, is
522     decremented by one, and that of $VAL is incremented by one.
523
524     @return
525     If the operation was successful, msymbol_put () returns 0.
526     Otherwise it returns -1 and assigns an error code to the external
527     variable #merror_code.  */
528
529 /***ja
530     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë
531
532     ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥·
533     ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹
534     ¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£$SYMBOL, $KEY ¤È¤â´û¤ËÀ¸À®¤µ¤ì¤¿¥·¥ó¥Ü
535     ¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
536
537     @return
538     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤ò
539     ÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
540
541 /***
542     @errors
543     @c MERROR_SYMBOL
544
545     @seealso
546     msymbol_get () */
547
548 int
549 msymbol_put (MSymbol symbol, MSymbol key, void *val)
550 {
551   if (symbol == Mnil || key == Mnil)
552     MERROR (MERROR_SYMBOL, -1);
553   mplist_put (&symbol->plist, key, val);
554   return 0;
555 }
556
557 /*=*/
558
559 /***en
560     @brief Get the value of a symbol property.
561
562     The msymbol_get () function searches for the value of the symbol
563     property that belongs to $SYMBOL and whose key is $KEY.  If
564     $SYMBOL has such a symbol property, its value is returned.
565     Otherwise @c NULL is returned.
566
567
568     @return
569     If an error is detected, msymbol_get () returns @c NULL and
570     assigns an error code to the external variable #merror_code.  */
571
572 /***ja
573     @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòõ¤¹
574
575     ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
576     ¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£
577     ¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß
578     ¤»¤º¡¢¤«¤Ä $KEY ¤ËÂФ¹¤ë¥×¥í¥Ð¥¤¥À´Ø¿ô¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤Î´Ø¿ô¤ò¸Æ¤ó
579     ¤Ç¤½¤ÎÌá¤êÃͤòÊÖ¤¹¡£³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â¥×¥í¥Ð¥¤¥À´Ø¿ô¤â¸
580     ºß¤·¤Ê¤¤¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c NULL ¤òÊÖ¤¹¡£
581
582     ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
583     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
584
585 /***
586     @errors
587     @c MERROR_SYMBOL
588
589     @seealso
590     msymbol_put () */
591
592 void *
593 msymbol_get (MSymbol symbol, MSymbol key)
594 {
595   MPlist *plist;
596
597   if (symbol == Mnil || key == Mnil)
598     return NULL;
599   plist = &symbol->plist;
600   MPLIST_FIND (plist, key);
601   return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
602 }
603
604 /*** @} */
605
606 #include <stdio.h>
607
608 /*** @addtogroup m17nDebug */
609 /*=*/
610 /*** @{ */
611
612 /***en
613     @brief Dump a symbol.
614
615     The mdebug_dump_symbol () function prints $SYMBOL in a human
616     readable way to the stderr.  $INDENT specifies how many columns to
617     indent the lines but the first one.
618
619     @return
620     This function returns $SYMBOL.
621
622     @errors
623     MERROR_DEBUG  */
624
625 MSymbol
626 mdebug_dump_symbol (MSymbol symbol, int indent)
627 {
628   char *prefix;
629   MPlist *plist;
630   char *name;
631
632   if (indent < 0)
633     MERROR (MERROR_DEBUG, Mnil);
634   prefix = (char *) alloca (indent + 1);
635   memset (prefix, 32, indent);
636   prefix[indent] = 0;
637
638   if (symbol == Mnil)
639     plist = NULL, name = "nil";
640   else
641     plist = &symbol->plist, name = symbol->name;
642
643   fprintf (stderr, "%s%s", prefix, name);
644   while (plist && MPLIST_KEY (plist) != Mnil)
645     {
646       fprintf (stderr, ":%s", MPLIST_KEY (plist)->name);
647       plist = MPLIST_NEXT (plist);
648     }
649   return symbol;
650 }
651
652 /***en
653     @brief Dump all symbol names.
654
655     The mdebug_dump_all_symbols () function prints names of all
656     symbols to the stderr.  $INDENT specifies how many columns to
657     indent the lines but the first one.
658
659     @return
660     This function returns #Mnil.
661
662     @errors
663     MERROR_DEBUG  */
664
665
666 MSymbol
667 mdebug_dump_all_symbols (int indent)
668 {
669   char *prefix;
670   int i;
671   MSymbol sym;
672
673   if (indent < 0)
674     MERROR (MERROR_DEBUG, Mnil);
675   prefix = (char *) alloca (indent + 1);
676   memset (prefix, 32, indent);
677   prefix[indent] = 0;
678
679   fprintf (stderr, "(symbol-list");
680   for (i = 0; i < SYMBOL_TABLE_SIZE; i++)
681     if ((sym = symbol_table[i]))
682       {
683         fprintf (stderr, "\n%s  (%4d", prefix, i);
684         for (; sym; sym = sym->next)
685           fprintf (stderr, " '%s'", sym->name);
686         fprintf (stderr, ")");
687       }
688   fprintf (stderr, ")");
689   return Mnil;
690 }
691
692 /*** @} */ 
693
694 /*
695   Local Variables:
696   coding: euc-japan
697   End:
698 */