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