*** empty log message ***
[m17n/m17n-lib.git] / src / charset.c
1 /* charset.c -- charset 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 /***en
23     @addtogroup m17nCharset
24     @brief Charset objects and API for them.
25
26     The m17n library uses @e charset objects to represent a coded
27     character sets (CCS).  The m17n library supports many predefined
28     coded character sets.  Moreover, application programs can add
29     other charsets.  A character can belong to multiple charsets.
30
31     The m17n library distinguishes the following three concepts:
32
33     @li A @e code-point is a number assigned by the CCS to each
34     character.  Code-points may or may not be continuous.  The type
35     @c unsigned is used to represent a code-point.  An invalid
36     code-point is represented by the macro @c MCHAR_INVALID_CODE.
37
38     @li A @e character @e index is the canonical index of a character
39     in a CCS.  The character that has the character index N occupies
40     the Nth position when all the characters in the current CCS are
41     sorted by their code-points.  Character indices in a CCS are
42     continuous and start with 0.
43
44     @li A @e character @e code is the internal representation in the
45     m17n library of a character.  A character code is a signed integer
46     of 21 bits or longer.
47
48     Each charset object defines how characters are converted between
49     code-points and character codes.  To @e encode means converting
50     code-points to character codes and to @e decode means converting
51     character codes to code-points.  */
52
53 /***ja
54     @addtogroup m17nCharset
55     @brief Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
56
57     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢Éä¹æ²½Ê¸»ú½¸¹ç (CCS) ¤ò @e Ê¸»ú¥»¥Ã¥È 
58     ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤Çɽ¸½¤¹¤ë¡£
59     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¿¤¯¤ÎÉä¹æ²½Ê¸»ú½¸¹ç¤ò¤¢¤é¤«¤¸¤á¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤·¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤¬Æȼ«¤Ëʸ»ú¥»¥Ã¥È¤òÄɲ乤뤳¤È¤â²Äǽ¤Ç¤¢¤ë¡£
60     °ì¤Ä¤Îʸ»ú¤ÏÊ£¿ô¤Îʸ»ú¥»¥Ã¥È¤Ë°¤·¤Æ¤â¤è¤¤¡£
61
62     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢°Ê²¼¤Î³µÇ°¤ò¶èÊ̤·¤Æ¤¤¤ë:
63
64     @li @e ¥³¡¼¥É¥Ý¥¤¥ó¥È ¤È¤Ï¡¢CCS ¤¬¤½¤ÎÃæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤ÆÄêµÁ¤¹¤ë¿ôÃͤǤ¢¤ë¡£
65     ¥³¡¼¥É¥Ý¥¤¥ó¥È¤ÏϢ³¤·¤Æ¤¤¤ë¤È¤Ï¸Â¤é¤Ê¤¤¡£¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ï
66     @c unsigned ·¿¤Ë¤è¤Ã¤Æɽ¤µ¤ì¤ë¡£Ìµ¸ú¤Ê¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ï¥Þ¥¯¥í
67     @c MCHAR_INVALID_CODE ¤Çɽ¤µ¤ì¤ë¡£
68
69     @li @e Ê¸»ú¥¤¥ó¥Ç¥Ã¥¯¥¹ ¤È¤Ï¡¢CCS Æâ¤Ç³Æʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤ëÀµµ¬²½¤µ¤ì¤¿¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¢¤ë¡£
70     Ê¸»ú¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬ N ¤Îʸ»ú¤Ï¡¢CCS Ãæ¤ÎÁ´Ê¸»ú¤ò¥³¡¼¥É¥Ý¥¤¥ó¥È½ç¤Ëʤ٤¿¤È¤­¤Ë N ÈÖÌܤ˸½¤ï¤ì¤ë¡£
71     CCS Ãæ¤Îʸ»ú¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÏϢ³¤·¤Æ¤ª¤ê¡¢0 ¤«¤é»Ï¤Þ¤ë¡£
72
73     @li @e Ê¸»ú¥³¡¼¥É ¤È¤Ï¡¢m17n ¥é¥¤¥Ö¥é¥êÆâ¤Ë¤ª¤±¤ëʸ»ú¤ÎÆâÉôɽ¸½¤Ç¤¢¤ê¡¢21 ¥Ó¥Ã¥È°Ê¾å¤ÎŤµ¤ò»ý¤ÄÉä¹çÉÕ¤­À°¿ô¤Ç¤¢¤ë¡£
74
75     ³Æʸ»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ï¡¢¤½¤Îʸ»ú¥»¥Ã¥È¤Ë°¤¹¤ëʸ»ú¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥³¡¼¥É¤È¤Î´Ö¤ÎÊÑ´¹¤òµ¬Äꤹ¤ë¡£
76     ¥³¡¼¥É¥Ý¥¤¥ó¥È¤«¤éʸ»ú¥³¡¼¥É¤Ø¤ÎÊÑ´¹¤ò @e ¥Ç¥³¡¼¥É
77     ¤È¸Æ¤Ó¡¢Ê¸»ú¥³¡¼¥É¤«¤é¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ø¤ÎÊÑ´¹¤ò @e ¥¨¥ó¥³¡¼¥É ¤È¸Æ¤Ö¡£  */
78
79 /*=*/
80 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
81 /*** @addtogroup m17nInternal
82      @{ */
83
84 #include <config.h>
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #include <limits.h>
89
90 #include "m17n.h"
91 #include "m17n-misc.h"
92 #include "internal.h"
93 #include "symbol.h"
94 #include "charset.h"
95 #include "coding.h"
96 #include "chartab.h"
97 #include "plist.h"
98
99 static int unified_max;
100
101 /** List of all charsets ever defined.  */
102
103 struct MCharsetList
104 {
105   int size, inc, used;
106   MCharset **charsets;
107 };
108
109 static struct MCharsetList charset_list;
110
111 static MPlist *charset_definition_list;
112
113 /** Make a charset object from the template of MCharset structure
114     CHARSET, and return a pointer to the new charset object.
115     CHARSET->code_range[4N + 2] and CHARSET->code_range[4N + 3] are
116     not yet set.  */
117
118 static MCharset *
119 make_charset (MCharset *charset)
120 {
121   unsigned min_code, max_code;
122   int i, n;
123   int *range = charset->code_range;
124
125   if (charset->dimension < 1 || charset->dimension > 4)
126     MERROR (MERROR_CHARSET, NULL);
127   if ((charset->final_byte > 0 && charset->final_byte < '0')
128       || charset->final_byte > 127)
129     MERROR (MERROR_CHARSET, NULL);
130
131   for (i = 0, n = 1; i < 4; i++)
132     {
133       if (range[i * 4] > range[i * 4 + 1])
134         MERROR (MERROR_CHARSET, NULL);
135       range[i * 4 + 2] = range[i * 4 + 1] - range[i * 4] + 1;
136       n *= range[i * 4 + 2];
137       range[i * 4 + 3] = n;
138     }
139
140   min_code = range[0] | (range[4] << 8) | (range[8] << 16) | (range[12] << 24);
141   if (charset->min_code == 0)
142     charset->min_code = min_code;
143   else if (charset->min_code < min_code)
144     MERROR (MERROR_CHARSET, NULL);
145   max_code = range[1] | (range[5] << 8) | (range[9] << 16) | (range[13] << 24);
146   if (charset->max_code == 0)  
147     charset->max_code = max_code;
148   else if (charset->max_code > max_code)
149     MERROR (MERROR_CHARSET, NULL);
150
151   charset->code_range_min_code = min_code;
152   charset->fully_loaded = 0;
153   charset->simple = 0;
154
155   if (charset->method == Msubset)
156     {
157       MCharset *parent;
158
159       if (charset->nparents != 1)
160         MERROR (MERROR_CHARSET, NULL);
161       parent = charset->parents[0];
162       if (parent->method == Msuperset
163           || charset->min_code - charset->subset_offset < parent->min_code
164           || charset->max_code - charset->subset_offset > parent->max_code)
165         MERROR (MERROR_CHARSET, NULL);
166     }
167   else if (charset->method == Msuperset)
168     {
169       if (charset->nparents < 2)
170         MERROR (MERROR_CHARSET, NULL);
171       for (i = 0; i < charset->nparents; i++)
172         if (charset->min_code > charset->parents[i]->min_code
173             || charset->max_code < charset->parents[i]->max_code)
174           MERROR (MERROR_CHARSET, NULL);
175     }
176   else
177     {
178       charset->no_code_gap
179         = (charset->dimension == 1
180            || (range[2] == 256
181                && (charset->dimension == 2
182                    || (range[6] == 256
183                        && (charset->dimension == 3
184                            || range[10] == 256)))));
185
186       if (! charset->no_code_gap)
187         {
188           int j;
189
190           memset (charset->code_range_mask, 0,
191                   sizeof charset->code_range_mask);
192           for (i = 0; i < 4; i++)
193             for (j = range[i * 4]; j <= range[i * 4 + 1]; j++)
194               charset->code_range_mask[j] |= (1 << i);
195         }
196
197       if (charset->method == Moffset)
198         {
199           charset->max_char = charset->min_char + range[15] - 1;
200           if (charset->min_char < 0
201               || charset->max_char < 0 || charset->max_char > unified_max)
202             MERROR (MERROR_CHARSET, NULL);
203           charset->simple = charset->no_code_gap;
204           charset->fully_loaded = 1;
205         }
206       else if (charset->method == Munify)
207         {
208           /* The magic number 12 below is to align to the SUB_BITS_2
209              (defined in chartab.c) boundary in a char-table.  */
210           unified_max -= ((range[15] >> 12) + 1) << 12;
211           charset->unified_max = unified_max;
212         }
213       else if (charset->method != Mmap)
214         MERROR (MERROR_CHARSET, NULL);
215     }
216
217   MLIST_APPEND1 (&charset_list, charsets, charset, MERROR_CHARSET);
218
219   if (charset->final_byte > 0)
220     {
221       MLIST_APPEND1 (&mcharset__iso_2022_table, charsets, charset,
222                      MERROR_CHARSET);
223       if (charset->revision <= 0)
224         {
225           int chars = range[2];
226
227           if (chars == 128)     /* ASCII case */
228             chars = 94;
229           else if (chars == 256) /* ISO-8859-X case */
230             chars = 96;
231           MCHARSET_ISO_2022 (charset->dimension, chars, charset->final_byte)
232             = charset;
233         }
234     }
235
236   return charset;
237 }
238
239 static int
240 load_charset_fully (MCharset *charset)
241 {
242   if (charset->method == Msubset)
243     {
244       MCharset *parent = charset->parents[0];
245
246       if (! parent->fully_loaded
247           && load_charset_fully (parent) < 0)
248         MERROR (MERROR_CHARSET, -1);
249       if (parent->method == Moffset)
250         {
251           unsigned code;
252
253           code = charset->min_code - charset->subset_offset;
254           charset->min_char = DECODE_CHAR (parent, code);
255           code = charset->max_code - charset->subset_offset;
256           charset->max_char = DECODE_CHAR (parent, code);
257         }
258       else
259         {
260           unsigned min_code = charset->min_code - charset->subset_offset;
261           unsigned max_code = charset->max_code - charset->subset_offset;
262           int min_char = DECODE_CHAR (parent, min_code);
263           int max_char = min_char;
264           
265           for (++min_code; min_code <= max_code; min_code++)
266             {
267               int c = DECODE_CHAR (parent, min_code);
268
269               if (c >= 0)
270                 {
271                   if (c < min_char)
272                     min_char = c;
273                   else if (c > max_char)
274                     max_char = c;
275                 }
276             }
277           charset->min_char = min_char;
278           charset->max_char = max_char;
279         }
280     }
281   else if (charset->method == Msuperset)
282     {
283       int min_char = 0, max_char = 0;
284       int i;
285
286       for (i = 0; i < charset->nparents; i++)
287         {
288           MCharset *parent = charset->parents[i];
289
290           if (! parent->fully_loaded
291               && load_charset_fully (parent) < 0)
292             MERROR (MERROR_CHARSET, -1);
293           if (i == 0)
294             min_char = parent->min_char, max_char = parent->max_char;
295           else if (parent->min_char < min_char)
296             min_char = parent->min_char;
297           else if (parent->max_char > max_char)
298             max_char = parent->max_char;
299         }
300       charset->min_char = min_char;
301       charset->max_char = max_char;
302     }
303   else                          /* charset->method is Mmap or Munify */
304     {
305       MDatabase *mdb = mdatabase_find (Mcharset, charset->name, Mnil, Mnil);
306       MPlist *plist;
307
308       if (! mdb || ! (plist = mdatabase_load (mdb)))
309         MERROR (MERROR_CHARSET, -1);
310       charset->decoder = mplist_value (plist);
311       charset->encoder = mplist_value (mplist_next (plist));
312       M17N_OBJECT_UNREF (plist);
313       mchartable_range (charset->encoder,
314                         &charset->min_char, &charset->max_char);
315       if (charset->method == Mmap)
316         charset->simple = charset->no_code_gap;
317       else
318         charset->max_char = charset->unified_max + 1 + charset->code_range[15];
319     }
320
321   charset->fully_loaded = 1;
322   return 0;
323 }
324
325 \f
326 /* Internal API */
327
328 MPlist *mcharset__cache;
329
330 /* Predefined charsets.  */
331 MCharset *mcharset__ascii;
332 MCharset *mcharset__binary;
333 MCharset *mcharset__m17n;
334 MCharset *mcharset__unicode;
335
336 MCharsetISO2022Table mcharset__iso_2022_table;
337
338 /** Initialize charset handler.  */
339
340 int
341 mcharset__init ()
342 {
343   MPlist *param, *pl;
344
345   unified_max = MCHAR_MAX;
346
347   mcharset__cache = mplist ();
348   mplist_set (mcharset__cache, Mt, NULL);
349
350   MLIST_INIT1 (&charset_list, charsets, 128);
351   MLIST_INIT1 (&mcharset__iso_2022_table, charsets, 128);
352   charset_definition_list = mplist ();
353
354   memset (mcharset__iso_2022_table.classified, 0,
355           sizeof (mcharset__iso_2022_table.classified));
356
357   Mcharset = msymbol ("charset");
358
359   Mmethod = msymbol ("method");
360   Moffset = msymbol ("offset");
361   Mmap = msymbol ("map");
362   Munify = msymbol ("unify");
363   Msubset = msymbol ("subset");
364   Msuperset = msymbol ("superset");
365
366   Mdimension = msymbol ("dimension");
367   Mmin_range = msymbol ("min-range");
368   Mmax_range = msymbol ("max-range");
369   Mmin_code = msymbol ("min-code");
370   Mmax_code = msymbol ("max-code");
371   Mascii_compatible = msymbol ("ascii-compatible");
372   Mfinal_byte = msymbol ("final-byte");
373   Mrevision = msymbol ("revision");
374   Mmin_char = msymbol ("min-char");
375   Mmapfile = msymbol_as_managing_key ("mapfile");
376   Mparents = msymbol_as_managing_key ("parents");
377   Msubset_offset = msymbol ("subset-offset");
378   Mdefine_coding = msymbol ("define-coding");
379   Maliases = msymbol_as_managing_key ("aliases");
380
381   param = mplist ();
382   pl = param;
383   /* Setup predefined charsets.  */
384   pl = mplist_add (pl, Mmethod, Moffset);
385   pl = mplist_add (pl, Mmin_range, (void *) 0);
386   pl = mplist_add (pl, Mmax_range, (void *) 0x7F);
387   pl = mplist_add (pl, Mascii_compatible, Mt);
388   pl = mplist_add (pl, Mfinal_byte, (void *) 'B');
389   pl = mplist_add (pl, Mmin_char, (void *) 0);
390   Mcharset_ascii = mchar_define_charset ("ascii", param);
391
392   mplist_put (param, Mmax_range, (void *) 0xFF);
393   mplist_put (param, Mfinal_byte, NULL);
394   Mcharset_iso_8859_1 = mchar_define_charset ("iso-8859-1", param);
395
396   mplist_put (param, Mmax_range, (void *) 0x10FFFF);
397   Mcharset_unicode = mchar_define_charset ("unicode", param);
398
399   mplist_put (param, Mmax_range, (void *) MCHAR_MAX);
400   Mcharset_m17n = mchar_define_charset ("m17n", param);
401
402   mplist_put (param, Mmax_range, (void *) 0xFF);
403   Mcharset_binary = mchar_define_charset ("binary", param);
404
405   M17N_OBJECT_UNREF (param);
406
407   mcharset__ascii = MCHARSET (Mcharset_ascii);
408   mcharset__binary = MCHARSET (Mcharset_binary);
409   mcharset__m17n = MCHARSET (Mcharset_m17n);
410   mcharset__unicode = MCHARSET (Mcharset_unicode);
411
412   return 0;
413 }
414
415 void
416 mcharset__fini (void)
417 {
418   int i;
419   MPlist *plist;
420
421   for (i = 0; i < charset_list.used; i++)
422     {
423       MCharset *charset = charset_list.charsets[i];
424
425       if (charset->decoder)
426         free (charset->decoder);
427       if (charset->encoder)
428         M17N_OBJECT_UNREF (charset->encoder);
429       free (charset);
430     }
431   M17N_OBJECT_UNREF (mcharset__cache);
432   MLIST_FREE1 (&charset_list, charsets);
433   MLIST_FREE1 (&mcharset__iso_2022_table, charsets);
434   MPLIST_DO (plist, charset_definition_list)
435     M17N_OBJECT_UNREF (MPLIST_VAL (plist));
436   M17N_OBJECT_UNREF (charset_definition_list);
437 }
438
439
440 MCharset *
441 mcharset__find (MSymbol name)
442 {
443   MCharset *charset;
444
445   charset = msymbol_get (name, Mcharset);
446   if (! charset)
447     {
448       MPlist *param = mplist_get (charset_definition_list, name);
449
450       MPLIST_KEY (mcharset__cache) = Mt;
451       if (! param)
452         return NULL;
453       param = mplist__from_plist (param);
454       mchar_define_charset (MSYMBOL_NAME (name), param);
455       charset = msymbol_get (name, Mcharset);
456       M17N_OBJECT_UNREF (param);
457     }
458   MPLIST_KEY (mcharset__cache) = name;
459   MPLIST_VAL (mcharset__cache) = charset;
460   return charset;
461 }
462
463
464 /** Return the character corresponding to code-point CODE in CHARSET.
465     If CODE is invalid for CHARSET, return -1.  */
466
467 int
468 mcharset__decode_char (MCharset *charset, unsigned code)
469 {
470   int idx;
471
472   if (code < 128 && charset->ascii_compatible)
473     return (int) code;
474   if (code < charset->min_code || code > charset->max_code)
475     return -1;
476
477   if (! charset->fully_loaded
478       && load_charset_fully (charset) < 0)
479     MERROR (MERROR_CHARSET, -1);
480
481   if (charset->method == Msubset)
482     {
483       MCharset *parent = charset->parents[0];
484
485       code -= charset->subset_offset;
486       return DECODE_CHAR (parent, code);
487     }
488
489   if (charset->method == Msuperset)
490     {
491       int i;
492
493       for (i = 0; i < charset->nparents; i++)
494         {
495           MCharset *parent = charset->parents[i];
496           int c = DECODE_CHAR (parent, code);
497
498           if (c >= 0)
499             return c;
500         }
501       return -1;
502     }
503
504   idx = CODE_POINT_TO_INDEX (charset, code);
505   if (idx < 0)
506     return -1;
507
508   if (charset->method == Mmap)
509     return charset->decoder[idx];
510
511   if (charset->method == Munify)
512     {
513       int c = charset->decoder[idx];
514
515       if (c < 0)
516         c = charset->unified_max + 1 + idx;
517       return c;
518     }
519
520   /* Now charset->method should be Moffset.  */
521   return (charset->min_char + idx);
522 }
523
524
525 /** Return the code point of character C in CHARSET.  If CHARSET does not
526     contain C, return MCHAR_INVALID_CODE.  */
527
528 unsigned
529 mcharset__encode_char (MCharset *charset, int c)
530 {
531   if (! charset->fully_loaded
532       && load_charset_fully (charset) < 0)
533     MERROR (MERROR_CHARSET, MCHAR_INVALID_CODE);
534
535   if (charset->method == Msubset)
536     {
537       MCharset *parent = charset->parents[0];
538       unsigned code = ENCODE_CHAR (parent, c);
539
540       if (code == MCHAR_INVALID_CODE)
541         return code;
542       code += charset->subset_offset;
543       if (code >= charset->min_code && code <= charset->max_code)
544         return code;
545       return MCHAR_INVALID_CODE;
546     }
547
548   if (charset->method == Msuperset)
549     {
550       int i;
551
552       for (i = 0; i < charset->nparents; i++)
553         {
554           MCharset *parent = charset->parents[i];
555           unsigned code = ENCODE_CHAR (parent, c);
556
557           if (code != MCHAR_INVALID_CODE)
558             return code;
559         }
560       return MCHAR_INVALID_CODE;
561     }
562
563   if (c < charset->min_char || c > charset->max_char)
564     return MCHAR_INVALID_CODE;
565
566   if (charset->method == Mmap)
567     return (unsigned) mchartable_lookup (charset->encoder, c);
568
569   if (charset->method == Munify)
570     {
571       if (c > charset->unified_max)
572         {
573           c -= charset->unified_max - 1;
574           return INDEX_TO_CODE_POINT (charset, c);
575         }
576       return (unsigned) mchartable_lookup (charset->encoder, c);
577     }
578
579   /* Now charset->method should be Moffset */
580   c -= charset->min_char;
581   return INDEX_TO_CODE_POINT (charset, c);
582 }
583
584 int
585 mcharset__load_from_database ()
586 {
587   MDatabase *mdb = mdatabase_find (msymbol ("charset-list"), Mnil, Mnil, Mnil);
588   MPlist *def_list, *plist;
589   MPlist *definitions = charset_definition_list;
590   int mdebug_mask = MDEBUG_CHARSET;
591
592   if (! mdb)
593     return 0;
594   MDEBUG_PUSH_TIME ();
595   def_list = (MPlist *) mdatabase_load (mdb);
596   MDEBUG_PRINT_TIME ("CHARSET", (stderr, " to load data."));
597   MDEBUG_POP_TIME ();
598   if (! def_list)
599     return -1;
600
601   MDEBUG_PUSH_TIME ();
602   MPLIST_DO (plist, def_list)
603     {
604       MPlist *pl, *p;
605       MSymbol name;
606
607       if (! MPLIST_PLIST_P (plist))
608         MERROR (MERROR_CHARSET, -1);
609       pl = MPLIST_PLIST (plist);
610       if (! MPLIST_SYMBOL_P (pl))
611         MERROR (MERROR_CHARSET, -1);
612       name = MPLIST_SYMBOL (pl);
613       pl = MPLIST_NEXT (pl);
614       definitions = mplist_add (definitions, name, pl);
615       M17N_OBJECT_REF (pl);
616       p = mplist__from_plist (pl);
617       mchar_define_charset (MSYMBOL_NAME (name), p);
618       M17N_OBJECT_UNREF (p);
619     }
620
621   M17N_OBJECT_UNREF (def_list);
622   MDEBUG_PRINT_TIME ("CHARSET", (stderr, " to parse the loaded data."));
623   MDEBUG_POP_TIME ();
624   return 0;
625 }
626
627 /*** @} */
628 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
629
630 \f
631 /* External API */
632
633 /*** @addtogroup m17nCharset */
634 /*** @{ */
635 /*=*/
636
637 #ifdef FOR_DOXYGEN
638 /***en
639     @brief Invalid code-point.
640
641     The macro #MCHAR_INVALID_CODE gives the invalid code-point.  */
642
643 /***ja
644     @brief Ìµ¸ú¤Ê¥³¡¼¥É¥Ý¥¤¥ó¥È.
645
646     ¥Þ¥¯¥í #MCHAR_INVALID_CODE ¤Ï̵¸ú¤Ê¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¼¨¤¹¡£  */
647
648 #define MCHAR_INVALID_CODE
649 #endif
650 /*=*/
651 /***en
652     @brief The symbol @c Mcharset.
653
654     Any decoded M-text has a text property whose key is the predefined
655     symbol @c Mcharset.  The name of @c Mcharset is
656     <tt>"charset"</tt>.  */
657
658 /***ja
659     @brief ¥·¥ó¥Ü¥ë @c Mcharset.
660
661     ¥Ç¥³¡¼¥É¤µ¤ì¤¿ M-text ¤Ï¡¢¥­¡¼¤¬ @c Mcharset
662     ¤Ç¤¢¤ë¤è¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡£
663     ¥·¥ó¥Ü¥ë @c Mcharset ¤Ï <tt>"charset"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£  */
664
665 MSymbol Mcharset;
666 /*=*/
667
668 /***en
669     @name Variables: Symbols representing a charset.
670
671     Each of the following symbols represents a predefined charset.  */
672
673 /***ja
674     @name ÊÑ¿ô: Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
675
676     °Ê²¼¤Î³Æ¥·¥ó¥Ü¥ë¤Ï¡¢ÄêµÁºÑ¤ßʸ»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£  */
677 /*=*/
678 /*** @{ */
679 /*=*/
680 /***en
681     @brief Symbol representing the charset ASCII.
682
683     The symbol #Mcharset_ascii has name <tt>"ascii"</tt> and represents
684     the charset ISO 646, USA Version X3.4-1968 (ISO-IR-6).  */
685 /***ja
686     @brief ASCII Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¥·¥ó¥Ü¥ë.
687
688     ¥·¥ó¥Ü¥ë #Mcharset_ascii ¤Ï <tt>"ascii"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ 
689     ISO 646, USA Version X3.4-1968 (ISO-IR-6) Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£
690      */
691
692 MSymbol Mcharset_ascii;
693
694 /*=*/
695 /***en
696     @brief Symbol representing the charset ISO/IEC 8859/1.
697
698     The symbol #Mcharset_iso_8859_1 has name <tt>"iso-8859-1"</tt>
699     and represents the charset ISO/IEC 8859-1:1998.  */
700 /***ja
701     @brief ISO/IEC 8859-1:1998 Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¥·¥ó¥Ü¥ë.
702
703     ¥·¥ó¥Ü¥ë #Mcharset_iso_8859_1 ¤Ï <tt>"iso-8859-1"</tt> 
704     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ISO/IEC 8859-1:1998 Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£
705     */
706
707 MSymbol Mcharset_iso_8859_1;
708
709 /***en
710     @brief Symbol representing the charset Unicode.
711
712     The symbol #Mcharset_unicode has name <tt>"unicode"</tt> and
713     represents the charset Unicode.  */
714 /***ja
715     @brief Unicode Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¥·¥ó¥Ü¥ë.
716
717     ¥·¥ó¥Ü¥ë #Mcharset_unicode ¤Ï <tt>"unicode"</tt> 
718     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Unicode Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£ */
719
720 MSymbol Mcharset_unicode;
721
722 /*=*/
723 /***en
724     @brief Symbol representing the largest charset.
725
726     The symbol #Mcharset_m17n has name <tt>"m17n"</tt> and
727     represents the charset that contains all characters supported by
728     the m17n library.  */ 
729 /***ja
730     @brief Á´Ê¸»ú¤ò´Þ¤àʸ»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¥·¥ó¥Ü¥ë.
731
732     ¥·¥ó¥Ü¥ë #Mcharset_m17n ¤Ï <tt>"m17n"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
733     m17n ¥é¥¤¥Ö¥é¥ê¤¬°·¤¦Á´¤Æ¤Îʸ»ú¤ò´Þ¤àʸ»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£ */
734
735 MSymbol Mcharset_m17n;
736
737 /*=*/
738 /***en
739     @brief Symbol representing the charset for ill-decoded characters.
740
741     The symbol #Mcharset_binary has name <tt>"binary"</tt> and
742     represents the fake charset which the decoding functions put to an
743     M-text as a text property when they encounter an invalid byte
744     (sequence).  
745
746     See @ref m17nConv for more details.  */
747
748 /***ja
749     @brief Àµ¤·¤¯¥Ç¥³¡¼¥É¤Ç¤­¤Ê¤¤Ê¸»ú¤Îʸ»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¥·¥ó¥Ü¥ë.
750
751     ¥·¥ó¥Ü¥ë #Mcharset_binary ¤Ï <tt>"binary"</tt> 
752     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢µ¶¤Î (fake) Ê¸»ú¥»¥Ã¥È¤òɽ¸½¤¹¤ë¡£
753     ¥Ç¥³¡¼¥É´Ø¿ô¤Ï¡¢M-text ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤È¤·¤Æ¡¢Ìµ¸ú¤Ê¥Ð¥¤¥È¡Ê¥·¡¼¥¯¥¨¥ó¥¹¡Ë¤ËÁø¶ø¤·¤¿°ÌÃÖ¤òÉղ乤롣
754
755      ¾ÜºÙ¤Ï @ref m17nConv »²¾È¤Î¤³¤È¡£ */
756
757 MSymbol Mcharset_binary;
758
759 /*=*/
760 /*** @} */
761 /*=*/
762
763 /***en
764     @name Variables: Parameter keys for mchar_define_charset ().
765
766     These are the predefined symbols to use as parameter keys for the
767     function mchar_define_charset () (which see).  */
768
769 /***ja
770     @name ÊÑ¿ô: mchar_define_charset ÍѤΥѥé¥á¡¼¥¿¡¦¥­¡¼
771
772     ¤³¤ì¤é¤Ï¡¢´Ø¿ô mchar_define_charset () ÍѤΥѥé¥á¡¼¥¿¡¦¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ 
773     ¾Ü¤·¤¯¤Ï¤³¤Î´Ø¿ô¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡£*/
774 /*** @{ */
775 /*=*/
776
777 /***en
778     Parameter key for mchar_define_charset () (which see). */ 
779
780 /***ja
781     ´Ø¿ô mchar_define_charset () ÍѤΥѥé¥á¡¼¥¿¡¦¥­¡¼. 
782     ¾Ü¤·¤¯¤Ï¤³¤Î´Ø¿ô¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡£*/ 
783
784 MSymbol Mmethod;
785 MSymbol Mdimension;
786 MSymbol Mmin_range;
787 MSymbol Mmax_range;
788 MSymbol Mmin_code;
789 MSymbol Mmax_code;
790 MSymbol Mascii_compatible;
791 MSymbol Mfinal_byte;
792 MSymbol Mrevision;
793 MSymbol Mmin_char;
794 MSymbol Mmapfile;
795 MSymbol Mparents;
796 MSymbol Msubset_offset;
797 MSymbol Mdefine_coding;
798 MSymbol Maliases;
799 /*=*/
800 /*** @} */
801 /*=*/
802
803 /***en
804     @name Variables: Symbols representing charset methods.
805
806     These are the predefined symbols that can be a value of the
807     #Mmethod parameter of a charset used in an argument to the
808     mchar_define_charset () function.
809
810     A method specifies how code-points and character codes are
811     converted.  See the documentation of the mchar_define_charset ()
812     function for the details.  */
813
814 /***ja
815     @name ÊÑ¿ô: Ê¸»ú¥»¥Ã¥È¤Î¥á¥½¥Ã¥É»ØÄê¤Ë»È¤ï¤ì¤ë¥·¥ó¥Ü¥ë
816
817     ¤³¤ì¤é¤Ï¡¢Ê¸»ú¥»¥Ã¥È¤Î @e ¥á¥½¥Ã¥É ¤ò»ØÄꤹ¤ë¤¿¤á¤ÎÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ê¸»ú¥»¥Ã¥È¤Î
818     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤʤ뤳¤È¤¬¤Ç¤­¤ë¡£
819     ¤³¤ÎÃͤϴؿô mchar_define_charset () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
820
821     ¥á¥½¥Ã¥É¤È¤Ï¡¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥³¡¼¥É¤òÁê¸ßÊÑ´¹¤¹¤ëºÝ¤ÎÊý¼°¤Î¤³¤È¤Ç¤¢¤ë¡£
822     ¾Ü¤·¤¯¤Ï´Ø¿ô mchar_define_charset () ¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡£  */
823 /*** @{ */
824 /*=*/
825 /***en
826     @brief Symbol for the offset type method of charset.
827
828     The symbol #Moffset has the name <tt>"offset"</tt> and, when used
829     as a value of #Mmethod parameter of a charset, it means that the
830     conversion of code-points and character codes of the charset is
831     done by this calculation:
832
833 @verbatim
834 CHARACTER-CODE = CODE-POINT - MIN-CODE + MIN-CHAR
835 @endverbatim
836
837     where, MIN-CODE is a value of #Mmin_code parameter of the charset,
838     and MIN-CHAR is a value of #Mmin_char parameter.  */
839
840 /***ja
841     @brief ¥ª¥Õ¥»¥Ã¥È·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë.
842
843     ¥·¥ó¥Ü¥ë #Moffset ¤Ï <tt>"offset"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥»¥Ã¥È¤Î
844     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥»¥Ã¥È¤Îʸ»ú¥³¡¼¥É¤Î´Ö¤ÎÊÑ´¹¤¬°Ê²¼¤Î¼°¤Ë½¾¤Ã¤Æ¹Ô¤ï¤ì¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
845
846 @verbatim
847 ʸ»ú¥³¡¼¥É = ¥³¡¼¥É¥Ý¥¤¥ó¥È - MIN-CODE + MIN-CHAR
848 @endverbatim
849
850     ¤³¤³¤Ç¡¢MIN-CODE ¤Ïʸ»ú¥»¥Ã¥È¤Î #Mmin_code ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤǤ¢¤ê¡¢MIN-CHAR ¤Ï
851     #Mmin_char ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤǤ¢¤ë¡£ */
852
853 MSymbol Moffset;
854 /*=*/
855
856 /***en @brief Symbol for the map type method of charset.
857
858     The symbol #Mmap has the name <tt>"map"</tt> and, when used as a
859     value of #Mmethod parameter of a charset, it means that the
860     conversion of code-points and character codes of the charset is
861     done by map looking up.  The map must be given by #Mmapfile
862     parameter.  */
863
864 /***ja @brief ¥Þ¥Ã¥×·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë.
865
866     ¥·¥ó¥Ü¥ë #Mmap ¤Ï <tt>"map"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥»¥Ã¥È¤Î 
867     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥»¥Ã¥È¤Îʸ»ú¥³¡¼¥É¤Î´Ö¤ÎÊÑ´¹¤¬¥Þ¥Ã¥×¤ò»²¾È¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¹Ô¤ï¤ì¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
868     ¥Þ¥Ã¥×¤Ï #Mmapfile ¥Ñ¥é¥á¡¼¥¿¤È¤·¤ÆÍ¿¤¨¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
869
870 MSymbol Mmap;
871 /*=*/
872
873 /***en @brief Symbol for the unify type method of charset.
874
875     The symbol #Munify has the name <tt>"unify"</tt> and, when used as
876     a value of #Mmethod parameter of a charset, it means that the
877     conversion of code-points and character codes of the charset is
878     done by map looking up and offsetting.  The map must be given by
879     #Mmapfile parameter.  For this kind of charset, a unique
880     continuous character code space for all characters is assigned.
881
882     If the map has an entry for a code-point, the conversion is done
883     by looking up the map.  Otherwise, the conversion is done by this
884     calculation:
885
886 @verbatim
887 CHARACTER-CODE = CODE-POINT - MIN-CODE + LOWEST-CHAR-CODE
888 @endverbatim
889
890     where, MIN-CODE is a value of #Mmin_code parameter of the charset,
891     and LOWEST-CHAR-CODE is the lowest character code of the assigned
892     code space.  */
893
894 /***ja @brief ¥æ¥Ë¥Õ¥¡¥¤·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë.
895
896     ¥·¥ó¥Ü¥ë #Minherit ¤Ï <tt>"unify"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥»¥Ã¥È¤Î 
897     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥»¥Ã¥È¤Îʸ»ú¥³¡¼¥É¤Î´Ö¤ÎÊÑ´¹¤¬¡¢¥Þ¥Ã¥×¤Î»²¾È¤È¥ª¥Õ¥»¥Ã¥È¤ÎÁȤ߹ç¤ï¤»¤Ë¤è¤Ã¤Æ¹Ô¤ï¤ì¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
898     ¥Þ¥Ã¥×¤Ï #Mmapfile ¥Ñ¥é¥á¡¼¥¿¤È¤·¤ÆÍ¿¤¨¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
899     ¤³¤Î¼ï¤Î³Æʸ»ú¥»¥Ã¥È¤Ë¤Ï¡¢Á´Ê¸»ú¤ËÂФ·¤ÆϢ³¤¹¤ë¥³¡¼¥É¥¹¥Ú¡¼¥¹¤¬¤½¤ì¤¾¤ì³ä¤êÅö¤Æ¤é¤ì¤ë¡£
900
901     ¥³¡¼¥É¥Ý¥¤¥ó¥È¤¬¥Þ¥Ã¥×¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ì¤Ð¡¢ÊÑ´¹¤Ï¥Þ¥Ã¥×»²¾È¤Ë¤è¤Ã¤Æ¹Ô¤ï¤ì¤ë¡£
902     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢°Ê²¼¤Î¼°¤Ë½¾¤¦¡£
903
904 @verbatim
905 CHARACTER-CODE = CODE-POINT - MIN-CODE + LOWEST-CHAR-CODE
906 @endverbatim
907     
908     ¤³¤³¤Ç¡¢MIN-CODE ¤Ïʸ»ú¥»¥Ã¥È¤Î #Mmin_code ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤǤ¢¤ê¡¢
909     LOWEST-CHAR-CODE ¤Ï³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥É¥¹¥Ú¡¼¥¹¤ÎºÇ¤â¾®¤µ¤¤Ê¸»ú¥³¡¼¥É¤Ç¤¢¤ë¡£
910     */
911
912 MSymbol Munify;
913 /*=*/
914
915 /***en
916     @brief Symbol for the subset type method of charset.
917
918     The symbol #Msubset has the name <tt>"subset"</tt> and, when used
919     as a value of #Mmethod parameter of a charset, it means that the
920     charset is a subset of a parent charset.  The parent charset must
921     be given by #Mparents parameter.  The conversion of code-points
922     and character codes of the charset is done conceptually by this
923     calculation:
924
925 @verbatim
926 CHARACTER-CODE = PARENT-CODE (CODE-POINT) + SUBSET-OFFSET
927 @endverbatim
928
929     where, PARENT-CODE is a pseudo function that returns a character
930     code of CODE-POINT in the parent charset, and SUBSET-OFFSET is a
931     value given by #Msubset_offset parameter.  */
932
933 /***ja @brief ¥µ¥Ö¥»¥Ã¥È·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë.
934
935     ¥·¥ó¥Ü¥ë #Msubset ¤Ï <tt>"subset"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥»¥Ã¥È¤Î
936     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢¤³¤Îʸ»ú¥»¥Ã¥È¤¬Ê̤Îʸ»ú¥»¥Ã¥È¡Ê¿Æʸ»ú¥»¥Ã¥È¡Ë¤ÎÉôʬ½¸¹ç¤Ç¤¢¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
937     ¿Æʸ»ú¥»¥Ã¥È¤Ï #Mparents ¥Ñ¥é¥á¡¼¥¿¤Ë¤è¤Ã¤ÆÍ¿¤¨¤é¤ì¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
938     ¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥»¥Ã¥È¤Îʸ»ú¥³¡¼¥É¤Î´Ö¤ÎÊÑ´¹¤Ï¡¢³µÇ°Åª¤Ë¤Ï°Ê²¼¤Î¼°¤Ë½¾¤¦¡£
939
940 @verbatim
941 CHARACTER-CODE = PARENT-CODE (CODE-POINT) + SUBSET-OFFSET
942 @endverbatim
943
944     ¤³¤³¤Ç PARENT-CODE ¤Ï CODE-POINT 
945     ¤Î¿Æʸ»ú¥»¥Ã¥ÈÃæ¤Ç¤Îʸ»ú¥³¡¼¥É¤òÊÖ¤¹µ¼´Ø¿ô¤Ç¤¢¤ê¡¢SUBSET-OFFSET ¤Ï 
946     #Msubset_offset ¥Ñ¥é¥á¡¼¥¿¤ÇÍ¿¤¨¤é¤ì¤ëÃͤǤ¢¤ë¡£
947     */
948
949 MSymbol Msubset;
950 /*=*/
951
952 /***en
953     @brief Symbol for the superset type method of charset.
954
955     The symbol #Msuperset has the name <tt>"superset"</tt> and, when
956     used as a value of #Mmethod parameter of a charset, it means that
957     the charset is a superset of parent charsets.  The parent charsets
958     must be given by #Mparents parameter.  */
959
960 /***ja
961     @brief ¥¹¡¼¥Ñ¡¼¥»¥Ã¥È·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë.
962
963     ¥·¥ó¥Ü¥ë #Msuperset ¤Ï <tt>"superset"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥»¥Ã¥È¤Î
964     #Mmethod ¥Ñ¥é¥á¡¼¥¿¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢¤³¤Îʸ»ú¥»¥Ã¥È¤¬Ê̤Îʸ»ú¥»¥Ã¥È¡Ê¿Æʸ»ú¥»¥Ã¥È¡Ë¤Î¾å°Ì½¸¹ç¤Ç¤¢¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
965     ¿Æʸ»ú¥»¥Ã¥È¤Ï #Mparents ¥Ñ¥é¥á¡¼¥¿¤Ë¤è¤Ã¤ÆÍ¿¤¨¤é¤ì¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
966     */
967
968 MSymbol Msuperset;
969 /*=*/
970 /*** @}  */ 
971
972 /***en
973     @brief Define a charset.
974
975     The mchar_define_charset () function defines a new charset and
976     makes it accessible via a symbol whose name is $NAME.  $PLIST
977     specifies parameters of the charset as below:
978
979     <ul>
980
981     <li> Key is #Mmethod, value is a symbol.
982
983     The value specifies the method for decoding/encoding code-points
984     in the charset.  It must be #Moffset, #Mmap (default), #Munify,
985     #Msubset, or #Msuperset.
986
987     <li> Key is #Mdimension, value is an integer
988
989     The value specifies the dimension of code-points of the charset.
990     It must be 1 (default), 2, 3, or 4.
991
992     <li> Key is #Mmin_range, value is an unsigned integer
993
994     The value specifies the minimum range of a code-point, which means
995     that the Nth byte of the value is the minimum Nth byte of
996     code-points of the charset.   The default value is 0.
997
998     <li> Key is #Mmax_range, value is an unsigned integer
999
1000     The value specifies the maximum range of a code-point, which means
1001     that the Nth byte of the value is the maximum Nth byte of
1002     code-points of the charset.  The default value is 0xFF, 0xFFFF,
1003     0xFFFFFF, or 0xFFFFFFFF if the dimension is 1, 2, 3, or 4
1004     respectively.
1005
1006     <li> Key is #Mmin_code, value is an unsigned integer
1007
1008     The value specifies the minimum code-point of
1009     the charset.  The default value is the minimum range.
1010
1011     <li> Key is #Mmax_code, value is an unsigned integer
1012
1013     The value specifies the maximum code-point of
1014     the charset.  The default value is the maximum range.
1015
1016     <li> Key is #Mascii_compatible, value is a symbol
1017
1018     The value specifies whether the charset is ASCII compatible or
1019     not.  If the value is #Mnil (default), it is not ASCII
1020     compatible, else compatible.
1021
1022     <li> Key is #Mfinal_byte, value is an integer
1023
1024     The value specifies the @e final @e byte of the charset registered
1025     in The International Registry.  It must be 0 (default) or 32..127.
1026     The value 0 means that the charset is not in the registry.
1027
1028     <li> Key is #Mrevision, value is an integer
1029
1030     The value specifies the @e revision @e number of the charset
1031     registered in The International Registry.  It must be 0..127.  If
1032     the charset is not in The International Registry, the value is
1033     ignored.  The value 0 means that the charset has no revision
1034     number.
1035
1036     <li> Key is #Mmin_char, value is an integer
1037
1038     The value specifies the minimum character code of the charset.
1039     The default value is 0.
1040
1041     <li> Key is #Mmapfile, value is an M-text
1042
1043     If the method is #Mmap or #Munify, a data that contains
1044     mapping information is added to the m17n database by calling
1045     the function mdatabase_define () with the value as an argument $EXTRA_INFO,
1046     i.e. the value is used as a file name of the data.
1047
1048     Otherwise, this parameter is ignored.
1049
1050     <li> Key is #Mparents, value is a plist
1051
1052     If the method is #Msubset, the value must is a plist of length
1053     1, and the value of the plist must be a symbol representing a
1054     parent charset.
1055
1056     If the method is #Msuperset, the value must be a plist of length
1057     less than 9, and the values of the plist must be symbols
1058     representing subset charsets.
1059
1060     Otherwise, this parameter is ignored.
1061
1062     <li> Key is #Mdefine_coding, value is a symbol
1063
1064     If the dimension of the charset is 1, the value specifies whether
1065     or not to define a coding system of the same name whose type is
1066     #Mcharset.  A coding system is defined if the value is not #Mnil.
1067
1068     Otherwise, this parameter is ignored.
1069
1070     </ul>
1071
1072     @return
1073     If the operation was successful, mchar_define_charset () returns a
1074     symbol whose name is $NAME.  Otherwise it returns #Mnil and
1075     assigns an error code to the external variable #merror_code.  */
1076
1077 /***ja
1078     @brief Ê¸»ú¥»¥Ã¥È¤òÄêµÁ¤¹¤ë.
1079
1080     ´Ø¿ô mchar_define_charset () ¤Ï¿·¤·¤¤Ê¸»ú¥»¥Ã¥È¤òÄêµÁ¤·¡¢¤½¤ì¤ò 
1081     $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë·Ðͳ¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¡£
1082     $PLIST ¤ÏÄêµÁ¤µ¤ì¤ëʸ»ú¥»¥Ã¥È¤Î¥Ñ¥é¥á¡¼¥¿¤ò°Ê²¼¤Î¤è¤¦¤Ë»ØÄꤹ¤ë¡£
1083
1084     <ul>
1085
1086     <li> ¥­¡¼¤¬ #Mmethod ¤ÇÃͤ¬¥·¥ó¥Ü¥ë¤Î»þ
1087
1088     Ãͤϡ¢#Moffset, #Mmap (¥Ç¥Õ¥©¥ë¥ÈÃÍ), #Munify, #Msubset,
1089     #Msuperset ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢Ê¸»ú¥»¥Ã¥È¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¥Ç¥³¡¼¥É¡¿¥¨¥ó¥³¡¼¥É¤¹¤ëºÝ¤Î¥á¥½¥Ã¥É¤ò»ØÄꤹ¤ë¡£
1090
1091     <li> ¥­¡¼¤¬ #Mdimension ¤ÇÃͤ¬À°¿ôÃͤλþ
1092
1093     Ãͤϡ¢1 (¥Ç¥Õ¥©¥ë¥ÈÃÍ), 2, 3, 4 
1094     ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢Ê¸»ú¥»¥Ã¥È¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î¼¡¸µ¤Ç¤¢¤ë¡£
1095
1096     <li> ¥­¡¼¤¬ #Mmin_range ¤ÇÃͤ¬ÈóÉéÀ°¿ôÃͤλþ
1097
1098     Ãͤϥ³¡¼¥É¥Ý¥¤¥ó¥È¤ÎºÇ¾®¤ÎÃͤǤ¢¤ë¡£¤¹¤Ê¤ï¤Á¡¢¤³¤ÎÃͤΠN 
1099     ÈÖÌܤΥХ¤¥È¤Ï¤³¤Îʸ»ú¥»¥Ã¥È¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î N ÈÖÌܤΥХ¤¥È¤ÎºÇ¾®¤Î¤â¤Î¤È¤Ê¤ë¡£
1100     ¥Ç¥Õ¥©¥ë¥ÈÃͤϠ0 ¡£
1101
1102     <li> ¥­¡¼¤¬ #Mmax_range ¤ÇÃͤ¬ÈóÉéÀ°¿ôÃͤλþ
1103
1104     Ãͤϥ³¡¼¥É¥Ý¥¤¥ó¥È¤ÎºÇÂç¤ÎÃͤǤ¢¤ë¡£¤¹¤Ê¤ï¤Á¡¢¤³¤ÎÃͤΠN 
1105     ÈÖÌܤΥХ¤¥È¤Ï¤³¤Îʸ»ú¥»¥Ã¥È¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î N ÈÖÌܤΥХ¤¥È¤ÎºÇÂç¤Î¤â¤Î¤È¤Ê¤ë¡£
1106     ¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î¼¡¸µ¤¬ 1, 2, 3, 4 ¤Î»þ¡¢¤½¤ì¤¾¤ì
1107     0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF ¡£
1108
1109     <li> ¥­¡¼¤¬ #Mmin_code ¤ÇÃͤ¬ÈóÉéÀ°¿ôÃͤλþ
1110
1111     ÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤ÎºÇ¾®¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϠ
1112     #Mmin_range ¤ÎÃÍ¡£
1113
1114     <li> ¥­¡¼¤¬ #Mmax_code ¤ÇÃͤ¬ÈóÉéÀ°¿ôÃͤλþ
1115
1116     ÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤ÎºÇÂç¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϠ
1117     #Mmax_range ¤ÎÃÍ¡£
1118
1119     <li> ¥­¡¼¤¬  #Mascii_compatible ¤ÇÃͤ¬¥·¥ó¥Ü¥ë¤Î»þ
1120
1121     ÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤¬ ASCII ¸ß´¹¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò¼¨¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÎ
1122     #Mnil ¤Ç¤¢¤ì¤Ð¸ß´¹¤Ç¤Ï¤Ê¤¯¡¢¤½¤ì°Ê³°¤Î¾ì¹ç¤Ï¸ß´¹¤Ç¤¢¤ë¡£
1123
1124     <li> ¥­¡¼¤¬  #Mfinal_byte ¤ÇÃͤ¬À°¿ôÃͤλþ
1125
1126     ÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤Î The International Registry ¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë 
1127     @e ½ªÃ¼¥Ð¥¤¥È ¤Ç¤¢¤ê¡¢0 (¥Ç¥Õ¥©¥ë¥ÈÃÍ) ¤Ç¤¢¤ë¤« 32..127 ¤Ç¤¢¤ë¡£0 
1128     ¤ÏÅÐÏ¿¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1129
1130     <li> ¥­¡¼¤¬  #Mrevision ¤ÇÃͤ¬À°¿ôÃͤλþ
1131
1132     ÃͤϠThe International Registry ¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë @e revision @e
1133     number ¤Ç¤¢¤ê¡¢0..127 ¤Ç¤¢¤ë¡£
1134     Ê¸»ú¥»¥Ã¥È¤¬ÅÐÏ¿¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¤³¤ÎÃͤÏ̵»ë¤µ¤ì¤ë¡£
1135     0 ¤Ï revision number ¤¬Â¸ºß¤·¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1136
1137     <li> ¥­¡¼¤¬  #Mmin_char ¤ÇÃͤ¬À°¿ôÃͤλþ
1138
1139     ÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤ÎºÇ¾®¤Îʸ»ú¥³¡¼¥É¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϠ0 ¡£
1140
1141     <li> ¥­¡¼¤¬ #Mmapfile ¤ÇÃͤ¬ M-text ¤Î»þ
1142
1143     ¥á¥½¥Ã¥É¤¬ #Mmap ¤« #Munify ¤Î»þ¡¢´Ø¿ô mdatabase_define () 
1144     ¤ò¤³¤ÎÃͤò°ú¿ô $EXTRA_INFO ¤È¤·¤Æ¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤Æ¡¢¥Þ¥Ã¥Ô¥ó¥°¤Ë´Ø¤¹¤ë¥Ç¡¼¥¿¤¬
1145     m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÄɲ䵤ì¤ë¡£
1146     ¤¹¤Ê¤ï¤Á¡¢¤³¤ÎÃͤϥǡ¼¥¿¥Õ¥¡¥¤¥ë¤Î̾Á°¤Ç¤¢¤ë¡£
1147
1148     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï̵»ë¤µ¤ì¤ë¡£
1149
1150     <li> ¥­¡¼¤¬ #Mparents ¤ÇÃͤ¬ plist ¤Î»þ
1151
1152     ¥á¥½¥Ã¥É¤¬ #Msubset ¤Ê¤é¤Ð¡¢ÃͤÏŤµ 1 ¤Î plist 
1153     ¤Ç¤¢¤ê¡¢¤½¤ÎÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤Î¾å°Ì½¸¹ç¤È¤Ê¤ëʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1154
1155     ¥á¥½¥Ã¥É¤¬ #Msuperset ¤Ê¤é¤Ð¡¢ÃͤÏŤµ 8 °Ê²¼¤Î plist 
1156     ¤Ç¤¢¤ê¡¢¤½¤ì¤é¤ÎÃͤϤ³¤Îʸ»ú¥»¥Ã¥È¤Î²¼°Ì½¸¹ç¤Ç¤¢¤ëʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1157
1158     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï̵»ë¤µ¤ì¤ë¡£
1159
1160     <li> ¥­¡¼¤¬  #Mdefine_coding ¤ÇÃͤ¬¥·¥ó¥Ü¥ë¤Î»þ
1161
1162     Ê¸»ú¥»¥Ã¥È¤Î¼¡¸µ¤¬ 1 ¤Ê¤é¤Ð¡¢Ãͤ¬ #Mnil °Ê³°¤Î¾ì¹ç¤Ë #Mcharset ·¿
1163     ¤ÇƱ¤¸Ì¾Á°¤ò»ý¤Ä¥³¡¼¥É·Ï¤òÄêµÁ¤¹¤ë¡£
1164
1165     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï̵»ë¤µ¤ì¤ë¡£
1166
1167     </ul>
1168
1169     @return 
1170     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_define_charset() ¤Ï $NAME 
1171     ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #Mnil ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1172     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£*/
1173
1174 /***
1175     @errors
1176     @c MERROR_CHARSET  */
1177
1178 MSymbol
1179 mchar_define_charset (const char *name, MPlist *plist)
1180 {
1181   MSymbol sym = msymbol (name);
1182   MCharset *charset;
1183   int i;
1184   unsigned min_range, max_range;
1185   MPlist *pl;
1186   MText *mapfile = (MText *) mplist_get (plist, Mmapfile);
1187
1188   MSTRUCT_CALLOC (charset, MERROR_CHARSET);
1189   charset->name = sym;
1190   charset->method = (MSymbol) mplist_get (plist, Mmethod);
1191   if (! charset->method)
1192     {
1193       if (mapfile)
1194         charset->method = Mmap;
1195       else
1196         charset->method = Moffset;
1197     }
1198   if (charset->method == Mmap || charset->method == Munify)
1199     {
1200       if (! mapfile)
1201         MERROR (MERROR_CHARSET, Mnil);
1202       mdatabase_define (Mcharset, sym, Mnil, Mnil, NULL, mapfile->data);
1203     }
1204   if (! (charset->dimension = (int) mplist_get (plist, Mdimension)))
1205     charset->dimension = 1;
1206
1207   min_range = (unsigned) mplist_get (plist, Mmin_range);
1208   if ((pl = mplist_find_by_key (plist, Mmax_range)))
1209     {
1210       max_range = (unsigned) MPLIST_VAL (pl);
1211       if (max_range >= 0x1000000)
1212         charset->dimension = 4;
1213       else if (max_range >= 0x10000 && charset->dimension < 3)
1214         charset->dimension = 3;
1215       else if (max_range >= 0x100 && charset->dimension < 2)
1216         charset->dimension = 2;
1217     }
1218   else if (charset->dimension == 1)
1219     max_range = 0xFF;
1220   else if (charset->dimension == 2)
1221     max_range = 0xFFFF;
1222   else if (charset->dimension == 3)
1223     max_range = 0xFFFFFF;
1224   else
1225     max_range = 0xFFFFFFFF;
1226
1227   memset (charset->code_range, 0, sizeof charset->code_range);
1228   for (i = 0; i < charset->dimension; i++, min_range >>= 8, max_range >>= 8)
1229     {
1230       charset->code_range[i * 4] = min_range & 0xFF;
1231       charset->code_range[i * 4 + 1] = max_range & 0xFF;
1232     }
1233   if ((charset->min_code = (int) mplist_get (plist, Mmin_code)) < min_range)
1234     charset->min_code = min_range;
1235   if ((charset->max_code = (int) mplist_get (plist, Mmax_code)) > max_range)
1236     charset->max_code = max_range;
1237   charset->ascii_compatible
1238     = (MSymbol) mplist_get (plist, Mascii_compatible) != Mnil;
1239   charset->final_byte = (int) mplist_get (plist, Mfinal_byte);
1240   charset->revision = (int) mplist_get (plist, Mrevision);
1241   charset->min_char = (int) mplist_get (plist, Mmin_char);
1242   pl = (MPlist *) mplist_get (plist, Mparents);
1243   charset->nparents = pl ? mplist_length (pl) : 0;
1244   if (charset->nparents > 8)
1245     charset->nparents = 8;
1246   for (i = 0; i < charset->nparents; i++, pl = MPLIST_NEXT (pl))
1247     {
1248       MSymbol parent_name;
1249
1250       if (MPLIST_KEY (pl) != Msymbol)
1251         MERROR (MERROR_CHARSET, Mnil);
1252       parent_name = MPLIST_SYMBOL (pl);
1253       if (! (charset->parents[i] = MCHARSET (parent_name)))
1254         MERROR (MERROR_CHARSET, Mnil);
1255     }
1256
1257   charset->subset_offset = (int) mplist_get (plist, Msubset_offset);
1258
1259   msymbol_put (sym, Mcharset, charset);
1260   charset = make_charset (charset);
1261   if (! charset)
1262     return Mnil;
1263   msymbol_put (msymbol__canonicalize (sym), Mcharset, charset);
1264
1265   for (pl = (MPlist *) mplist_get (plist, Maliases);
1266        pl && MPLIST_KEY (pl) == Msymbol;
1267        pl = MPLIST_NEXT (pl))
1268     {
1269       MSymbol alias = MPLIST_SYMBOL (pl);
1270
1271       msymbol_put (alias, Mcharset, charset);
1272       msymbol_put (msymbol__canonicalize (alias), Mcharset, charset);
1273     }
1274
1275   if (mplist_get (plist, Mdefine_coding)
1276       && charset->dimension == 1
1277       && charset->code_range[0] == 0 && charset->code_range[1] == 255)
1278     mconv__register_charset_coding (sym);
1279   return (sym);
1280 }
1281
1282 /*=*/
1283
1284 /***en
1285     @brief Resolve charset name.
1286
1287     The mchar_resolve_charset () function returns $SYMBOL if it
1288     represents a charset.  Otherwise, canonicalize $SYMBOL as to a
1289     charset name, and if the canonicalized name represents a charset,
1290     return it.  Otherwise, return #Mnil.  */
1291
1292 /***ja
1293     @brief Ê¸»ú¥»¥Ã¥È̾¤ò²ò·è¤¹¤ë.
1294
1295     ´Ø¿ô mchar_resolve_charset () ¤Ï $SYMBOL 
1296     ¤¬Ê¸»ú¥»¥Ã¥È¤ò¼¨¤·¤Æ¤¤¤ì¤Ð¤½¤ì¤òÊÖ¤¹¡£
1297
1298     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢$SYMBOL ¤òʸ»ú¥»¥Ã¥È̾¤È¤·¤ÆÀµµ¬²½¤·¡¢¤½¤ì¤¬Ê¸»ú¥»¥Ã¥È¤ò¼¨¤·¤Æ¤¤¤Æ¤¤¤ì¤ÐÀµµ¬²½¤·¤¿¤â¤Î¤òÊÖ¤¹¡£
1299     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢#Mnil ¤òÊÖ¤¹¡£ */
1300
1301 MSymbol
1302 mchar_resolve_charset (MSymbol symbol)
1303 {
1304   MCharset *charset = (MCharset *) msymbol_get (symbol, Mcharset);
1305
1306   if (! charset)
1307     {
1308       symbol = msymbol__canonicalize (symbol);
1309       charset = (MCharset *) msymbol_get (symbol, Mcharset);
1310     }
1311
1312   return (charset ? charset->name : Mnil);
1313 }
1314
1315 /*=*/
1316
1317 /***en
1318     @brief List symbols representing charsets.
1319
1320     The mchar_list_charsets () function makes an array of symbols
1321     representing a charset, stores the pointer to the array in a place
1322     pointed to by $SYMBOLS, and returns the length of the array.  */
1323
1324 /***ja
1325     @brief Ê¸»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤òÎóµó¤¹¤ë.
1326
1327     ´Ø¿ô mchar_list_charsets () 
1328     ¤Ï¡¢Ê¸»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤òʤ٤¿ÇÛÎó¤òºî¤ê¡¢$SYMBOLS 
1329     ¤Ç¥Ý¥¤¥ó¥È¤µ¤ì¤¿¾ì½ê¤Ë¤³¤ÎÇÛÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃÖ¤­¡¢ÇÛÎó¤ÎŤµ¤òÊÖ¤¹¡£ */
1330
1331 int
1332 mchar_list_charset (MSymbol **symbols)
1333 {
1334   int i;
1335
1336   MTABLE_MALLOC ((*symbols), charset_list.used, MERROR_CHARSET);
1337   for (i = 0; i < charset_list.used; i++)
1338     (*symbols)[i] = charset_list.charsets[i]->name;
1339   return i;
1340 }
1341
1342 /*=*/
1343
1344 /***en
1345     @brief Decode a code-point.
1346
1347     The mchar_decode () function decodes code-point $CODE in the
1348     charset represented by the symbol $CHARSET_NAME to get a character
1349     code.
1350
1351     @return
1352     If decoding was successful, mchar_decode () returns the decoded
1353     character code.  Otherwise it returns -1.  */
1354
1355 /***ja
1356     @brief ¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¥Ç¥³¡¼¥É¤¹¤ë.
1357
1358     ´Ø¿ô mchar_decode () ¤Ï¡¢¥·¥ó¥Ü¥ë $CHARSET_NAME ¤Ç¼¨¤µ¤ì¤ëʸ»ú¥»¥Ã¥ÈÆâ¤Î
1359     $CODE ¤È¤¤¤¦¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¥Ç¥³¡¼¥É¤·¤Æʸ»ú¥³¡¼¥É¤òÆÀ¤ë¡£
1360
1361     @return
1362     ¥Ç¥³¡¼¥É¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_decode () ¤Ï¥Ç¥³¡¼¥É¤µ¤ì¤¿Ê¸»ú¥³¡¼¥É¤òÊÖ¤¹¡£
1363     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£  */
1364
1365 /***
1366     @seealso
1367     mchar_encode ()  */
1368
1369 int
1370 mchar_decode (MSymbol charset_name, unsigned code)
1371 {
1372   MCharset *charset = MCHARSET (charset_name);
1373
1374   if (! charset)
1375     return MCHAR_INVALID_CODE;
1376   return DECODE_CHAR (charset, code);
1377 }
1378
1379 /*=*/
1380
1381 /***en
1382     @brief Encode a character code.
1383
1384     The mchar_encode () function encodes character code $C to get a
1385     code-point in the charset represented by the symbol $CHARSET_NAME.
1386
1387     @return
1388     If encoding was successful, mchar_encode () returns the encoded
1389     code-point.  Otherwise it returns #MCHAR_INVALID_CODE.  */
1390
1391 /***ja
1392     @brief Ê¸»ú¥³¡¼¥É¤ò¥¨¥ó¥³¡¼¥É¤¹¤ë.
1393
1394     ´Ø¿ô mchar_encode () ¤Ï¡¢Ê¸»ú¥³¡¼¥É $C ¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¥·¥ó¥Ü¥ë
1395     $CHARSET_NAME ¤Ç¼¨¤µ¤ì¤ëʸ»ú¥»¥Ã¥ÈÆâ¤Ë¤ª¤±¤ë¥³¡¼¥É¥Ý¥¤¥ó¥È¤òÆÀ¤ë¡£
1396
1397     @return
1398     ¥¨¥ó¥³¡¼¥É¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_encode () ¤Ï¥¨¥ó¡¼¥É¤µ¤ì¤¿¥³¡¼¥É¥Ý¥¤¥ó¥È¤òÊÖ¤¹¡£
1399     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #MCHAR_INVALID_CODE ¤òÊÖ¤¹¡£  */
1400
1401 /***
1402     @seealso
1403     mchar_decode ()  */
1404
1405 unsigned
1406 mchar_encode (MSymbol charset_name, int c)
1407 {
1408   MCharset *charset = MCHARSET (charset_name);
1409
1410   if (! charset)
1411     return MCHAR_INVALID_CODE;
1412   return ENCODE_CHAR (charset, c);
1413 }
1414
1415 /*=*/
1416
1417 /***en
1418     @brief Call a function for all the characters in a specified charset.
1419
1420     The mcharset_map_chars () function calls $FUNC for all the
1421     characters in the charset named $CHARSET_NAME.  A call is done for
1422     a chunk of consecutive characters rather than character by
1423     character.
1424
1425     $FUNC receives three arguments: $FROM, $TO, and $ARG.  $FROM and
1426     $TO specify the range of character codes in $CHARSET.  $ARG is the
1427     same as $FUNC_ARG.
1428
1429     @return
1430     If the operation was successful, mcharset_map_chars () returns 0.
1431     Otherwise, it returns -1 and assigns an error code to the external
1432     variable #merror_code.  */
1433
1434 /***ja
1435     @brief »ØÄꤷ¤¿Ê¸»ú¥»¥Ã¥È¤Î¤¹¤Ù¤Æ¤Îʸ»ú¤ËÂФ·¤Æ´Ø¿ô¤ò¸Æ¤Ö.
1436
1437     ´Ø¿ô mcharset_map_chars () ¤Ï $CHARSET_NAME 
1438     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Äʸ»ú¥»¥Ã¥ÈÃæ¤Î¤¹¤Ù¤Æ¤Îʸ»ú¤ËÂФ·¤Æ $FUNC ¤ò¸Æ¤Ö¡£
1439     ¸Æ¤Ó½Ð¤·¤Ï°ìʸ»úËè¤Ç¤Ï¤Ê¤¯¡¢Ï¢Â³¤·¤¿Ê¸»ú¤Î¤Þ¤È¤Þ¤êñ°Ì¤Ç¹Ô¤Ê¤ï¤ì¤ë¡£
1440
1441     ´Ø¿ô $FUNC ¤Ë¤Ï$FROM, $TO, $ARG ¤Î£³°ú¿ô¤¬ÅϤµ¤ì¤ë¡£$FROM ¤È $TO 
1442     ¤Ï $CHARSET Ãæ¤Îʸ»ú¥³¡¼¥É¤ÎÈϰϤò»ØÄꤹ¤ë¡£$ARG ¤Ï $FUNC_ARG 
1443     ¤ÈƱ¤¸¤Ç¤¢¤ë¡£
1444
1445     @return
1446     ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mcharset_map_chars () ¤Ï 0 ¤òÊÖ¤¹¡£
1447     ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1448
1449 /*** 
1450     @errors
1451     @c MERROR_CHARSET */
1452
1453 int
1454 mchar_map_charset (MSymbol charset_name,
1455                    void (*func) (int from, int to, void *arg),
1456                    void *func_arg)
1457 {
1458   MCharset *charset;
1459
1460   charset = MCHARSET (charset_name);
1461   if (! charset)
1462     MERROR (MERROR_CHARSET, -1);
1463
1464   if (charset->encoder)
1465     {
1466       int c = charset->min_char;
1467       int next_c;
1468
1469       if ((int) mchartable__lookup (charset->encoder, c, &next_c, 1) < 0)
1470         c = next_c;
1471       while (c <= charset->max_char)
1472         {
1473           if ((int) mchartable__lookup (charset->encoder, c, &next_c, 1) >= 0)
1474             (*func) (c, next_c - 1, func_arg);    
1475           c = next_c;
1476         }
1477     }
1478   else
1479     (*func) (charset->min_char, charset->max_char, func_arg);
1480   return 0;
1481 }
1482
1483 /*=*/
1484
1485 /*** @} */
1486
1487 /*
1488   Local Variables:
1489   coding: euc-japan
1490   End:
1491 */