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 ³¤·¤¿Ê¸»ú¥³¡¼¥É¤ò»ý¤Äʸ»ú¤ÏƱ¤¸¾ðÊó¤ò»ý¤Ä¤³¤È¤¬Â¿¤¤¡£
55 ¤³¤Î¤è¤¦¤Ê·¹¸þ¤òÍøÍѤ·¤Æʸ»ú¤È¤½¤ÎÉղþðÊó¤ò¸úΨŪ¤Ë³ÊǼ¤¹¤ë¤¿¤á¤Ë¡¢
56 m17n ¥é¥¤¥Ö¥é¥ê¤Ï @e ʸ»ú¥Æ¡¼¥Ö¥ë (chartable) ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤ò
57 ÍѤ¤¤ë¡£Ê¸»ú¥Æ¡¼¥Ö¥ë¤ÏÇÛÎó¤Ç¤Ï¤Ê¤¤¤¬¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï
58 ʸ»ú¥Æ¡¼¥Ö¥ë¤òÇÛÎó¤Î°ì¼ï¤È¤·¤Æ°·¤¦¤³¤È¤¬¤Ç¤¤ë¡£¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤ÎÆÃ
59 Äê¤Î¾ðÊó¤Ï¡¢¤½¤Î¾ðÊó¤ò»ý¤Äʸ»ú¥Æ¡¼¥Ö¥ë¤ò¤½¤Îʸ»ú¤Î¥³¡¼¥É¤Ç°ú¤¯¤³¤È
62 ʸ»ú¥Æ¡¼¥Ö¥ë¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ */
65 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
66 /*** @addtogroup m17nInternal
77 #include "m17n-misc.h"
81 static M17NObjectArray chartable_table;
83 /*** Maximum depth of char-table. */
84 #define CHAR_TAB_MAX_DEPTH 3
86 /** @name Define: Number of characters covered by char-table of each level.
89 /** BITs for number of characters covered by char-table of each
91 #if MCHAR_MAX < 0x400000
93 #define SUB_BITS_0 22 /* i.e. 0x400000 chars */
94 #define SUB_BITS_1 16 /* i.e. 0x10000 chars */
95 #define SUB_BITS_2 12 /* i.e. 0x1000 chars */
96 #define SUB_BITS_3 7 /* i.e. 0x80 chars */
98 #else /* MCHAR_MAX >= 0x400000 */
100 #define SUB_BITS_0 31
101 #define SUB_BITS_1 24
102 #define SUB_BITS_2 16
108 /** How many characters a char-table covers at each level. */
109 static const int chartab_chars[] =
115 /** How many slots a char-table has at each level. */
116 static const int chartab_slots[] =
117 { (1 << (SUB_BITS_0 - SUB_BITS_1)),
118 (1 << (SUB_BITS_1 - SUB_BITS_2)),
119 (1 << (SUB_BITS_2 - SUB_BITS_3)),
122 /** Mask bits to obtain the valid bits from a character code for looking
123 up a char-table of each level. */
124 static const int chartab_mask[] =
125 { (int) ((((unsigned) 1) << SUB_BITS_0) - 1),
126 (1 << SUB_BITS_1) - 1,
127 (1 << SUB_BITS_2) - 1,
128 (1 << SUB_BITS_3) - 1 };
130 /** Bit-shifting counts to obtain a valid index from a character code
131 for looking up a char-table of each level. */
132 static const int chartab_shift[] =
133 { SUB_BITS_1, SUB_BITS_2, SUB_BITS_3, 0 };
136 /** Index for looking up character C in a char-table at DEPTH. */
137 #define SUB_IDX(depth, c) \
138 (((c) & chartab_mask[depth]) >> chartab_shift[depth])
141 /** Structure of sub char-table. */
142 typedef struct MSubCharTable MSubCharTable;
148 /* The depth of the table; 0, 1, 2, or 3. */
151 /* The minimum character covered by the table. */
154 #else /* SUB_BITS_0 <= 24 */
156 /* The value is ((<depth> << 24) | <min_char>). */
159 #endif /* SUB_BITS_0 <= 24 */
161 /** The default value of characters covered by the table. */
164 /** For a table of bottom level, array of values. For a non-bottom
165 table, array of sub char-tables. It may be NULL if all
166 characters covered by the table has <default_value>. */
169 MSubCharTable *tables;
174 #define TABLE_DEPTH(table) ((table)->depth)
175 #define TABLE_MIN_CHAR(table) ((table)->min_char)
176 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
177 ((table)->depth = (DEPTH), (table)->min_char = (MIN_CHAR))
178 #else /* SUB_BITS_0 <= 24 */
179 #define TABLE_DEPTH(table) ((table)->depth_min_char >> 24)
180 #define TABLE_MIN_CHAR(table) ((table)->depth_min_char & 0xFFFFFF)
181 #define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
182 ((table)->depth_min_char = ((DEPTH) << 24) | (MIN_CHAR))
183 #endif /* SUB_BITS_0 <= 24 */
185 /** Structure of char-table. */
189 /** Common header for a managed object. */
192 /** Key of the table. */
195 /** The minimum and maximum characters covered by the table. */
196 int min_char, max_char;
198 MSubCharTable subtable;
204 /* Local functions. */
206 /** Allocate and initialize an array of sub-tables for sub char-table
207 TABLE. It is assumed that TABLE_DEPTH (TABLE) <
208 CHAR_TAB_MAX_DEPTH.*/
211 make_sub_tables (MSubCharTable *table, int managedp)
213 int depth = TABLE_DEPTH (table);
214 int min_char = TABLE_MIN_CHAR (table);
215 int slots = chartab_slots[depth];
216 int chars = chartab_chars[depth + 1];
217 MSubCharTable *tables;
220 MTABLE_MALLOC (tables, slots, MERROR_CHARTABLE);
222 for (i = 0; i < slots; i++, min_char += chars)
224 SET_DEPTH_MIN_CHAR (tables + i, depth + 1, min_char);
225 tables[i].default_value = table->default_value;
226 tables[i].contents.tables = NULL;
228 if (managedp && table->default_value)
229 M17N_OBJECT_REF_NTIMES (tables->default_value, slots);
230 table->contents.tables = tables;
234 /** Allocate and initialize an array of values for sub char-table
235 TABLE. It is assumed that TABLE_DEPTH (TABLE) ==
236 CHAR_TAB_MAX_DEPTH. */
239 make_sub_values (MSubCharTable *table, int managedp)
241 int slots = chartab_slots[CHAR_TAB_MAX_DEPTH];
245 MTABLE_MALLOC (values, slots, MERROR_CHARTABLE);
247 for (i = 0; i < slots; i++)
248 values[i] = table->default_value;
249 if (managedp && table->default_value)
250 M17N_OBJECT_REF_NTIMES (table->default_value, slots);
251 table->contents.values = values;
255 /** Free contents of sub char-table TABLE and the default value of
256 TABLE. Free also the sub-tables recursively. */
259 free_sub_tables (MSubCharTable *table, int managedp)
261 int depth = TABLE_DEPTH (table);
262 int slots = chartab_slots[depth];
264 if (table->contents.tables)
266 if (depth < CHAR_TAB_MAX_DEPTH)
269 free_sub_tables (table->contents.tables + slots, managedp);
270 free (table->contents.tables);
277 if (table->contents.values[slots])
278 M17N_OBJECT_UNREF (table->contents.values[slots]);
280 free (table->contents.values);
282 table->contents.tables = NULL;
284 if (managedp && table->default_value)
285 M17N_OBJECT_UNREF (table->default_value);
289 /** In sub char-table TABLE, set value VAL for characters of the range
293 set_chartable_range (MSubCharTable *table, int from, int to, void *val,
296 int depth = TABLE_DEPTH (table);
297 int min_char = TABLE_MIN_CHAR (table);
298 int max_char = min_char + (chartab_chars[depth] - 1);
301 if (max_char < 0 || max_char > MCHAR_MAX)
302 max_char = MCHAR_MAX;
309 if (from == min_char && to == max_char)
311 free_sub_tables (table, managedp);
313 M17N_OBJECT_REF (val);
314 table->default_value = val;
318 if (depth < CHAR_TAB_MAX_DEPTH)
320 if (! table->contents.tables)
321 make_sub_tables (table, managedp);
322 i = SUB_IDX (depth, from);
323 table = table->contents.tables + i;
324 while (i < chartab_slots[depth] && TABLE_MIN_CHAR (table) <= to)
326 set_chartable_range (table, from, to, val, managedp);
332 int idx_from = SUB_IDX (depth, from);
333 int idx_to = SUB_IDX (depth, to);
335 if (! table->contents.values)
336 make_sub_values (table, managedp);
337 for (i = idx_from; i <= idx_to; i++)
339 if (managedp && table->contents.values[i])
340 M17N_OBJECT_UNREF (table->contents.values[i]);
341 table->contents.values[i] = val;
344 M17N_OBJECT_REF_NTIMES (val, (idx_to - idx_from + 1));
349 /** Lookup the sub char-table TABLE for the character C. If NEXT_C is
350 not NULL, set *NEXT_C to the next interesting character to lookup
351 for. If DEFAULT_P is zero, the next interesting character is what
352 possibly has the different value than C. Otherwise, the next
353 interesting character is what possibly has the default value (if C
354 has a value deferent from the default value) or has a value
355 different from the default value (if C has the default value). */
358 lookup_chartable (MSubCharTable *table, int c, int *next_c, int default_p)
360 int depth = TABLE_DEPTH (table);
362 void *default_value = table->default_value;
367 if (! table->contents.tables)
370 *next_c = TABLE_MIN_CHAR (table) + chartab_chars[depth];
371 return table->default_value;
373 if (depth == CHAR_TAB_MAX_DEPTH)
375 table = table->contents.tables + SUB_IDX (depth, c);
379 idx = SUB_IDX (depth, c);
380 val = table->contents.values[idx];
384 int max_char = TABLE_MIN_CHAR (table) + (chartab_chars[depth] - 1);
386 if (max_char < 0 || max_char > MCHAR_MAX)
387 max_char = MCHAR_MAX;
388 if (default_p && val != default_value)
391 while (c >= 0 && c <= max_char
392 && table->contents.values[idx] != default_value);
397 while (c >= 0 && c <= max_char
398 && table->contents.values[idx] == val);
405 /** Call FUNC for characters in sub char-table TABLE. Ignore such
406 characters that has a value IGNORE. FUNC is called with four
407 arguments; FROM, TO, VAL, and ARG (same as FUNC_ARG). If
408 DEFAULT_P is zero, FROM and TO are range of characters that has
409 the same value VAL. Otherwise, FROM and TO are range of
410 characters that has the different value than the default value of
414 map_chartable (MSubCharTable *table, void *ignore, int default_p,
415 void (*func) (int, int, void *, void *),
422 current = lookup_chartable (table, 0, &next_c, default_p);
424 while (c >= 0 && c <= MCHAR_MAX)
426 void *next = lookup_chartable (table, c, &next_c, default_p);
430 if (current != ignore)
431 (*func) (from, c - 1, current, func_arg);
437 if (from <= MCHAR_MAX && current != ignore)
438 (*func) (from, MCHAR_MAX, current, func_arg);
442 /* Return the smallest character whose value is not DEFAULT_VALUE in
443 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
447 chartab_min_non_default_char (MSubCharTable *table, void *default_value)
449 int depth = TABLE_DEPTH (table);
453 if (!table->contents.tables)
454 return (default_value == table->default_value
455 ? -1 : TABLE_MIN_CHAR (table));
457 slots = chartab_slots[depth];
459 if (depth == CHAR_TAB_MAX_DEPTH)
461 for (i = 0; i < slots; i++)
462 if (table->contents.values[i] != default_value)
463 return (TABLE_MIN_CHAR (table) + i);
467 for (i = 0; i < slots; i++)
468 if ((c = chartab_min_non_default_char (table->contents.tables + i,
477 /* Return the largest character whose value is not DEFAULT_VALUE in
478 TABLE. If all characters in TABLE have DEFAULT_VALUE, return
482 chartab_max_non_default_char (MSubCharTable *table, void *default_value)
484 int depth = TABLE_DEPTH (table);
488 if (!table->contents.tables)
489 return (default_value == table->default_value
490 ? -1 : TABLE_MIN_CHAR (table) + chartab_chars[depth] - 1);
492 slots = chartab_slots[depth];
494 if (depth == CHAR_TAB_MAX_DEPTH)
496 for (i = slots - 1; i >= 0; i--)
497 if (table->contents.values[i] != default_value)
498 return (TABLE_MIN_CHAR (table) + i);
502 for (i = slots - 1; i >= 0; i--)
503 if ((c = chartab_max_non_default_char (table->contents.tables + i,
512 free_chartable (void *object)
514 MCharTable *table = (MCharTable *) object;
515 int managedp = table->key != Mnil && table->key->managing_key;
517 if (table->subtable.contents.tables)
521 for (i = 0; i < chartab_slots[0]; i++)
522 free_sub_tables (table->subtable.contents.tables + i, managedp);
523 free (table->subtable.contents.tables);
524 if (managedp && table->subtable.default_value)
525 M17N_OBJECT_UNREF (table->subtable.default_value);
527 M17N_OBJECT_UNREGISTER (chartable_table, table);
533 /* Support function of mdebug_dump_chartab. */
536 dump_sub_chartab (MSubCharTable *table, void *default_value,
537 MSymbol key, int indent)
539 int depth = TABLE_DEPTH (table);
540 int min_char = TABLE_MIN_CHAR (table);
541 int max_char = min_char + (chartab_chars[depth] - 1);
542 char *prefix = (char *) alloca (indent + 1);
545 if (max_char < 0 || max_char > MCHAR_MAX)
546 max_char = MCHAR_MAX;
548 memset (prefix, 32, indent);
551 if (! table->contents.tables && table->default_value == default_value)
553 fprintf (stderr, "\n%s(sub%d (U+%04X U+%04X) ",
554 prefix, depth, min_char, max_char);
557 if (table->default_value)
558 fprintf (stderr, "(default %s)",
559 ((MSymbol) table->default_value)->name);
561 fprintf (stderr, "(default nil)");
564 fprintf (stderr, "(default #x%X)", (unsigned) table->default_value);
566 default_value = table->default_value;
567 if (table->contents.tables)
569 if (depth < CHAR_TAB_MAX_DEPTH)
570 for (i = 0; i < chartab_slots[depth]; i++)
571 dump_sub_chartab (table->contents.tables + i, default_value,
574 for (i = 0; i < chartab_slots[depth]; i++, min_char++)
576 void **val = table->contents.values + i;
578 if (val == default_value)
580 default_value = *val;
581 fprintf (stderr, "\n%s (U+%04X", prefix, min_char);
582 while (i + 1 < chartab_slots[depth]
583 && val[1] == default_value)
584 i++, val++, min_char++;
585 fprintf (stderr, "-U+%04X ", min_char);
589 fprintf (stderr, "%s)", ((MSymbol) default_value)->name);
591 fprintf (stderr, "nil)");
594 fprintf (stderr, " #xx%X)", (unsigned) default_value);
597 fprintf (stderr, ")");
606 chartable_table.count = 0;
613 mdebug__report_object ("Chartable", &chartable_table);
617 mchartable__lookup (MCharTable *table, int c, int *next_c, int default_p)
619 return lookup_chartable (&table->subtable, c, next_c, default_p);
623 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
628 /*** @addtogroup m17nChartable */
633 @brief Symbol whose name is "char-table".
635 The symbol @c Mchar_table has the name <tt>"char-table"</tt>. */
638 @brief "char-table" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
640 ¥·¥ó¥Ü¥ë @c Mchar_table ¤Ï̾Á° <tt>"char-table"</tt> ¤ò»ý¤Ä¡£
648 @brief Create a new chartable.
650 The mchartable () function creates a new chartable object with
651 symbol $KEY and the default value $DEFAULT_VALUE. If $KEY is a
652 managing key, the elements of the table (including the default
653 value) are managed objects or NULL.
656 If the operation was successful, mchartable () returns a pointer
657 to the created chartable. Otherwise it returns @c NULL and
658 assigns an error code to the external variable #merror_code. */
661 @brief ¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë.
663 ´Ø¿ô mchartable () ¤Ï¥¡¼¤¬ $KEY ¤ÇÍ×ÁǤΥǥե©¥ë¥ÈÃͤ¬
664 $DEFAULT_VALUE ¤Ç¤¢¤ë¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë¡£¤â¤· $KEY ¤¬´ÉÍý¥¡¼
665 ¤Ç¤¢¤ì¤Ð¡¢¤³¤Î¥Æ¡¼¥Ö¥ë¤ÎÍ×ÁǤϡʥǥե©¥ë¥ÈÃͤò´Þ¤á¤Æ¡Ë´ÉÍý²¼¥ª¥Ö¥¸¥§
666 ¥¯¥È¤« NULL ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
669 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable () ¤ÏºîÀ®¤µ¤ì¤¿Ê¸»ú¥Æ¡¼¥Ö¥ë¤Ø¤Î¥Ý¥¤¥ó
670 ¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨
671 ¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
674 mchartable (MSymbol key, void *default_value)
678 M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE);
679 M17N_OBJECT_REGISTER (chartable_table, table);
682 table->max_char = -1;
683 SET_DEPTH_MIN_CHAR (&table->subtable, 0, 0);
684 table->subtable.default_value = default_value;
685 if (key != Mnil && key->managing_key && default_value)
686 M17N_OBJECT_REF (default_value);
687 table->subtable.contents.tables = NULL;
694 @brief Return the assigned value of a character in a chartable.
696 The mchartable_lookup () function returns the value assigned to
697 character $C in chartable $TABLE. If no value has been set for $C
698 explicitly, the default value of $TABLE is returned. If $C is not
699 a valid character, mchartable_lookup () returns @c NULL and
700 assigns an error code to the external variable #merror_code. */
703 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Çʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹.
705 ´Ø¿ô mchartable_lookup () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Çʸ»ú $C ¤Ë³ä¤ê
706 Åö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹¡£$C ¤ËÂФ¹¤ëÌÀ¼¨Åª¤ÊÃͤ¬¤Ê¤±¤ì¤Ð¡¢$TABLE ¤Î¥Ç¥Õ¥©
707 ¥ë¥ÈÃͤòÊÖ¤¹¡£$C ¤¬ÂÅÅö¤Êʸ»ú¤Ç¤Ê¤±¤ì¤Ð¡¢mchartable_lookup () ¤Ï
708 @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
718 mchartable_lookup (MCharTable *table, int c)
720 M_CHECK_CHAR (c, NULL);
722 if (c < table->min_char || c > table->max_char)
723 return table->subtable.default_value;
724 return lookup_chartable (&table->subtable, c, NULL, 0);
730 @brief Assign a value to a character in a chartable.
732 The mchartable_set () function sets the value of character $C in
733 chartable $TABLE to $VAL.
736 If the operation was successful, mchartable_set () returns 0.
737 Otherwise it returns -1 and assigns an error code to the external
738 variable #merror_code. */
741 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Ç¤Îʸ»ú¤ÎÃͤòÀßÄꤹ¤ë.
743 ´Ø¿ô mchartable_set () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú $C ¤Ë
744 ÃÍ $VAL ¤ò³ä¤êÅö¤Æ¤ë¡£
747 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchartable_set () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1
748 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
755 mchartable_lookup (), mchartable_set_range () */
759 mchartable_set (MCharTable *table, int c, void *val)
761 int managedp = table->key != Mnil && table->key->managing_key;
762 MSubCharTable *sub = &table->subtable;
765 M_CHECK_CHAR (c, -1);
767 if (table->max_char < 0)
768 table->min_char = table->max_char = c;
771 if (c < table->min_char)
773 else if (c > table->max_char)
777 for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++)
779 if (! sub->contents.tables)
781 if (sub->default_value == val)
783 make_sub_tables (sub, managedp);
785 sub = sub->contents.tables + SUB_IDX (i, c);
787 if (! sub->contents.values)
789 if (sub->default_value == val)
791 make_sub_values (sub, managedp);
793 sub->contents.values[SUB_IDX (3, c)] = val;
795 M17N_OBJECT_REF (val);
802 @brief Assign a value to the characters in the specified range.
804 The mchartable_set_range () function assigns value $VAL to the
805 characters from $FROM to $TO (both inclusive) in chartable $TABLE.
808 If the operation was successful, mchartable_set_range () returns
809 0. Otherwise it returns -1 and assigns an error code to the
810 external variable #merror_code. If $FROM is greater than $TO,
811 mchartable_set_range () returns immediately without an error. */
814 @brief »ØÄêÈϰϤÎʸ»ú¤ËÃͤòÀßÄꤹ¤ë.
816 ´Ø¿ô mchartable_set_range () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Î $FROM ¤«
817 ¤é $TO ¤Þ¤Ç¡Êξü¤ò´Þ¤à¡Ë¤Îʸ»ú¤Ë¡¢ÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£
820 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable_set_range () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
821 -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£$FROM ¤¬
822 $TO ¤è¤êÂ礤¤¤È¤¤Ë¤Ï¡¢ mchartable_set_range () ¤Ï²¿¤â¤»¤º¡¢¥¨¥é¡¼
833 mchartable_set_range (MCharTable *table, int from, int to, void *val)
835 int managedp = table->key != Mnil && table->key->managing_key;
837 M_CHECK_CHAR (from, -1);
838 M_CHECK_CHAR (to, -1);
843 if (table->max_char < 0)
844 table->min_char = from, table->max_char = to;
846 if (from < table->min_char)
847 table->min_char = from;
848 if (to > table->max_char)
849 table->max_char = to;
851 set_chartable_range (&table->subtable, from, to, val, managedp);
858 @brief Search for characters that have non-default value.
860 The mchartable_range () function searches chartable $TABLE for the
861 first and the last character codes that do not have the default
862 value of $TABLE, and set $FROM and $TO to them, respectively. If
863 all characters have the default value, both $FROM and $TO are set
867 @brief Ãͤ¬¥Ç¥Õ¥©¥ë¥È¤È°Û¤Ê¤ëʸ»ú¤òõ¤¹.
869 ´Ø¿ô mchartable_range () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Ç¡¢$TABLE ¤Î¥Ç¥Õ¥©
870 ¥ë¥ÈÃͰʳ°¤ÎÃͤò»ý¤ÄºÇ½é¤ÈºÇ¸å¤Îʸ»ú¤òõ¤·¡¢¤½¤ì¤¾¤ì¤ò $FROM ¤È
871 $TO ¤ËÀßÄꤹ¤ë¡£¤¹¤Ù¤Æ¤Îʸ»ú¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤòÃͤȤ·¤Æ»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
872 $FROM ¤È $TO ¤ò -1¤ËÀßÄꤹ¤ë¡£ */
875 mchartable_range (MCharTable *table, int *from, int *to)
877 *from = chartab_min_non_default_char (&table->subtable,
878 table->subtable.default_value);
882 *to = chartab_max_non_default_char (&table->subtable,
883 table->subtable.default_value);
889 @brief Call a function for characters in a chartable.
891 The mchartable_map () function calls function $FUNC for characters
892 in chartable $TABLE. No function call occurs for characters that
893 have value $IGNORE in $TABLE. Comparison of $IGNORE and character
894 value is done with the operator @c ==. Be careful when you use
895 string literals or pointers.
897 Instead of calling $FUNC for each character, mchartable_map ()
898 tries to optimize the number of function calls, i.e. it makes a
899 single function call for a chunk of characters when those
900 consecutive characters have the same value.
902 No matter how long the character chunk is, $FUNC is called with
903 four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both
904 inclusive) defines the range of characters that have value $VAL.
905 $ARG is the same as $FUNC_ARG.
908 This function always returns 0. */
911 @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Îʸ»ú¤ËÂФ·¤Æ»ØÄê¤Î´Ø¿ô¤ò¸Æ¤Ö.
913 ´Ø¿ô mchartable_map () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú¤ËÂФ·¤Æ´Ø
914 ¿ô $FUNC ¤ò¸Æ¤Ö¡£¤¿¤À¤·$TABLE Ãæ¤Ç¤âÃͤ¬ $IGNORE ¤Ç¤¢¤ëʸ»ú¤Ë¤Ä¤¤
915 ¤Æ¤Ï´Ø¿ô¸Æ¤Ó½Ð¤·¤ò¹Ô¤Ê¤ï¤Ê¤¤¡£$IGNORE ¤Èʸ»ú¤ÎÃͤÎÈæ³Ó¤Ï @c == ¤Ç
916 ¹Ô¤Ê¤¦¤Î¤Ç¡¢Ê¸»úÎó¥ê¥Æ¥é¥ë¤ä¥Ý¥¤¥ó¥¿¤ò»È¤¦ºÝ¤Ë¤ÏÃí°Õ¤òÍפ¹¤ë¡£
918 mchartable_map () ¤Ï¡¢°ìʸ»ú¤´¤È¤Ë $FUNC ¤ò¸Æ¤Ö¤Î¤Ç¤Ï¤Ê¤¯¡¢´Ø¿ô¸Æ
919 ¤Ó½Ð¤·¤Î²ó¿ô¤òºÇŬ²½¤·¤è¤¦¤È¤¹¤ë¡£¤¹¤Ê¤ï¤Á¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸Ãͤò
920 »ý¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Îʸ»ú¤Î¤Þ¤È¤Þ¤êÁ´ÂΤˤĤ¤¤Æ°ìÅ٤δؿô¸Æ¤Ó½Ð
923 ʸ»ú¤Î¤Þ¤È¤Þ¤ê¤ÎÂ礤µ¤Ë¤«¤«¤ï¤é¤º¡¢$FUNC ¤Ï $FROM, $TO, $VAL, $ARG
924 ¤Î£´°ú¿ô¤Ç¸Æ¤Ð¤ì¤ë¡£$FROM ¤È $TO ¡Êξü¤ò´Þ¤à¡Ë¤Ï $VAL ¤òÃͤȤ·¤Æ
925 »ý¤Äʸ»ú¤ÎÈϰϤò¼¨¤·¡¢$ARG ¤Ï $FUNC_ARG ¤½¤Î¤â¤Î¤Ç¤¢¤ë¡£
928 ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë0¤òÊÖ¤¹¡£ */
931 mchartable_map (MCharTable *table, void *ignore,
932 void (*func) (int, int, void *, void *),
935 map_chartable (&table->subtable, ignore, 0, func, func_arg);
943 /*** @addtogroup m17nDebug */
948 @brief Dump a chartable.
950 The mdebug_dump_chartab () function prints a chartable $TABLE in a
951 human readable way to the stderr. $INDENT specifies how many
952 columns to indent the lines but the first one.
955 This function returns $TABLE. */
958 @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤ò¥À¥ó¥×¤¹¤ë.
960 ´Ø¿ô mdebug_dump_chartab () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE ¤ò stderr ¤Ë¿Í´Ö
961 ¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
964 ¤³¤Î´Ø¿ô¤Ï $TABLE ¤òÊÖ¤¹¡£ */
967 mdebug_dump_chartab (MCharTable *table, int indent)
969 fprintf (stderr, "(chartab (U+%04X U+%04X)",
970 table->min_char, table->max_char);
971 dump_sub_chartab (&table->subtable, table->subtable.default_value,
972 table->key, indent + 2);
973 fprintf (stderr, ")");