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