1 /* character.c -- character 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 m17nCharacter
25     @brief Character objects and API for them.
26 
27     The m17n library represents a @e character by a character code (an
28     integer).  The minimum character code is @c 0.  The maximum
29     character code is defined by the macro #MCHAR_MAX.  It is
30     assured that #MCHAR_MAX is not smaller than @c 0x3FFFFF (22
31     bits).
32 
33     Characters @c 0 to @c 0x10FFFF are equivalent to the Unicode
34     characters of the same code values.
35 
36     A character can have zero or more properties called @e character
37     @e properties.  A character property consists of a @e key and a
38     @e value, where key is a symbol and value is anything that can be
39     cast to <tt>(void *)</tt>.  "The character property that belongs
40     to character C and whose key is K" may be shortened to "the K
41     property of C".  */
42 
43 /***ja
44     @addtogroup m17nCharacter
45     @brief ʸ�����֥������ȤȤ���˴ؤ��� API.
46 
47     m17n �饤�֥��� @e ʸ�� ��ʸ�������ɡ������ˤ�ɽ�����롣
48     �Ǿ���ʸ�������ɤ� @c 0 �Ǥ��ꡢ�����ʸ�������ɤϥޥ��� #MCHAR_MAX
49     �ˤ�ä��������Ƥ��롣#MCHAR_MAX �� @c 0x3FFFFF��22�ӥåȡ�
50     �ʾ�Ǥ��뤳�Ȥ��ݾڤ���Ƥ��롣
51 
52     @c 0 ���� @c 0x10FFFF �ޤǤ�ʸ���ϡ������Ʊ���ͤ���� Unicode
53     ��ʸ���˳�����Ƥ��Ƥ��롣
54 
55     ��ʸ���� @e ʸ���ץ�ѥƥ� �ȸƤ֥ץ�ѥƥ��� 0 �İʾ���Ĥ��Ȥ��Ǥ��롣
56     ʸ���ץ�ѥƥ��� @e ���� �� @e �� ����ʤ롣
57     �����ϥ���ܥ�Ǥ��ꡢ�ͤ� <tt>(void *)</tt> ���˥��㥹�ȤǤ����Τʤ鲿�Ǥ�褤��
58     ��ʸ�� C ��ʸ���ץ�ѥƥ��Τ��������� K �Ǥ����Ρפ��ñ�ˡ�ʸ�� C
59     �� K �ץ�ѥƥ��פȸƤ֤��Ȥ����롣  */
60 /*=*/
61 
62 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
63 /*** @addtogroup m17nInternal
64      @{ */
65 
66 #include <config.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <limits.h>
70 #include <ctype.h>
71 #include <stdio.h>
72 
73 #include "m17n-core.h"
74 #include "m17n-misc.h"
75 #include "internal.h"
76 
77 typedef struct
78 {
79   MSymbol type;
80   void *mdb;
81   MCharTable *table;
82 } MCharPropRecord;
83 
84 static MPlist *char_prop_list;
85 
86 static void
free_string(int from,int to,void * str,void * arg)87 free_string (int from, int to, void *str, void *arg)
88 {
89   free (str);
90 }
91 
92 
93 /* Internal API */
94 
95 int
mchar__init()96 mchar__init ()
97 {
98   Mname = msymbol ("name");
99   Mcategory = msymbol ("category");
100   Mcombining_class = msymbol ("combining-class");
101   Mbidi_category = msymbol ("bidirectional-category");
102   Msimple_case_folding = msymbol ("simple-case-folding");
103   Mcomplicated_case_folding = msymbol ("complicated-case-folding");
104   Mcased = msymbol ("cased");
105   Msoft_dotted = msymbol ("soft-dotted");
106   Mcase_mapping = msymbol ("case-mapping");
107   Mblock = msymbol ("block");
108   Mscript = msymbol ("script");
109 
110   return 0;
111 }
112 
113 void
mchar__fini(void)114 mchar__fini (void)
115 {
116   MPlist *p;
117 
118   if (char_prop_list)
119     {
120       for (p = char_prop_list; mplist_key (p) != Mnil; p = mplist_next (p))
121 	{
122 	  MCharPropRecord *record = mplist_value (p);
123 
124 	  if (record->table)
125 	    {
126 	      if (record->type == Mstring)
127 		mchartable_map (record->table, NULL, free_string, NULL);
128 	      M17N_OBJECT_UNREF (record->table);
129 	    }
130 	  free (record);
131 	}
132       M17N_OBJECT_UNREF (char_prop_list);
133     }
134 }
135 
136 void
mchar__define_prop(MSymbol key,MSymbol type,void * mdb)137 mchar__define_prop (MSymbol key, MSymbol type, void *mdb)
138 {
139   MCharPropRecord *record;
140 
141   if (char_prop_list)
142     record = mplist_get (char_prop_list, key);
143   else
144     char_prop_list = mplist (), record = NULL;
145   if (record)
146     {
147       if (record->table)
148 	M17N_OBJECT_UNREF (record->table);
149     }
150   else
151     {
152       MSTRUCT_CALLOC (record, MERROR_CHAR);
153       mplist_put (char_prop_list, key, record);
154     }
155 
156   record->type = type;
157   record->mdb = mdb;
158   if (mdb)
159     {
160       record->table = NULL;
161     }
162   else
163     {
164       void *default_value = NULL;
165 
166       if (type == Minteger)
167 	default_value = (void *) -1;
168       record->table = mchartable (type, default_value);
169     }
170 }
171 
172 
173 /*** @} */
174 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
175 
176 /* External API */
177 
178 /*** @addtogroup m17nCharacter
179      @{ */
180 /*=*/
181 
182 #ifdef FOR_DOXYGEN
183 /***en
184     @brief Maximum character code.
185 
186     The macro #MCHAR_MAX gives the maximum character code.  */
187 
188 /***ja
189     @brief ʸ�������ɤκ�����.
190 
191     �ޥ��� #MCHAR_MAX ��ʸ�������ɤκ����ͤ�ɽ����  */
192 
193 #define MCHAR_MAX
194 /*=*/
195 #endif /* FOR_DOXYGEN */
196 
197 /***en
198     @name Variables: Keys of character properties
199 
200     These symbols are used as keys of character properties.  */
201 
202 /***ja
203     @ingroup m17nCharacter
204     @name �ѿ�: ʸ���ץ�ѥƥ��Υ���
205 
206     �����Υ���ܥ��ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣*/
207 
208 /*=*/
209 /*** @{ */
210 
211 /***en
212     @brief Key for script.
213 
214     The symbol #Mscript has the name <tt>"script"</tt> and is used as the key
215     of a character property.  The value of such a property is a symbol
216     representing the script to which the character belongs.
217 
218     Each symbol that represents a script has one of the names listed in
219     the <em>Unicode Technical Report #24</em>.  */
220 
221 /***ja
222     @brief ������ץȤ�ɽ�魯����.
223 
224     ����ܥ� #Mscript �� <tt>"script"</tt>
225     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
226     ���Υץ�ѥƥ����ͤϡ�����ʸ����°���륹����ץȤ�ɽ�魯����ܥ�Ǥ��롣
227 
228     ������ץȤ�ɽ�魯����ܥ��̾���ϡ�<em>Unicode Technical Report
229     #24</em> �˥ꥹ�Ȥ���Ƥ����ΤΤ����줫�Ǥ��롣  */
230 
231 MSymbol Mscript;
232 
233 /*=*/
234 
235 /***en
236     @brief Key for character name.
237 
238     The symbol #Mname has the name <tt>"name"</tt> and is used as
239     the key of a character property.  The value of such a property is a
240     C-string representing the name of the character.  */
241 
242 /***ja
243     @brief ̾����ɽ�魯����.
244 
245     ����ܥ� #Mname �� <tt>"name"</tt>
246     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
247     ���Υץ�ѥƥ����ͤϤ���ʸ����̾����ɽ�魯 C ��ʸ����Ǥ��롣  */
248 
249 MSymbol Mname;
250 
251 /*=*/
252 
253 /***en
254     @brief Key for general category.
255 
256     The symbol #Mcategory has the name <tt>"category"</tt> and is
257     used as the key of a character property.  The value of such a
258     property is a symbol representing the <em>general category</em> of
259     the character.
260 
261     Each symbol that represents a general category has one of the
262     names listed as abbreviations for <em>General Category</em> in
263     Unicode.  */
264 
265 /***ja
266     @brief ���̥��ƥ����ɽ�魯����.
267 
268     ����ܥ� #Mcategory �� <tt>"category"</tt>
269     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
270     ���Υץ�ѥƥ����ͤϡ��б����� <em>���̥��ƥ���</em> ��ɽ�魯����ܥ�Ǥ��롣
271 
272     ���̥��ƥ����ɽ�魯����ܥ��̾���ϡ�<em>General Category</em>
273     �ξ�ά���Ȥ��� Unicode ���������Ƥ����ΤǤ��롣  */
274 
275 MSymbol Mcategory;
276 
277 /*=*/
278 
279 /***en
280     @brief Key for canonical combining class.
281 
282     The symbol #Mcombining_class has the name
283     <tt>"combining-class"</tt> and is used as the key of a character
284     property.  The value of such a property is an integer that
285     represents the <em>canonical combining class</em> of the character.
286 
287     The meaning of each integer that represents a canonical combining
288     class is identical to the one defined in Unicode.  */
289 
290 /***ja
291     @brief ɸ���祯�饹��ɽ�魯����.
292 
293     ����ܥ� #Mcombining_class �� <tt>"combining-class"</tt>
294     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
295     ���Υץ�ѥƥ����ͤϡ��б����� @e ɸ���祯�饹 ��ɽ�魯�����Ǥ��롣
296 
297     ɸ���祯�饹��ɽ�魯�����ΰ�̣�ϡ�Unicode
298     ���������Ƥ����Τ�Ʊ���Ǥ��롣  */
299 
300 MSymbol Mcombining_class;
301 /*=*/
302 
303 /***en
304     @brief Key for bidi category.
305 
306     The symbol #Mbidi_category has the name <tt>"bidi-category"</tt>
307     and is used as the key of a character property.  The value of such
308     a property is a symbol that represents the <em>bidirectional
309     category</em> of the character.
310 
311     Each symbol that represents a bidirectional category has one of
312     the names listed as types of <em>Bidirectional Category</em> in
313     Unicode.  */
314 
315 /***ja
316     @brief ���������ƥ����ɽ�魯����.
317 
318     ����ܥ� #Mbidi_category �� <tt>"bidi-category"</tt>
319     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
320     ���Υץ�ѥƥ����ͤϡ��б����� @e ���������ƥ��� ��ɽ�魯����ܥ�Ǥ��롣
321 
322     ���������ƥ����ɽ�魯����ܥ��̾���ϡ�<em>Bidirectional
323     Category</em> �η��Ȥ��� Unicode ���������Ƥ����ΤǤ��롣  */
324 
325 MSymbol Mbidi_category;
326 /*=*/
327 
328 /***en
329     @brief Key for corresponding single lowercase character.
330 
331     The symbol #Msimple_case_folding has the name
332     <tt>"simple-case-folding"</tt> and is used as the key of a
333     character property.  The value of such a property is the
334     corresponding single lowercase character that is used when
335     comparing M-texts ignoring cases.
336 
337     If a character requires a complicated comparison (i.e. cannot be
338     compared by simply mapping to another single character), the value
339     of such a property is @c 0xFFFF.  In this case, the character has
340     another property whose key is #Mcomplicated_case_folding.  */
341 
342 /***ja
343     @brief �б����뾮ʸ����ʸ����ɽ�魯����.
344 
345     ����ܥ� #Msimple_case_folding �� <tt>"simple-case-folding"</tt>
346     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
347     ���Υץ�ѥƥ����ͤϡ��б����뾮ʸ����ʸ���Ǥ��ꡢ��ʸ������ʸ���ζ��̤�̵�뤷��ʸ������Ӥκݤ˻Ȥ��롣
348 
349     ʣ���������ˡ��ɬ�פȤ���ʸ���Ǥ��ä����
350     ���̤ΰ�ʸ�����б��դ��뤳�Ȥˤ�ä���ӤǤ��ʤ����ˡ����Υץ�ѥƥ����ͤ�
351     @c 0xFFFF �ˤʤ롣���ξ�礽��ʸ���ϡ�#Mcomplicated_case_folding
352     �Ȥ���������ʸ���ץ�ѥƥ�����ġ�  */
353 
354 MSymbol Msimple_case_folding;
355 /*=*/
356 
357 /***en
358     @brief Key for corresponding multiple lowercase characters.
359 
360     The symbol #Mcomplicated_case_folding has the name
361     <tt>"complicated-case-folding"</tt> and is used as the key of a
362     character property.  The value of such a property is the
363     corresponding M-text that contains a sequence of lowercase
364     characters to be used for comparing M-texts ignoring case.  */
365 
366 /***ja
367     @brief �б����뾮ʸ�������ɽ�魯����.
368 
369     ����ܥ� #Mcomplicated_case_folding ��
370     <tt>"complicated-case-folding"</tt>
371     �Ȥ���̾���������ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣
372     ���Υץ�ѥƥ����ͤϡ��б����뾮ʸ������ʤ� M-text �Ǥ��ꡢ��ʸ������ʸ���ζ��̤�̵�뤷��ʸ������Ӥκݤ˻�
373     ���롣
374       */
375 
376 MSymbol Mcomplicated_case_folding;
377 /*=*/
378 
379 /***en
380     @brief Key for values used in case operation.
381 
382     The symbol #Mcased has the name <tt>"cased"</tt> and is used as
383     the key of charater property.  The value of such a property is an
384     integer value 1, 2, or 3 representing "cased", "case-ignorable",
385     and both of them respective.  See the Unicode Standard 5.0
386     (Section 3.13 Default Case Algorithm) for the detail.
387  */
388 
389 /***ja
390     @brief Case �������Ѥ������ͤΥ���.
391 
392     ����ܥ� #Mcased �ϡ�<tt>"cased"</tt> �Ȥ���̾���������ʸ���ץ��
393     �ƥ��Υ����Ȥ��ƻȤ��롣���Υץ�ѥƥ����ͤ������� 1, 2, 3 �Τ���
394     �줫�Ǥ��ꡢ���줾�� "cased", "case-ignorable", ����ξ�����̣���롣
395     �ܺ٤ˤĤ��Ƥϡ�the Unicode Standard 5.0 (Section 3.13 Default
396     Case Algorithm) ���ȡ�
397  */
398 MSymbol Mcased;
399 
400 /*=*/
401 /***en
402     @brief Key for values used in case operation.
403 
404     The symbol #Msoft_dotted has the name <tt>"soft-dotted"</tt> and
405     is used as the key of charater property.  The value of such a
406     property is #Mt if a character has "Soft_Dotted" property, and
407     #Mnil otherwise.  See the Unicode Standard 5.0 (Section 3.13
408     Default Case Algorithm) for the detail.  */
409 
410 /***ja
411     @brief Case �������Ѥ������ͤΥ���.
412 
413     ����ܥ� #Msoft_dotted �ϡ�<tt>"soft-dotted"</tt> �Ȥ���̾���������
414     ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣���Υץ�ѥƥ����ͤϡ�ʸ����
415     "Soft_Dotted"�ץ�ѥƥ�����ľ��ˤ� #Mt, �����Ǥʤ���� #Mnil ��
416     ���롣 �ܺ٤ˤĤ��Ƥϡ�the Unicode Standard 5.0 (Section 3.13
417     Default Case Algorithm) ���ȡ�
418  */
419 MSymbol Msoft_dotted;
420 
421 /*=*/
422 /***en
423     @brief Key for values used in case operation.
424 
425     The symbol #Mcase_mapping has the name <tt>"case-mapping"</tt> and
426     is used as the key of charater property.  The value of such a
427     property is a plist of three M-Texts; lower, title, and upper of
428     the corresponding character.  See the Unicode Standard 5.0
429     (Section 5.18 Case Mappings) for the detail.  */
430 
431 /***ja
432     @brief Case �������Ѥ������ͤΥ���.
433 
434     ����ܥ� #Mcase_mapping �ϡ�<tt>"case-mapping"</tt> �Ȥ���̾�����
435     ����ʸ���ץ�ѥƥ��Υ����Ȥ��ƻȤ��롣���Υץ�ѥƥ����ͤϡ�����
436     �� M-text�����ʤ������ʸ���� lower, title, �� upper����ʤ� plist
437     �Ǥ��롣 �ܺ٤ˤĤ��Ƥϡ�the Unicode Standard 5.0 (Section 3.13
438     Default Case Algorithm) ���ȡ�
439 */
440 MSymbol Mcase_mapping;
441 
442 /*=*/
443 /***en
444     @brief Key for script block name.
445 
446     The symbol #Mblock the name <tt>"block"</tt> and is used as the
447     key of charater property.  The value of such a property is a
448     symbol representing a script block of the corresponding
449     character.  */
450 /***ja
451     @brief ������ץȥ֥�å�̾��ɽ������.
452 
453     ����ܥ� #Mblock �ϡ�<tt>"block"</tt> �Ȥ���̾��������ʸ���ץ��
454     �ƥ��Υ����Ȥ��ƻȤ��롣���Υץ�ѥƥ����ͤϡ�����ʸ���Υ������
455     �ȥ֥�å�̾��ɽ������ܥ�Ǥ��롣*/
456 MSymbol Mblock;
457 
458 /*** @} */
459 /*=*/
460 
461 /***en
462     @brief Define a character property.
463 
464     The mchar_define_property () function searches the m17n database
465     for a data whose tags are \<#Mchar_table, $TYPE, $SYM \>.
466     Here, $SYM is a symbol whose name is $NAME.  $TYPE must be
467     #Mstring, #Mtext, #Msymbol, #Minteger, or #Mplist.
468 
469     @return
470     If the operation was successful, mchar_define_property () returns
471     $SYM.  Otherwise it returns #Mnil.  */
472 
473 /***ja
474     @brief ʸ���ץ�ѥƥ����������.
475 
476     �ؿ� mchar_define_property () �ϡ� \<#Mchar_table, $TYPE, $SYM \>
477     �Ȥ�����������ä��ǡ����١����� m17n �������١�������õ����
478     ������ $SYM �� $NAME �Ȥ���̾���Υ���ܥ�Ǥ��롣$TYPE ��#Mstring,
479     #Mtext, #Msymbol, #Minteger, #Mplist �Τ����줫�Ǥʤ���Фʤ�ʤ���
480 
481     @return
482     ��������������� mchar_define_property () ��$SYM ���֤���
483     ���Ԥ������� #Mnil ���֤���  */
484 
485 /***
486     @errors
487     @c MERROR_DB
488 
489     @seealso
490     mchar_get_prop (), mchar_put_prop ()  */
491 
492 MSymbol
mchar_define_property(const char * name,MSymbol type)493 mchar_define_property (const char *name, MSymbol type)
494 {
495   MSymbol key = msymbol (name);
496   void *mdb;
497 
498   mdb = mdatabase_find (Mchar_table, type, key, Mnil);
499   if (! mdb)
500     return Mnil;
501   mchar__define_prop (key, type, mdb);
502   return key;
503 }
504 
505 /*=*/
506 
507 /***en
508     @brief Get the value of a character property.
509 
510     The mchar_get_prop () function searches character $C for the
511     character property whose key is $KEY.
512 
513     @return
514     If the operation was successful, mchar_get_prop () returns the
515     value of the character property.  Otherwise it returns @c
516     NULL.  */
517 
518 /***ja
519     @brief ʸ���ץ�ѥƥ����ͤ�����.
520 
521     �ؿ� mchar_get_prop () �ϡ�ʸ�� $C ��ʸ���ץ�ѥƥ��Τ���������
522     $KEY �Ǥ����Τ�õ����
523 
524     @return
525     ��������������� mchar_get_prop () �ϸ��Ĥ��ä��ץ�ѥƥ����ͤ��֤���
526     ���Ԥ������� @c NULL ���֤���
527 
528     @latexonly \IPAlabel{mchar_get_prop} @endlatexonly
529 */
530 /***
531     @errors
532     @c MERROR_SYMBOL, @c MERROR_DB
533 
534     @seealso
535     mchar_define_property (), mchar_put_prop ()  */
536 
537 void *
mchar_get_prop(int c,MSymbol key)538 mchar_get_prop (int c, MSymbol key)
539 {
540   MCharPropRecord *record;
541 
542   if (! char_prop_list)
543     return NULL;
544   record = mplist_get (char_prop_list, key);
545   if (! record)
546     return NULL;
547   if (record->mdb)
548     {
549       record->table = mdatabase_load (record->mdb);
550       if (! record->table)
551 	MERROR (MERROR_DB, NULL);
552       record->mdb = NULL;
553     }
554   return mchartable_lookup (record->table, c);
555 }
556 
557 /*=*/
558 
559 /***en
560     @brief Set the value of a character property.
561 
562     The mchar_put_prop () function searches character $C for the
563     character property whose key is $KEY and assigns $VAL to the value
564     of the found property.
565 
566     @return
567     If the operation was successful, mchar_put_prop () returns 0.
568     Otherwise, it returns -1.  */
569 /***ja
570     @brief ʸ���ץ�ѥƥ����ͤ����ꤹ��.
571 
572     �ؿ� mchar_put_prop () �ϡ�ʸ�� $C ��ʸ���ץ�ѥƥ��Τ��������� $KEY
573     �Ǥ����Τ�õ���������ͤȤ��� $VAL �����ꤹ�롣
574 
575     @return
576     ��������������� mchar_put_prop () ��0���֤������Ԥ�������-1���֤���  */
577 /***
578     @errors
579     @c MERROR_SYMBOL, @c MERROR_DB
580 
581     @seealso
582     mchar_define_property (), mchar_get_prop ()   */
583 
584 int
mchar_put_prop(int c,MSymbol key,void * val)585 mchar_put_prop (int c, MSymbol key, void *val)
586 {
587   MCharPropRecord *record;
588 
589   if (! char_prop_list)
590     MERROR (MERROR_CHAR, -1);
591   record = mplist_get (char_prop_list, key);
592   if (! record)
593     return -1;
594   if (record->mdb)
595     {
596       record->table = mdatabase_load (record->mdb);
597       if (! record->table)
598 	MERROR (MERROR_DB, -1);
599       record->mdb = NULL;
600     }
601   return mchartable_set (record->table, c, val);
602 }
603 
604 /*=*/
605 
606 /***en
607     @brief Get the char-table for a character property.
608 
609     The mchar_get_prop_table () function returns a char-table that
610     contains the character property whose key is $KEY.  If $TYPE is
611     not NULL, this function stores the type of the property in the
612     place pointed by $TYPE.  See mchar_define_property () for types of
613     character property.
614 
615     @return
616     If $KEY is a valid character property key, this function returns a
617     char-table.  Otherwise NULL is retuned.  */
618 
619 /***ja
620     @brief ʸ���ץ�ѥƥ���ʸ���ơ��֥������.
621 
622     �ؿ� mchar_get_prop_table () �ϡ������� $KEY �Ǥ���ʸ���ץ�ѥƥ�
623     ��ޤ�ʸ���ơ��֥���֤����⤷ $TYPE �� NULL �Ǥʤ���С� $TYPE ��
624     �ؤ������ˤ���ʸ���Υץ�ѥƥ����Ǽ���롣ʸ���ץ�ѥƥ��μ���
625     �˴ؤ��Ƥ� mchar_define_property () ���衣
626 
627     @return
628     �⤷ $KEY ��������ʸ���ץ�ѥƥ��Υ����Ǥ���С�ʸ���ơ��֥뤬�֤�
629     ��롣�����Ǥʤ����� NULL ���֤���롣  */
630 
631 MCharTable *
mchar_get_prop_table(MSymbol key,MSymbol * type)632 mchar_get_prop_table (MSymbol key, MSymbol *type)
633 {
634   MCharPropRecord *record;
635 
636   if (! char_prop_list)
637     return NULL;
638   record = mplist_get (char_prop_list, key);
639   if (! record)
640     return NULL;
641   if (record->mdb)
642     {
643       record->table = mdatabase_load (record->mdb);
644       if (! record->table)
645 	MERROR (MERROR_DB, NULL);
646       record->mdb = NULL;
647     }
648   if (type)
649     *type = record->type;
650   return record->table;
651 }
652 
653 /*** @} */
654 
655 /*
656   Local Variables:
657   coding: euc-japan
658   End:
659 */
660