(doc-view-mode-map): Bind `q' to quit-window, as is the custom.
[emacs.git] / src / chartab.c
blob165fa0dd8952d2dc1c402f20457d36461a589b18
1 /* chartab.c -- char-table support
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
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/>. */
21 #include <config.h>
22 #include "lisp.h"
23 #include "character.h"
24 #include "charset.h"
25 #include "ccl.h"
27 /* 64/16/32/128 */
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
37 covers. */
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),
42 1 };
44 /* Number of characters (in bits) each element of Nth level char-table
45 covers. */
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),
49 CHARTAB_SIZE_BITS_3,
50 0 };
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. */)
64 (purpose, init)
65 register Lisp_Object purpose, init;
67 Lisp_Object vector;
68 Lisp_Object n;
69 int n_extras;
70 int size;
72 CHECK_SYMBOL (purpose);
73 n = Fget (purpose, Qchar_table_extra_slots);
74 if (NILP (n))
75 n_extras = 0;
76 else
78 CHECK_NATNUM (n);
79 n_extras = XINT (n);
80 if (n_extras > 10)
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));
90 return vector;
93 static Lisp_Object
94 make_sub_char_table (depth, min_char, defalt)
95 int depth, min_char;
96 Lisp_Object defalt;
98 Lisp_Object table;
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);
106 return table;
109 static Lisp_Object
110 char_table_ascii (table)
111 Lisp_Object table;
113 Lisp_Object sub;
115 sub = XCHAR_TABLE (table)->contents[0];
116 if (! SUB_CHAR_TABLE_P (sub))
117 return sub;
118 sub = XSUB_CHAR_TABLE (sub)->contents[0];
119 if (! SUB_CHAR_TABLE_P (sub))
120 return sub;
121 return XSUB_CHAR_TABLE (sub)->contents[0];
124 Lisp_Object
125 copy_sub_char_table (table)
126 Lisp_Object table;
128 Lisp_Object copy;
129 int depth = XINT (XSUB_CHAR_TABLE (table)->depth);
130 int min_char = XINT (XSUB_CHAR_TABLE (table)->min_char);
131 Lisp_Object val;
132 int i;
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);
141 else
142 XSUB_CHAR_TABLE (copy)->contents[i] = val;
145 return copy;
149 Lisp_Object
150 copy_char_table (table)
151 Lisp_Object table;
153 Lisp_Object copy;
154 int size = XCHAR_TABLE (table)->size & PSEUDOVECTOR_SIZE_MASK;
155 int i;
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 XCHAR_TABLE (copy)->ascii = XCHAR_TABLE (table)->ascii;
163 for (i = 0; i < chartab_size[0]; i++)
164 XCHAR_TABLE (copy)->contents[i]
165 = (SUB_CHAR_TABLE_P (XCHAR_TABLE (table)->contents[i])
166 ? copy_sub_char_table (XCHAR_TABLE (table)->contents[i])
167 : XCHAR_TABLE (table)->contents[i]);
168 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (copy)->ascii))
169 XCHAR_TABLE (copy)->ascii = char_table_ascii (copy);
170 size -= VECSIZE (struct Lisp_Char_Table) - 1;
171 for (i = 0; i < size; i++)
172 XCHAR_TABLE (copy)->extras[i] = XCHAR_TABLE (table)->extras[i];
174 XSETCHAR_TABLE (copy, XCHAR_TABLE (copy));
175 return copy;
178 Lisp_Object
179 sub_char_table_ref (table, c)
180 Lisp_Object table;
181 int c;
183 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
184 int depth = XINT (tbl->depth);
185 int min_char = XINT (tbl->min_char);
186 Lisp_Object val;
188 val = tbl->contents[CHARTAB_IDX (c, depth, min_char)];
189 if (SUB_CHAR_TABLE_P (val))
190 val = sub_char_table_ref (val, c);
191 return val;
194 Lisp_Object
195 char_table_ref (table, c)
196 Lisp_Object table;
197 int c;
199 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
200 Lisp_Object val;
202 if (ASCII_CHAR_P (c))
204 val = tbl->ascii;
205 if (SUB_CHAR_TABLE_P (val))
206 val = XSUB_CHAR_TABLE (val)->contents[c];
208 else
210 val = tbl->contents[CHARTAB_IDX (c, 0, 0)];
211 if (SUB_CHAR_TABLE_P (val))
212 val = sub_char_table_ref (val, c);
214 if (NILP (val))
216 val = tbl->defalt;
217 if (NILP (val) && CHAR_TABLE_P (tbl->parent))
218 val = char_table_ref (tbl->parent, c);
220 return val;
223 static Lisp_Object
224 sub_char_table_ref_and_range (table, c, from, to, defalt)
225 Lisp_Object table;
226 int c;
227 int *from, *to;
228 Lisp_Object defalt;
230 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
231 int depth = XINT (tbl->depth);
232 int min_char = XINT (tbl->min_char);
233 int max_char = min_char + chartab_chars[depth - 1] - 1;
234 int index = CHARTAB_IDX (c, depth, min_char);
235 Lisp_Object val;
237 val = tbl->contents[index];
238 *from = min_char + index * chartab_chars[depth];
239 *to = *from + chartab_chars[depth] - 1;
240 if (SUB_CHAR_TABLE_P (val))
241 val = sub_char_table_ref_and_range (val, c, from, to, defalt);
242 else if (NILP (val))
243 val = defalt;
245 while (*from > min_char
246 && *from == min_char + index * chartab_chars[depth])
248 Lisp_Object this_val;
249 int this_from = *from - chartab_chars[depth];
250 int this_to = *from - 1;
252 index--;
253 this_val = tbl->contents[index];
254 if (SUB_CHAR_TABLE_P (this_val))
255 this_val = sub_char_table_ref_and_range (this_val, this_to,
256 &this_from, &this_to,
257 defalt);
258 else if (NILP (this_val))
259 this_val = defalt;
261 if (! EQ (this_val, val))
262 break;
263 *from = this_from;
265 index = CHARTAB_IDX (c, depth, min_char);
266 while (*to < max_char
267 && *to == min_char + (index + 1) * chartab_chars[depth] - 1)
269 Lisp_Object this_val;
270 int this_from = *to + 1;
271 int this_to = this_from + chartab_chars[depth] - 1;
273 index++;
274 this_val = tbl->contents[index];
275 if (SUB_CHAR_TABLE_P (this_val))
276 this_val = sub_char_table_ref_and_range (this_val, this_from,
277 &this_from, &this_to,
278 defalt);
279 else if (NILP (this_val))
280 this_val = defalt;
281 if (! EQ (this_val, val))
282 break;
283 *to = this_to;
286 return val;
290 /* Return the value for C in char-table TABLE. Set *FROM and *TO to
291 the range of characters (containing C) that have the same value as
292 C. It is not assured that the value of (*FROM - 1) and (*TO + 1)
293 is different from that of C. */
295 Lisp_Object
296 char_table_ref_and_range (table, c, from, to)
297 Lisp_Object table;
298 int c;
299 int *from, *to;
301 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
302 int index = CHARTAB_IDX (c, 0, 0);
303 Lisp_Object val;
305 val = tbl->contents[index];
306 *from = index * chartab_chars[0];
307 *to = *from + chartab_chars[0] - 1;
308 if (SUB_CHAR_TABLE_P (val))
309 val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt);
310 else if (NILP (val))
311 val = tbl->defalt;
313 while (*from > 0 && *from == index * chartab_chars[0])
315 Lisp_Object this_val;
316 int this_from = *from - chartab_chars[0];
317 int this_to = *from - 1;
319 index--;
320 this_val = tbl->contents[index];
321 if (SUB_CHAR_TABLE_P (this_val))
322 this_val = sub_char_table_ref_and_range (this_val, this_to,
323 &this_from, &this_to,
324 tbl->defalt);
325 else if (NILP (this_val))
326 this_val = tbl->defalt;
328 if (! EQ (this_val, val))
329 break;
330 *from = this_from;
332 while (*to < MAX_CHAR && *to == (index + 1) * chartab_chars[0] - 1)
334 Lisp_Object this_val;
335 int this_from = *to + 1;
336 int this_to = this_from + chartab_chars[0] - 1;
338 index++;
339 this_val = tbl->contents[index];
340 if (SUB_CHAR_TABLE_P (this_val))
341 this_val = sub_char_table_ref_and_range (this_val, this_from,
342 &this_from, &this_to,
343 tbl->defalt);
344 else if (NILP (this_val))
345 this_val = tbl->defalt;
346 if (! EQ (this_val, val))
347 break;
348 *to = this_to;
351 return val;
355 #define ASET_RANGE(ARRAY, FROM, TO, LIMIT, VAL) \
356 do { \
357 int limit = (TO) < (LIMIT) ? (TO) : (LIMIT); \
358 for (; (FROM) < limit; (FROM)++) (ARRAY)->contents[(FROM)] = (VAL); \
359 } while (0)
361 #define GET_SUB_CHAR_TABLE(TABLE, SUBTABLE, IDX, DEPTH, MIN_CHAR) \
362 do { \
363 (SUBTABLE) = (TABLE)->contents[(IDX)]; \
364 if (!SUB_CHAR_TABLE_P (SUBTABLE)) \
365 (SUBTABLE) = make_sub_char_table ((DEPTH), (MIN_CHAR), (SUBTABLE)); \
366 } while (0)
369 static void
370 sub_char_table_set (table, c, val)
371 Lisp_Object table;
372 int c;
373 Lisp_Object val;
375 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
376 int depth = XINT ((tbl)->depth);
377 int min_char = XINT ((tbl)->min_char);
378 int i = CHARTAB_IDX (c, depth, min_char);
379 Lisp_Object sub;
381 if (depth == 3)
382 tbl->contents[i] = val;
383 else
385 sub = tbl->contents[i];
386 if (! SUB_CHAR_TABLE_P (sub))
388 sub = make_sub_char_table (depth + 1,
389 min_char + i * chartab_chars[depth], sub);
390 tbl->contents[i] = sub;
392 sub_char_table_set (sub, c, val);
396 Lisp_Object
397 char_table_set (table, c, val)
398 Lisp_Object table;
399 int c;
400 Lisp_Object val;
402 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
404 if (ASCII_CHAR_P (c)
405 && SUB_CHAR_TABLE_P (tbl->ascii))
407 XSUB_CHAR_TABLE (tbl->ascii)->contents[c] = val;
409 else
411 int i = CHARTAB_IDX (c, 0, 0);
412 Lisp_Object sub;
414 sub = tbl->contents[i];
415 if (! SUB_CHAR_TABLE_P (sub))
417 sub = make_sub_char_table (1, i * chartab_chars[0], sub);
418 tbl->contents[i] = sub;
420 sub_char_table_set (sub, c, val);
421 if (ASCII_CHAR_P (c))
422 tbl->ascii = char_table_ascii (table);
424 return val;
427 static void
428 sub_char_table_set_range (table, depth, min_char, from, to, val)
429 Lisp_Object *table;
430 int depth;
431 int min_char;
432 int from, to;
433 Lisp_Object val;
435 int max_char = min_char + chartab_chars[depth] - 1;
437 if (depth == 3 || (from <= min_char && to >= max_char))
438 *table = val;
439 else
441 int i, j;
443 depth++;
444 if (! SUB_CHAR_TABLE_P (*table))
445 *table = make_sub_char_table (depth, min_char, *table);
446 if (from < min_char)
447 from = min_char;
448 if (to > max_char)
449 to = max_char;
450 i = CHARTAB_IDX (from, depth, min_char);
451 j = CHARTAB_IDX (to, depth, min_char);
452 min_char += chartab_chars[depth] * i;
453 for (; i <= j; i++, min_char += chartab_chars[depth])
454 sub_char_table_set_range (XSUB_CHAR_TABLE (*table)->contents + i,
455 depth, min_char, from, to, val);
460 Lisp_Object
461 char_table_set_range (table, from, to, val)
462 Lisp_Object table;
463 int from, to;
464 Lisp_Object val;
466 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
467 Lisp_Object *contents = tbl->contents;
468 int i, min_char;
470 if (from == to)
471 char_table_set (table, from, val);
472 else
474 for (i = CHARTAB_IDX (from, 0, 0), min_char = i * chartab_chars[0];
475 min_char <= to;
476 i++, min_char += chartab_chars[0])
477 sub_char_table_set_range (contents + i, 0, min_char, from, to, val);
478 if (ASCII_CHAR_P (from))
479 tbl->ascii = char_table_ascii (table);
481 return val;
485 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
486 1, 1, 0,
487 doc: /*
488 Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
489 (char_table)
490 Lisp_Object char_table;
492 CHECK_CHAR_TABLE (char_table);
494 return XCHAR_TABLE (char_table)->purpose;
497 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
498 1, 1, 0,
499 doc: /* Return the parent char-table of CHAR-TABLE.
500 The value is either nil or another char-table.
501 If CHAR-TABLE holds nil for a given character,
502 then the actual applicable value is inherited from the parent char-table
503 \(or from its parents, if necessary). */)
504 (char_table)
505 Lisp_Object char_table;
507 CHECK_CHAR_TABLE (char_table);
509 return XCHAR_TABLE (char_table)->parent;
512 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
513 2, 2, 0,
514 doc: /* Set the parent char-table of CHAR-TABLE to PARENT.
515 Return PARENT. PARENT must be either nil or another char-table. */)
516 (char_table, parent)
517 Lisp_Object char_table, parent;
519 Lisp_Object temp;
521 CHECK_CHAR_TABLE (char_table);
523 if (!NILP (parent))
525 CHECK_CHAR_TABLE (parent);
527 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
528 if (EQ (temp, char_table))
529 error ("Attempt to make a chartable be its own parent");
532 XCHAR_TABLE (char_table)->parent = parent;
534 return parent;
537 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
538 2, 2, 0,
539 doc: /* Return the value of CHAR-TABLE's extra-slot number N. */)
540 (char_table, n)
541 Lisp_Object char_table, n;
543 CHECK_CHAR_TABLE (char_table);
544 CHECK_NUMBER (n);
545 if (XINT (n) < 0
546 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
547 args_out_of_range (char_table, n);
549 return XCHAR_TABLE (char_table)->extras[XINT (n)];
552 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
553 Sset_char_table_extra_slot,
554 3, 3, 0,
555 doc: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
556 (char_table, n, value)
557 Lisp_Object char_table, n, value;
559 CHECK_CHAR_TABLE (char_table);
560 CHECK_NUMBER (n);
561 if (XINT (n) < 0
562 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
563 args_out_of_range (char_table, n);
565 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
568 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
569 2, 2, 0,
570 doc: /* Return the value in CHAR-TABLE for a range of characters RANGE.
571 RANGE should be nil (for the default value),
572 a cons of character codes (for characters in the range), or a character code. */)
573 (char_table, range)
574 Lisp_Object char_table, range;
576 Lisp_Object val;
577 CHECK_CHAR_TABLE (char_table);
579 if (EQ (range, Qnil))
580 val = XCHAR_TABLE (char_table)->defalt;
581 else if (INTEGERP (range))
582 val = CHAR_TABLE_REF (char_table, XINT (range));
583 else if (CONSP (range))
585 int from, to;
587 CHECK_CHARACTER_CAR (range);
588 CHECK_CHARACTER_CDR (range);
589 val = char_table_ref_and_range (char_table, XINT (XCAR (range)),
590 &from, &to);
591 /* Not yet implemented. */
593 else
594 error ("Invalid RANGE argument to `char-table-range'");
595 return val;
598 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
599 3, 3, 0,
600 doc: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
601 RANGE should be t (for all characters), nil (for the default value),
602 a cons of character codes (for characters in the range),
603 or a character code. Return VALUE. */)
604 (char_table, range, value)
605 Lisp_Object char_table, range, value;
607 CHECK_CHAR_TABLE (char_table);
608 if (EQ (range, Qt))
610 int i;
612 XCHAR_TABLE (char_table)->ascii = value;
613 for (i = 0; i < chartab_size[0]; i++)
614 XCHAR_TABLE (char_table)->contents[i] = value;
616 else if (EQ (range, Qnil))
617 XCHAR_TABLE (char_table)->defalt = value;
618 else if (INTEGERP (range))
619 char_table_set (char_table, XINT (range), value);
620 else if (CONSP (range))
622 CHECK_CHARACTER_CAR (range);
623 CHECK_CHARACTER_CDR (range);
624 char_table_set_range (char_table,
625 XINT (XCAR (range)), XINT (XCDR (range)), value);
627 else
628 error ("Invalid RANGE argument to `set-char-table-range'");
630 return value;
633 DEFUN ("set-char-table-default", Fset_char_table_default,
634 Sset_char_table_default, 3, 3, 0,
635 doc: /*
636 This function is obsolete and has no effect. */)
637 (char_table, ch, value)
638 Lisp_Object char_table, ch, value;
640 return Qnil;
643 /* Look up the element in TABLE at index CH, and return it as an
644 integer. If the element is not a character, return CH itself. */
647 char_table_translate (table, ch)
648 Lisp_Object table;
649 int ch;
651 Lisp_Object value;
652 value = Faref (table, make_number (ch));
653 if (! CHARACTERP (value))
654 return ch;
655 return XINT (value);
658 static Lisp_Object
659 optimize_sub_char_table (table)
660 Lisp_Object table;
662 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
663 int depth = XINT (tbl->depth);
664 Lisp_Object elt, this;
665 int i;
667 elt = XSUB_CHAR_TABLE (table)->contents[0];
668 if (SUB_CHAR_TABLE_P (elt))
669 elt = XSUB_CHAR_TABLE (table)->contents[0] = optimize_sub_char_table (elt);
670 if (SUB_CHAR_TABLE_P (elt))
671 return table;
672 for (i = 1; i < chartab_size[depth]; i++)
674 this = XSUB_CHAR_TABLE (table)->contents[i];
675 if (SUB_CHAR_TABLE_P (this))
676 this = XSUB_CHAR_TABLE (table)->contents[i]
677 = optimize_sub_char_table (this);
678 if (SUB_CHAR_TABLE_P (this)
679 || NILP (Fequal (this, elt)))
680 break;
683 return (i < chartab_size[depth] ? table : elt);
686 DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
687 1, 1, 0,
688 doc: /* Optimize CHAR-TABLE. */)
689 (char_table)
690 Lisp_Object char_table;
692 Lisp_Object elt;
693 int i;
695 CHECK_CHAR_TABLE (char_table);
697 for (i = 0; i < chartab_size[0]; i++)
699 elt = XCHAR_TABLE (char_table)->contents[i];
700 if (SUB_CHAR_TABLE_P (elt))
701 XCHAR_TABLE (char_table)->contents[i] = optimize_sub_char_table (elt);
703 return Qnil;
707 /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table),
708 calling it for each character or group of characters that share a
709 value. RANGE is a cons (FROM . TO) specifying the range of target
710 characters, VAL is a value of FROM in TABLE, DEFAULT_VAL is the
711 default value of the char-table, PARENT is the parent of the
712 char-table.
714 ARG is passed to C_FUNCTION when that is called.
716 It returns the value of last character covered by TABLE (not the
717 value inheritted from the parent), and by side-effect, the car part
718 of RANGE is updated to the minimum character C where C and all the
719 following characters in TABLE have the same value. */
721 static Lisp_Object
722 map_sub_char_table (c_function, function, table, arg, val, range,
723 default_val, parent)
724 void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
725 Lisp_Object function, table, arg, val, range, default_val, parent;
727 /* Pointer to the elements of TABLE. */
728 Lisp_Object *contents;
729 /* Depth of TABLE. */
730 int depth;
731 /* Minimum and maxinum characters covered by TABLE. */
732 int min_char, max_char;
733 /* Number of characters covered by one element of TABLE. */
734 int chars_in_block;
735 int from = XINT (XCAR (range)), to = XINT (XCDR (range));
736 int i, c;
738 if (SUB_CHAR_TABLE_P (table))
740 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
742 depth = XINT (tbl->depth);
743 contents = tbl->contents;
744 min_char = XINT (tbl->min_char);
745 max_char = min_char + chartab_chars[depth - 1] - 1;
747 else
749 depth = 0;
750 contents = XCHAR_TABLE (table)->contents;
751 min_char = 0;
752 max_char = MAX_CHAR;
754 chars_in_block = chartab_chars[depth];
756 if (to < max_char)
757 max_char = to;
758 /* Set I to the index of the first element to check. */
759 if (from <= min_char)
760 i = 0;
761 else
762 i = (from - min_char) / chars_in_block;
763 for (c = min_char + chars_in_block * i; c <= max_char;
764 i++, c += chars_in_block)
766 Lisp_Object this = contents[i];
767 int nextc = c + chars_in_block;
769 if (SUB_CHAR_TABLE_P (this))
771 if (to >= nextc)
772 XSETCDR (range, make_number (nextc - 1));
773 val = map_sub_char_table (c_function, function, this, arg,
774 val, range, default_val, parent);
776 else
778 if (NILP (this))
779 this = default_val;
780 if (NILP (Fequal (val, this)))
782 int different_value = 1;
784 if (NILP (val))
786 if (! NILP (parent))
788 Lisp_Object temp = XCHAR_TABLE (parent)->parent;
790 /* This is to get a value of FROM in PARENT
791 without checking the parent of PARENT. */
792 XCHAR_TABLE (parent)->parent = Qnil;
793 val = CHAR_TABLE_REF (parent, from);
794 XCHAR_TABLE (parent)->parent = temp;
795 XSETCDR (range, make_number (c - 1));
796 val = map_sub_char_table (c_function, function,
797 parent, arg, val, range,
798 XCHAR_TABLE (parent)->defalt,
799 XCHAR_TABLE (parent)->parent);
800 if (! NILP (Fequal (val, this)))
801 different_value = 0;
804 if (! NILP (val) && different_value)
806 XSETCDR (range, make_number (c - 1));
807 if (EQ (XCAR (range), XCDR (range)))
809 if (c_function)
810 (*c_function) (arg, XCAR (range), val);
811 else
812 call2 (function, XCAR (range), val);
814 else
816 if (c_function)
817 (*c_function) (arg, range, val);
818 else
819 call2 (function, range, val);
822 val = this;
823 from = c;
824 XSETCAR (range, make_number (c));
827 XSETCDR (range, make_number (to));
829 return val;
833 /* Map C_FUNCTION or FUNCTION over TABLE, calling it for each
834 character or group of characters that share a value.
836 ARG is passed to C_FUNCTION when that is called. */
838 void
839 map_char_table (c_function, function, table, arg)
840 void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
841 Lisp_Object function, table, arg;
843 Lisp_Object range, val;
844 int c, i;
845 struct gcpro gcpro1, gcpro2, gcpro3;
847 range = Fcons (make_number (0), make_number (MAX_CHAR));
848 GCPRO3 (table, arg, range);
849 val = XCHAR_TABLE (table)->ascii;
850 if (SUB_CHAR_TABLE_P (val))
851 val = XSUB_CHAR_TABLE (val)->contents[0];
852 val = map_sub_char_table (c_function, function, table, arg, val, range,
853 XCHAR_TABLE (table)->defalt,
854 XCHAR_TABLE (table)->parent);
855 /* If VAL is nil and TABLE has a parent, we must consult the parent
856 recursively. */
857 while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent))
859 Lisp_Object parent = XCHAR_TABLE (table)->parent;
860 Lisp_Object temp = XCHAR_TABLE (parent)->parent;
861 int from = XINT (XCAR (range));
863 /* This is to get a value of FROM in PARENT without checking the
864 parent of PARENT. */
865 XCHAR_TABLE (parent)->parent = Qnil;
866 val = CHAR_TABLE_REF (parent, from);
867 XCHAR_TABLE (parent)->parent = temp;
868 val = map_sub_char_table (c_function, function, parent, arg, val, range,
869 XCHAR_TABLE (parent)->defalt,
870 XCHAR_TABLE (parent)->parent);
871 table = parent;
874 if (! NILP (val))
876 if (EQ (XCAR (range), XCDR (range)))
878 if (c_function)
879 (*c_function) (arg, XCAR (range), val);
880 else
881 call2 (function, XCAR (range), val);
883 else
885 if (c_function)
886 (*c_function) (arg, range, val);
887 else
888 call2 (function, range, val);
892 UNGCPRO;
895 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
896 2, 2, 0,
897 doc: /*
898 Call FUNCTION for each character in CHAR-TABLE that has non-nil value.
899 FUNCTION is called with two arguments--a key and a value.
900 The key is a character code or a cons of character codes specifying a
901 range of characters that have the same value. */)
902 (function, char_table)
903 Lisp_Object function, char_table;
905 CHECK_CHAR_TABLE (char_table);
907 map_char_table (NULL, function, char_table, char_table);
908 return Qnil;
912 static void
913 map_sub_char_table_for_charset (c_function, function, table, arg, range,
914 charset, from, to)
915 void (*c_function) P_ ((Lisp_Object, Lisp_Object));
916 Lisp_Object function, table, arg, range;
917 struct charset *charset;
918 unsigned from, to;
920 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
921 int depth = XINT (tbl->depth);
922 int c, i;
924 if (depth < 3)
925 for (i = 0, c = XINT (tbl->min_char); i < chartab_size[depth];
926 i++, c += chartab_chars[depth])
928 Lisp_Object this;
930 this = tbl->contents[i];
931 if (SUB_CHAR_TABLE_P (this))
932 map_sub_char_table_for_charset (c_function, function, this, arg,
933 range, charset, from, to);
934 else
936 if (! NILP (XCAR (range)))
938 XSETCDR (range, make_number (c - 1));
939 if (c_function)
940 (*c_function) (arg, range);
941 else
942 call2 (function, range, arg);
944 XSETCAR (range, Qnil);
947 else
948 for (i = 0, c = XINT (tbl->min_char); i < chartab_size[depth]; i++, c ++)
950 Lisp_Object this;
951 unsigned code;
953 this = tbl->contents[i];
954 if (NILP (this)
955 || (charset
956 && (code = ENCODE_CHAR (charset, c),
957 (code < from || code > to))))
959 if (! NILP (XCAR (range)))
961 XSETCDR (range, make_number (c - 1));
962 if (c_function)
963 (*c_function) (arg, range);
964 else
965 call2 (function, range, arg);
966 XSETCAR (range, Qnil);
969 else
971 if (NILP (XCAR (range)))
972 XSETCAR (range, make_number (c));
978 void
979 map_char_table_for_charset (c_function, function, table, arg,
980 charset, from, to)
981 void (*c_function) P_ ((Lisp_Object, Lisp_Object));
982 Lisp_Object function, table, arg;
983 struct charset *charset;
984 unsigned from, to;
986 Lisp_Object range;
987 int c, i;
988 struct gcpro gcpro1;
990 range = Fcons (Qnil, Qnil);
991 GCPRO1 (range);
993 for (i = 0, c = 0; i < chartab_size[0]; i++, c += chartab_chars[0])
995 Lisp_Object this;
997 this = XCHAR_TABLE (table)->contents[i];
998 if (SUB_CHAR_TABLE_P (this))
999 map_sub_char_table_for_charset (c_function, function, this, arg,
1000 range, charset, from, to);
1001 else
1003 if (! NILP (XCAR (range)))
1005 XSETCDR (range, make_number (c - 1));
1006 if (c_function)
1007 (*c_function) (arg, range);
1008 else
1009 call2 (function, range, arg);
1011 XSETCAR (range, Qnil);
1014 if (! NILP (XCAR (range)))
1016 XSETCDR (range, make_number (c - 1));
1017 if (c_function)
1018 (*c_function) (arg, range);
1019 else
1020 call2 (function, range, arg);
1023 UNGCPRO;
1027 void
1028 syms_of_chartab ()
1030 defsubr (&Smake_char_table);
1031 defsubr (&Schar_table_parent);
1032 defsubr (&Schar_table_subtype);
1033 defsubr (&Sset_char_table_parent);
1034 defsubr (&Schar_table_extra_slot);
1035 defsubr (&Sset_char_table_extra_slot);
1036 defsubr (&Schar_table_range);
1037 defsubr (&Sset_char_table_range);
1038 defsubr (&Sset_char_table_default);
1039 defsubr (&Soptimize_char_table);
1040 defsubr (&Smap_char_table);
1043 /* arch-tag: 18b5b560-7ab5-4108-b09e-d5dd65dc6fda
1044 (do not change this comment) */