1 /* chartab.h -- character table module.
2 Copyright (C) 2003, 2004
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., 59 Temple Place, Suite 330, Boston, MA
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 chartables as if they were arrays.
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 ¤¢¤ë¡£¤·¤«¤·Ä̾ïɬÍפȤʤëʸ»ú¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Ï¡¢¤¢¤ëÆÃÄê¤ÎÈϰϤÎʸ
52 »ú¤Ë¤Î¤ßÉÕ¤¤¤Æ¤¤¤ë¤³¤È¤¬Â¿¤¤¡£Á´Ê¸»ú¤Ë´Ø¤·¤Æ¾ðÊ󤬤¢¤ë¾ì¹ç¤Ë¤â¡¢Ï¢
53 ³¤·¤¿Ê¸»ú¥³¡¼¥É¤ò»ý¤Äʸ»ú¤ÏƱ¤¸¾ðÊó¤ò»ý¤Ä¤³¤È¤¬Â¿¤¤¡£¤½¤³¤Ç¡¢¤³¤Î
54 ¤è¤¦¤Ê¾õ¶·¤Ë¤ª¤¤¤Æ¸úΨŪ¤Ë¾ðÊó¤ò³ÊǼ¤Ç¤¤ë¤â¤Î¤È¤·¤Æ¡¢m17n ¥é¥¤¥Ö
55 ¥é¥ê¤Ï @e ʸ»ú¥Æ¡¼¥Ö¥ë (chartable) ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤òÍѤ¤¤ë¡£¥¢
56 ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë¤òÇÛÎó¤Î°ì¼ï¤È¸«¤Ê¤¹¤³¤È¤¬
57 ¤Ç¤¤ë¡£¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤ÎÆÃÄê¤Î¾ðÊó¤Ï¡¢¤½¤Î¾ðÊó¤ò»ý¤Äʸ»ú¥Æ¡¼¥Ö¥ë
58 ¤ò¤½¤Îʸ»ú¤Î¥³¡¼¥É¤Ç°ú¤¯¤³¤È¤ÇÆÀ¤é¤ì¤ë¡£ */
61 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
62 /*** @addtogroup m17nInternal
73 #include "m17n-misc.h"
77 static M17NObjectArray chartable_table;
79 /*** Maximum depth of char-table. */
80 #define CHAR_TAB_MAX_DEPTH 3
82 /** @name Define: Number of characters covered by char-table of each level.
85 /** BITs for number of characters covered by char-table of each
87 #if MCHAR_MAX < 0x400000
89 #define SUB_BITS_0 22 /* i.e. 0x400000 chars */
90 #define SUB_BITS_1 16 /* i.e. 0x10000 chars */
91 #define SUB_BITS_2 12 /* i.e. 0x1000 chars */
92 #define SUB_BITS_3 7 /* i.e. 0x80 chars */
94 #else /* MCHAR_MAX >= 0x400000 */
104 /** How many characters a char-table covers at each level. */
105 static const int chartab_chars[] =
111 /** How many slots a char-table has at each level. */
112 static const int chartab_slots[] =
113 { (1 << (SUB_BITS_0 - SUB_BITS_1)),
114 (1 << (SUB_BITS_1 - SUB_BITS_2)),
115 (1 << (SUB_BITS_2 - SUB_BITS_3)),
118 /** Mask bits to obtain the valid bits from a character code for looking
119 up a char-table of each level. */
120 static const int chartab_mask[] =
121 { (int) ((((unsigned) 1) << SUB_BITS_0) - 1),
122 (1 << SUB_BITS_1) - 1,
123 (1 << SUB_BITS_2) - 1,
124 (1 << SUB_BITS_3) - 1 };
126 /** Bit-shifting counts to obtain a valid index from a character code
127 for looking up a char-table of each level. */
128 static const int chartab_shift[] =
129 { SUB_BITS_1, SUB_BITS_2, SUB_BITS_3, 0 };
132 /** Index for looking up character C in a char-table at DEPTH. */
133 #define SUB_IDX(depth, c) \
134 (((c) & chartab_mask[depth]) >> chartab_shift[depth])
137 /** Structure of sub char-table. */
138 typedef struct MSubCharTable MSubCharTable;
144 /* The depth of the table; 0, 1, 2, or 3. */
147 /* The minimum character covered by the table. */
150 #else /* SUB_BITS_0 <= 24 */
152 /* The value is ((<depth> << 24) | <min_char>). */
155 #endif /* SUB_BITS_0 <= 24 */
157 /** The default value of characters covered by the table. */
160 /** For a table of bottom level, array of values. For a non-bottom
161 table, array of sub char-tables. It may be NULL if all
162 characters covered by the table has <default_value>. */
165 MSubCharTable *tables;
170 #define TABLE_DEPTH(table) ((table)->depth)
171 #define TABLE_MIN_CHAR(table) ((table)->min_char)
172 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
173 ((table)->depth = (DEPTH), (table)->min_char = (MIN_CHAR))
174 #else /* SUB_BITS_0 <= 24 */
175 #define TABLE_DEPTH(table) ((table)->depth_min_char >> 24)
176 #define TABLE_MIN_CHAR(table) ((table)->depth_min_char & 0xFFFFFF)
177 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
178 ((table)->depth_min_char = ((DEPTH) << 24) | (MIN_CHAR))
179 #endif /* SUB_BITS_0 <= 24 */
181 /** Structure of char-table. */
185 /** Common header for a managed object. */
188 /** Key of the table. */
191 /** The minimum and maximum characters covered by the table. */
192 int min_char, max_char;
194 MSubCharTable subtable;
200 /* Local functions. */
202 /** Allocate and initialize an array of sub-tables for sub char-table
203 TABLE. It is assumed that TABLE_DEPTH (TABLE) <
204 CHAR_TAB_MAX_DEPTH.*/
207 make_sub_tables (MSubCharTable *table, int managedp)
209 int depth = TABLE_DEPTH (table);
210 int min_char = TABLE_MIN_CHAR (table);
211 int slots = chartab_slots[depth];
212 int chars = chartab_chars[depth + 1];
213 MSubCharTable *tables;
216 MTABLE_MALLOC (tables, slots, MERROR_CHARTABLE);
218 for (i = 0; i < slots; i++, min_char += chars)
220 SET_DEPTH_MIN_CHAR (tables + i, depth + 1, min_char);
221 tables[i].default_value = table->default_value;
222 tables[i].contents.tables = NULL;
224 if (managedp && table->default_value)
225 M17N_OBJECT_REF_NTIMES (tables->default_value, slots);
226 table->contents.tables = tables;
230 /** Allocate and initialize an array of values for sub char-table
231 TABLE. It is assumed that TABLE_DEPTH (TABLE) ==
232 CHAR_TAB_MAX_DEPTH. */
235 make_sub_values (MSubCharTable *table, int managedp)
237 int slots = chartab_slots[CHAR_TAB_MAX_DEPTH];
241 MTABLE_MALLOC (values, slots, MERROR_CHARTABLE);
243 for (i = 0; i < slots; i++)
244 values[i] = table->default_value;
245 if (managedp && table->default_value)
246 M17N_OBJECT_REF_NTIMES (table->default_value, slots);
247 table->contents.values = values;
251 /** Free contents of sub char-table TABLE and the default value of
252 TABLE. Free also the sub-tables recursively. */
255 free_sub_tables (MSubCharTable *table, int managedp)
257 int depth = TABLE_DEPTH (table);
258 int slots = chartab_slots[depth];
260 if (table->contents.tables)
262 if (depth < CHAR_TAB_MAX_DEPTH)
265 free_sub_tables (table->contents.tables + slots, managedp);
266 free (table->contents.tables);
273 if (table->contents.values[slots])
274 M17N_OBJECT_UNREF (table->contents.values[slots]);
276 free (table->contents.values);
278 table->contents.tables = NULL;
280 if (managedp && table->default_value)
281 M17N_OBJECT_UNREF (table->default_value);
285 /** In sub char-table TABLE, set value VAL for characters of the range
289 set_chartable_range (MSubCharTable *table, int from, int to, void *val,
292 int depth = TABLE_DEPTH (table);
293 int min_char = TABLE_MIN_CHAR (table);
294 int max_char = min_char + (chartab_chars[depth] - 1);
297 if (max_char < 0 || max_char > MCHAR_MAX)
298 max_char = MCHAR_MAX;
305 if (from == min_char && to == max_char)
307 free_sub_tables (table, managedp);
309 M17N_OBJECT_REF (val);
310 table->default_value = val;
314 if (depth < CHAR_TAB_MAX_DEPTH)
316 if (! table->contents.tables)
317 make_sub_tables (table, managedp);
318 i = SUB_IDX (depth, from);
319 table = table->contents.tables + i;
320 while (i < chartab_slots[depth] && TABLE_MIN_CHAR (table) <= to)
322 set_chartable_range (table, from, to, val, managedp);
328 int idx_from = SUB_IDX (depth, from);
329 int idx_to = SUB_IDX (depth, to);
331 if (! table->contents.values)
332 make_sub_values (table, managedp);
333 for (i = idx_from; i <= idx_to; i++)
335 if (managedp && table->contents.values[i])
336 M17N_OBJECT_UNREF (table->contents.values[i]);
337 table->contents.values[i] = val;
340 M17N_OBJECT_REF_NTIMES (val, (idx_to - idx_from + 1));
345 /** Lookup the sub char-table TABLE for the character C. If NEXT_C is
346 not NULL, set *NEXT_C to the next interesting character to lookup
347 for. If DEFAULT_P is zero, the next interesting character is what
348 possibly has the different value than C. Otherwise, the next
349 interesting character is what possibly has the default value (if C
350 has a value deferent from the default value) or has a value
351 different from the default value (if C has the default value). */
354 lookup_chartable (MSubCharTable *table, int c, int *next_c, int default_p)
356 int depth = TABLE_DEPTH (table);
358 void *default_value = table->default_value;
363 if (! table->contents.tables)
366 *next_c = TABLE_MIN_CHAR (table) + chartab_chars[depth];
367 return table->default_value;
369 if (depth == CHAR_TAB_MAX_DEPTH)
371 table = table->contents.tables + SUB_IDX (depth, c);
375 idx = SUB_IDX (depth, c);
376 val = table->contents.values[idx];
380 int max_char = TABLE_MIN_CHAR (table) + (chartab_chars[depth] - 1);
382 if (max_char < 0 || max_char > MCHAR_MAX)
383 max_char = MCHAR_MAX;
384 if (default_p && val != default_value)
387 while (c >= 0 && c <= max_char
388 && table->contents.values[idx] != default_value);
393 while (c >= 0 && c <= max_char
394 && table->contents.values[idx] == val);
401 /** Call FUNC for characters in sub char-table TABLE. Ignore such
402 characters that has a value IGNORE. FUNC is called with four
403 arguments; FROM, TO, VAL, and ARG (same as FUNC_ARG). If
404 DEFAULT_P is zero, FROM and TO are range of characters that has
405 the same value VAL. Otherwise, FROM and TO are range of
406 characters that has the different value than the default value of
410 map_chartable (MSubCharTable *table, void *ignore, int default_p,
411 void (*func) (int, int, void *, void *),
418 current = lookup_chartable (table, 0, &next_c, default_p);
420 while (c >= 0 && c <= MCHAR_MAX)
422 void *next = lookup_chartable (table, c, &next_c, default_p);
426 if (current != ignore)
427 (*func) (from, c - 1, current, func_arg);
433 if (from <= MCHAR_MAX && current != ignore)
434 (*func) (from, MCHAR_MAX, current, func_arg);
438 /* Return the smallest character whose value is not DEFAULT_VALUE in
439 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
443 chartab_min_non_default_char (MSubCharTable *table, void *default_value)
445 int depth = TABLE_DEPTH (table);
449 if (!table->contents.tables)
450 return (default_value == table->default_value
451 ? -1 : TABLE_MIN_CHAR (table));
453 slots = chartab_slots[depth];
455 if (depth == CHAR_TAB_MAX_DEPTH)
457 for (i = 0; i < slots; i++)
458 if (table->contents.values[i] != default_value)
459 return (TABLE_MIN_CHAR (table) + i);
463 for (i = 0; i < slots; i++)
464 if ((c = chartab_min_non_default_char (table->contents.tables + i,
473 /* Return the largest character whose value is not DEFAULT_VALUE in
474 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
478 chartab_max_non_default_char (MSubCharTable *table, void *default_value)
480 int depth = TABLE_DEPTH (table);
484 if (!table->contents.tables)
485 return (default_value == table->default_value
486 ? -1 : TABLE_MIN_CHAR (table) + chartab_chars[depth] - 1);
488 slots = chartab_slots[depth];
490 if (depth == CHAR_TAB_MAX_DEPTH)
492 for (i = slots - 1; i >= 0; i--)
493 if (table->contents.values[i] != default_value)
494 return (TABLE_MIN_CHAR (table) + i);
498 for (i = slots - 1; i >= 0; i--)
499 if ((c = chartab_max_non_default_char (table->contents.tables + i,
508 free_chartable (void *object)
510 MCharTable *table = (MCharTable *) object;
511 int managedp = table->key != Mnil && table->key->managing_key;
513 if (table->subtable.contents.tables)
517 for (i = 0; i < chartab_slots[0]; i++)
518 free_sub_tables (table->subtable.contents.tables + i, managedp);
519 free (table->subtable.contents.tables);
520 if (managedp && table->subtable.default_value)
521 M17N_OBJECT_UNREF (table->subtable.default_value);
523 M17N_OBJECT_UNREGISTER (chartable_table, table);
529 /* Support function of mdebug_dump_chartab. */
532 dump_sub_chartab (MSubCharTable *table, void *default_value,
533 MSymbol key, int indent)
535 int depth = TABLE_DEPTH (table);
536 int min_char = TABLE_MIN_CHAR (table);
537 int max_char = min_char + (chartab_chars[depth] - 1);
538 char *prefix = (char *) alloca (indent + 1);
541 if (max_char < 0 || max_char > MCHAR_MAX)
542 max_char = MCHAR_MAX;
544 memset (prefix, 32, indent);
547 if (! table->contents.tables && table->default_value == default_value)
549 fprintf (stderr, "\n%s(sub%d (U+%04X U+%04X) ",
550 prefix, depth, min_char, max_char);
553 if (table->default_value)
554 fprintf (stderr, "(default %s)",
555 ((MSymbol) table->default_value)->name);
557 fprintf (stderr, "(default nil)");
560 fprintf (stderr, "(default #x%X)", (unsigned) table->default_value);
562 default_value = table->default_value;
563 if (table->contents.tables)
565 if (depth < CHAR_TAB_MAX_DEPTH)
566 for (i = 0; i < chartab_slots[depth]; i++)
567 dump_sub_chartab (table->contents.tables + i, default_value,
570 for (i = 0; i < chartab_slots[depth]; i++, min_char++)
572 void **val = table->contents.values + i;
574 if (val == default_value)
576 default_value = *val;
577 fprintf (stderr, "\n%s (U+%04X", prefix, min_char);
578 while (i + 1 < chartab_slots[depth]
579 && val[1] == default_value)
580 i++, val++, min_char++;
581 fprintf (stderr, "-U+%04X ", min_char);
585 fprintf (stderr, "%s)", ((MSymbol) default_value)->name);
587 fprintf (stderr, "nil)");
590 fprintf (stderr, " #xx%X)", (unsigned) default_value);
593 fprintf (stderr, ")");
602 chartable_table.count = 0;
609 mdebug__report_object ("Chartable", &chartable_table);
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 @c merror_code. */
657 @brief ¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë
659 ´Ø¿ô mchartable () ¤Ï¥¡¼¤¬ $KEY ¤ÇÍ×ÁǤΥǥե©¥ë¥ÈÃͤ¬
660 $DEFAULT_VALUE ¤Ç¤¢¤ë¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë¡£¤â¤· $KEY ¤¬´ÉÍý¥¡¼
661 ¤Ç¤¢¤ì¤Ð¡¢¤³¤Î¥Æ¡¼¥Ö¥ë¤ÎÍ×ÁǤϡʥǥե©¥ë¥ÈÃͤò´Þ¤á¤Æ¡Ë´ÉÍý²¼¥ª¥Ö¥¸¥§
665 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable () ¤ÏºîÀ®¤µ¤ì¤¿Ê¸»ú¥Æ¡¼¥Ö¥ë¤Ø¤Î¥Ý¥¤¥ó
666 ¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨
667 ¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
670 mchartable (MSymbol key, void *default_value)
674 M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE);
675 M17N_OBJECT_REGISTER (chartable_table, table);
678 table->max_char = -1;
679 SET_DEPTH_MIN_CHAR (&table->subtable, 0, 0);
680 table->subtable.default_value = default_value;
681 if (key != Mnil && key->managing_key && default_value)
682 M17N_OBJECT_REF (default_value);
683 table->subtable.contents.tables = NULL;
690 @brief Return the assigned value of a character in a chartable.
692 The mchartable_lookup () function returns the value assigned to
693 character $C in chartable $TABLE. If no value has been set for $C
694 explicitly, the default value of $TABLE is returned. If $C is not
695 a valid character, mchartable_lookup () returns @c NULL and
696 assigns an error code to the external variable @c merror_code. */
699 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Çʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹
701 ´Ø¿ô mchartable_lookup () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Çʸ»ú $C ¤Ë³ä¤ê
702 Åö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹¡£$C ¤ËÂФ¹¤ëÌÀ¼¨Åª¤ÊÃͤ¬¤Ê¤±¤ì¤Ð¡¢$TABLE ¤Î¥Ç¥Õ¥©
703 ¥ë¥ÈÃͤòÊÖ¤¹¡£$C ¤¬ÂÅÅö¤Êʸ»ú¤Ç¤Ê¤±¤ì¤Ð¡¢mchartable_lookup () ¤Ï
704 @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
714 mchartable_lookup (MCharTable *table, int c)
716 M_CHECK_CHAR (c, NULL);
718 if (c < table->min_char || c > table->max_char)
719 return table->subtable.default_value;
720 return lookup_chartable (&table->subtable, c, NULL, 0);
726 @brief Assign a value to a character in a chartable.
728 The mchartable_set () function sets the value of character $C in
729 chartable $TABLE to $VAL.
732 If the operation was successful, mchartable_set () returns 0.
733 Otherwise it returns -1 and assigns an error code to the external
734 variable @c merror_code. */
737 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Ç¤Îʸ»ú¤ÎÃͤòÀßÄꤹ¤ë
739 ´Ø¿ô mchartable_set () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú $C ¤Ë
740 ÃÍ $VAL ¤ò³ä¤êÅö¤Æ¤ë¡£
743 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchartable_set () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1
744 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
751 mchartable_lookup (), mchartable_set_range () */
755 mchartable_set (MCharTable *table, int c, void *val)
757 int managedp = table->key != Mnil && table->key->managing_key;
758 MSubCharTable *sub = &table->subtable;
761 M_CHECK_CHAR (c, -1);
763 if (table->max_char < 0)
764 table->min_char = table->max_char = c;
767 if (c < table->min_char)
769 else if (c > table->max_char)
773 for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++)
775 if (! sub->contents.tables)
777 if (sub->default_value == val)
779 make_sub_tables (sub, managedp);
781 sub = sub->contents.tables + SUB_IDX (i, c);
783 if (! sub->contents.values)
785 if (sub->default_value == val)
787 make_sub_values (sub, managedp);
789 sub->contents.values[SUB_IDX (3, c)] = val;
791 M17N_OBJECT_REF (val);
798 @brief Assign a value to the characters in the specified range.
800 The mchartable_set_range () function assigns value $VAL to the
801 characters from $FROM to $TO (both inclusive) in chartable $TABLE.
804 If the operation was successful, mchartable_set_range () returns
805 0. Otherwise it returns -1 and assigns an error code to the
806 external variable @c merror_code. If $FROM is greater than $TO,
807 mchartable_set_range () returns immediately without an error. */
810 @brief »ØÄêÈϰϤÎʸ»ú¤ÎÃͤòÀßÄꤹ¤ë
812 ´Ø¿ô mchartable_set_range () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Î $FROM ¤«
813 ¤é $TO ¤Þ¤Ç¡Êξü¤ò´Þ¤à¡Ë¤Îʸ»ú¤Ë¡¢ÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£
816 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable_set_range () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
817 -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£$FROM ¤¬
818 $TO ¤è¤êÂ礤¤¤È¤¤Ë¤Ï¡¢ mchartable_set_range () ¤Ï²¿¤â¤»¤º¡¢¥¨¥é¡¼
829 mchartable_set_range (MCharTable *table, int from, int to, void *val)
831 int managedp = table->key != Mnil && table->key->managing_key;
833 M_CHECK_CHAR (from, -1);
834 M_CHECK_CHAR (to, -1);
839 if (table->max_char < 0)
840 table->min_char = from, table->max_char = to;
842 if (from < table->min_char)
843 table->min_char = from;
844 if (to > table->max_char)
845 table->max_char = to;
847 set_chartable_range (&table->subtable, from, to, val, managedp);
854 @brief Search for characters that have non-default value.
856 The mchartable_range () function searches chartable $TABLE for the
857 first and the last character codes that do not have the default
858 value of $TABLE, and set $FROM and $TO to them, respectively. If
859 all characters have the default value, both $FROM and $TO are set
863 @brief Ãͤ¬¥Ç¥Õ¥©¥ë¥È¤È°Û¤Ê¤ëʸ»ú¤òõ¤¹
865 ´Ø¿ô mchartable_range () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Ç¡¢$TABLE ¤Î¥Ç¥Õ¥©
866 ¥ë¥ÈÃͰʳ°¤ÎÃͤò»ý¤ÄºÇ½é¤ÈºÇ¸å¤Îʸ»ú¤òÄ´¤Ù¡¢¤½¤ì¤¾¤ì¤ò $FROM ¤È
867 $TO ¤ËÀßÄꤹ¤ë¡£¤¹¤Ù¤Æ¤Îʸ»ú¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤòÃͤȤ·¤Æ»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
868 $FROM ¤È $TO ¤ò -1¤ËÀßÄꤹ¤ë¡£ */
871 mchartable_range (MCharTable *table, int *from, int *to)
873 *from = chartab_min_non_default_char (&table->subtable,
874 table->subtable.default_value);
878 *to = chartab_max_non_default_char (&table->subtable,
879 table->subtable.default_value);
885 @brief Call a function for characters in a chartable.
887 The mchartable_map () function calls function $FUNC for characters
888 in chartable $TABLE. No function call occurs for characters that
889 have value $IGNORE in $TABLE. Comparison of $IGNORE and character
890 value is done with the operator @c ==. Be careful when you use
891 string literals or pointers.
893 Instead of calling $FUNC for each character, mchartable_map ()
894 tries to optimize the number of function calls, i.e. it makes a
895 single function call for a chunk of characters when those
896 consecutive characters have the same value.
898 No matter how long the character chunk is, $FUNC is called with
899 four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both
900 inclusive) defines the range of characters that have value $VAL.
901 $ARG is the same as $FUNC_ARG.
904 This function always returns 0. */
907 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Îʸ»ú¤ËÂФ·¤Æ»ØÄê¤Î´Ø¿ô¤ò¸Æ¤Ö
909 ´Ø¿ô mchartable_map () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú¤ËÂФ·¤Æ´Ø
910 ¿ô $FUNC ¤ò¸Æ¤Ö¡£¤¿¤À¤·Ãͤ¬ $IGNORE ¤Ç¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô¸Æ¤Ó½Ð
911 ¤·¤ò¹Ô¤Ê¤ï¤Ê¤¤¡£$IGNORE ¤Èʸ»ú¤ÎÃͤÎÈæ³Ó¤Ï @c == ¤Ç¹Ô¤Ê¤¦¤Î¤Ç¡¢Ê¸»úÎó
912 ¥ê¥Æ¥é¥ë¤ä¥Ý¥¤¥ó¥¿¤ò»È¤¦ºÝ¤Ë¤ÏÃí°Õ¤òÍפ¹¤ë¡£
914 mchartable_map () ¤Ï¡¢°ìʸ»ú¤´¤È¤Ë $FUNC ¤ò¸Æ¤Ö¤Î¤Ç¤Ï¤Ê¤¯¡¢´Ø¿ô¸Æ
915 ¤Ó½Ð¤·¤Î²ó¿ô¤òºÇŬ²½¤·¤è¤¦¤È¤¹¤ë¡£¤¹¤Ê¤ï¤Á¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸Ãͤò
916 »ý¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Îʸ»ú¤Î¤Þ¤È¤Þ¤êÁ´ÂΤˤĤ¤¤Æ°ìÅ٤δؿô¸Æ¤Ó½Ð
919 ʸ»ú¤Î¤Þ¤È¤Þ¤ê¤ÎÂ礤µ¤Ë¤«¤«¤ï¤é¤º¡¢$FUNC ¤Ï $FROM, $TO, $VAL, $ARG
920 ¤Î£´°ú¿ô¤Ç¸Æ¤Ð¤ì¤ë¡£$FROM ¤È $TO ¡Êξü¤ò´Þ¤à¡Ë¤Ï $VAL ¤òÃͤȤ·¤Æ
921 »ý¤Äʸ»ú¤ÎÈϰϤò¼¨¤·¡¢$ARG ¤Ï $FUNC_ARG ¤½¤Î¤â¤Î¤Ç¤¢¤ë¡£
924 ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë0¤òÊÖ¤¹¡£ */
927 mchartable_map (MCharTable *table, void *ignore,
928 void (*func) (int, int, void *, void *),
931 map_chartable (&table->subtable, ignore, 0, func, func_arg);
939 /*** @addtogroup m17nDebug */
944 @brief Dump a chartable.
946 The mdebug_dump_chartab () function prints a chartable $TABLE in a
947 human readable way to the stderr. $INDENT specifies how many
948 columns to indent the lines but the first one.
951 This function returns $TABLE. */
954 mdebug_dump_chartab (MCharTable *table, int indent)
956 fprintf (stderr, "(chartab (U+%04X U+%04X)",
957 table->min_char, table->max_char);
958 dump_sub_chartab (&table->subtable, table->subtable.default_value,
959 table->key, indent + 2);
960 fprintf (stderr, ")");