1 /* chartab.h -- character table module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
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.
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.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nChartable
25 @brief Chartable objects and API for them.
27 The m17n library supports enormous number of characters. Thus, if
28 attributes of each character are to be stored in a simple array,
29 such an array would be impractically big. The attributes usually
30 used, however, are often assigned only to a range of characters.
31 Even when all characters have attributes, characters of
32 consecutive character code tend to have the same attribute values.
34 The m17n library utilizes this tendency to store characters and
35 their attribute values efficiently in an object called @e
36 Chartable. Although a chartable object is not a simple array,
37 application programs can handle a chartable as if it is an array.
38 Attribute values of a character can be obtained by accessing a
39 Chartable for the attribute with the character code of the
42 A chartable is a managed object. */
45 @addtogroup m17nChartable ʸ»ú¥Æ¡¼¥Ö¥ë
47 @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
49 m17n ¥é¥¤¥Ö¥é¥ê¤¬°·¤¦Ê¸»ú¤Î¶õ´Ö¤Ï¹Âç¤Ç¤¢¤ë¤¿¤á¡¢Ê¸»úËè¤Î¾ðÊó¤òñ½ã¤ÊÇÛÎó¤Ë³ÊǼ¤·¤è¤¦¤È¤¹¤ë¤È¡¢¤½¤ÎÇÛÎó¤ÏµðÂç¤Ë¤Ê¤ê¤¹¤®¡¢Èó¼ÂÍÑŪ¤Ç¤¢¤ë¡£
50 ¤·¤«¤·Ä̾ïɬÍפȤʤëʸ»ú¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Ï¡¢¤¢¤ëÆÃÄê¤ÎÈϰϤÎʸ»ú¤Ë¤Î¤ßÉÕ¤¤¤Æ¤¤¤ë¤³¤È¤¬Â¿¤¤¡£
51 Á´Ê¸»ú¤Ë´Ø¤·¤Æ¾ðÊ󤬤¢¤ë¾ì¹ç¤Ë¤â¡¢Ï¢Â³¤·¤¿Ê¸»ú¥³¡¼¥É¤ò»ý¤Äʸ»ú¤ÏƱ¤¸¾ðÊó¤ò»ý¤Ä¤³¤È¤¬Â¿¤¤¡£
53 ¤³¤Î¤è¤¦¤Ê·¹¸þ¤òÍøÍѤ·¤Æʸ»ú¤È¤½¤ÎÉղþðÊó¤ò¸úΨŪ¤Ë³ÊǼ¤¹¤ë¤¿¤á¤Ë¡¢
54 m17n ¥é¥¤¥Ö¥é¥ê¤Ï @e ʸ»ú¥Æ¡¼¥Ö¥ë (chartable) ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤òÍѤ¤¤ë¡£
55 ʸ»ú¥Æ¡¼¥Ö¥ë¤ÏÇÛÎó¤Ç¤Ï¤Ê¤¤¤¬¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ïʸ»ú¥Æ¡¼¥Ö¥ë¤òÇÛÎó¤Î°ì¼ï¤È¤·¤Æ°·¤¦¤³¤È¤¬¤Ç¤¤ë¡£
56 ¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤ÎÆÃÄê¤Î¾ðÊó¤Ï¡¢¤½¤Î¾ðÊó¤ò»ý¤Äʸ»ú¥Æ¡¼¥Ö¥ë¤ò¤½¤Îʸ»ú¤Î¥³¡¼¥É¤Ç°ú¤¯¤³¤È
59 ʸ»ú¥Æ¡¼¥Ö¥ë¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ */
62 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
63 /*** @addtogroup m17nInternal
74 #include "m17n-misc.h"
78 static M17NObjectArray chartable_table;
80 /*** Maximum depth of char-table. */
81 #define CHAR_TAB_MAX_DEPTH 3
83 /** @name Define: Number of characters covered by char-table of each level.
86 /** BITs for number of characters covered by char-table of each
88 #if MCHAR_MAX < 0x400000
90 #define SUB_BITS_0 22 /* i.e. 0x400000 chars */
91 #define SUB_BITS_1 16 /* i.e. 0x10000 chars */
92 #define SUB_BITS_2 12 /* i.e. 0x1000 chars */
93 #define SUB_BITS_3 7 /* i.e. 0x80 chars */
95 #else /* MCHAR_MAX >= 0x400000 */
105 /** How many characters a char-table covers at each level. */
106 static const int chartab_chars[] =
112 /** How many slots a char-table has at each level. */
113 static const int chartab_slots[] =
114 { (1 << (SUB_BITS_0 - SUB_BITS_1)),
115 (1 << (SUB_BITS_1 - SUB_BITS_2)),
116 (1 << (SUB_BITS_2 - SUB_BITS_3)),
119 /** Mask bits to obtain the valid bits from a character code for looking
120 up a char-table of each level. */
121 static const int chartab_mask[] =
122 { (int) ((((unsigned) 1) << SUB_BITS_0) - 1),
123 (1 << SUB_BITS_1) - 1,
124 (1 << SUB_BITS_2) - 1,
125 (1 << SUB_BITS_3) - 1 };
127 /** Bit-shifting counts to obtain a valid index from a character code
128 for looking up a char-table of each level. */
129 static const int chartab_shift[] =
130 { SUB_BITS_1, SUB_BITS_2, SUB_BITS_3, 0 };
133 /** Index for looking up character C in a char-table at DEPTH. */
134 #define SUB_IDX(depth, c) \
135 (((c) & chartab_mask[depth]) >> chartab_shift[depth])
138 /** Structure of sub char-table. */
139 typedef struct MSubCharTable MSubCharTable;
145 /* The depth of the table; 0, 1, 2, or 3. */
148 /* The minimum character covered by the table. */
151 #else /* SUB_BITS_0 <= 24 */
153 /* The value is ((<depth> << 24) | <min_char>). */
156 #endif /* SUB_BITS_0 <= 24 */
158 /** The default value of characters covered by the table. */
161 /** For a table of bottom level, array of values. For a non-bottom
162 table, array of sub char-tables. It may be NULL if all
163 characters covered by the table has <default_value>. */
166 MSubCharTable *tables;
171 #define TABLE_DEPTH(table) ((table)->depth)
172 #define TABLE_MIN_CHAR(table) ((table)->min_char)
173 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
174 ((table)->depth = (DEPTH), (table)->min_char = (MIN_CHAR))
175 #else /* SUB_BITS_0 <= 24 */
176 #define TABLE_DEPTH(table) ((table)->depth_min_char >> 24)
177 #define TABLE_MIN_CHAR(table) ((table)->depth_min_char & 0xFFFFFF)
178 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
179 ((table)->depth_min_char = ((DEPTH) << 24) | (MIN_CHAR))
180 #endif /* SUB_BITS_0 <= 24 */
182 /** Structure of char-table. */
186 /** Common header for a managed object. */
189 /** Key of the table. */
192 /** The minimum and maximum characters covered by the table. */
193 int min_char, max_char;
195 MSubCharTable subtable;
201 /* Local functions. */
203 /** Allocate and initialize an array of sub-tables for sub char-table
204 TABLE. It is assumed that TABLE_DEPTH (TABLE) <
205 CHAR_TAB_MAX_DEPTH.*/
208 make_sub_tables (MSubCharTable *table, int managedp)
210 int depth = TABLE_DEPTH (table);
211 int min_char = TABLE_MIN_CHAR (table);
212 int slots = chartab_slots[depth];
213 int chars = chartab_chars[depth + 1];
214 MSubCharTable *tables;
217 MTABLE_MALLOC (tables, slots, MERROR_CHARTABLE);
219 for (i = 0; i < slots; i++, min_char += chars)
221 SET_DEPTH_MIN_CHAR (tables + i, depth + 1, min_char);
222 tables[i].default_value = table->default_value;
223 tables[i].contents.tables = NULL;
225 if (managedp && table->default_value)
226 M17N_OBJECT_REF_NTIMES (tables->default_value, slots);
227 table->contents.tables = tables;
231 /** Allocate and initialize an array of values for sub char-table
232 TABLE. It is assumed that TABLE_DEPTH (TABLE) ==
233 CHAR_TAB_MAX_DEPTH. */
236 make_sub_values (MSubCharTable *table, int managedp)
238 int slots = chartab_slots[CHAR_TAB_MAX_DEPTH];
242 MTABLE_MALLOC (values, slots, MERROR_CHARTABLE);
244 for (i = 0; i < slots; i++)
245 values[i] = table->default_value;
246 if (managedp && table->default_value)
247 M17N_OBJECT_REF_NTIMES (table->default_value, slots);
248 table->contents.values = values;
252 /** Free contents of sub char-table TABLE and the default value of
253 TABLE. Free also the sub-tables recursively. */
256 free_sub_tables (MSubCharTable *table, int managedp)
258 int depth = TABLE_DEPTH (table);
259 int slots = chartab_slots[depth];
261 if (table->contents.tables)
263 if (depth < CHAR_TAB_MAX_DEPTH)
266 free_sub_tables (table->contents.tables + slots, managedp);
267 free (table->contents.tables);
274 if (table->contents.values[slots])
275 M17N_OBJECT_UNREF (table->contents.values[slots]);
277 free (table->contents.values);
279 table->contents.tables = NULL;
281 if (managedp && table->default_value)
282 M17N_OBJECT_UNREF (table->default_value);
286 /** In sub char-table TABLE, set value VAL for characters of the range
290 set_chartable_range (MSubCharTable *table, int from, int to, void *val,
293 int depth = TABLE_DEPTH (table);
294 int min_char = TABLE_MIN_CHAR (table);
295 int max_char = min_char + (chartab_chars[depth] - 1);
298 if (max_char < 0 || max_char > MCHAR_MAX)
299 max_char = MCHAR_MAX;
306 if (from == min_char && to == max_char)
308 free_sub_tables (table, managedp);
310 M17N_OBJECT_REF (val);
311 table->default_value = val;
315 if (depth < CHAR_TAB_MAX_DEPTH)
317 if (! table->contents.tables)
318 make_sub_tables (table, managedp);
319 i = SUB_IDX (depth, from);
320 table = table->contents.tables + i;
321 while (i < chartab_slots[depth] && TABLE_MIN_CHAR (table) <= to)
323 set_chartable_range (table, from, to, val, managedp);
329 int idx_from = SUB_IDX (depth, from);
330 int idx_to = SUB_IDX (depth, to);
332 if (! table->contents.values)
333 make_sub_values (table, managedp);
334 for (i = idx_from; i <= idx_to; i++)
336 if (managedp && table->contents.values[i])
337 M17N_OBJECT_UNREF (table->contents.values[i]);
338 table->contents.values[i] = val;
341 M17N_OBJECT_REF_NTIMES (val, (idx_to - idx_from + 1));
346 /** Lookup the sub char-table TABLE for the character C. If NEXT_C is
347 not NULL, set *NEXT_C to the next interesting character to lookup
348 for. If DEFAULT_P is zero, the next interesting character is what
349 possibly has the different value than C. Otherwise, the next
350 interesting character is what possibly has the default value (if C
351 has a value deferent from the default value) or has a value
352 different from the default value (if C has the default value). */
355 lookup_chartable (MSubCharTable *table, int c, int *next_c, int default_p)
357 int depth = TABLE_DEPTH (table);
359 void *default_value = table->default_value;
364 if (! table->contents.tables)
367 *next_c = TABLE_MIN_CHAR (table) + chartab_chars[depth];
368 return table->default_value;
370 if (depth == CHAR_TAB_MAX_DEPTH)
372 table = table->contents.tables + SUB_IDX (depth, c);
376 idx = SUB_IDX (depth, c);
377 val = table->contents.values[idx];
381 int max_char = TABLE_MIN_CHAR (table) + (chartab_chars[depth] - 1);
383 if (max_char < 0 || max_char > MCHAR_MAX)
384 max_char = MCHAR_MAX;
385 if (default_p && val != default_value)
388 while (c >= 0 && c <= max_char
389 && table->contents.values[idx] != default_value);
394 while (c >= 0 && c <= max_char
395 && table->contents.values[idx] == val);
402 /** Call FUNC for characters in sub char-table TABLE. Ignore such
403 characters that has a value IGNORE. FUNC is called with four
404 arguments; FROM, TO, VAL, and ARG (same as FUNC_ARG). If
405 DEFAULT_P is zero, FROM and TO are range of characters that has
406 the same value VAL. Otherwise, FROM and TO are range of
407 characters that has the different value than the default value of
411 map_chartable (MSubCharTable *table, void *ignore, int default_p,
412 void (*func) (int, int, void *, void *),
419 current = lookup_chartable (table, 0, &next_c, default_p);
421 while (c >= 0 && c <= MCHAR_MAX)
423 void *next = lookup_chartable (table, c, &next_c, default_p);
427 if (current != ignore)
428 (*func) (from, c - 1, current, func_arg);
434 if (from <= MCHAR_MAX && current != ignore)
435 (*func) (from, MCHAR_MAX, current, func_arg);
439 /* Return the smallest character whose value is not DEFAULT_VALUE in
440 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
444 chartab_min_non_default_char (MSubCharTable *table, void *default_value)
446 int depth = TABLE_DEPTH (table);
450 if (!table->contents.tables)
451 return (default_value == table->default_value
452 ? -1 : TABLE_MIN_CHAR (table));
454 slots = chartab_slots[depth];
456 if (depth == CHAR_TAB_MAX_DEPTH)
458 for (i = 0; i < slots; i++)
459 if (table->contents.values[i] != default_value)
460 return (TABLE_MIN_CHAR (table) + i);
464 for (i = 0; i < slots; i++)
465 if ((c = chartab_min_non_default_char (table->contents.tables + i,
474 /* Return the largest character whose value is not DEFAULT_VALUE in
475 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
479 chartab_max_non_default_char (MSubCharTable *table, void *default_value)
481 int depth = TABLE_DEPTH (table);
485 if (!table->contents.tables)
486 return (default_value == table->default_value
487 ? -1 : TABLE_MIN_CHAR (table) + chartab_chars[depth] - 1);
489 slots = chartab_slots[depth];
491 if (depth == CHAR_TAB_MAX_DEPTH)
493 for (i = slots - 1; i >= 0; i--)
494 if (table->contents.values[i] != default_value)
495 return (TABLE_MIN_CHAR (table) + i);
499 for (i = slots - 1; i >= 0; i--)
500 if ((c = chartab_max_non_default_char (table->contents.tables + i,
509 free_chartable (void *object)
511 MCharTable *table = (MCharTable *) object;
512 int managedp = table->key != Mnil && table->key->managing_key;
514 if (table->subtable.contents.tables)
518 for (i = 0; i < chartab_slots[0]; i++)
519 free_sub_tables (table->subtable.contents.tables + i, managedp);
520 free (table->subtable.contents.tables);
521 if (managedp && table->subtable.default_value)
522 M17N_OBJECT_UNREF (table->subtable.default_value);
524 M17N_OBJECT_UNREGISTER (chartable_table, table);
530 /* Support function of mdebug_dump_chartab. */
533 dump_sub_chartab (MSubCharTable *table, void *default_value,
534 MSymbol key, int indent)
536 int depth = TABLE_DEPTH (table);
537 int min_char = TABLE_MIN_CHAR (table);
538 int max_char = min_char + (chartab_chars[depth] - 1);
539 char *prefix = (char *) alloca (indent + 1);
542 if (max_char < 0 || max_char > MCHAR_MAX)
543 max_char = MCHAR_MAX;
545 memset (prefix, 32, indent);
548 if (! table->contents.tables && table->default_value == default_value)
550 fprintf (stderr, "\n%s(sub%d (U+%04X U+%04X) ",
551 prefix, depth, min_char, max_char);
554 if (table->default_value)
555 fprintf (stderr, "(default %s)",
556 ((MSymbol) table->default_value)->name);
558 fprintf (stderr, "(default nil)");
561 fprintf (stderr, "(default #x%X)", (unsigned) table->default_value);
563 default_value = table->default_value;
564 if (table->contents.tables)
566 if (depth < CHAR_TAB_MAX_DEPTH)
567 for (i = 0; i < chartab_slots[depth]; i++)
568 dump_sub_chartab (table->contents.tables + i, default_value,
571 for (i = 0; i < chartab_slots[depth]; i++, min_char++)
573 void **val = table->contents.values + i;
575 if (val == default_value)
577 default_value = *val;
578 fprintf (stderr, "\n%s (U+%04X", prefix, min_char);
579 while (i + 1 < chartab_slots[depth]
580 && val[1] == default_value)
581 i++, val++, min_char++;
582 fprintf (stderr, "-U+%04X ", min_char);
586 fprintf (stderr, "%s)", ((MSymbol) default_value)->name);
588 fprintf (stderr, "nil)");
591 fprintf (stderr, " #xx%X)", (unsigned) default_value);
594 fprintf (stderr, ")");
603 M17N_OBJECT_ADD_ARRAY (chartable_table, "Chartable");
613 mchartable__lookup (MCharTable *table, int c, int *next_c, int default_p)
615 return lookup_chartable (&table->subtable, c, next_c, default_p);
619 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
624 /*** @addtogroup m17nChartable */
629 @brief Symbol whose name is "char-table".
631 The symbol @c Mchar_table has the name <tt>"char-table"</tt>. */
634 @brief "char-table" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
636 ¥·¥ó¥Ü¥ë @c Mchar_table ¤Ï̾Á° <tt>"char-table"</tt> ¤ò»ý¤Ä¡£
644 @brief Create a new chartable.
646 The mchartable () function creates a new chartable object with
647 symbol $KEY and the default value $DEFAULT_VALUE. If $KEY is a
648 managing key, the elements of the table (including the default
649 value) are managed objects or NULL.
652 If the operation was successful, mchartable () returns a pointer
653 to the created chartable. Otherwise it returns @c NULL and
654 assigns an error code to the external variable #merror_code. */
657 @brief ¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë.
659 ´Ø¿ô mchartable () ¤Ï¥¡¼¤¬ $KEY ¤ÇÍ×ÁǤΥǥե©¥ë¥ÈÃͤ¬
660 $DEFAULT_VALUE ¤Ç¤¢¤ë¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë¡£¤â¤· $KEY
661 ¤¬´ÉÍý¥¡¼¤Ç¤¢¤ì¤Ð¡¢¤³¤Î¥Æ¡¼¥Ö¥ë¤ÎÍ×ÁǤϡʥǥե©¥ë¥ÈÃͤò´Þ¤á¤Æ¡Ë´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤«
662 NULL ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
665 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable () ¤ÏºîÀ®¤µ¤ì¤¿Ê¸»ú¥Æ¡¼¥Ö¥ë¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
666 ¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
669 mchartable (MSymbol key, void *default_value)
673 M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE);
674 M17N_OBJECT_REGISTER (chartable_table, table);
676 table->min_char = -1;
677 table->max_char = -1;
678 SET_DEPTH_MIN_CHAR (&table->subtable, 0, 0);
679 table->subtable.default_value = default_value;
680 if (key != Mnil && key->managing_key && default_value)
681 M17N_OBJECT_REF (default_value);
682 table->subtable.contents.tables = NULL;
689 @brief Return the minimum character whose value is set in a chartabe.
691 The mchartable_min_char () function return the minimum character
692 whose value is set in chartable $TABLE. No character is set its
693 value, the function returns -1.
697 mchartable_min_char (MCharTable *table)
699 return table->min_char;
705 @brief Return the maximum character whose value is set in a chartabe.
707 The mchartable_max_char () function return the maximum character
708 whose value is set in chartable $TABLE. No character is set its
709 value, the function returns -1.
713 mchartable_max_char (MCharTable *table)
715 return table->max_char;
721 @brief Return the assigned value of a character in a chartable.
723 The mchartable_lookup () function returns the value assigned to
724 character $C in chartable $TABLE. If no value has been set for $C
725 explicitly, the default value of $TABLE is returned. If $C is not
726 a valid character, mchartable_lookup () returns @c NULL and
727 assigns an error code to the external variable #merror_code. */
730 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Çʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹.
732 ´Ø¿ô mchartable_lookup () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Çʸ»ú $C
733 ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹¡£$C ¤ËÂФ¹¤ëÌÀ¼¨Åª¤ÊÃͤ¬¤Ê¤±¤ì¤Ð¡¢$TABLE
734 ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòÊÖ¤¹¡£$C ¤¬ÂÅÅö¤Êʸ»ú¤Ç¤Ê¤±¤ì¤Ð¡¢mchartable_lookup () ¤Ï
735 @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
745 mchartable_lookup (MCharTable *table, int c)
747 M_CHECK_CHAR (c, NULL);
749 if (c < table->min_char || c > table->max_char)
750 return table->subtable.default_value;
751 return lookup_chartable (&table->subtable, c, NULL, 0);
757 @brief Assign a value to a character in a chartable.
759 The mchartable_set () function sets the value of character $C in
760 chartable $TABLE to $VAL.
763 If the operation was successful, mchartable_set () returns 0.
764 Otherwise it returns -1 and assigns an error code to the external
765 variable #merror_code. */
768 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Ç¤Îʸ»ú¤ÎÃͤòÀßÄꤹ¤ë.
770 ´Ø¿ô mchartable_set () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú $C
771 ¤ËÃÍ $VAL ¤ò³ä¤êÅö¤Æ¤ë¡£
774 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchartable_set () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1
775 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
782 mchartable_lookup (), mchartable_set_range () */
786 mchartable_set (MCharTable *table, int c, void *val)
788 int managedp = table->key != Mnil && table->key->managing_key;
789 MSubCharTable *sub = &table->subtable;
792 M_CHECK_CHAR (c, -1);
794 if (table->max_char < 0)
795 table->min_char = table->max_char = c;
798 if (c < table->min_char)
800 else if (c > table->max_char)
804 for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++)
806 if (! sub->contents.tables)
808 if (sub->default_value == val)
810 make_sub_tables (sub, managedp);
812 sub = sub->contents.tables + SUB_IDX (i, c);
814 if (! sub->contents.values)
816 if (sub->default_value == val)
818 make_sub_values (sub, managedp);
820 sub->contents.values[SUB_IDX (3, c)] = val;
822 M17N_OBJECT_REF (val);
829 @brief Assign a value to the characters in the specified range.
831 The mchartable_set_range () function assigns value $VAL to the
832 characters from $FROM to $TO (both inclusive) in chartable $TABLE.
835 If the operation was successful, mchartable_set_range () returns
836 0. Otherwise it returns -1 and assigns an error code to the
837 external variable #merror_code. If $FROM is greater than $TO,
838 mchartable_set_range () returns immediately without an error. */
841 @brief »ØÄêÈϰϤÎʸ»ú¤ËÃͤòÀßÄꤹ¤ë.
843 ´Ø¿ô mchartable_set_range () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Î $FROM
844 ¤«¤é $TO ¤Þ¤Ç¡Êξü¤ò´Þ¤à¡Ë¤Îʸ»ú¤Ë¡¢ÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£
847 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable_set_range () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
848 -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£$FROM ¤¬
849 $TO ¤è¤êÂ礤¤¤È¤¤Ë¤Ï¡¢ mchartable_set_range ()
850 ¤Ï²¿¤â¤»¤º¡¢¥¨¥é¡¼¤âµ¯¤³¤µ¤Ê¤¤¡£ */
860 mchartable_set_range (MCharTable *table, int from, int to, void *val)
862 int managedp = table->key != Mnil && table->key->managing_key;
864 M_CHECK_CHAR (from, -1);
865 M_CHECK_CHAR (to, -1);
870 if (table->max_char < 0)
871 table->min_char = from, table->max_char = to;
873 if (from < table->min_char)
874 table->min_char = from;
875 if (to > table->max_char)
876 table->max_char = to;
878 set_chartable_range (&table->subtable, from, to, val, managedp);
885 @brief Search for characters that have non-default value.
887 The mchartable_range () function searches chartable $TABLE for the
888 first and the last character codes that do not have the default
889 value of $TABLE, and set $FROM and $TO to them, respectively. If
890 all characters have the default value, both $FROM and $TO are set
894 @brief Ãͤ¬¥Ç¥Õ¥©¥ë¥È¤È°Û¤Ê¤ëʸ»ú¤òõ¤¹.
896 ´Ø¿ô mchartable_range () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Ç¡¢$TABLE
897 ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͰʳ°¤ÎÃͤò»ý¤ÄºÇ½é¤ÈºÇ¸å¤Îʸ»ú¤òõ¤·¡¢¤½¤ì¤¾¤ì¤ò $FROM
898 ¤È $TO ¤ËÀßÄꤹ¤ë¡£¤¹¤Ù¤Æ¤Îʸ»ú¤¬ÃͤȤ·¤Æ¥Ç¥Õ¥©¥ë¥ÈÃͤò¤È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï
899 $FROM ¤È $TO ¤ò -1¤ËÀßÄꤹ¤ë¡£ */
902 mchartable_range (MCharTable *table, int *from, int *to)
904 *from = chartab_min_non_default_char (&table->subtable,
905 table->subtable.default_value);
909 *to = chartab_max_non_default_char (&table->subtable,
910 table->subtable.default_value);
916 @brief Call a function for characters in a chartable.
918 The mchartable_map () function calls function $FUNC for characters
919 in chartable $TABLE. No function call occurs for characters that
920 have value $IGNORE in $TABLE. Comparison of $IGNORE and character
921 value is done with the operator @c ==. Be careful when you use
922 string literals or pointers.
924 Instead of calling $FUNC for each character, mchartable_map ()
925 tries to optimize the number of function calls, i.e. it makes a
926 single function call for a chunk of characters when those
927 consecutive characters have the same value.
929 No matter how long the character chunk is, $FUNC is called with
930 four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both
931 inclusive) defines the range of characters that have value $VAL.
932 $ARG is the same as $FUNC_ARG.
935 This function always returns 0. */
938 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Îʸ»ú¤ËÂФ·¤Æ»ØÄê¤Î´Ø¿ô¤ò¸Æ¤Ö.
940 ´Ø¿ô mchartable_map () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú¤ËÂФ·¤Æ´Ø¿ô
941 $FUNC ¤ò¸Æ¤Ö¡£¤¿¤À¤·$TABLE Ãæ¤Ç¤âÃͤ¬ $IGNORE
942 ¤Ç¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô¸Æ¤Ó½Ð¤·¤ò¹Ô¤Ê¤ï¤Ê¤¤¡£$IGNORE ¤Èʸ»ú¤ÎÃͤÎÈæ³Ó¤Ï
943 @c == ¤Ç¹Ô¤Ê¤¦¤Î¤Ç¡¢Ê¸»úÎó¥ê¥Æ¥é¥ë¤ä¥Ý¥¤¥ó¥¿¤ò»È¤¦ºÝ¤Ë¤ÏÃí°Õ¤òÍפ¹¤ë¡£
945 mchartable_map () ¤Ï¡¢°ìʸ»ú¤´¤È¤Ë $FUNC
946 ¤ò¸Æ¤Ö¤Î¤Ç¤Ï¤Ê¤¯¡¢´Ø¿ô¸Æ¤Ó½Ð¤·¤Î²ó¿ô¤òºÇŬ²½¤·¤è¤¦¤È¤¹¤ë¡£
947 ¤¹¤Ê¤ï¤Á¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸Ãͤò»ý¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Îʸ»ú¤Î¤Þ¤È¤Þ¤êÁ´ÂΤˤĤ¤¤Æ°ìÅ٤δؿô¸Æ¤Ó½Ð
950 ʸ»ú¤Î¤Þ¤È¤Þ¤ê¤ÎÂ礤µ¤Ë¤«¤«¤ï¤é¤º¡¢$FUNC ¤Ï $FROM, $TO, $VAL, $ARG
951 ¤Î£´°ú¿ô¤Ç¸Æ¤Ð¤ì¤ë¡£$FROM ¤È $TO ¡Êξü¤ò´Þ¤à¡Ë¤Ï $VAL
952 ¤òÃͤȤ·¤Æ»ý¤Äʸ»ú¤ÎÈϰϤò¼¨¤·¡¢$ARG ¤Ï $FUNC_ARG ¤½¤Î¤â¤Î¤Ç¤¢¤ë¡£
955 ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë0¤òÊÖ¤¹¡£ */
958 mchartable_map (MCharTable *table, void *ignore,
959 void (*func) (int, int, void *, void *),
962 map_chartable (&table->subtable, ignore, 0, func, func_arg);
970 /*** @addtogroup m17nDebug */
975 @brief Dump a chartable.
977 The mdebug_dump_chartab () function prints a chartable $TABLE in a
978 human readable way to the stderr. $INDENT specifies how many
979 columns to indent the lines but the first one.
982 This function returns $TABLE. */
985 @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤ò¥À¥ó¥×¤¹¤ë.
987 ´Ø¿ô mdebug_dump_chartab () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE ¤ò stderr
988 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
991 ¤³¤Î´Ø¿ô¤Ï $TABLE ¤òÊÖ¤¹¡£ */
994 mdebug_dump_chartab (MCharTable *table, int indent)
996 fprintf (stderr, "(chartab (U+%04X U+%04X)",
997 table->min_char, table->max_char);
998 dump_sub_chartab (&table->subtable, table->subtable.default_value,
999 table->key, indent + 2);
1000 fprintf (stderr, ")");