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    Boston, MA 02110-1301 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
hash_string(const char * str,int len)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 *
serialize_symbol(void * val)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 *
deserialize_symbol(MPlist * plist)128 deserialize_symbol (MPlist *plist)
129 {
130   return (MPLIST_SYMBOL_P (plist) ? MPLIST_SYMBOL (plist) : Mnil);
131 }
132 
133 
134 /* Internal API */
135 
136 int
msymbol__init()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
msymbol__fini()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
msymbol__free_table()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
msymbol__with_len(const char * name,int len)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 *
msymbol__list(MSymbol prop)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
msymbol__canonicalize(MSymbol sym)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 
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
msymbol(const char * name)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
msymbol_as_managing_key(const char * name)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
msymbol_is_managing_key(MSymbol symbol)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
msymbol_exist(const char * name)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 *
msymbol_name(MSymbol symbol)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
msymbol_put(MSymbol symbol,MSymbol key,void * val)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 *
msymbol_get(MSymbol symbol,MSymbol key)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
msymbol_put_func(MSymbol symbol,MSymbol key,M17NFunc func)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
msymbol_get_func(MSymbol symbol,MSymbol key)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
mdebug_dump_symbol(MSymbol symbol,int indent)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
mdebug_dump_all_symbols(int indent)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 */
849