1 /* chartab.c -- char-table support
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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/>. */
24 #include "character.h"
30 /* Number of elements in Nth level char-table. */
31 const int chartab_size
[4] =
32 { (1 << CHARTAB_SIZE_BITS_0
),
33 (1 << CHARTAB_SIZE_BITS_1
),
34 (1 << CHARTAB_SIZE_BITS_2
),
35 (1 << CHARTAB_SIZE_BITS_3
) };
37 /* Number of characters each element of Nth level char-table
39 static const int chartab_chars
[4] =
40 { (1 << (CHARTAB_SIZE_BITS_1
+ CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
)),
41 (1 << (CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
)),
42 (1 << CHARTAB_SIZE_BITS_3
),
45 /* Number of characters (in bits) each element of Nth level char-table
47 static const int chartab_bits
[4] =
48 { (CHARTAB_SIZE_BITS_1
+ CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
),
49 (CHARTAB_SIZE_BITS_2
+ CHARTAB_SIZE_BITS_3
),
53 #define CHARTAB_IDX(c, depth, min_char) \
54 (((c) - (min_char)) >> chartab_bits[(depth)])
57 /* Preamble for uniprop (Unicode character property) tables. See the
58 comment of "Unicode character property tables". */
60 /* Purpose of uniprop tables. */
61 static Lisp_Object Qchar_code_property_table
;
63 /* Types of decoder and encoder functions for uniprop values. */
64 typedef Lisp_Object (*uniprop_decoder_t
) (Lisp_Object
, Lisp_Object
);
65 typedef Lisp_Object (*uniprop_encoder_t
) (Lisp_Object
, Lisp_Object
);
67 static Lisp_Object
uniprop_table_uncompress (Lisp_Object
, int);
68 static uniprop_decoder_t
uniprop_get_decoder (Lisp_Object
);
70 /* 1 iff TABLE is a uniprop table. */
71 #define UNIPROP_TABLE_P(TABLE) \
72 (EQ (XCHAR_TABLE (TABLE)->purpose, Qchar_code_property_table) \
73 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (TABLE)) == 5)
75 /* Return a decoder for values in the uniprop table TABLE. */
76 #define UNIPROP_GET_DECODER(TABLE) \
77 (UNIPROP_TABLE_P (TABLE) ? uniprop_get_decoder (TABLE) : NULL)
79 /* Nonzero iff OBJ is a string representing uniprop values of 128
80 succeeding characters (the bottom level of a char-table) by a
81 compressed format. We are sure that no property value has a string
82 starting with '\001' nor '\002'. */
83 #define UNIPROP_COMPRESSED_FORM_P(OBJ) \
84 (STRINGP (OBJ) && SCHARS (OBJ) > 0 \
85 && ((SREF (OBJ, 0) == 1 || (SREF (OBJ, 0) == 2))))
88 CHECK_CHAR_TABLE (Lisp_Object x
)
90 CHECK_TYPE (CHAR_TABLE_P (x
), Qchar_table_p
, x
);
94 set_char_table_ascii (Lisp_Object table
, Lisp_Object val
)
96 XCHAR_TABLE (table
)->ascii
= val
;
99 set_char_table_parent (Lisp_Object table
, Lisp_Object val
)
101 XCHAR_TABLE (table
)->parent
= val
;
104 DEFUN ("make-char-table", Fmake_char_table
, Smake_char_table
, 1, 2, 0,
105 doc
: /* Return a newly created char-table, with purpose PURPOSE.
106 Each element is initialized to INIT, which defaults to nil.
108 PURPOSE should be a symbol. If it has a `char-table-extra-slots'
109 property, the property's value should be an integer between 0 and 10
110 that specifies how many extra slots the char-table has. Otherwise,
111 the char-table has no extra slot. */)
112 (register Lisp_Object purpose
, Lisp_Object init
)
119 CHECK_SYMBOL (purpose
);
120 n
= Fget (purpose
, Qchar_table_extra_slots
);
127 args_out_of_range (n
, Qnil
);
131 size
= CHAR_TABLE_STANDARD_SLOTS
+ n_extras
;
132 vector
= Fmake_vector (make_number (size
), init
);
133 XSETPVECTYPE (XVECTOR (vector
), PVEC_CHAR_TABLE
);
134 set_char_table_parent (vector
, Qnil
);
135 set_char_table_purpose (vector
, purpose
);
136 XSETCHAR_TABLE (vector
, XCHAR_TABLE (vector
));
141 make_sub_char_table (int depth
, int min_char
, Lisp_Object defalt
)
144 int size
= CHAR_TABLE_STANDARD_SLOTS
+ chartab_size
[depth
];
146 table
= Fmake_vector (make_number (size
), defalt
);
147 XSETPVECTYPE (XVECTOR (table
), PVEC_SUB_CHAR_TABLE
);
148 XSUB_CHAR_TABLE (table
)->depth
= make_number (depth
);
149 XSUB_CHAR_TABLE (table
)->min_char
= make_number (min_char
);
155 char_table_ascii (Lisp_Object table
)
157 Lisp_Object sub
, val
;
159 sub
= XCHAR_TABLE (table
)->contents
[0];
160 if (! SUB_CHAR_TABLE_P (sub
))
162 sub
= XSUB_CHAR_TABLE (sub
)->contents
[0];
163 if (! SUB_CHAR_TABLE_P (sub
))
165 val
= XSUB_CHAR_TABLE (sub
)->contents
[0];
166 if (UNIPROP_TABLE_P (table
) && UNIPROP_COMPRESSED_FORM_P (val
))
167 val
= uniprop_table_uncompress (sub
, 0);
172 copy_sub_char_table (Lisp_Object table
)
174 int depth
= XINT (XSUB_CHAR_TABLE (table
)->depth
);
175 int min_char
= XINT (XSUB_CHAR_TABLE (table
)->min_char
);
176 Lisp_Object copy
= make_sub_char_table (depth
, min_char
, Qnil
);
179 /* Recursively copy any sub char-tables. */
180 for (i
= 0; i
< chartab_size
[depth
]; i
++)
182 Lisp_Object val
= XSUB_CHAR_TABLE (table
)->contents
[i
];
183 set_sub_char_table_contents
184 (copy
, i
, SUB_CHAR_TABLE_P (val
) ? copy_sub_char_table (val
) : val
);
192 copy_char_table (Lisp_Object table
)
195 int size
= XCHAR_TABLE (table
)->header
.size
& PSEUDOVECTOR_SIZE_MASK
;
198 copy
= Fmake_vector (make_number (size
), Qnil
);
199 XSETPVECTYPE (XVECTOR (copy
), PVEC_CHAR_TABLE
);
200 set_char_table_defalt (copy
, XCHAR_TABLE (table
)->defalt
);
201 set_char_table_parent (copy
, XCHAR_TABLE (table
)->parent
);
202 set_char_table_purpose (copy
, XCHAR_TABLE (table
)->purpose
);
203 for (i
= 0; i
< chartab_size
[0]; i
++)
204 set_char_table_contents
206 (SUB_CHAR_TABLE_P (XCHAR_TABLE (table
)->contents
[i
])
207 ? copy_sub_char_table (XCHAR_TABLE (table
)->contents
[i
])
208 : XCHAR_TABLE (table
)->contents
[i
]));
209 set_char_table_ascii (copy
, char_table_ascii (copy
));
210 size
-= CHAR_TABLE_STANDARD_SLOTS
;
211 for (i
= 0; i
< size
; i
++)
212 set_char_table_extras (copy
, i
, XCHAR_TABLE (table
)->extras
[i
]);
214 XSETCHAR_TABLE (copy
, XCHAR_TABLE (copy
));
219 sub_char_table_ref (Lisp_Object table
, int c
, bool is_uniprop
)
221 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
222 int depth
= XINT (tbl
->depth
);
223 int min_char
= XINT (tbl
->min_char
);
225 int idx
= CHARTAB_IDX (c
, depth
, min_char
);
227 val
= tbl
->contents
[idx
];
228 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
229 val
= uniprop_table_uncompress (table
, idx
);
230 if (SUB_CHAR_TABLE_P (val
))
231 val
= sub_char_table_ref (val
, c
, is_uniprop
);
236 char_table_ref (Lisp_Object table
, int c
)
238 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
241 if (ASCII_CHAR_P (c
))
244 if (SUB_CHAR_TABLE_P (val
))
245 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
249 val
= tbl
->contents
[CHARTAB_IDX (c
, 0, 0)];
250 if (SUB_CHAR_TABLE_P (val
))
251 val
= sub_char_table_ref (val
, c
, UNIPROP_TABLE_P (table
));
256 if (NILP (val
) && CHAR_TABLE_P (tbl
->parent
))
257 val
= char_table_ref (tbl
->parent
, c
);
263 sub_char_table_ref_and_range (Lisp_Object table
, int c
, int *from
, int *to
,
264 Lisp_Object defalt
, bool is_uniprop
)
266 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
267 int depth
= XINT (tbl
->depth
);
268 int min_char
= XINT (tbl
->min_char
);
269 int chartab_idx
= CHARTAB_IDX (c
, depth
, min_char
), idx
;
272 val
= tbl
->contents
[chartab_idx
];
273 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
274 val
= uniprop_table_uncompress (table
, chartab_idx
);
275 if (SUB_CHAR_TABLE_P (val
))
276 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, defalt
, is_uniprop
);
281 while (idx
> 0 && *from
< min_char
+ idx
* chartab_chars
[depth
])
283 Lisp_Object this_val
;
285 c
= min_char
+ idx
* chartab_chars
[depth
] - 1;
287 this_val
= tbl
->contents
[idx
];
288 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
289 this_val
= uniprop_table_uncompress (table
, idx
);
290 if (SUB_CHAR_TABLE_P (this_val
))
291 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
,
293 else if (NILP (this_val
))
296 if (! EQ (this_val
, val
))
302 while (((c
= (chartab_idx
+ 1) * chartab_chars
[depth
])
303 < chartab_chars
[depth
- 1])
304 && (c
+= min_char
) <= *to
)
306 Lisp_Object this_val
;
309 this_val
= tbl
->contents
[chartab_idx
];
310 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
311 this_val
= uniprop_table_uncompress (table
, chartab_idx
);
312 if (SUB_CHAR_TABLE_P (this_val
))
313 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
,
315 else if (NILP (this_val
))
317 if (! EQ (this_val
, val
))
328 /* Return the value for C in char-table TABLE. Shrink the range *FROM
329 and *TO to cover characters (containing C) that have the same value
330 as C. It is not assured that the values of (*FROM - 1) and (*TO +
331 1) are different from that of C. */
334 char_table_ref_and_range (Lisp_Object table
, int c
, int *from
, int *to
)
336 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
337 int chartab_idx
= CHARTAB_IDX (c
, 0, 0), idx
;
339 bool is_uniprop
= UNIPROP_TABLE_P (table
);
341 val
= tbl
->contents
[chartab_idx
];
346 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
347 val
= uniprop_table_uncompress (table
, chartab_idx
);
348 if (SUB_CHAR_TABLE_P (val
))
349 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, tbl
->defalt
,
354 while (*from
< idx
* chartab_chars
[0])
356 Lisp_Object this_val
;
358 c
= idx
* chartab_chars
[0] - 1;
360 this_val
= tbl
->contents
[idx
];
361 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
362 this_val
= uniprop_table_uncompress (table
, idx
);
363 if (SUB_CHAR_TABLE_P (this_val
))
364 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
365 tbl
->defalt
, is_uniprop
);
366 else if (NILP (this_val
))
367 this_val
= tbl
->defalt
;
369 if (! EQ (this_val
, val
))
375 while (*to
>= (chartab_idx
+ 1) * chartab_chars
[0])
377 Lisp_Object this_val
;
380 c
= chartab_idx
* chartab_chars
[0];
381 this_val
= tbl
->contents
[chartab_idx
];
382 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
383 this_val
= uniprop_table_uncompress (table
, chartab_idx
);
384 if (SUB_CHAR_TABLE_P (this_val
))
385 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
386 tbl
->defalt
, is_uniprop
);
387 else if (NILP (this_val
))
388 this_val
= tbl
->defalt
;
389 if (! EQ (this_val
, val
))
401 sub_char_table_set (Lisp_Object table
, int c
, Lisp_Object val
, bool is_uniprop
)
403 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
404 int depth
= XINT ((tbl
)->depth
);
405 int min_char
= XINT ((tbl
)->min_char
);
406 int i
= CHARTAB_IDX (c
, depth
, min_char
);
410 set_sub_char_table_contents (table
, i
, val
);
413 sub
= tbl
->contents
[i
];
414 if (! SUB_CHAR_TABLE_P (sub
))
416 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (sub
))
417 sub
= uniprop_table_uncompress (table
, i
);
420 sub
= make_sub_char_table (depth
+ 1,
421 min_char
+ i
* chartab_chars
[depth
],
423 set_sub_char_table_contents (table
, i
, sub
);
426 sub_char_table_set (sub
, c
, val
, is_uniprop
);
431 char_table_set (Lisp_Object table
, int c
, Lisp_Object val
)
433 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
436 && SUB_CHAR_TABLE_P (tbl
->ascii
))
437 set_sub_char_table_contents (tbl
->ascii
, c
, val
);
440 int i
= CHARTAB_IDX (c
, 0, 0);
443 sub
= tbl
->contents
[i
];
444 if (! SUB_CHAR_TABLE_P (sub
))
446 sub
= make_sub_char_table (1, i
* chartab_chars
[0], sub
);
447 set_char_table_contents (table
, i
, sub
);
449 sub_char_table_set (sub
, c
, val
, UNIPROP_TABLE_P (table
));
450 if (ASCII_CHAR_P (c
))
451 set_char_table_ascii (table
, char_table_ascii (table
));
456 sub_char_table_set_range (Lisp_Object table
, int from
, int to
, Lisp_Object val
,
459 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
460 int depth
= XINT ((tbl
)->depth
);
461 int min_char
= XINT ((tbl
)->min_char
);
462 int chars_in_block
= chartab_chars
[depth
];
463 int i
, c
, lim
= chartab_size
[depth
];
467 i
= CHARTAB_IDX (from
, depth
, min_char
);
468 c
= min_char
+ chars_in_block
* i
;
469 for (; i
< lim
; i
++, c
+= chars_in_block
)
473 if (from
<= c
&& c
+ chars_in_block
- 1 <= to
)
474 set_sub_char_table_contents (table
, i
, val
);
477 Lisp_Object sub
= tbl
->contents
[i
];
478 if (! SUB_CHAR_TABLE_P (sub
))
480 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (sub
))
481 sub
= uniprop_table_uncompress (table
, i
);
484 sub
= make_sub_char_table (depth
+ 1, c
, sub
);
485 set_sub_char_table_contents (table
, i
, sub
);
488 sub_char_table_set_range (sub
, from
, to
, val
, is_uniprop
);
495 char_table_set_range (Lisp_Object table
, int from
, int to
, Lisp_Object val
)
497 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
500 char_table_set (table
, from
, val
);
503 bool is_uniprop
= UNIPROP_TABLE_P (table
);
504 int lim
= CHARTAB_IDX (to
, 0, 0);
507 for (i
= CHARTAB_IDX (from
, 0, 0), c
= 0; i
<= lim
;
508 i
++, c
+= chartab_chars
[0])
512 if (from
<= c
&& c
+ chartab_chars
[0] - 1 <= to
)
513 set_char_table_contents (table
, i
, val
);
516 Lisp_Object sub
= tbl
->contents
[i
];
517 if (! SUB_CHAR_TABLE_P (sub
))
519 sub
= make_sub_char_table (1, i
* chartab_chars
[0], sub
);
520 set_char_table_contents (table
, i
, sub
);
522 sub_char_table_set_range (sub
, from
, to
, val
, is_uniprop
);
525 if (ASCII_CHAR_P (from
))
526 set_char_table_ascii (table
, char_table_ascii (table
));
531 DEFUN ("char-table-subtype", Fchar_table_subtype
, Schar_table_subtype
,
534 Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
535 (Lisp_Object char_table
)
537 CHECK_CHAR_TABLE (char_table
);
539 return XCHAR_TABLE (char_table
)->purpose
;
542 DEFUN ("char-table-parent", Fchar_table_parent
, Schar_table_parent
,
544 doc
: /* Return the parent char-table of CHAR-TABLE.
545 The value is either nil or another char-table.
546 If CHAR-TABLE holds nil for a given character,
547 then the actual applicable value is inherited from the parent char-table
548 \(or from its parents, if necessary). */)
549 (Lisp_Object char_table
)
551 CHECK_CHAR_TABLE (char_table
);
553 return XCHAR_TABLE (char_table
)->parent
;
556 DEFUN ("set-char-table-parent", Fset_char_table_parent
, Sset_char_table_parent
,
558 doc
: /* Set the parent char-table of CHAR-TABLE to PARENT.
559 Return PARENT. PARENT must be either nil or another char-table. */)
560 (Lisp_Object char_table
, Lisp_Object parent
)
564 CHECK_CHAR_TABLE (char_table
);
568 CHECK_CHAR_TABLE (parent
);
570 for (temp
= parent
; !NILP (temp
); temp
= XCHAR_TABLE (temp
)->parent
)
571 if (EQ (temp
, char_table
))
572 error ("Attempt to make a chartable be its own parent");
575 set_char_table_parent (char_table
, parent
);
580 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot
, Schar_table_extra_slot
,
582 doc
: /* Return the value of CHAR-TABLE's extra-slot number N. */)
583 (Lisp_Object char_table
, Lisp_Object n
)
585 CHECK_CHAR_TABLE (char_table
);
588 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
589 args_out_of_range (char_table
, n
);
591 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)];
594 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot
,
595 Sset_char_table_extra_slot
,
597 doc
: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
598 (Lisp_Object char_table
, Lisp_Object n
, Lisp_Object value
)
600 CHECK_CHAR_TABLE (char_table
);
603 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
604 args_out_of_range (char_table
, n
);
606 set_char_table_extras (char_table
, XINT (n
), value
);
610 DEFUN ("char-table-range", Fchar_table_range
, Schar_table_range
,
612 doc
: /* Return the value in CHAR-TABLE for a range of characters RANGE.
613 RANGE should be nil (for the default value),
614 a cons of character codes (for characters in the range), or a character code. */)
615 (Lisp_Object char_table
, Lisp_Object range
)
618 CHECK_CHAR_TABLE (char_table
);
620 if (EQ (range
, Qnil
))
621 val
= XCHAR_TABLE (char_table
)->defalt
;
622 else if (CHARACTERP (range
))
623 val
= CHAR_TABLE_REF (char_table
, XFASTINT (range
));
624 else if (CONSP (range
))
628 CHECK_CHARACTER_CAR (range
);
629 CHECK_CHARACTER_CDR (range
);
630 from
= XFASTINT (XCAR (range
));
631 to
= XFASTINT (XCDR (range
));
632 val
= char_table_ref_and_range (char_table
, from
, &from
, &to
);
633 /* Not yet implemented. */
636 error ("Invalid RANGE argument to `char-table-range'");
640 DEFUN ("set-char-table-range", Fset_char_table_range
, Sset_char_table_range
,
642 doc
: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
643 RANGE should be t (for all characters), nil (for the default value),
644 a cons of character codes (for characters in the range),
645 or a character code. Return VALUE. */)
646 (Lisp_Object char_table
, Lisp_Object range
, Lisp_Object value
)
648 CHECK_CHAR_TABLE (char_table
);
653 set_char_table_ascii (char_table
, value
);
654 for (i
= 0; i
< chartab_size
[0]; i
++)
655 set_char_table_contents (char_table
, i
, value
);
657 else if (EQ (range
, Qnil
))
658 set_char_table_defalt (char_table
, value
);
659 else if (CHARACTERP (range
))
660 char_table_set (char_table
, XINT (range
), value
);
661 else if (CONSP (range
))
663 CHECK_CHARACTER_CAR (range
);
664 CHECK_CHARACTER_CDR (range
);
665 char_table_set_range (char_table
,
666 XINT (XCAR (range
)), XINT (XCDR (range
)), value
);
669 error ("Invalid RANGE argument to `set-char-table-range'");
674 /* Look up the element in TABLE at index CH, and return it as an
675 integer. If the element is not a character, return CH itself. */
678 char_table_translate (Lisp_Object table
, int ch
)
681 value
= Faref (table
, make_number (ch
));
682 if (! CHARACTERP (value
))
688 optimize_sub_char_table (Lisp_Object table
, Lisp_Object test
)
690 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
691 int depth
= XINT (tbl
->depth
);
692 Lisp_Object elt
, this;
696 elt
= XSUB_CHAR_TABLE (table
)->contents
[0];
697 if (SUB_CHAR_TABLE_P (elt
))
699 elt
= optimize_sub_char_table (elt
, test
);
700 set_sub_char_table_contents (table
, 0, elt
);
702 optimizable
= SUB_CHAR_TABLE_P (elt
) ? 0 : 1;
703 for (i
= 1; i
< chartab_size
[depth
]; i
++)
705 this = XSUB_CHAR_TABLE (table
)->contents
[i
];
706 if (SUB_CHAR_TABLE_P (this))
708 this = optimize_sub_char_table (this, test
);
709 set_sub_char_table_contents (table
, i
, this);
712 && (NILP (test
) ? NILP (Fequal (this, elt
)) /* defaults to `equal'. */
713 : EQ (test
, Qeq
) ? !EQ (this, elt
) /* Optimize `eq' case. */
714 : NILP (call2 (test
, this, elt
))))
718 return (optimizable
? elt
: table
);
721 DEFUN ("optimize-char-table", Foptimize_char_table
, Soptimize_char_table
,
723 doc
: /* Optimize CHAR-TABLE.
724 TEST is the comparison function used to decide whether two entries are
725 equivalent and can be merged. It defaults to `equal'. */)
726 (Lisp_Object char_table
, Lisp_Object test
)
731 CHECK_CHAR_TABLE (char_table
);
733 for (i
= 0; i
< chartab_size
[0]; i
++)
735 elt
= XCHAR_TABLE (char_table
)->contents
[i
];
736 if (SUB_CHAR_TABLE_P (elt
))
737 set_char_table_contents
738 (char_table
, i
, optimize_sub_char_table (elt
, test
));
740 /* Reset the `ascii' cache, in case it got optimized away. */
741 set_char_table_ascii (char_table
, char_table_ascii (char_table
));
747 /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table),
748 calling it for each character or group of characters that share a
749 value. RANGE is a cons (FROM . TO) specifying the range of target
750 characters, VAL is a value of FROM in TABLE, TOP is the top
753 ARG is passed to C_FUNCTION when that is called.
755 It returns the value of last character covered by TABLE (not the
756 value inherited from the parent), and by side-effect, the car part
757 of RANGE is updated to the minimum character C where C and all the
758 following characters in TABLE have the same value. */
761 map_sub_char_table (void (*c_function
) (Lisp_Object
, Lisp_Object
, Lisp_Object
),
762 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
, Lisp_Object val
,
763 Lisp_Object range
, Lisp_Object top
)
765 /* Depth of TABLE. */
767 /* Minimum and maximum characters covered by TABLE. */
768 int min_char
, max_char
;
769 /* Number of characters covered by one element of TABLE. */
771 int from
= XINT (XCAR (range
)), to
= XINT (XCDR (range
));
773 bool is_uniprop
= UNIPROP_TABLE_P (top
);
774 uniprop_decoder_t decoder
= UNIPROP_GET_DECODER (top
);
776 if (SUB_CHAR_TABLE_P (table
))
778 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
780 depth
= XINT (tbl
->depth
);
781 min_char
= XINT (tbl
->min_char
);
782 max_char
= min_char
+ chartab_chars
[depth
- 1] - 1;
790 chars_in_block
= chartab_chars
[depth
];
794 /* Set I to the index of the first element to check. */
795 if (from
<= min_char
)
798 i
= (from
- min_char
) / chars_in_block
;
799 for (c
= min_char
+ chars_in_block
* i
; c
<= max_char
;
800 i
++, c
+= chars_in_block
)
802 Lisp_Object
this = (SUB_CHAR_TABLE_P (table
)
803 ? XSUB_CHAR_TABLE (table
)->contents
[i
]
804 : XCHAR_TABLE (table
)->contents
[i
]);
805 int nextc
= c
+ chars_in_block
;
807 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this))
808 this = uniprop_table_uncompress (table
, i
);
809 if (SUB_CHAR_TABLE_P (this))
812 XSETCDR (range
, make_number (nextc
- 1));
813 val
= map_sub_char_table (c_function
, function
, this, arg
,
819 this = XCHAR_TABLE (top
)->defalt
;
822 bool different_value
= 1;
826 if (! NILP (XCHAR_TABLE (top
)->parent
))
828 Lisp_Object parent
= XCHAR_TABLE (top
)->parent
;
829 Lisp_Object temp
= XCHAR_TABLE (parent
)->parent
;
831 /* This is to get a value of FROM in PARENT
832 without checking the parent of PARENT. */
833 set_char_table_parent (parent
, Qnil
);
834 val
= CHAR_TABLE_REF (parent
, from
);
835 set_char_table_parent (parent
, temp
);
836 XSETCDR (range
, make_number (c
- 1));
837 val
= map_sub_char_table (c_function
, function
,
838 parent
, arg
, val
, range
,
844 if (! NILP (val
) && different_value
)
846 XSETCDR (range
, make_number (c
- 1));
847 if (EQ (XCAR (range
), XCDR (range
)))
850 (*c_function
) (arg
, XCAR (range
), val
);
854 val
= decoder (top
, val
);
855 call2 (function
, XCAR (range
), val
);
861 (*c_function
) (arg
, range
, val
);
865 val
= decoder (top
, val
);
866 call2 (function
, range
, val
);
872 XSETCAR (range
, make_number (c
));
875 XSETCDR (range
, make_number (to
));
881 /* Map C_FUNCTION or FUNCTION over TABLE, calling it for each
882 character or group of characters that share a value.
884 ARG is passed to C_FUNCTION when that is called. */
887 map_char_table (void (*c_function
) (Lisp_Object
, Lisp_Object
, Lisp_Object
),
888 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
)
890 Lisp_Object range
, val
, parent
;
891 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
892 uniprop_decoder_t decoder
= UNIPROP_GET_DECODER (table
);
894 range
= Fcons (make_number (0), make_number (MAX_CHAR
));
895 parent
= XCHAR_TABLE (table
)->parent
;
897 GCPRO4 (table
, arg
, range
, parent
);
898 val
= XCHAR_TABLE (table
)->ascii
;
899 if (SUB_CHAR_TABLE_P (val
))
900 val
= XSUB_CHAR_TABLE (val
)->contents
[0];
901 val
= map_sub_char_table (c_function
, function
, table
, arg
, val
, range
,
904 /* If VAL is nil and TABLE has a parent, we must consult the parent
906 while (NILP (val
) && ! NILP (XCHAR_TABLE (table
)->parent
))
909 int from
= XINT (XCAR (range
));
911 parent
= XCHAR_TABLE (table
)->parent
;
912 temp
= XCHAR_TABLE (parent
)->parent
;
913 /* This is to get a value of FROM in PARENT without checking the
915 set_char_table_parent (parent
, Qnil
);
916 val
= CHAR_TABLE_REF (parent
, from
);
917 set_char_table_parent (parent
, temp
);
918 val
= map_sub_char_table (c_function
, function
, parent
, arg
, val
, range
,
925 if (EQ (XCAR (range
), XCDR (range
)))
928 (*c_function
) (arg
, XCAR (range
), val
);
932 val
= decoder (table
, val
);
933 call2 (function
, XCAR (range
), val
);
939 (*c_function
) (arg
, range
, val
);
943 val
= decoder (table
, val
);
944 call2 (function
, range
, val
);
952 DEFUN ("map-char-table", Fmap_char_table
, Smap_char_table
,
954 doc
: /* Call FUNCTION for each character in CHAR-TABLE that has non-nil value.
955 FUNCTION is called with two arguments, KEY and VALUE.
956 KEY is a character code or a cons of character codes specifying a
957 range of characters that have the same value.
958 VALUE is what (char-table-range CHAR-TABLE KEY) returns. */)
959 (Lisp_Object function
, Lisp_Object char_table
)
961 CHECK_CHAR_TABLE (char_table
);
963 map_char_table (NULL
, function
, char_table
, char_table
);
969 map_sub_char_table_for_charset (void (*c_function
) (Lisp_Object
, Lisp_Object
),
970 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
,
971 Lisp_Object range
, struct charset
*charset
,
972 unsigned from
, unsigned to
)
974 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
975 int depth
= XINT (tbl
->depth
);
979 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
];
980 i
++, c
+= chartab_chars
[depth
])
984 this = tbl
->contents
[i
];
985 if (SUB_CHAR_TABLE_P (this))
986 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
987 range
, charset
, from
, to
);
990 if (! NILP (XCAR (range
)))
992 XSETCDR (range
, make_number (c
- 1));
994 (*c_function
) (arg
, range
);
996 call2 (function
, range
, arg
);
998 XSETCAR (range
, Qnil
);
1002 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
]; i
++, c
++)
1007 this = tbl
->contents
[i
];
1010 && (code
= ENCODE_CHAR (charset
, c
),
1011 (code
< from
|| code
> to
))))
1013 if (! NILP (XCAR (range
)))
1015 XSETCDR (range
, make_number (c
- 1));
1017 (*c_function
) (arg
, range
);
1019 call2 (function
, range
, arg
);
1020 XSETCAR (range
, Qnil
);
1025 if (NILP (XCAR (range
)))
1026 XSETCAR (range
, make_number (c
));
1032 /* Support function for `map-charset-chars'. Map C_FUNCTION or
1033 FUNCTION over TABLE, calling it for each character or a group of
1034 succeeding characters that have non-nil value in TABLE. TABLE is a
1035 "mapping table" or a "deunifier table" of a certain charset.
1037 If CHARSET is not NULL (this is the case that `map-charset-chars'
1038 is called with non-nil FROM-CODE and TO-CODE), it is a charset who
1039 owns TABLE, and the function is called only on a character in the
1040 range FROM and TO. FROM and TO are not character codes, but code
1041 points of a character in CHARSET.
1043 This function is called in these two cases:
1045 (1) A charset has a mapping file name in :map property.
1047 (2) A charset has an upper code space in :offset property and a
1048 mapping file name in :unify-map property. In this case, this
1049 function is called only for characters in the Unicode code space.
1050 Characters in upper code space are handled directly in
1051 map_charset_chars. */
1054 map_char_table_for_charset (void (*c_function
) (Lisp_Object
, Lisp_Object
),
1055 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
,
1056 struct charset
*charset
,
1057 unsigned from
, unsigned to
)
1061 struct gcpro gcpro1
;
1063 range
= Fcons (Qnil
, Qnil
);
1066 for (i
= 0, c
= 0; i
< chartab_size
[0]; i
++, c
+= chartab_chars
[0])
1070 this = XCHAR_TABLE (table
)->contents
[i
];
1071 if (SUB_CHAR_TABLE_P (this))
1072 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
1073 range
, charset
, from
, to
);
1076 if (! NILP (XCAR (range
)))
1078 XSETCDR (range
, make_number (c
- 1));
1080 (*c_function
) (arg
, range
);
1082 call2 (function
, range
, arg
);
1084 XSETCAR (range
, Qnil
);
1087 if (! NILP (XCAR (range
)))
1089 XSETCDR (range
, make_number (c
- 1));
1091 (*c_function
) (arg
, range
);
1093 call2 (function
, range
, arg
);
1100 /* Unicode character property tables.
1102 This section provides a convenient and efficient way to get Unicode
1103 character properties of characters from C code (from Lisp, you must
1104 use get-char-code-property).
1106 The typical usage is to get a char-table object for a specific
1107 property like this (use of the "bidi-class" property below is just
1110 Lisp_Object bidi_class_table = uniprop_table (intern ("bidi-class"));
1112 (uniprop_table can return nil if it fails to find data for the
1113 named property, or if it fails to load the appropriate Lisp support
1114 file, so the return value should be tested to be non-nil, before it
1117 To get a property value for character CH use CHAR_TABLE_REF:
1119 Lisp_Object bidi_class = CHAR_TABLE_REF (bidi_class_table, CH);
1121 In this case, what you actually get is an index number to the
1122 vector of property values (symbols nil, L, R, etc).
1124 The full list of Unicode character properties supported by Emacs is
1125 documented in the ELisp manual, in the node "Character Properties".
1127 A table for Unicode character property has these characteristics:
1129 o The purpose is `char-code-property-table', which implies that the
1130 table has 5 extra slots.
1132 o The second extra slot is a Lisp function, an index (integer) to
1133 the array uniprop_decoder[], or nil. If it is a Lisp function, we
1134 can't use such a table from C (at the moment). If it is nil, it
1135 means that we don't have to decode values.
1137 o The third extra slot is a Lisp function, an index (integer) to
1138 the array uniprop_encoder[], or nil. If it is a Lisp function, we
1139 can't use such a table from C (at the moment). If it is nil, it
1140 means that we don't have to encode values. */
1143 /* Uncompress the IDXth element of sub-char-table TABLE. */
1146 uniprop_table_uncompress (Lisp_Object table
, int idx
)
1148 Lisp_Object val
= XSUB_CHAR_TABLE (table
)->contents
[idx
];
1149 int min_char
= (XINT (XSUB_CHAR_TABLE (table
)->min_char
)
1150 + chartab_chars
[2] * idx
);
1151 Lisp_Object sub
= make_sub_char_table (3, min_char
, Qnil
);
1152 const unsigned char *p
, *pend
;
1154 set_sub_char_table_contents (table
, idx
, sub
);
1155 p
= SDATA (val
), pend
= p
+ SBYTES (val
);
1160 idx
= STRING_CHAR_ADVANCE (p
);
1161 while (p
< pend
&& idx
< chartab_chars
[2])
1163 int v
= STRING_CHAR_ADVANCE (p
);
1164 set_sub_char_table_contents
1165 (sub
, idx
++, v
> 0 ? make_number (v
) : Qnil
);
1170 /* RUN-LENGTH TABLE */
1172 for (idx
= 0; p
< pend
; )
1174 int v
= STRING_CHAR_ADVANCE (p
);
1180 count
= STRING_CHAR_AND_LENGTH (p
, len
);
1190 set_sub_char_table_contents (sub
, idx
++, make_number (v
));
1193 /* It seems that we don't need this function because C code won't need
1194 to get a property that is compressed in this form. */
1198 /* WORD-LIST TABLE */
1205 /* Decode VALUE as an element of char-table TABLE. */
1208 uniprop_decode_value_run_length (Lisp_Object table
, Lisp_Object value
)
1210 if (VECTORP (XCHAR_TABLE (table
)->extras
[4]))
1212 Lisp_Object valvec
= XCHAR_TABLE (table
)->extras
[4];
1214 if (XINT (value
) >= 0 && XINT (value
) < ASIZE (valvec
))
1215 value
= AREF (valvec
, XINT (value
));
1220 static uniprop_decoder_t uniprop_decoder
[] =
1221 { uniprop_decode_value_run_length
};
1223 static int uniprop_decoder_count
1224 = (sizeof uniprop_decoder
) / sizeof (uniprop_decoder
[0]);
1227 /* Return the decoder of char-table TABLE or nil if none. */
1229 static uniprop_decoder_t
1230 uniprop_get_decoder (Lisp_Object table
)
1234 if (! INTEGERP (XCHAR_TABLE (table
)->extras
[1]))
1236 i
= XINT (XCHAR_TABLE (table
)->extras
[1]);
1237 if (i
< 0 || i
>= uniprop_decoder_count
)
1239 return uniprop_decoder
[i
];
1243 /* Encode VALUE as an element of char-table TABLE which contains
1244 characters as elements. */
1247 uniprop_encode_value_character (Lisp_Object table
, Lisp_Object value
)
1249 if (! NILP (value
) && ! CHARACTERP (value
))
1250 wrong_type_argument (Qintegerp
, value
);
1255 /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1259 uniprop_encode_value_run_length (Lisp_Object table
, Lisp_Object value
)
1261 Lisp_Object
*value_table
= XVECTOR (XCHAR_TABLE (table
)->extras
[4])->u
.contents
;
1262 int i
, size
= ASIZE (XCHAR_TABLE (table
)->extras
[4]);
1264 for (i
= 0; i
< size
; i
++)
1265 if (EQ (value
, value_table
[i
]))
1268 wrong_type_argument (build_string ("Unicode property value"), value
);
1269 return make_number (i
);
1273 /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1274 compression and contains numbers as elements . */
1277 uniprop_encode_value_numeric (Lisp_Object table
, Lisp_Object value
)
1279 Lisp_Object
*value_table
= XVECTOR (XCHAR_TABLE (table
)->extras
[4])->u
.contents
;
1280 int i
, size
= ASIZE (XCHAR_TABLE (table
)->extras
[4]);
1282 CHECK_NUMBER (value
);
1283 for (i
= 0; i
< size
; i
++)
1284 if (EQ (value
, value_table
[i
]))
1286 value
= make_number (i
);
1289 Lisp_Object args
[2];
1291 args
[0] = XCHAR_TABLE (table
)->extras
[4];
1292 args
[1] = Fmake_vector (make_number (1), value
);
1293 set_char_table_extras (table
, 4, Fvconcat (2, args
));
1295 return make_number (i
);
1298 static uniprop_encoder_t uniprop_encoder
[] =
1299 { uniprop_encode_value_character
,
1300 uniprop_encode_value_run_length
,
1301 uniprop_encode_value_numeric
};
1303 static int uniprop_encoder_count
1304 = (sizeof uniprop_encoder
) / sizeof (uniprop_encoder
[0]);
1307 /* Return the encoder of char-table TABLE or nil if none. */
1309 static uniprop_decoder_t
1310 uniprop_get_encoder (Lisp_Object table
)
1314 if (! INTEGERP (XCHAR_TABLE (table
)->extras
[2]))
1316 i
= XINT (XCHAR_TABLE (table
)->extras
[2]);
1317 if (i
< 0 || i
>= uniprop_encoder_count
)
1319 return uniprop_encoder
[i
];
1322 /* Return a char-table for Unicode character property PROP. This
1323 function may load a Lisp file and thus may cause
1324 garbage-collection. */
1327 uniprop_table (Lisp_Object prop
)
1329 Lisp_Object val
, table
, result
;
1331 val
= Fassq (prop
, Vchar_code_property_alist
);
1335 if (STRINGP (table
))
1337 struct gcpro gcpro1
;
1339 result
= Fload (concat2 (build_string ("international/"), table
),
1346 if (! CHAR_TABLE_P (table
)
1347 || ! UNIPROP_TABLE_P (table
))
1349 val
= XCHAR_TABLE (table
)->extras
[1];
1351 ? (XINT (val
) < 0 || XINT (val
) >= uniprop_decoder_count
)
1354 /* Prepare ASCII values in advance for CHAR_TABLE_REF. */
1355 set_char_table_ascii (table
, char_table_ascii (table
));
1359 DEFUN ("unicode-property-table-internal", Funicode_property_table_internal
,
1360 Sunicode_property_table_internal
, 1, 1, 0,
1361 doc
: /* Return a char-table for Unicode character property PROP.
1362 Use `get-unicode-property-internal' and
1363 `put-unicode-property-internal' instead of `aref' and `aset' to get
1364 and put an element value. */)
1367 Lisp_Object table
= uniprop_table (prop
);
1369 if (CHAR_TABLE_P (table
))
1371 return Fcdr (Fassq (prop
, Vchar_code_property_alist
));
1374 DEFUN ("get-unicode-property-internal", Fget_unicode_property_internal
,
1375 Sget_unicode_property_internal
, 2, 2, 0,
1376 doc
: /* Return an element of CHAR-TABLE for character CH.
1377 CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1378 (Lisp_Object char_table
, Lisp_Object ch
)
1381 uniprop_decoder_t decoder
;
1383 CHECK_CHAR_TABLE (char_table
);
1384 CHECK_CHARACTER (ch
);
1385 if (! UNIPROP_TABLE_P (char_table
))
1386 error ("Invalid Unicode property table");
1387 val
= CHAR_TABLE_REF (char_table
, XINT (ch
));
1388 decoder
= uniprop_get_decoder (char_table
);
1389 return (decoder
? decoder (char_table
, val
) : val
);
1392 DEFUN ("put-unicode-property-internal", Fput_unicode_property_internal
,
1393 Sput_unicode_property_internal
, 3, 3, 0,
1394 doc
: /* Set an element of CHAR-TABLE for character CH to VALUE.
1395 CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1396 (Lisp_Object char_table
, Lisp_Object ch
, Lisp_Object value
)
1398 uniprop_encoder_t encoder
;
1400 CHECK_CHAR_TABLE (char_table
);
1401 CHECK_CHARACTER (ch
);
1402 if (! UNIPROP_TABLE_P (char_table
))
1403 error ("Invalid Unicode property table");
1404 encoder
= uniprop_get_encoder (char_table
);
1406 value
= encoder (char_table
, value
);
1407 CHAR_TABLE_SET (char_table
, XINT (ch
), value
);
1413 syms_of_chartab (void)
1415 DEFSYM (Qchar_code_property_table
, "char-code-property-table");
1417 defsubr (&Smake_char_table
);
1418 defsubr (&Schar_table_parent
);
1419 defsubr (&Schar_table_subtype
);
1420 defsubr (&Sset_char_table_parent
);
1421 defsubr (&Schar_table_extra_slot
);
1422 defsubr (&Sset_char_table_extra_slot
);
1423 defsubr (&Schar_table_range
);
1424 defsubr (&Sset_char_table_range
);
1425 defsubr (&Soptimize_char_table
);
1426 defsubr (&Smap_char_table
);
1427 defsubr (&Sunicode_property_table_internal
);
1428 defsubr (&Sget_unicode_property_internal
);
1429 defsubr (&Sput_unicode_property_internal
);
1431 /* Each element has the form (PROP . TABLE).
1432 PROP is a symbol representing a character property.
1433 TABLE is a char-table containing the property value for each character.
1434 TABLE may be a name of file to load to build a char-table.
1435 This variable should be modified only through
1436 `define-char-code-property'. */
1438 DEFVAR_LISP ("char-code-property-alist", Vchar_code_property_alist
,
1439 doc
: /* Alist of character property name vs char-table containing property values.
1440 Internal use only. */);
1441 Vchar_code_property_alist
= Qnil
;