1 /* chartab.h -- character table module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
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 (mdebug__output, "\n%s(sub%d (U+%04X U+%04X) ",
551 prefix, depth, min_char, max_char);
554 if (table->default_value)
555 fprintf (mdebug__output, "(default %s)",
556 ((MSymbol) table->default_value)->name);
558 fprintf (mdebug__output, "(default nil)");
561 fprintf (mdebug__output, "(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 (mdebug__output, "\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 (mdebug__output, "-U+%04X ", min_char);
586 fprintf (mdebug__output, "%s)",
587 ((MSymbol) default_value)->name);
589 fprintf (mdebug__output, "nil)");
592 fprintf (mdebug__output, " #xx%X)", (unsigned) default_value);
595 fprintf (mdebug__output, ")");
604 M17N_OBJECT_ADD_ARRAY (chartable_table, "Chartable");
614 mchartable__lookup (MCharTable *table, int c, int *next_c, int default_p)
616 return lookup_chartable (&table->subtable, c, next_c, default_p);
620 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
625 /*** @addtogroup m17nChartable */
630 @brief Symbol whose name is "char-table".
632 The symbol @c Mchar_table has the name <tt>"char-table"</tt>. */
635 @brief "char-table" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
637 ¥·¥ó¥Ü¥ë @c Mchar_table ¤Ï̾Á° <tt>"char-table"</tt> ¤ò»ý¤Ä¡£
645 @brief Create a new chartable.
647 The mchartable () function creates a new chartable object with
648 symbol $KEY and the default value $DEFAULT_VALUE. If $KEY is a
649 managing key, the elements of the table (including the default
650 value) are managed objects or NULL.
653 If the operation was successful, mchartable () returns a pointer
654 to the created chartable. Otherwise it returns @c NULL and
655 assigns an error code to the external variable #merror_code. */
658 @brief ¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë.
660 ´Ø¿ô mchartable () ¤Ï¥¡¼¤¬ $KEY ¤ÇÍ×ÁǤΥǥե©¥ë¥ÈÃͤ¬
661 $DEFAULT_VALUE ¤Ç¤¢¤ë¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë¡£¤â¤· $KEY
662 ¤¬´ÉÍý¥¡¼¤Ç¤¢¤ì¤Ð¡¢¤³¤Î¥Æ¡¼¥Ö¥ë¤ÎÍ×ÁǤϡʥǥե©¥ë¥ÈÃͤò´Þ¤á¤Æ¡Ë´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤«
663 NULL ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
666 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable () ¤ÏºîÀ®¤µ¤ì¤¿Ê¸»ú¥Æ¡¼¥Ö¥ë¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
667 ¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
670 mchartable (MSymbol key, void *default_value)
674 M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE);
675 M17N_OBJECT_REGISTER (chartable_table, table);
677 table->min_char = -1;
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 minimum character whose value is set in a chartabe.
692 The mchartable_min_char () function return the minimum character
693 whose value is set in chartable $TABLE. No character is set its
694 value, the function returns -1.
698 mchartable_min_char (MCharTable *table)
700 return table->min_char;
706 @brief Return the maximum character whose value is set in a chartabe.
708 The mchartable_max_char () function return the maximum character
709 whose value is set in chartable $TABLE. No character is set its
710 value, the function returns -1.
714 mchartable_max_char (MCharTable *table)
716 return table->max_char;
722 @brief Return the assigned value of a character in a chartable.
724 The mchartable_lookup () function returns the value assigned to
725 character $C in chartable $TABLE. If no value has been set for $C
726 explicitly, the default value of $TABLE is returned. If $C is not
727 a valid character, mchartable_lookup () returns @c NULL and
728 assigns an error code to the external variable #merror_code. */
731 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Çʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹.
733 ´Ø¿ô mchartable_lookup () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Çʸ»ú $C
734 ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹¡£$C ¤ËÂФ¹¤ëÌÀ¼¨Åª¤ÊÃͤ¬¤Ê¤±¤ì¤Ð¡¢$TABLE
735 ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòÊÖ¤¹¡£$C ¤¬ÂÅÅö¤Êʸ»ú¤Ç¤Ê¤±¤ì¤Ð¡¢mchartable_lookup () ¤Ï
736 @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
746 mchartable_lookup (MCharTable *table, int c)
748 M_CHECK_CHAR (c, NULL);
750 if (c < table->min_char || c > table->max_char)
751 return table->subtable.default_value;
752 return lookup_chartable (&table->subtable, c, NULL, 0);
758 @brief Assign a value to a character in a chartable.
760 The mchartable_set () function sets the value of character $C in
761 chartable $TABLE to $VAL.
764 If the operation was successful, mchartable_set () returns 0.
765 Otherwise it returns -1 and assigns an error code to the external
766 variable #merror_code. */
769 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Ç¤Îʸ»ú¤ÎÃͤòÀßÄꤹ¤ë.
771 ´Ø¿ô mchartable_set () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú $C
772 ¤ËÃÍ $VAL ¤ò³ä¤êÅö¤Æ¤ë¡£
775 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchartable_set () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1
776 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
783 mchartable_lookup (), mchartable_set_range () */
787 mchartable_set (MCharTable *table, int c, void *val)
789 int managedp = table->key != Mnil && table->key->managing_key;
790 MSubCharTable *sub = &table->subtable;
793 M_CHECK_CHAR (c, -1);
795 if (table->max_char < 0)
796 table->min_char = table->max_char = c;
799 if (c < table->min_char)
801 else if (c > table->max_char)
805 for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++)
807 if (! sub->contents.tables)
809 if (sub->default_value == val)
811 make_sub_tables (sub, managedp);
813 sub = sub->contents.tables + SUB_IDX (i, c);
815 if (! sub->contents.values)
817 if (sub->default_value == val)
819 make_sub_values (sub, managedp);
821 sub->contents.values[SUB_IDX (3, c)] = val;
823 M17N_OBJECT_REF (val);
830 @brief Assign a value to the characters in the specified range.
832 The mchartable_set_range () function assigns value $VAL to the
833 characters from $FROM to $TO (both inclusive) in chartable $TABLE.
836 If the operation was successful, mchartable_set_range () returns
837 0. Otherwise it returns -1 and assigns an error code to the
838 external variable #merror_code. If $FROM is greater than $TO,
839 mchartable_set_range () returns immediately without an error. */
842 @brief »ØÄêÈϰϤÎʸ»ú¤ËÃͤòÀßÄꤹ¤ë.
844 ´Ø¿ô mchartable_set_range () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Î $FROM
845 ¤«¤é $TO ¤Þ¤Ç¡Êξü¤ò´Þ¤à¡Ë¤Îʸ»ú¤Ë¡¢ÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£
848 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable_set_range () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
849 -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£$FROM ¤¬
850 $TO ¤è¤êÂ礤¤¤È¤¤Ë¤Ï¡¢ mchartable_set_range ()
851 ¤Ï²¿¤â¤»¤º¡¢¥¨¥é¡¼¤âµ¯¤³¤µ¤Ê¤¤¡£ */
861 mchartable_set_range (MCharTable *table, int from, int to, void *val)
863 int managedp = table->key != Mnil && table->key->managing_key;
865 M_CHECK_CHAR (from, -1);
866 M_CHECK_CHAR (to, -1);
871 if (table->max_char < 0)
872 table->min_char = from, table->max_char = to;
874 if (from < table->min_char)
875 table->min_char = from;
876 if (to > table->max_char)
877 table->max_char = to;
879 set_chartable_range (&table->subtable, from, to, val, managedp);
886 @brief Search for characters that have non-default value.
888 The mchartable_range () function searches chartable $TABLE for the
889 first and the last character codes that do not have the default
890 value of $TABLE, and set $FROM and $TO to them, respectively. If
891 all characters have the default value, both $FROM and $TO are set
895 @brief Ãͤ¬¥Ç¥Õ¥©¥ë¥È¤È°Û¤Ê¤ëʸ»ú¤òõ¤¹.
897 ´Ø¿ô mchartable_range () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Ç¡¢$TABLE
898 ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͰʳ°¤ÎÃͤò»ý¤ÄºÇ½é¤ÈºÇ¸å¤Îʸ»ú¤òõ¤·¡¢¤½¤ì¤¾¤ì¤ò $FROM
899 ¤È $TO ¤ËÀßÄꤹ¤ë¡£¤¹¤Ù¤Æ¤Îʸ»ú¤¬ÃͤȤ·¤Æ¥Ç¥Õ¥©¥ë¥ÈÃͤò¤È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï
900 $FROM ¤È $TO ¤ò -1¤ËÀßÄꤹ¤ë¡£ */
903 mchartable_range (MCharTable *table, int *from, int *to)
905 *from = chartab_min_non_default_char (&table->subtable,
906 table->subtable.default_value);
910 *to = chartab_max_non_default_char (&table->subtable,
911 table->subtable.default_value);
917 @brief Call a function for characters in a chartable.
919 The mchartable_map () function calls function $FUNC for characters
920 in chartable $TABLE. No function call occurs for characters that
921 have value $IGNORE in $TABLE. Comparison of $IGNORE and character
922 value is done with the operator @c ==. Be careful when you use
923 string literals or pointers.
925 Instead of calling $FUNC for each character, mchartable_map ()
926 tries to optimize the number of function calls, i.e. it makes a
927 single function call for a chunk of characters when those
928 consecutive characters have the same value.
930 No matter how long the character chunk is, $FUNC is called with
931 four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both
932 inclusive) defines the range of characters that have value $VAL.
933 $ARG is the same as $FUNC_ARG.
936 This function always returns 0. */
939 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Îʸ»ú¤ËÂФ·¤Æ»ØÄê¤Î´Ø¿ô¤ò¸Æ¤Ö.
941 ´Ø¿ô mchartable_map () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú¤ËÂФ·¤Æ´Ø¿ô
942 $FUNC ¤ò¸Æ¤Ö¡£¤¿¤À¤·$TABLE Ãæ¤Ç¤âÃͤ¬ $IGNORE
943 ¤Ç¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô¸Æ¤Ó½Ð¤·¤ò¹Ô¤Ê¤ï¤Ê¤¤¡£$IGNORE ¤Èʸ»ú¤ÎÃͤÎÈæ³Ó¤Ï
944 @c == ¤Ç¹Ô¤Ê¤¦¤Î¤Ç¡¢Ê¸»úÎó¥ê¥Æ¥é¥ë¤ä¥Ý¥¤¥ó¥¿¤ò»È¤¦ºÝ¤Ë¤ÏÃí°Õ¤òÍפ¹¤ë¡£
946 mchartable_map () ¤Ï¡¢°ìʸ»ú¤´¤È¤Ë $FUNC
947 ¤ò¸Æ¤Ö¤Î¤Ç¤Ï¤Ê¤¯¡¢´Ø¿ô¸Æ¤Ó½Ð¤·¤Î²ó¿ô¤òºÇŬ²½¤·¤è¤¦¤È¤¹¤ë¡£
948 ¤¹¤Ê¤ï¤Á¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸Ãͤò»ý¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Îʸ»ú¤Î¤Þ¤È¤Þ¤êÁ´ÂΤˤĤ¤¤Æ°ìÅ٤δؿô¸Æ¤Ó½Ð
951 ʸ»ú¤Î¤Þ¤È¤Þ¤ê¤ÎÂ礤µ¤Ë¤«¤«¤ï¤é¤º¡¢$FUNC ¤Ï $FROM, $TO, $VAL, $ARG
952 ¤Î£´°ú¿ô¤Ç¸Æ¤Ð¤ì¤ë¡£$FROM ¤È $TO ¡Êξü¤ò´Þ¤à¡Ë¤Ï $VAL
953 ¤òÃͤȤ·¤Æ»ý¤Äʸ»ú¤ÎÈϰϤò¼¨¤·¡¢$ARG ¤Ï $FUNC_ARG ¤½¤Î¤â¤Î¤Ç¤¢¤ë¡£
956 ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë0¤òÊÖ¤¹¡£ */
959 mchartable_map (MCharTable *table, void *ignore,
960 void (*func) (int, int, void *, void *),
963 map_chartable (&table->subtable, ignore, 0, func, func_arg);
971 /*** @addtogroup m17nDebug */
976 @brief Dump a chartable.
978 The mdebug_dump_chartab () function prints a chartable $TABLE in a
979 human readable way to the stderr or to what specified by the
980 environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
981 many columns to indent the lines but the first one.
984 This function returns $TABLE. */
987 @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤ò¥À¥ó¥×¤¹¤ë.
989 ´Ø¿ô mdebug_dump_chartab () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE ¤òɸ½à¥¨¥é¡¼½ÐÎÏ
990 ¤â¤·¤¯¤Ï´Ä¶ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆÉ
991 ¤Ê·Á¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
994 ¤³¤Î´Ø¿ô¤Ï $TABLE ¤òÊÖ¤¹¡£ */
997 mdebug_dump_chartab (MCharTable *table, int indent)
999 fprintf (mdebug__output, "(chartab (U+%04X U+%04X)",
1000 table->min_char, table->max_char);
1001 dump_sub_chartab (&table->subtable, table->subtable.default_value,
1002 table->key, indent + 2);
1003 fprintf (mdebug__output, ")");