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 DEFUN ("make-char-table", Fmake_char_table
, Smake_char_table
, 1, 2, 0,
89 doc
: /* Return a newly created char-table, with purpose PURPOSE.
90 Each element is initialized to INIT, which defaults to nil.
92 PURPOSE should be a symbol. If it has a `char-table-extra-slots'
93 property, the property's value should be an integer between 0 and 10
94 that specifies how many extra slots the char-table has. Otherwise,
95 the char-table has no extra slot. */)
96 (register Lisp_Object purpose
, Lisp_Object init
)
103 CHECK_SYMBOL (purpose
);
104 n
= Fget (purpose
, Qchar_table_extra_slots
);
112 args_out_of_range (n
, Qnil
);
115 size
= VECSIZE (struct Lisp_Char_Table
) - 1 + n_extras
;
116 vector
= Fmake_vector (make_number (size
), init
);
117 XSETPVECTYPE (XVECTOR (vector
), PVEC_CHAR_TABLE
);
118 XCHAR_TABLE (vector
)->parent
= Qnil
;
119 XCHAR_TABLE (vector
)->purpose
= purpose
;
120 XSETCHAR_TABLE (vector
, XCHAR_TABLE (vector
));
125 make_sub_char_table (int depth
, int min_char
, Lisp_Object defalt
)
128 int size
= VECSIZE (struct Lisp_Sub_Char_Table
) - 1 + chartab_size
[depth
];
130 table
= Fmake_vector (make_number (size
), defalt
);
131 XSETPVECTYPE (XVECTOR (table
), PVEC_SUB_CHAR_TABLE
);
132 XSUB_CHAR_TABLE (table
)->depth
= make_number (depth
);
133 XSUB_CHAR_TABLE (table
)->min_char
= make_number (min_char
);
139 char_table_ascii (Lisp_Object table
)
141 Lisp_Object sub
, val
;
143 sub
= XCHAR_TABLE (table
)->contents
[0];
144 if (! SUB_CHAR_TABLE_P (sub
))
146 sub
= XSUB_CHAR_TABLE (sub
)->contents
[0];
147 if (! SUB_CHAR_TABLE_P (sub
))
149 val
= XSUB_CHAR_TABLE (sub
)->contents
[0];
150 if (UNIPROP_TABLE_P (table
) && UNIPROP_COMPRESSED_FORM_P (val
))
151 val
= uniprop_table_uncompress (sub
, 0);
156 copy_sub_char_table (Lisp_Object table
)
159 int depth
= XINT (XSUB_CHAR_TABLE (table
)->depth
);
160 int min_char
= XINT (XSUB_CHAR_TABLE (table
)->min_char
);
164 copy
= make_sub_char_table (depth
, min_char
, Qnil
);
165 /* Recursively copy any sub char-tables. */
166 for (i
= 0; i
< chartab_size
[depth
]; i
++)
168 val
= XSUB_CHAR_TABLE (table
)->contents
[i
];
169 if (SUB_CHAR_TABLE_P (val
))
170 XSUB_CHAR_TABLE (copy
)->contents
[i
] = copy_sub_char_table (val
);
172 XSUB_CHAR_TABLE (copy
)->contents
[i
] = val
;
180 copy_char_table (Lisp_Object table
)
183 int size
= XCHAR_TABLE (table
)->header
.size
& PSEUDOVECTOR_SIZE_MASK
;
186 copy
= Fmake_vector (make_number (size
), Qnil
);
187 XSETPVECTYPE (XVECTOR (copy
), PVEC_CHAR_TABLE
);
188 XCHAR_TABLE (copy
)->defalt
= XCHAR_TABLE (table
)->defalt
;
189 XCHAR_TABLE (copy
)->parent
= XCHAR_TABLE (table
)->parent
;
190 XCHAR_TABLE (copy
)->purpose
= XCHAR_TABLE (table
)->purpose
;
191 for (i
= 0; i
< chartab_size
[0]; i
++)
192 XCHAR_TABLE (copy
)->contents
[i
]
193 = (SUB_CHAR_TABLE_P (XCHAR_TABLE (table
)->contents
[i
])
194 ? copy_sub_char_table (XCHAR_TABLE (table
)->contents
[i
])
195 : XCHAR_TABLE (table
)->contents
[i
]);
196 XCHAR_TABLE (copy
)->ascii
= char_table_ascii (copy
);
197 size
-= VECSIZE (struct Lisp_Char_Table
) - 1;
198 for (i
= 0; i
< size
; i
++)
199 XCHAR_TABLE (copy
)->extras
[i
] = XCHAR_TABLE (table
)->extras
[i
];
201 XSETCHAR_TABLE (copy
, XCHAR_TABLE (copy
));
206 sub_char_table_ref (Lisp_Object table
, int c
, int is_uniprop
)
208 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
209 int depth
= XINT (tbl
->depth
);
210 int min_char
= XINT (tbl
->min_char
);
212 int idx
= CHARTAB_IDX (c
, depth
, min_char
);
214 val
= tbl
->contents
[idx
];
215 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
216 val
= uniprop_table_uncompress (table
, idx
);
217 if (SUB_CHAR_TABLE_P (val
))
218 val
= sub_char_table_ref (val
, c
, is_uniprop
);
223 char_table_ref (Lisp_Object table
, int c
)
225 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
228 if (ASCII_CHAR_P (c
))
231 if (SUB_CHAR_TABLE_P (val
))
232 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
236 val
= tbl
->contents
[CHARTAB_IDX (c
, 0, 0)];
237 if (SUB_CHAR_TABLE_P (val
))
238 val
= sub_char_table_ref (val
, c
, UNIPROP_TABLE_P (table
));
243 if (NILP (val
) && CHAR_TABLE_P (tbl
->parent
))
244 val
= char_table_ref (tbl
->parent
, c
);
250 sub_char_table_ref_and_range (Lisp_Object table
, int c
, int *from
, int *to
,
251 Lisp_Object defalt
, int is_uniprop
)
253 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
254 int depth
= XINT (tbl
->depth
);
255 int min_char
= XINT (tbl
->min_char
);
256 int chartab_idx
= CHARTAB_IDX (c
, depth
, min_char
), idx
;
259 val
= tbl
->contents
[chartab_idx
];
260 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
261 val
= uniprop_table_uncompress (table
, chartab_idx
);
262 if (SUB_CHAR_TABLE_P (val
))
263 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, defalt
, is_uniprop
);
268 while (idx
> 0 && *from
< min_char
+ idx
* chartab_chars
[depth
])
270 Lisp_Object this_val
;
272 c
= min_char
+ idx
* chartab_chars
[depth
] - 1;
274 this_val
= tbl
->contents
[idx
];
275 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
276 this_val
= uniprop_table_uncompress (table
, idx
);
277 if (SUB_CHAR_TABLE_P (this_val
))
278 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
,
280 else if (NILP (this_val
))
283 if (! EQ (this_val
, val
))
289 while (((c
= (chartab_idx
+ 1) * chartab_chars
[depth
])
290 < chartab_chars
[depth
- 1])
291 && (c
+= min_char
) <= *to
)
293 Lisp_Object this_val
;
296 this_val
= tbl
->contents
[chartab_idx
];
297 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
298 this_val
= uniprop_table_uncompress (table
, chartab_idx
);
299 if (SUB_CHAR_TABLE_P (this_val
))
300 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
, defalt
,
302 else if (NILP (this_val
))
304 if (! EQ (this_val
, val
))
315 /* Return the value for C in char-table TABLE. Shrink the range *FROM
316 and *TO to cover characters (containing C) that have the same value
317 as C. It is not assured that the values of (*FROM - 1) and (*TO +
318 1) are different from that of C. */
321 char_table_ref_and_range (Lisp_Object table
, int c
, int *from
, int *to
)
323 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
324 int chartab_idx
= CHARTAB_IDX (c
, 0, 0), idx
;
326 int is_uniprop
= UNIPROP_TABLE_P (table
);
328 val
= tbl
->contents
[chartab_idx
];
333 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (val
))
334 val
= uniprop_table_uncompress (table
, chartab_idx
);
335 if (SUB_CHAR_TABLE_P (val
))
336 val
= sub_char_table_ref_and_range (val
, c
, from
, to
, tbl
->defalt
,
341 while (*from
< idx
* chartab_chars
[0])
343 Lisp_Object this_val
;
345 c
= idx
* chartab_chars
[0] - 1;
347 this_val
= tbl
->contents
[idx
];
348 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
349 this_val
= uniprop_table_uncompress (table
, idx
);
350 if (SUB_CHAR_TABLE_P (this_val
))
351 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
352 tbl
->defalt
, is_uniprop
);
353 else if (NILP (this_val
))
354 this_val
= tbl
->defalt
;
356 if (! EQ (this_val
, val
))
362 while (*to
>= (chartab_idx
+ 1) * chartab_chars
[0])
364 Lisp_Object this_val
;
367 c
= chartab_idx
* chartab_chars
[0];
368 this_val
= tbl
->contents
[chartab_idx
];
369 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this_val
))
370 this_val
= uniprop_table_uncompress (table
, chartab_idx
);
371 if (SUB_CHAR_TABLE_P (this_val
))
372 this_val
= sub_char_table_ref_and_range (this_val
, c
, from
, to
,
373 tbl
->defalt
, is_uniprop
);
374 else if (NILP (this_val
))
375 this_val
= tbl
->defalt
;
376 if (! EQ (this_val
, val
))
388 sub_char_table_set (Lisp_Object table
, int c
, Lisp_Object val
, int is_uniprop
)
390 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
391 int depth
= XINT ((tbl
)->depth
);
392 int min_char
= XINT ((tbl
)->min_char
);
393 int i
= CHARTAB_IDX (c
, depth
, min_char
);
397 tbl
->contents
[i
] = val
;
400 sub
= tbl
->contents
[i
];
401 if (! SUB_CHAR_TABLE_P (sub
))
403 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (sub
))
404 sub
= uniprop_table_uncompress (table
, i
);
407 sub
= make_sub_char_table (depth
+ 1,
408 min_char
+ i
* chartab_chars
[depth
],
410 tbl
->contents
[i
] = sub
;
413 sub_char_table_set (sub
, c
, val
, is_uniprop
);
418 char_table_set (Lisp_Object table
, int c
, Lisp_Object val
)
420 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
423 && SUB_CHAR_TABLE_P (tbl
->ascii
))
425 XSUB_CHAR_TABLE (tbl
->ascii
)->contents
[c
] = val
;
429 int i
= CHARTAB_IDX (c
, 0, 0);
432 sub
= tbl
->contents
[i
];
433 if (! SUB_CHAR_TABLE_P (sub
))
435 sub
= make_sub_char_table (1, i
* chartab_chars
[0], sub
);
436 tbl
->contents
[i
] = sub
;
438 sub_char_table_set (sub
, c
, val
, UNIPROP_TABLE_P (table
));
439 if (ASCII_CHAR_P (c
))
440 tbl
->ascii
= char_table_ascii (table
);
446 sub_char_table_set_range (Lisp_Object table
, int from
, int to
, Lisp_Object val
,
449 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
450 int depth
= XINT ((tbl
)->depth
);
451 int min_char
= XINT ((tbl
)->min_char
);
452 int chars_in_block
= chartab_chars
[depth
];
453 int i
, c
, lim
= chartab_size
[depth
];
457 i
= CHARTAB_IDX (from
, depth
, min_char
);
458 c
= min_char
+ chars_in_block
* i
;
459 for (; i
< lim
; i
++, c
+= chars_in_block
)
463 if (from
<= c
&& c
+ chars_in_block
- 1 <= to
)
464 tbl
->contents
[i
] = val
;
467 Lisp_Object sub
= tbl
->contents
[i
];
468 if (! SUB_CHAR_TABLE_P (sub
))
470 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (sub
))
471 sub
= uniprop_table_uncompress (table
, i
);
474 sub
= make_sub_char_table (depth
+ 1, c
, sub
);
475 tbl
->contents
[i
] = sub
;
478 sub_char_table_set_range (sub
, from
, to
, val
, is_uniprop
);
485 char_table_set_range (Lisp_Object table
, int from
, int to
, Lisp_Object val
)
487 struct Lisp_Char_Table
*tbl
= XCHAR_TABLE (table
);
490 char_table_set (table
, from
, val
);
493 int is_uniprop
= UNIPROP_TABLE_P (table
);
494 int lim
= CHARTAB_IDX (to
, 0, 0);
497 for (i
= CHARTAB_IDX (from
, 0, 0), c
= 0; i
<= lim
;
498 i
++, c
+= chartab_chars
[0])
502 if (from
<= c
&& c
+ chartab_chars
[0] - 1 <= to
)
503 tbl
->contents
[i
] = val
;
506 Lisp_Object sub
= tbl
->contents
[i
];
507 if (! SUB_CHAR_TABLE_P (sub
))
509 sub
= make_sub_char_table (1, i
* chartab_chars
[0], sub
);
510 tbl
->contents
[i
] = sub
;
512 sub_char_table_set_range (sub
, from
, to
, val
, is_uniprop
);
515 if (ASCII_CHAR_P (from
))
516 tbl
->ascii
= char_table_ascii (table
);
522 DEFUN ("char-table-subtype", Fchar_table_subtype
, Schar_table_subtype
,
525 Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
526 (Lisp_Object char_table
)
528 CHECK_CHAR_TABLE (char_table
);
530 return XCHAR_TABLE (char_table
)->purpose
;
533 DEFUN ("char-table-parent", Fchar_table_parent
, Schar_table_parent
,
535 doc
: /* Return the parent char-table of CHAR-TABLE.
536 The value is either nil or another char-table.
537 If CHAR-TABLE holds nil for a given character,
538 then the actual applicable value is inherited from the parent char-table
539 \(or from its parents, if necessary). */)
540 (Lisp_Object char_table
)
542 CHECK_CHAR_TABLE (char_table
);
544 return XCHAR_TABLE (char_table
)->parent
;
547 DEFUN ("set-char-table-parent", Fset_char_table_parent
, Sset_char_table_parent
,
549 doc
: /* Set the parent char-table of CHAR-TABLE to PARENT.
550 Return PARENT. PARENT must be either nil or another char-table. */)
551 (Lisp_Object char_table
, Lisp_Object parent
)
555 CHECK_CHAR_TABLE (char_table
);
559 CHECK_CHAR_TABLE (parent
);
561 for (temp
= parent
; !NILP (temp
); temp
= XCHAR_TABLE (temp
)->parent
)
562 if (EQ (temp
, char_table
))
563 error ("Attempt to make a chartable be its own parent");
566 XCHAR_TABLE (char_table
)->parent
= parent
;
571 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot
, Schar_table_extra_slot
,
573 doc
: /* Return the value of CHAR-TABLE's extra-slot number N. */)
574 (Lisp_Object char_table
, Lisp_Object n
)
576 CHECK_CHAR_TABLE (char_table
);
579 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
580 args_out_of_range (char_table
, n
);
582 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)];
585 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot
,
586 Sset_char_table_extra_slot
,
588 doc
: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
589 (Lisp_Object char_table
, Lisp_Object n
, Lisp_Object value
)
591 CHECK_CHAR_TABLE (char_table
);
592 if (EQ (XCHAR_TABLE (char_table
)->purpose
, Qchar_code_property_table
))
593 error ("Can't change extra-slot of char-code-property-table");
596 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
597 args_out_of_range (char_table
, n
);
599 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)] = value
;
602 DEFUN ("char-table-range", Fchar_table_range
, Schar_table_range
,
604 doc
: /* Return the value in CHAR-TABLE for a range of characters RANGE.
605 RANGE should be nil (for the default value),
606 a cons of character codes (for characters in the range), or a character code. */)
607 (Lisp_Object char_table
, Lisp_Object range
)
610 CHECK_CHAR_TABLE (char_table
);
612 if (EQ (range
, Qnil
))
613 val
= XCHAR_TABLE (char_table
)->defalt
;
614 else if (CHARACTERP (range
))
615 val
= CHAR_TABLE_REF (char_table
, XFASTINT (range
));
616 else if (CONSP (range
))
620 CHECK_CHARACTER_CAR (range
);
621 CHECK_CHARACTER_CDR (range
);
622 from
= XFASTINT (XCAR (range
));
623 to
= XFASTINT (XCDR (range
));
624 val
= char_table_ref_and_range (char_table
, from
, &from
, &to
);
625 /* Not yet implemented. */
628 error ("Invalid RANGE argument to `char-table-range'");
632 DEFUN ("set-char-table-range", Fset_char_table_range
, Sset_char_table_range
,
634 doc
: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
635 RANGE should be t (for all characters), nil (for the default value),
636 a cons of character codes (for characters in the range),
637 or a character code. Return VALUE. */)
638 (Lisp_Object char_table
, Lisp_Object range
, Lisp_Object value
)
640 CHECK_CHAR_TABLE (char_table
);
645 XCHAR_TABLE (char_table
)->ascii
= value
;
646 for (i
= 0; i
< chartab_size
[0]; i
++)
647 XCHAR_TABLE (char_table
)->contents
[i
] = value
;
649 else if (EQ (range
, Qnil
))
650 XCHAR_TABLE (char_table
)->defalt
= value
;
651 else if (INTEGERP (range
))
652 char_table_set (char_table
, XINT (range
), value
);
653 else if (CONSP (range
))
655 CHECK_CHARACTER_CAR (range
);
656 CHECK_CHARACTER_CDR (range
);
657 char_table_set_range (char_table
,
658 XINT (XCAR (range
)), XINT (XCDR (range
)), value
);
661 error ("Invalid RANGE argument to `set-char-table-range'");
666 DEFUN ("set-char-table-default", Fset_char_table_default
,
667 Sset_char_table_default
, 3, 3, 0,
669 This function is obsolete and has no effect. */)
670 (Lisp_Object char_table
, Lisp_Object ch
, Lisp_Object value
)
675 /* Look up the element in TABLE at index CH, and return it as an
676 integer. If the element is not a character, return CH itself. */
679 char_table_translate (Lisp_Object table
, int ch
)
682 value
= Faref (table
, make_number (ch
));
683 if (! CHARACTERP (value
))
689 optimize_sub_char_table (Lisp_Object table
, Lisp_Object test
)
691 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
692 int depth
= XINT (tbl
->depth
);
693 Lisp_Object elt
, this;
696 elt
= XSUB_CHAR_TABLE (table
)->contents
[0];
697 if (SUB_CHAR_TABLE_P (elt
))
698 elt
= XSUB_CHAR_TABLE (table
)->contents
[0]
699 = optimize_sub_char_table (elt
, test
);
700 optimizable
= SUB_CHAR_TABLE_P (elt
) ? 0 : 1;
701 for (i
= 1; i
< chartab_size
[depth
]; i
++)
703 this = XSUB_CHAR_TABLE (table
)->contents
[i
];
704 if (SUB_CHAR_TABLE_P (this))
705 this = XSUB_CHAR_TABLE (table
)->contents
[i
]
706 = optimize_sub_char_table (this, test
);
708 && (NILP (test
) ? NILP (Fequal (this, elt
)) /* defaults to `equal'. */
709 : EQ (test
, Qeq
) ? !EQ (this, elt
) /* Optimize `eq' case. */
710 : NILP (call2 (test
, this, elt
))))
714 return (optimizable
? elt
: table
);
717 DEFUN ("optimize-char-table", Foptimize_char_table
, Soptimize_char_table
,
719 doc
: /* Optimize CHAR-TABLE.
720 TEST is the comparison function used to decide whether two entries are
721 equivalent and can be merged. It defaults to `equal'. */)
722 (Lisp_Object char_table
, Lisp_Object test
)
727 CHECK_CHAR_TABLE (char_table
);
729 for (i
= 0; i
< chartab_size
[0]; i
++)
731 elt
= XCHAR_TABLE (char_table
)->contents
[i
];
732 if (SUB_CHAR_TABLE_P (elt
))
733 XCHAR_TABLE (char_table
)->contents
[i
]
734 = optimize_sub_char_table (elt
, test
);
736 /* Reset the `ascii' cache, in case it got optimized away. */
737 XCHAR_TABLE (char_table
)->ascii
= char_table_ascii (char_table
);
743 /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table),
744 calling it for each character or group of characters that share a
745 value. RANGE is a cons (FROM . TO) specifying the range of target
746 characters, VAL is a value of FROM in TABLE, TOP is the top
749 ARG is passed to C_FUNCTION when that is called.
751 It returns the value of last character covered by TABLE (not the
752 value inheritted from the parent), and by side-effect, the car part
753 of RANGE is updated to the minimum character C where C and all the
754 following characters in TABLE have the same value. */
757 map_sub_char_table (void (*c_function
) (Lisp_Object
, Lisp_Object
, Lisp_Object
),
758 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
, Lisp_Object val
,
759 Lisp_Object range
, Lisp_Object top
)
761 /* Depth of TABLE. */
763 /* Minimum and maxinum characters covered by TABLE. */
764 int min_char
, max_char
;
765 /* Number of characters covered by one element of TABLE. */
767 int from
= XINT (XCAR (range
)), to
= XINT (XCDR (range
));
769 int is_uniprop
= UNIPROP_TABLE_P (top
);
770 uniprop_decoder_t decoder
= UNIPROP_GET_DECODER (top
);
772 if (SUB_CHAR_TABLE_P (table
))
774 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
776 depth
= XINT (tbl
->depth
);
777 min_char
= XINT (tbl
->min_char
);
778 max_char
= min_char
+ chartab_chars
[depth
- 1] - 1;
786 chars_in_block
= chartab_chars
[depth
];
790 /* Set I to the index of the first element to check. */
791 if (from
<= min_char
)
794 i
= (from
- min_char
) / chars_in_block
;
795 for (c
= min_char
+ chars_in_block
* i
; c
<= max_char
;
796 i
++, c
+= chars_in_block
)
798 Lisp_Object
this = (SUB_CHAR_TABLE_P (table
)
799 ? XSUB_CHAR_TABLE (table
)->contents
[i
]
800 : XCHAR_TABLE (table
)->contents
[i
]);
801 int nextc
= c
+ chars_in_block
;
803 if (is_uniprop
&& UNIPROP_COMPRESSED_FORM_P (this))
804 this = uniprop_table_uncompress (table
, i
);
805 if (SUB_CHAR_TABLE_P (this))
808 XSETCDR (range
, make_number (nextc
- 1));
809 val
= map_sub_char_table (c_function
, function
, this, arg
,
815 this = XCHAR_TABLE (top
)->defalt
;
818 int different_value
= 1;
822 if (! NILP (XCHAR_TABLE (top
)->parent
))
824 Lisp_Object parent
= XCHAR_TABLE (top
)->parent
;
825 Lisp_Object temp
= XCHAR_TABLE (parent
)->parent
;
827 /* This is to get a value of FROM in PARENT
828 without checking the parent of PARENT. */
829 XCHAR_TABLE (parent
)->parent
= Qnil
;
830 val
= CHAR_TABLE_REF (parent
, from
);
831 XCHAR_TABLE (parent
)->parent
= temp
;
832 XSETCDR (range
, make_number (c
- 1));
833 val
= map_sub_char_table (c_function
, function
,
834 parent
, arg
, val
, range
,
840 if (! NILP (val
) && different_value
)
842 XSETCDR (range
, make_number (c
- 1));
843 if (EQ (XCAR (range
), XCDR (range
)))
846 (*c_function
) (arg
, XCAR (range
), val
);
850 val
= decoder (top
, val
);
851 call2 (function
, XCAR (range
), val
);
857 (*c_function
) (arg
, range
, val
);
861 val
= decoder (top
, val
);
862 call2 (function
, range
, val
);
868 XSETCAR (range
, make_number (c
));
871 XSETCDR (range
, make_number (to
));
877 /* Map C_FUNCTION or FUNCTION over TABLE, calling it for each
878 character or group of characters that share a value.
880 ARG is passed to C_FUNCTION when that is called. */
883 map_char_table (void (*c_function
) (Lisp_Object
, Lisp_Object
, Lisp_Object
),
884 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
)
886 Lisp_Object range
, val
, parent
;
887 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
888 uniprop_decoder_t decoder
= UNIPROP_GET_DECODER (table
);
890 range
= Fcons (make_number (0), make_number (MAX_CHAR
));
891 parent
= XCHAR_TABLE (table
)->parent
;
893 GCPRO4 (table
, arg
, range
, parent
);
894 val
= XCHAR_TABLE (table
)->ascii
;
895 if (SUB_CHAR_TABLE_P (val
))
896 val
= XSUB_CHAR_TABLE (val
)->contents
[0];
897 val
= map_sub_char_table (c_function
, function
, table
, arg
, val
, range
,
900 /* If VAL is nil and TABLE has a parent, we must consult the parent
902 while (NILP (val
) && ! NILP (XCHAR_TABLE (table
)->parent
))
905 int from
= XINT (XCAR (range
));
907 parent
= XCHAR_TABLE (table
)->parent
;
908 temp
= XCHAR_TABLE (parent
)->parent
;
909 /* This is to get a value of FROM in PARENT without checking the
911 XCHAR_TABLE (parent
)->parent
= Qnil
;
912 val
= CHAR_TABLE_REF (parent
, from
);
913 XCHAR_TABLE (parent
)->parent
= temp
;
914 val
= map_sub_char_table (c_function
, function
, parent
, arg
, val
, range
,
921 if (EQ (XCAR (range
), XCDR (range
)))
924 (*c_function
) (arg
, XCAR (range
), val
);
928 val
= decoder (table
, val
);
929 call2 (function
, XCAR (range
), val
);
935 (*c_function
) (arg
, range
, val
);
939 val
= decoder (table
, val
);
940 call2 (function
, range
, val
);
948 DEFUN ("map-char-table", Fmap_char_table
, Smap_char_table
,
951 Call FUNCTION for each character in CHAR-TABLE that has non-nil value.
952 FUNCTION is called with two arguments--a key and a value.
953 The key is a character code or a cons of character codes specifying a
954 range of characters that have the same value. */)
955 (Lisp_Object function
, Lisp_Object char_table
)
957 CHECK_CHAR_TABLE (char_table
);
959 map_char_table (NULL
, function
, char_table
, char_table
);
965 map_sub_char_table_for_charset (void (*c_function
) (Lisp_Object
, Lisp_Object
),
966 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
,
967 Lisp_Object range
, struct charset
*charset
,
968 unsigned from
, unsigned to
)
970 struct Lisp_Sub_Char_Table
*tbl
= XSUB_CHAR_TABLE (table
);
971 int depth
= XINT (tbl
->depth
);
975 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
];
976 i
++, c
+= chartab_chars
[depth
])
980 this = tbl
->contents
[i
];
981 if (SUB_CHAR_TABLE_P (this))
982 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
983 range
, charset
, from
, to
);
986 if (! NILP (XCAR (range
)))
988 XSETCDR (range
, make_number (c
- 1));
990 (*c_function
) (arg
, range
);
992 call2 (function
, range
, arg
);
994 XSETCAR (range
, Qnil
);
998 for (i
= 0, c
= XINT (tbl
->min_char
); i
< chartab_size
[depth
]; i
++, c
++)
1003 this = tbl
->contents
[i
];
1006 && (code
= ENCODE_CHAR (charset
, c
),
1007 (code
< from
|| code
> to
))))
1009 if (! NILP (XCAR (range
)))
1011 XSETCDR (range
, make_number (c
- 1));
1013 (*c_function
) (arg
, range
);
1015 call2 (function
, range
, arg
);
1016 XSETCAR (range
, Qnil
);
1021 if (NILP (XCAR (range
)))
1022 XSETCAR (range
, make_number (c
));
1028 /* Support function for `map-charset-chars'. Map C_FUNCTION or
1029 FUNCTION over TABLE, calling it for each character or a group of
1030 succeeding characters that have non-nil value in TABLE. TABLE is a
1031 "mapping table" or a "deunifier table" of a certain charset.
1033 If CHARSET is not NULL (this is the case that `map-charset-chars'
1034 is called with non-nil FROM-CODE and TO-CODE), it is a charset who
1035 owns TABLE, and the function is called only on a character in the
1036 range FROM and TO. FROM and TO are not character codes, but code
1037 points of a character in CHARSET.
1039 This function is called in these two cases:
1041 (1) A charset has a mapping file name in :map property.
1043 (2) A charset has an upper code space in :offset property and a
1044 mapping file name in :unify-map property. In this case, this
1045 function is called only for characters in the Unicode code space.
1046 Characters in upper code space are handled directly in
1047 map_charset_chars. */
1050 map_char_table_for_charset (void (*c_function
) (Lisp_Object
, Lisp_Object
),
1051 Lisp_Object function
, Lisp_Object table
, Lisp_Object arg
,
1052 struct charset
*charset
,
1053 unsigned from
, unsigned to
)
1057 struct gcpro gcpro1
;
1059 range
= Fcons (Qnil
, Qnil
);
1062 for (i
= 0, c
= 0; i
< chartab_size
[0]; i
++, c
+= chartab_chars
[0])
1066 this = XCHAR_TABLE (table
)->contents
[i
];
1067 if (SUB_CHAR_TABLE_P (this))
1068 map_sub_char_table_for_charset (c_function
, function
, this, arg
,
1069 range
, charset
, from
, to
);
1072 if (! NILP (XCAR (range
)))
1074 XSETCDR (range
, make_number (c
- 1));
1076 (*c_function
) (arg
, range
);
1078 call2 (function
, range
, arg
);
1080 XSETCAR (range
, Qnil
);
1083 if (! NILP (XCAR (range
)))
1085 XSETCDR (range
, make_number (c
- 1));
1087 (*c_function
) (arg
, range
);
1089 call2 (function
, range
, arg
);
1096 /* Unicode character property tables.
1098 This section provides a convenient and efficient way to get a
1099 Unicode character property from C code (from Lisp, you must use
1100 get-char-code-property).
1102 The typical usage is to get a char-table for a specific property at
1103 a proper initialization time as this:
1105 Lisp_Object bidi_class_table = uniprop_table (intern ("bidi-class"));
1107 and get a property value for character CH as this:
1109 Lisp_Object bidi_class = CHAR_TABLE_REF (CH, bidi_class_table);
1111 In this case, what you actually get is an index number to the
1112 vector of property values (symbols nil, L, R, etc).
1114 A table for Unicode character property has these characteristics:
1116 o The purpose is `char-code-property-table', which implies that the
1117 table has 5 extra slots.
1119 o The second extra slot is a Lisp function, an index (integer) to
1120 the array uniprop_decoder[], or nil. If it is a Lisp function, we
1121 can't use such a table from C (at the moment). If it is nil, it
1122 means that we don't have to decode values.
1124 o The third extra slot is a Lisp function, an index (integer) to
1125 the array uniprop_enncoder[], or nil. If it is a Lisp function, we
1126 can't use such a table from C (at the moment). If it is nil, it
1127 means that we don't have to encode values. */
1130 /* Uncompress the IDXth element of sub-char-table TABLE. */
1133 uniprop_table_uncompress (Lisp_Object table
, int idx
)
1135 Lisp_Object val
= XSUB_CHAR_TABLE (table
)->contents
[idx
];
1136 int min_char
= (XINT (XSUB_CHAR_TABLE (table
)->min_char
)
1137 + chartab_chars
[2] * idx
);
1138 Lisp_Object sub
= make_sub_char_table (3, min_char
, Qnil
);
1139 struct Lisp_Sub_Char_Table
*subtbl
= XSUB_CHAR_TABLE (sub
);
1140 const unsigned char *p
, *pend
;
1142 XSUB_CHAR_TABLE (table
)->contents
[idx
] = sub
;
1143 p
= SDATA (val
), pend
= p
+ SBYTES (val
);
1148 idx
= STRING_CHAR_ADVANCE (p
);
1149 while (p
< pend
&& idx
< chartab_chars
[2])
1151 int v
= STRING_CHAR_ADVANCE (p
);
1152 subtbl
->contents
[idx
++] = v
> 0 ? make_number (v
) : Qnil
;
1157 /* RUN-LENGTH TABLE */
1159 for (idx
= 0; p
< pend
; )
1161 int v
= STRING_CHAR_ADVANCE (p
);
1167 count
= STRING_CHAR_AND_LENGTH (p
, len
);
1177 subtbl
->contents
[idx
++] = make_number (v
);
1180 /* It seems that we don't need this function because C code won't need
1181 to get a property that is compressed in this form. */
1185 /* WORD-LIST TABLE */
1192 /* Decode VALUE as an elemnet of char-table TABLE. */
1195 uniprop_decode_value_run_length (Lisp_Object table
, Lisp_Object value
)
1197 if (VECTORP (XCHAR_TABLE (table
)->extras
[4]))
1199 Lisp_Object valvec
= XCHAR_TABLE (table
)->extras
[4];
1201 if (XINT (value
) >= 0 && XINT (value
) < ASIZE (valvec
))
1202 value
= AREF (valvec
, XINT (value
));
1207 static uniprop_decoder_t uniprop_decoder
[] =
1208 { uniprop_decode_value_run_length
};
1210 static int uniprop_decoder_count
1211 = (sizeof uniprop_decoder
) / sizeof (uniprop_decoder
[0]);
1214 /* Return the decoder of char-table TABLE or nil if none. */
1216 static uniprop_decoder_t
1217 uniprop_get_decoder (Lisp_Object table
)
1221 if (! INTEGERP (XCHAR_TABLE (table
)->extras
[1]))
1223 i
= XINT (XCHAR_TABLE (table
)->extras
[1]);
1224 if (i
< 0 || i
>= uniprop_decoder_count
)
1226 return uniprop_decoder
[i
];
1230 /* Encode VALUE as an element of char-table TABLE which contains
1231 characters as elements. */
1234 uniprop_encode_value_character (Lisp_Object table
, Lisp_Object value
)
1236 if (! NILP (value
) && ! CHARACTERP (value
))
1237 wrong_type_argument (Qintegerp
, value
);
1242 /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1246 uniprop_encode_value_run_length (Lisp_Object table
, Lisp_Object value
)
1248 Lisp_Object
*value_table
= XVECTOR (XCHAR_TABLE (table
)->extras
[4])->contents
;
1249 int i
, size
= ASIZE (XCHAR_TABLE (table
)->extras
[4]);
1251 for (i
= 0; i
< size
; i
++)
1252 if (EQ (value
, value_table
[i
]))
1255 wrong_type_argument (build_string ("Unicode property value"), value
);
1256 return make_number (i
);
1260 /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1261 compression and contains numbers as elements . */
1264 uniprop_encode_value_numeric (Lisp_Object table
, Lisp_Object value
)
1266 Lisp_Object
*value_table
= XVECTOR (XCHAR_TABLE (table
)->extras
[4])->contents
;
1267 int i
, size
= ASIZE (XCHAR_TABLE (table
)->extras
[4]);
1269 CHECK_NUMBER (value
);
1270 for (i
= 0; i
< size
; i
++)
1271 if (EQ (value
, value_table
[i
]))
1273 value
= make_number (i
);
1276 Lisp_Object args
[2];
1278 args
[0] = XCHAR_TABLE (table
)->extras
[4];
1279 args
[1] = Fmake_vector (make_number (1), value
);
1280 XCHAR_TABLE (table
)->extras
[4] = Fvconcat (2, args
);
1282 return make_number (i
);
1285 static uniprop_encoder_t uniprop_encoder
[] =
1286 { uniprop_encode_value_character
,
1287 uniprop_encode_value_run_length
,
1288 uniprop_encode_value_numeric
};
1290 static int uniprop_encoder_count
1291 = (sizeof uniprop_encoder
) / sizeof (uniprop_encoder
[0]);
1294 /* Return the encoder of char-table TABLE or nil if none. */
1296 static uniprop_decoder_t
1297 uniprop_get_encoder (Lisp_Object table
)
1301 if (! INTEGERP (XCHAR_TABLE (table
)->extras
[2]))
1303 i
= XINT (XCHAR_TABLE (table
)->extras
[2]);
1304 if (i
< 0 || i
>= uniprop_encoder_count
)
1306 return uniprop_encoder
[i
];
1309 /* Return a char-table for Unicode character property PROP. This
1310 function may load a Lisp file and thus may cause
1311 garbage-collection. */
1314 uniprop_table (Lisp_Object prop
)
1316 Lisp_Object val
, table
, result
;
1318 val
= Fassq (prop
, Vchar_code_property_alist
);
1322 if (STRINGP (table
))
1324 struct gcpro gcpro1
;
1326 result
= Fload (concat2 (build_string ("international/"), table
),
1333 if (! CHAR_TABLE_P (table
)
1334 || ! UNIPROP_TABLE_P (table
))
1336 val
= XCHAR_TABLE (table
)->extras
[1];
1338 ? (XINT (val
) < 0 || XINT (val
) >= uniprop_decoder_count
)
1341 /* Prepare ASCII values in advance for CHAR_TABLE_REF. */
1342 XCHAR_TABLE (table
)->ascii
= char_table_ascii (table
);
1346 DEFUN ("unicode-property-table-internal", Funicode_property_table_internal
,
1347 Sunicode_property_table_internal
, 1, 1, 0,
1348 doc
: /* Return a char-table for Unicode character property PROP.
1349 Use `get-unicode-property-internal' and
1350 `put-unicode-property-internal' instead of `aref' and `aset' to get
1351 and put an element value. */)
1354 Lisp_Object table
= uniprop_table (prop
);
1356 if (CHAR_TABLE_P (table
))
1358 return Fcdr (Fassq (prop
, Vchar_code_property_alist
));
1361 DEFUN ("get-unicode-property-internal", Fget_unicode_property_internal
,
1362 Sget_unicode_property_internal
, 2, 2, 0,
1363 doc
: /* Return an element of CHAR-TABLE for character CH.
1364 CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1365 (Lisp_Object char_table
, Lisp_Object ch
)
1368 uniprop_decoder_t decoder
;
1370 CHECK_CHAR_TABLE (char_table
);
1371 CHECK_CHARACTER (ch
);
1372 if (! UNIPROP_TABLE_P (char_table
))
1373 error ("Invalid Unicode property table");
1374 val
= CHAR_TABLE_REF (char_table
, XINT (ch
));
1375 decoder
= uniprop_get_decoder (char_table
);
1376 return (decoder
? decoder (char_table
, val
) : val
);
1379 DEFUN ("put-unicode-property-internal", Fput_unicode_property_internal
,
1380 Sput_unicode_property_internal
, 3, 3, 0,
1381 doc
: /* Set an element of CHAR-TABLE for character CH to VALUE.
1382 CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1383 (Lisp_Object char_table
, Lisp_Object ch
, Lisp_Object value
)
1385 uniprop_encoder_t encoder
;
1387 CHECK_CHAR_TABLE (char_table
);
1388 CHECK_CHARACTER (ch
);
1389 if (! UNIPROP_TABLE_P (char_table
))
1390 error ("Invalid Unicode property table");
1391 encoder
= uniprop_get_encoder (char_table
);
1393 value
= encoder (char_table
, value
);
1394 CHAR_TABLE_SET (char_table
, XINT (ch
), value
);
1400 syms_of_chartab (void)
1402 DEFSYM (Qchar_code_property_table
, "char-code-property-table");
1404 defsubr (&Smake_char_table
);
1405 defsubr (&Schar_table_parent
);
1406 defsubr (&Schar_table_subtype
);
1407 defsubr (&Sset_char_table_parent
);
1408 defsubr (&Schar_table_extra_slot
);
1409 defsubr (&Sset_char_table_extra_slot
);
1410 defsubr (&Schar_table_range
);
1411 defsubr (&Sset_char_table_range
);
1412 defsubr (&Sset_char_table_default
);
1413 defsubr (&Soptimize_char_table
);
1414 defsubr (&Smap_char_table
);
1415 defsubr (&Sunicode_property_table_internal
);
1416 defsubr (&Sget_unicode_property_internal
);
1417 defsubr (&Sput_unicode_property_internal
);
1419 /* Each element has the form (PROP . TABLE).
1420 PROP is a symbol representing a character property.
1421 TABLE is a char-table containing the property value for each character.
1422 TABLE may be a name of file to load to build a char-table.
1423 This variable should be modified only through
1424 `define-char-code-property'. */
1426 DEFVAR_LISP ("char-code-property-alist", Vchar_code_property_alist
,
1427 doc
: /* Alist of character property name vs char-table containing property values.
1428 Internal use only. */);
1429 Vchar_code_property_alist
= Qnil
;