1 /* chartab.c -- char-table support
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H13PRO009
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs 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
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 #include "character.h"
29 /* Number of elements in Nth level char-table. */
30 const int chartab_size
[4] =
31 { (1 << CHARTAB_SIZE_BITS_0
),
32 (1 << CHARTAB_SIZE_BITS_1
),
33 (1 << CHARTAB_SIZE_BITS_2
),
34 (1 << CHARTAB_SIZE_BITS_3
) };
36 /* Number of characters each element of Nth level char-table
38 const int chartab_chars
[4] =
39 { (1 << (CHARTAB_SIZE_BITS_1
+ CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
)),
40 (1 << (CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
)),
41 (1 << CHARTAB_SIZE_BITS_3
),
44 /* Number of characters (in bits) each element of Nth level char-table
46 const int chartab_bits
[4] =
47 { (CHARTAB_SIZE_BITS_1
+ CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
),
48 (CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
),
52 #define CHARTAB_IDX(c, depth, min_char) \
53 (((c) - (min_char)) >> chartab_bits[(depth)])
56 DEFUN ("make-char-table", Fmake_char_table
, Smake_char_table
, 1, 2, 0,
57 doc
: /* Return a newly created char-table, with purpose PURPOSE.
58 Each element is initialized to INIT, which defaults to nil.
60 PURPOSE should be a symbol. If it has a `char-table-extra-slots'
61 property, the property's value should be an integer between 0 and 10
62 that specifies how many extra slots the char-table has. Otherwise,
63 the char-table has no extra slot. */)
65 register Lisp_Object purpose
, init
;
72 CHECK_SYMBOL (purpose
);
73 n
= Fget (purpose
, Qchar_table_extra_slots
);
81 args_out_of_range (n
, Qnil
);
84 size
= VECSIZE (struct Lisp_Char_Table
) - 1 + n_extras
;
85 vector
= Fmake_vector (make_number (size
), init
);
86 XSETPVECTYPE (XVECTOR (vector
), PVEC_CHAR_TABLE
);
87 XCHAR_TABLE (vector
)->parent
= Qnil
;
88 XCHAR_TABLE (vector
)->purpose
= purpose
;
89 XSETCHAR_TABLE (vector
, XCHAR_TABLE (vector
));
94 make_sub_char_table (depth
, min_char
, defalt
)
99 int size
= VECSIZE (struct Lisp_Sub_Char_Table
) - 1 + chartab_size
[depth
];
101 table
= Fmake_vector (make_number (size
), defalt
);
102 XSETPVECTYPE (XVECTOR (table
), PVEC_SUB_CHAR_TABLE
);
103 XSUB_CHAR_TABLE (table
)->depth
= make_number (depth
);
104 XSUB_CHAR_TABLE (table
)->min_char
= make_number (min_char
);
110 char_table_ascii (table
)
115 sub
= XCHAR_TABLE (table
)->contents
[0];
116 if (! SUB_CHAR_TABLE_P (sub
))
118 sub
= XSUB_CHAR_TABLE (sub
)->contents
[0];
119 if (! SUB_CHAR_TABLE_P (sub
))
121 return XSUB_CHAR_TABLE (sub
)->contents
[0];
125 copy_sub_char_table (table
)
129 int depth
= XINT (XSUB_CHAR_TABLE (table
)->depth
);
130 int min_char
= XINT (XSUB_CHAR_TABLE (table
)->min_char
);
134 copy
= make_sub_char_table (depth
, min_char
, Qnil
);
135 /* Recursively copy any sub char-tables. */
136 for (i
= 0; i
< chartab_size
[depth
]; i
++)
138 val
= XSUB_CHAR_TABLE (table
)->contents
[i
];
139 if (SUB_CHAR_TABLE_P (val
))
140 XSUB_CHAR_TABLE (copy
)->contents
[i
] = copy_sub_char_table (val
);
142 XSUB_CHAR_TABLE (copy
)->contents
[i
] = val
;
150 copy_char_table (table
)
154 int size
= XCHAR_TABLE (table
)->size
& PSEUDOVECTOR_SIZE_MASK
;
157 copy
= Fmake_vector (make_number (size
), Qnil
);
158 XSETPVECTYPE (XVECTOR (copy
), PVEC_CHAR_TABLE
);
159 XCHAR_TABLE (copy
)->defalt
= XCHAR_TABLE (table
)->defalt
;
160 XCHAR_TABLE (copy
)->parent
= XCHAR_TABLE (table
)->parent
;
161 XCHAR_TABLE (copy
)->purpose
= XCHAR_TABLE (table
)->purpose
;
162 for (i
= 0; i
< chartab_size
[0]; i
++)
163 XCHAR_TABLE (copy
)->contents
[i
]
164 = (SUB_CHAR_TABLE_P (XCHAR_TABLE (table
)->contents
[i
])
165 ? copy_sub_char_table (XCHAR_TABLE (table
)->contents
[i
])
166 : XCHAR_TABLE (table
)->contents
[i
]);
167 XCHAR_TABLE (copy
)->ascii
= char_table_ascii (copy
);
168 size
-= VECSIZE (struct Lisp_Char_Table
) - 1;
169 for (i
= 0; i
< size
; i
++)
170 XCHAR_TABLE (copy
)->extras
[i
] = XCHAR_TABLE (table
)->extras
[i
];
172 XSETCHAR_TABLE (copy
, XCHAR_TABLE (copy
));
177 sub_char_table_ref (table
, c
)
181 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
182 int depth
= XINT (tbl
->depth
);
183 int min_char
= XINT (tbl
->min_char
);
186 val
= tbl
->contents
[CHARTAB_IDX (c
, depth
, min_char
)];
187 if (SUB_CHAR_TABLE_P (val
))
188 val
= sub_char_table_ref (val
, c
);
193 char_table_ref (table
, c
)
197 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
200 if (ASCII_CHAR_P (c
))
203 if (SUB_CHAR_TABLE_P (val
))
204 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
208 val
= tbl
->contents
[CHARTAB_IDX (c
, 0, 0)];
209 if (SUB_CHAR_TABLE_P (val
))
210 val
= sub_char_table_ref (val
, c
);
215 if (NILP (val
) && CHAR_TABLE_P (tbl
->parent
))
216 val
= char_table_ref (tbl
->parent
, c
);
222 sub_char_table_ref_and_range (table
, c
, from
, to
, defalt
)
228 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
229 int depth
= XINT (tbl
->depth
);
230 int min_char
= XINT (tbl
->min_char
);
231 int max_char
= min_char
+ chartab_chars
[depth
- 1] - 1;
232 int index
= CHARTAB_IDX (c
, depth
, min_char
), idx
;
235 val
= tbl
->contents
[index
];
236 if (SUB_CHAR_TABLE_P (val
))
237 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, defalt
);
242 while (idx
> 0 && *from
< min_char
+ idx
* chartab_chars
[depth
])
244 Lisp_Object this_val
;
246 c
= min_char
+ idx
* chartab_chars
[depth
] - 1;
248 this_val
= tbl
->contents
[idx
];
249 if (SUB_CHAR_TABLE_P (this_val
))
250 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
);
251 else if (NILP (this_val
))
254 if (! EQ (this_val
, val
))
260 while ((c
= min_char
+ (index
+ 1) * chartab_chars
[depth
]) < max_char
263 Lisp_Object this_val
;
266 this_val
= tbl
->contents
[index
];
267 if (SUB_CHAR_TABLE_P (this_val
))
268 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
);
269 else if (NILP (this_val
))
271 if (! EQ (this_val
, val
))
282 /* Return the value for C in char-table TABLE. Shrink the range *FROM
283 and *TO to cover characters (containing C) that have the same value
284 as C. It is not assured that the values of (*FROM - 1) and (*TO +
285 1) are different from that of C. */
288 char_table_ref_and_range (table
, c
, from
, to
)
293 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
294 int index
= CHARTAB_IDX (c
, 0, 0), idx
;
297 val
= tbl
->contents
[index
];
302 if (SUB_CHAR_TABLE_P (val
))
303 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, tbl
->defalt
);
308 while (*from
< idx
* chartab_chars
[0])
310 Lisp_Object this_val
;
312 c
= idx
* chartab_chars
[0] - 1;
314 this_val
= tbl
->contents
[idx
];
315 if (SUB_CHAR_TABLE_P (this_val
))
316 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
318 else if (NILP (this_val
))
319 this_val
= tbl
->defalt
;
321 if (! EQ (this_val
, val
))
327 while (*to
>= (index
+ 1) * chartab_chars
[0])
329 Lisp_Object this_val
;
332 c
= index
* chartab_chars
[0];
333 this_val
= tbl
->contents
[index
];
334 if (SUB_CHAR_TABLE_P (this_val
))
335 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
337 else if (NILP (this_val
))
338 this_val
= tbl
->defalt
;
339 if (! EQ (this_val
, val
))
350 #define ASET_RANGE(ARRAY, FROM, TO, LIMIT, VAL) \
352 int limit = (TO) < (LIMIT) ? (TO) : (LIMIT); \
353 for (; (FROM) < limit; (FROM)++) (ARRAY)->contents[(FROM)] = (VAL); \
356 #define GET_SUB_CHAR_TABLE(TABLE, SUBTABLE, IDX, DEPTH, MIN_CHAR) \
358 (SUBTABLE) = (TABLE)->contents[(IDX)]; \
359 if (!SUB_CHAR_TABLE_P (SUBTABLE)) \
360 (SUBTABLE) = make_sub_char_table ((DEPTH), (MIN_CHAR), (SUBTABLE)); \
365 sub_char_table_set (table
, c
, val
)
370 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
371 int depth
= XINT ((tbl
)->depth
);
372 int min_char
= XINT ((tbl
)->min_char
);
373 int i
= CHARTAB_IDX (c
, depth
, min_char
);
377 tbl
->contents
[i
] = val
;
380 sub
= tbl
->contents
[i
];
381 if (! SUB_CHAR_TABLE_P (sub
))
383 sub
= make_sub_char_table (depth
+ 1,
384 min_char
+ i
* chartab_chars
[depth
], sub
);
385 tbl
->contents
[i
] = sub
;
387 sub_char_table_set (sub
, c
, val
);
392 char_table_set (table
, c
, val
)
397 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
400 && SUB_CHAR_TABLE_P (tbl
->ascii
))
402 XSUB_CHAR_TABLE (tbl
->ascii
)->contents
[c
] = val
;
406 int i
= CHARTAB_IDX (c
, 0, 0);
409 sub
= tbl
->contents
[i
];
410 if (! SUB_CHAR_TABLE_P (sub
))
412 sub
= make_sub_char_table (1, i
* chartab_chars
[0], sub
);
413 tbl
->contents
[i
] = sub
;
415 sub_char_table_set (sub
, c
, val
);
416 if (ASCII_CHAR_P (c
))
417 tbl
->ascii
= char_table_ascii (table
);
423 sub_char_table_set_range (table
, depth
, min_char
, from
, to
, val
)
430 int max_char
= min_char
+ chartab_chars
[depth
] - 1;
432 if (depth
== 3 || (from
<= min_char
&& to
>= max_char
))
439 if (! SUB_CHAR_TABLE_P (*table
))
440 *table
= make_sub_char_table (depth
, min_char
, *table
);
445 i
= CHARTAB_IDX (from
, depth
, min_char
);
446 j
= CHARTAB_IDX (to
, depth
, min_char
);
447 min_char
+= chartab_chars
[depth
] * i
;
448 for (; i
<= j
; i
++, min_char
+= chartab_chars
[depth
])
449 sub_char_table_set_range (XSUB_CHAR_TABLE (*table
)->contents
+ i
,
450 depth
, min_char
, from
, to
, val
);
456 char_table_set_range (table
, from
, to
, val
)
461 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
462 Lisp_Object
*contents
= tbl
->contents
;
466 char_table_set (table
, from
, val
);
469 for (i
= CHARTAB_IDX (from
, 0, 0), min_char
= i
* chartab_chars
[0];
471 i
++, min_char
+= chartab_chars
[0])
472 sub_char_table_set_range (contents
+ i
, 0, min_char
, from
, to
, val
);
473 if (ASCII_CHAR_P (from
))
474 tbl
->ascii
= char_table_ascii (table
);
480 DEFUN ("char-table-subtype", Fchar_table_subtype
, Schar_table_subtype
,
483 Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
485 Lisp_Object char_table
;
487 CHECK_CHAR_TABLE (char_table
);
489 return XCHAR_TABLE (char_table
)->purpose
;
492 DEFUN ("char-table-parent", Fchar_table_parent
, Schar_table_parent
,
494 doc
: /* Return the parent char-table of CHAR-TABLE.
495 The value is either nil or another char-table.
496 If CHAR-TABLE holds nil for a given character,
497 then the actual applicable value is inherited from the parent char-table
498 \(or from its parents, if necessary). */)
500 Lisp_Object char_table
;
502 CHECK_CHAR_TABLE (char_table
);
504 return XCHAR_TABLE (char_table
)->parent
;
507 DEFUN ("set-char-table-parent", Fset_char_table_parent
, Sset_char_table_parent
,
509 doc
: /* Set the parent char-table of CHAR-TABLE to PARENT.
510 Return PARENT. PARENT must be either nil or another char-table. */)
512 Lisp_Object char_table
, parent
;
516 CHECK_CHAR_TABLE (char_table
);
520 CHECK_CHAR_TABLE (parent
);
522 for (temp
= parent
; !NILP (temp
); temp
= XCHAR_TABLE (temp
)->parent
)
523 if (EQ (temp
, char_table
))
524 error ("Attempt to make a chartable be its own parent");
527 XCHAR_TABLE (char_table
)->parent
= parent
;
532 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot
, Schar_table_extra_slot
,
534 doc
: /* Return the value of CHAR-TABLE's extra-slot number N. */)
536 Lisp_Object char_table
, n
;
538 CHECK_CHAR_TABLE (char_table
);
541 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
542 args_out_of_range (char_table
, n
);
544 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)];
547 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot
,
548 Sset_char_table_extra_slot
,
550 doc
: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
551 (char_table
, n
, value
)
552 Lisp_Object char_table
, n
, value
;
554 CHECK_CHAR_TABLE (char_table
);
557 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
558 args_out_of_range (char_table
, n
);
560 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)] = value
;
563 DEFUN ("char-table-range", Fchar_table_range
, Schar_table_range
,
565 doc
: /* Return the value in CHAR-TABLE for a range of characters RANGE.
566 RANGE should be nil (for the default value),
567 a cons of character codes (for characters in the range), or a character code. */)
569 Lisp_Object char_table
, range
;
572 CHECK_CHAR_TABLE (char_table
);
574 if (EQ (range
, Qnil
))
575 val
= XCHAR_TABLE (char_table
)->defalt
;
576 else if (INTEGERP (range
))
577 val
= CHAR_TABLE_REF (char_table
, XINT (range
));
578 else if (CONSP (range
))
582 CHECK_CHARACTER_CAR (range
);
583 CHECK_CHARACTER_CDR (range
);
584 val
= char_table_ref_and_range (char_table
, XINT (XCAR (range
)),
586 /* Not yet implemented. */
589 error ("Invalid RANGE argument to `char-table-range'");
593 DEFUN ("set-char-table-range", Fset_char_table_range
, Sset_char_table_range
,
595 doc
: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
596 RANGE should be t (for all characters), nil (for the default value),
597 a cons of character codes (for characters in the range),
598 or a character code. Return VALUE. */)
599 (char_table
, range
, value
)
600 Lisp_Object char_table
, range
, value
;
602 CHECK_CHAR_TABLE (char_table
);
607 XCHAR_TABLE (char_table
)->ascii
= value
;
608 for (i
= 0; i
< chartab_size
[0]; i
++)
609 XCHAR_TABLE (char_table
)->contents
[i
] = value
;
611 else if (EQ (range
, Qnil
))
612 XCHAR_TABLE (char_table
)->defalt
= value
;
613 else if (INTEGERP (range
))
614 char_table_set (char_table
, XINT (range
), value
);
615 else if (CONSP (range
))
617 CHECK_CHARACTER_CAR (range
);
618 CHECK_CHARACTER_CDR (range
);
619 char_table_set_range (char_table
,
620 XINT (XCAR (range
)), XINT (XCDR (range
)), value
);
623 error ("Invalid RANGE argument to `set-char-table-range'");
628 DEFUN ("set-char-table-default", Fset_char_table_default
,
629 Sset_char_table_default
, 3, 3, 0,
631 This function is obsolete and has no effect. */)
632 (char_table
, ch
, value
)
633 Lisp_Object char_table
, ch
, value
;
638 /* Look up the element in TABLE at index CH, and return it as an
639 integer. If the element is not a character, return CH itself. */
642 char_table_translate (table
, ch
)
647 value
= Faref (table
, make_number (ch
));
648 if (! CHARACTERP (value
))
654 optimize_sub_char_table (table
, test
)
655 Lisp_Object table
, test
;
657 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
658 int depth
= XINT (tbl
->depth
);
659 Lisp_Object elt
, this;
662 elt
= XSUB_CHAR_TABLE (table
)->contents
[0];
663 if (SUB_CHAR_TABLE_P (elt
))
664 elt
= XSUB_CHAR_TABLE (table
)->contents
[0]
665 = optimize_sub_char_table (elt
, test
);
666 optimizable
= SUB_CHAR_TABLE_P (elt
) ? 0 : 1;
667 for (i
= 1; i
< chartab_size
[depth
]; i
++)
669 this = XSUB_CHAR_TABLE (table
)->contents
[i
];
670 if (SUB_CHAR_TABLE_P (this))
671 this = XSUB_CHAR_TABLE (table
)->contents
[i
]
672 = optimize_sub_char_table (this, test
);
674 && (NILP (test
) ? NILP (Fequal (this, elt
)) /* defaults to `equal'. */
675 : EQ (test
, Qeq
) ? !EQ (this, elt
) /* Optimize `eq' case. */
676 : NILP (call2 (test
, this, elt
))))
680 return (optimizable
? elt
: table
);
683 DEFUN ("optimize-char-table", Foptimize_char_table
, Soptimize_char_table
,
685 doc
: /* Optimize CHAR-TABLE.
686 TEST is the comparison function used to decide whether two entries are
687 equivalent and can be merged. It defaults to `equal'. */)
689 Lisp_Object char_table
, test
;
694 CHECK_CHAR_TABLE (char_table
);
696 for (i
= 0; i
< chartab_size
[0]; i
++)
698 elt
= XCHAR_TABLE (char_table
)->contents
[i
];
699 if (SUB_CHAR_TABLE_P (elt
))
700 XCHAR_TABLE (char_table
)->contents
[i
]
701 = optimize_sub_char_table (elt
, test
);
703 /* Reset the `ascii' cache, in case it got optimized away. */
704 XCHAR_TABLE (char_table
)->ascii
= char_table_ascii (char_table
);
710 /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table),
711 calling it for each character or group of characters that share a
712 value. RANGE is a cons (FROM . TO) specifying the range of target
713 characters, VAL is a value of FROM in TABLE, DEFAULT_VAL is the
714 default value of the char-table, PARENT is the parent of the
717 ARG is passed to C_FUNCTION when that is called.
719 It returns the value of last character covered by TABLE (not the
720 value inheritted from the parent), and by side-effect, the car part
721 of RANGE is updated to the minimum character C where C and all the
722 following characters in TABLE have the same value. */
725 map_sub_char_table (c_function
, function
, table
, arg
, val
, range
,
727 void (*c_function
) P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
728 Lisp_Object function
, table
, arg
, val
, range
, default_val
, parent
;
730 /* Pointer to the elements of TABLE. */
731 Lisp_Object
*contents
;
732 /* Depth of TABLE. */
734 /* Minimum and maxinum characters covered by TABLE. */
735 int min_char
, max_char
;
736 /* Number of characters covered by one element of TABLE. */
738 int from
= XINT (XCAR (range
)), to
= XINT (XCDR (range
));
741 if (SUB_CHAR_TABLE_P (table
))
743 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
745 depth
= XINT (tbl
->depth
);
746 contents
= tbl
->contents
;
747 min_char
= XINT (tbl
->min_char
);
748 max_char
= min_char
+ chartab_chars
[depth
- 1] - 1;
753 contents
= XCHAR_TABLE (table
)->contents
;
757 chars_in_block
= chartab_chars
[depth
];
761 /* Set I to the index of the first element to check. */
762 if (from
<= min_char
)
765 i
= (from
- min_char
) / chars_in_block
;
766 for (c
= min_char
+ chars_in_block
* i
; c
<= max_char
;
767 i
++, c
+= chars_in_block
)
769 Lisp_Object
this = contents
[i
];
770 int nextc
= c
+ chars_in_block
;
772 if (SUB_CHAR_TABLE_P (this))
775 XSETCDR (range
, make_number (nextc
- 1));
776 val
= map_sub_char_table (c_function
, function
, this, arg
,
777 val
, range
, default_val
, parent
);
785 int different_value
= 1;
791 Lisp_Object temp
= XCHAR_TABLE (parent
)->parent
;
793 /* This is to get a value of FROM in PARENT
794 without checking the parent of PARENT. */
795 XCHAR_TABLE (parent
)->parent
= Qnil
;
796 val
= CHAR_TABLE_REF (parent
, from
);
797 XCHAR_TABLE (parent
)->parent
= temp
;
798 XSETCDR (range
, make_number (c
- 1));
799 val
= map_sub_char_table (c_function
, function
,
800 parent
, arg
, val
, range
,
801 XCHAR_TABLE (parent
)->defalt
,
802 XCHAR_TABLE (parent
)->parent
);
807 if (! NILP (val
) && different_value
)
809 XSETCDR (range
, make_number (c
- 1));
810 if (EQ (XCAR (range
), XCDR (range
)))
813 (*c_function
) (arg
, XCAR (range
), val
);
815 call2 (function
, XCAR (range
), val
);
820 (*c_function
) (arg
, range
, val
);
822 call2 (function
, range
, val
);
827 XSETCAR (range
, make_number (c
));
830 XSETCDR (range
, make_number (to
));
836 /* Map C_FUNCTION or FUNCTION over TABLE, calling it for each
837 character or group of characters that share a value.
839 ARG is passed to C_FUNCTION when that is called. */
842 map_char_table (c_function
, function
, table
, arg
)
843 void (*c_function
) P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
844 Lisp_Object function
, table
, arg
;
846 Lisp_Object range
, val
;
847 struct gcpro gcpro1
, gcpro2
, gcpro3
;
849 range
= Fcons (make_number (0), make_number (MAX_CHAR
));
850 GCPRO3 (table
, arg
, range
);
851 val
= XCHAR_TABLE (table
)->ascii
;
852 if (SUB_CHAR_TABLE_P (val
))
853 val
= XSUB_CHAR_TABLE (val
)->contents
[0];
854 val
= map_sub_char_table (c_function
, function
, table
, arg
, val
, range
,
855 XCHAR_TABLE (table
)->defalt
,
856 XCHAR_TABLE (table
)->parent
);
857 /* If VAL is nil and TABLE has a parent, we must consult the parent
859 while (NILP (val
) && ! NILP (XCHAR_TABLE (table
)->parent
))
861 Lisp_Object parent
= XCHAR_TABLE (table
)->parent
;
862 Lisp_Object temp
= XCHAR_TABLE (parent
)->parent
;
863 int from
= XINT (XCAR (range
));
865 /* This is to get a value of FROM in PARENT without checking the
867 XCHAR_TABLE (parent
)->parent
= Qnil
;
868 val
= CHAR_TABLE_REF (parent
, from
);
869 XCHAR_TABLE (parent
)->parent
= temp
;
870 val
= map_sub_char_table (c_function
, function
, parent
, arg
, val
, range
,
871 XCHAR_TABLE (parent
)->defalt
,
872 XCHAR_TABLE (parent
)->parent
);
878 if (EQ (XCAR (range
), XCDR (range
)))
881 (*c_function
) (arg
, XCAR (range
), val
);
883 call2 (function
, XCAR (range
), val
);
888 (*c_function
) (arg
, range
, val
);
890 call2 (function
, range
, val
);
897 DEFUN ("map-char-table", Fmap_char_table
, Smap_char_table
,
900 Call FUNCTION for each character in CHAR-TABLE that has non-nil value.
901 FUNCTION is called with two arguments--a key and a value.
902 The key is a character code or a cons of character codes specifying a
903 range of characters that have the same value. */)
904 (function
, char_table
)
905 Lisp_Object function
, char_table
;
907 CHECK_CHAR_TABLE (char_table
);
909 map_char_table (NULL
, function
, char_table
, char_table
);
915 map_sub_char_table_for_charset (c_function
, function
, table
, arg
, range
,
917 void (*c_function
) P_ ((Lisp_Object
, Lisp_Object
));
918 Lisp_Object function
, table
, arg
, range
;
919 struct charset
*charset
;
922 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
923 int depth
= XINT (tbl
->depth
);
927 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
];
928 i
++, c
+= chartab_chars
[depth
])
932 this = tbl
->contents
[i
];
933 if (SUB_CHAR_TABLE_P (this))
934 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
935 range
, charset
, from
, to
);
938 if (! NILP (XCAR (range
)))
940 XSETCDR (range
, make_number (c
- 1));
942 (*c_function
) (arg
, range
);
944 call2 (function
, range
, arg
);
946 XSETCAR (range
, Qnil
);
950 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
]; i
++, c
++)
955 this = tbl
->contents
[i
];
958 && (code
= ENCODE_CHAR (charset
, c
),
959 (code
< from
|| code
> to
))))
961 if (! NILP (XCAR (range
)))
963 XSETCDR (range
, make_number (c
- 1));
965 (*c_function
) (arg
, range
);
967 call2 (function
, range
, arg
);
968 XSETCAR (range
, Qnil
);
973 if (NILP (XCAR (range
)))
974 XSETCAR (range
, make_number (c
));
980 /* Support function for `map-charset-chars'. Map C_FUNCTION or
981 FUNCTION over TABLE, calling it for each character or a group of
982 succeeding characters that have non-nil value in TABLE. TABLE is a
983 "mapping table" or a "deunifier table" of a certain charset.
985 If CHARSET is not NULL (this is the case that `map-charset-chars'
986 is called with non-nil FROM-CODE and TO-CODE), it is a charset who
987 owns TABLE, and the function is called only on a character in the
988 range FROM and TO. FROM and TO are not character codes, but code
989 points of a character in CHARSET.
991 This function is called in these two cases:
993 (1) A charset has a mapping file name in :map property.
995 (2) A charset has an upper code space in :offset property and a
996 mapping file name in :unify-map property. In this case, this
997 function is called only for characters in the Unicode code space.
998 Characters in upper code space are handled directly in
999 map_charset_chars. */
1002 map_char_table_for_charset (c_function
, function
, table
, arg
,
1004 void (*c_function
) P_ ((Lisp_Object
, Lisp_Object
));
1005 Lisp_Object function
, table
, arg
;
1006 struct charset
*charset
;
1011 struct gcpro gcpro1
;
1013 range
= Fcons (Qnil
, Qnil
);
1016 for (i
= 0, c
= 0; i
< chartab_size
[0]; i
++, c
+= chartab_chars
[0])
1020 this = XCHAR_TABLE (table
)->contents
[i
];
1021 if (SUB_CHAR_TABLE_P (this))
1022 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
1023 range
, charset
, from
, to
);
1026 if (! NILP (XCAR (range
)))
1028 XSETCDR (range
, make_number (c
- 1));
1030 (*c_function
) (arg
, range
);
1032 call2 (function
, range
, arg
);
1034 XSETCAR (range
, Qnil
);
1037 if (! NILP (XCAR (range
)))
1039 XSETCDR (range
, make_number (c
- 1));
1041 (*c_function
) (arg
, range
);
1043 call2 (function
, range
, arg
);
1053 defsubr (&Smake_char_table
);
1054 defsubr (&Schar_table_parent
);
1055 defsubr (&Schar_table_subtype
);
1056 defsubr (&Sset_char_table_parent
);
1057 defsubr (&Schar_table_extra_slot
);
1058 defsubr (&Sset_char_table_extra_slot
);
1059 defsubr (&Schar_table_range
);
1060 defsubr (&Sset_char_table_range
);
1061 defsubr (&Sset_char_table_default
);
1062 defsubr (&Soptimize_char_table
);
1063 defsubr (&Smap_char_table
);
1066 /* arch-tag: 18b5b560-7ab5-4108-b09e-d5dd65dc6fda
1067 (do not change this comment) */