1 /* SXEmacs routines to deal with char tables.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1995, 1996 Ben Wing.
5 Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN.
6 Licensed to the Free Software Foundation.
8 This file is part of SXEmacs
10 SXEmacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 SXEmacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 /* Synched up with: Mule 2.3. Not synched with FSF.
26 This file was written independently of the FSF implementation,
27 and is not compatible. */
31 Ben Wing: wrote, for 19.13 (Mule). Some category table stuff
32 loosely based on the original Mule.
33 Jareth Hein: fixed a couple of bugs in the implementation, and
34 added regex support for categories with check_category_at
44 Lisp_Object Qchar_tablep, Qchar_table;
46 Lisp_Object Vall_syntax_tables;
49 Lisp_Object Qcategory_table_p;
50 Lisp_Object Qcategory_designator_p;
51 Lisp_Object Qcategory_table_value_p;
53 Lisp_Object Vstandard_category_table;
55 /* Variables to determine word boundary. */
56 Lisp_Object Vword_combining_categories, Vword_separating_categories;
59 /* A char table maps from ranges of characters to values.
61 Implementing a general data structure that maps from arbitrary
62 ranges of numbers to values is tricky to do efficiently. As it
63 happens, it should suffice (and is usually more convenient, anyway)
64 when dealing with characters to restrict the sorts of ranges that
65 can be assigned values, as follows:
68 2) All characters in a charset.
69 3) All characters in a particular row of a charset, where a "row"
70 means all characters with the same first byte.
71 4) A particular character in a charset.
73 We use char tables to generalize the 256-element vectors now
74 littering the Emacs code.
76 Possible uses (all should be converted at some point):
82 5) keyboard-translate-table?
85 abstract type to generalize the Emacs vectors and Mule
86 vectors-of-vectors goo.
89 /************************************************************************/
90 /* Char Table object */
91 /************************************************************************/
95 static Lisp_Object mark_char_table_entry(Lisp_Object obj)
97 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(obj);
100 for (i = 0; i < 96; i++) {
101 mark_object(cte->level2[i]);
106 static int char_table_entry_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
108 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY(obj1);
109 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY(obj2);
112 for (i = 0; i < 96; i++)
114 (cte1->level2[i], cte2->level2[i], depth + 1))
120 static unsigned long char_table_entry_hash(Lisp_Object obj, int depth)
122 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(obj);
124 return internal_array_hash(cte->level2, 96, depth);
127 static const struct lrecord_description char_table_entry_description[] = {
128 {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Char_Table_Entry, level2), 96},
132 DEFINE_LRECORD_IMPLEMENTATION("char-table-entry", char_table_entry,
133 mark_char_table_entry, internal_object_printer,
134 0, char_table_entry_equal,
135 char_table_entry_hash,
136 char_table_entry_description,
137 Lisp_Char_Table_Entry);
140 static Lisp_Object mark_char_table(Lisp_Object obj)
142 Lisp_Char_Table *ct = XCHAR_TABLE(obj);
145 for (i = 0; i < NUM_ASCII_CHARS; i++)
146 mark_object(ct->ascii[i]);
148 for (i = 0; i < NUM_LEADING_BYTES; i++)
149 mark_object(ct->level1[i]);
151 return ct->mirror_table;
154 /* WARNING: All functions of this nature need to be written extremely
155 carefully to avoid crashes during GC. Cf. prune_specifiers()
156 and prune_weak_hash_tables(). */
158 void prune_syntax_tables(void)
160 Lisp_Object rest, prev = Qnil;
162 for (rest = Vall_syntax_tables;
163 !NILP(rest); rest = XCHAR_TABLE(rest)->next_table) {
164 if (!marked_p(rest)) {
165 /* This table is garbage. Remove it from the list. */
168 XCHAR_TABLE(rest)->next_table;
170 XCHAR_TABLE(prev)->next_table =
171 XCHAR_TABLE(rest)->next_table;
176 static Lisp_Object char_table_type_to_symbol(enum char_table_type type)
182 case CHAR_TABLE_TYPE_GENERIC:
184 case CHAR_TABLE_TYPE_SYNTAX:
186 case CHAR_TABLE_TYPE_DISPLAY:
188 case CHAR_TABLE_TYPE_CHAR:
191 case CHAR_TABLE_TYPE_CATEGORY:
197 static enum char_table_type symbol_to_char_table_type(Lisp_Object symbol)
199 CHECK_SYMBOL(symbol);
201 if (EQ(symbol, Qgeneric))
202 return CHAR_TABLE_TYPE_GENERIC;
203 if (EQ(symbol, Qsyntax))
204 return CHAR_TABLE_TYPE_SYNTAX;
205 if (EQ(symbol, Qdisplay))
206 return CHAR_TABLE_TYPE_DISPLAY;
207 if (EQ(symbol, Qchar))
208 return CHAR_TABLE_TYPE_CHAR;
210 if (EQ(symbol, Qcategory))
211 return CHAR_TABLE_TYPE_CATEGORY;
214 signal_simple_error("Unrecognized char table type", symbol);
215 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
219 print_chartab_range(Emchar first, Emchar last, Lisp_Object val,
220 Lisp_Object printcharfun)
223 write_c_string(" (", printcharfun);
224 print_internal(make_char(first), printcharfun, 0);
225 write_c_string(" ", printcharfun);
226 print_internal(make_char(last), printcharfun, 0);
227 write_c_string(") ", printcharfun);
229 write_c_string(" ", printcharfun);
230 print_internal(make_char(first), printcharfun, 0);
231 write_c_string(" ", printcharfun);
233 print_internal(val, printcharfun, 1);
239 print_chartab_charset_row(Lisp_Object charset,
241 Lisp_Char_Table_Entry * cte, Lisp_Object printcharfun)
244 Lisp_Object cat = Qunbound;
247 for (i = 32; i < 128; i++) {
248 Lisp_Object pam = cte->level2[i - 32];
258 print_chartab_range(MAKE_CHAR
260 MAKE_CHAR(charset, i - 1,
264 print_chartab_range(MAKE_CHAR
265 (charset, row, first),
266 MAKE_CHAR(charset, row,
276 print_chartab_range(MAKE_CHAR(charset, first, 0),
277 MAKE_CHAR(charset, i - 1, 0),
280 print_chartab_range(MAKE_CHAR(charset, row, first),
281 MAKE_CHAR(charset, row, i - 1),
287 print_chartab_two_byte_charset(Lisp_Object charset,
288 Lisp_Char_Table_Entry * cte,
289 Lisp_Object printcharfun)
293 for (i = 32; i < 128; i++) {
294 Lisp_Object jen = cte->level2[i - 32];
296 if (!CHAR_TABLE_ENTRYP(jen)) {
297 write_c_string(" [", printcharfun);
298 print_internal(XCHARSET_NAME(charset), printcharfun, 0);
299 write_fmt_str(printcharfun, " %d] ", i);
300 print_internal(jen, printcharfun, 0);
302 print_chartab_charset_row(charset, i,
303 XCHAR_TABLE_ENTRY(jen),
311 print_char_table(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
313 Lisp_Char_Table *ct = XCHAR_TABLE(obj);
314 Lisp_Object tmp_sym = char_table_type_to_symbol(ct->type);
316 write_fmt_string(printcharfun, "#s(char-table type %s data (",
317 string_data(symbol_name(XSYMBOL(tmp_sym))));
319 /* Now write out the ASCII/Control-1 stuff. */
323 Lisp_Object val = Qunbound;
325 for (i = 0; i < NUM_ASCII_CHARS; i++) {
332 if (!EQ(ct->ascii[i], val)) {
333 print_chartab_range(first, i - 1, val,
341 print_chartab_range(first, i - 1, val, printcharfun);
348 for (i = MIN_LEADING_BYTE;
349 i < MIN_LEADING_BYTE + NUM_LEADING_BYTES; i++) {
350 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
351 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(i);
353 if (!CHARSETP(charset) || i == LEADING_BYTE_ASCII
354 || i == LEADING_BYTE_CONTROL_1)
356 if (!CHAR_TABLE_ENTRYP(ann)) {
357 write_c_string(" ", printcharfun);
358 print_internal(XCHARSET_NAME(charset),
360 write_c_string(" ", printcharfun);
361 print_internal(ann, printcharfun, 0);
363 Lisp_Char_Table_Entry *cte =
364 XCHAR_TABLE_ENTRY(ann);
365 if (XCHARSET_DIMENSION(charset) == 1)
366 print_chartab_charset_row(charset, -1,
370 print_chartab_two_byte_charset(charset,
378 write_c_string("))", printcharfun);
381 static int char_table_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
383 Lisp_Char_Table *ct1 = XCHAR_TABLE(obj1);
384 Lisp_Char_Table *ct2 = XCHAR_TABLE(obj2);
387 if (CHAR_TABLE_TYPE(ct1) != CHAR_TABLE_TYPE(ct2))
390 for (i = 0; i < NUM_ASCII_CHARS; i++)
391 if (!internal_equal(ct1->ascii[i], ct2->ascii[i], depth + 1))
395 for (i = 0; i < NUM_LEADING_BYTES; i++)
396 if (!internal_equal(ct1->level1[i], ct2->level1[i], depth + 1))
403 static unsigned long char_table_hash(Lisp_Object obj, int depth)
405 Lisp_Char_Table *ct = XCHAR_TABLE(obj);
406 unsigned long hashval = internal_array_hash(ct->ascii, NUM_ASCII_CHARS,
409 hashval = HASH2(hashval,
410 internal_array_hash(ct->level1, NUM_LEADING_BYTES,
416 static const struct lrecord_description char_table_description[] = {
417 {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Char_Table, ascii),
420 {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Char_Table, level1),
423 {XD_LISP_OBJECT, offsetof(Lisp_Char_Table, mirror_table)},
424 {XD_LO_LINK, offsetof(Lisp_Char_Table, next_table)},
428 DEFINE_LRECORD_IMPLEMENTATION("char-table", char_table,
429 mark_char_table, print_char_table, 0,
430 char_table_equal, char_table_hash,
431 char_table_description, Lisp_Char_Table);
433 DEFUN("char-table-p", Fchar_table_p, 1, 1, 0, /*
434 Return non-nil if OBJECT is a char table.
436 A char table is a table that maps characters (or ranges of characters)
437 to values. Char tables are specialized for characters, only allowing
438 particular sorts of ranges to be assigned values. Although this
439 loses in generality, it makes for extremely fast (constant-time)
440 lookups, and thus is feasible for applications that do an extremely
441 large number of lookups (e.g. scanning a buffer for a character in
442 a particular syntax, where a lookup in the syntax table must occur
445 When Mule support exists, the types of ranges that can be assigned
450 -- a single row in a two-octet charset
451 -- a single character
453 When Mule support is not present, the types of ranges that can be
457 -- a single character
459 To create a char table, use `make-char-table'.
460 To modify a char table, use `put-char-table' or `remove-char-table'.
461 To retrieve the value for a particular character, use `get-char-table'.
462 See also `map-char-table', `clear-char-table', `copy-char-table',
463 `valid-char-table-type-p', `char-table-type-list',
464 `valid-char-table-value-p', and `check-char-table-value'.
468 return CHAR_TABLEP(object) ? Qt : Qnil;
471 DEFUN("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
472 Return a list of the recognized char table types.
473 See `valid-char-table-type-p'.
478 return list5(Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
480 return list4(Qchar, Qdisplay, Qgeneric, Qsyntax);
484 DEFUN("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
485 Return t if TYPE if a recognized char table type.
487 Each char table type is used for a different purpose and allows different
488 sorts of values. The different char table types are
491 Used for category tables, which specify the regexp categories
492 that a character is in. The valid values are nil or a
493 bit vector of 95 elements. Higher-level Lisp functions are
494 provided for working with category tables. Currently categories
495 and category tables only exist when Mule support is present.
497 A generalized char table, for mapping from one character to
498 another. Used for case tables, syntax matching tables,
499 `keyboard-translate-table', etc. The valid values are characters.
501 An even more generalized char table, for mapping from a
502 character to anything.
504 Used for display tables, which specify how a particular character
505 is to appear when displayed. #### Not yet implemented.
507 Used for syntax tables, which specify the syntax of a particular
508 character. Higher-level Lisp functions are provided for
509 working with syntax tables. The valid values are integers.
514 return (EQ(type, Qchar) ||
516 EQ(type, Qcategory) ||
518 EQ(type, Qdisplay) ||
519 EQ(type, Qgeneric) || EQ(type, Qsyntax)) ? Qt : Qnil;
522 DEFUN("char-table-type", Fchar_table_type, 1, 1, 0, /*
523 Return the type of CHAR-TABLE.
524 See `valid-char-table-type-p'.
528 CHECK_CHAR_TABLE(char_table);
529 return char_table_type_to_symbol(XCHAR_TABLE(char_table)->type);
532 void fill_char_table(Lisp_Char_Table * ct, Lisp_Object value)
536 for (i = 0; i < NUM_ASCII_CHARS; i++)
537 ct->ascii[i] = value;
539 for (i = 0; i < NUM_LEADING_BYTES; i++)
540 ct->level1[i] = value;
543 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
544 update_syntax_table(ct);
547 DEFUN("reset-char-table", Freset_char_table, 1, 1, 0, /*
548 Reset CHAR-TABLE to its default state.
554 CHECK_CHAR_TABLE(char_table);
555 ct = XCHAR_TABLE(char_table);
558 case CHAR_TABLE_TYPE_CHAR:
559 fill_char_table(ct, make_char(0));
561 case CHAR_TABLE_TYPE_DISPLAY:
562 case CHAR_TABLE_TYPE_GENERIC:
564 case CHAR_TABLE_TYPE_CATEGORY:
566 fill_char_table(ct, Qnil);
569 case CHAR_TABLE_TYPE_SYNTAX:
570 fill_char_table(ct, make_int(Sinherit));
580 DEFUN("make-char-table", Fmake_char_table, 1, 1, 0, /*
581 Return a new, empty char table of type TYPE.
582 Currently recognized types are 'char, 'category, 'display, 'generic,
583 and 'syntax. See `valid-char-table-type-p'.
589 enum char_table_type ty = symbol_to_char_table_type(type);
591 ct = alloc_lcrecord_type(Lisp_Char_Table, &lrecord_char_table);
593 if (ty == CHAR_TABLE_TYPE_SYNTAX) {
594 ct->mirror_table = Fmake_char_table(Qgeneric);
595 fill_char_table(XCHAR_TABLE(ct->mirror_table),
598 ct->mirror_table = Qnil;
599 ct->next_table = Qnil;
600 XSETCHAR_TABLE(obj, ct);
601 if (ty == CHAR_TABLE_TYPE_SYNTAX) {
602 ct->next_table = Vall_syntax_tables;
603 Vall_syntax_tables = obj;
605 Freset_char_table(obj);
611 static Lisp_Object make_char_table_entry(Lisp_Object initval)
615 Lisp_Char_Table_Entry *cte =
616 alloc_lcrecord_type(Lisp_Char_Table_Entry,
617 &lrecord_char_table_entry);
619 for (i = 0; i < 96; i++)
620 cte->level2[i] = initval;
622 XSETCHAR_TABLE_ENTRY(obj, cte);
626 static Lisp_Object copy_char_table_entry(Lisp_Object entry)
628 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(entry);
631 Lisp_Char_Table_Entry *ctenew =
632 alloc_lcrecord_type(Lisp_Char_Table_Entry,
633 &lrecord_char_table_entry);
635 for (i = 0; i < 96; i++) {
636 Lisp_Object new = cte->level2[i];
637 if (CHAR_TABLE_ENTRYP(new))
638 ctenew->level2[i] = copy_char_table_entry(new);
640 ctenew->level2[i] = new;
643 XSETCHAR_TABLE_ENTRY(obj, ctenew);
649 DEFUN("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
650 Return a new char table which is a copy of CHAR-TABLE.
651 It will contain the same values for the same characters and ranges
652 as CHAR-TABLE. The values will not themselves be copied.
656 Lisp_Char_Table *ct, *ctnew;
660 CHECK_CHAR_TABLE(char_table);
661 ct = XCHAR_TABLE(char_table);
662 ctnew = alloc_lcrecord_type(Lisp_Char_Table, &lrecord_char_table);
663 ctnew->type = ct->type;
665 for (i = 0; i < NUM_ASCII_CHARS; i++) {
666 Lisp_Object new = ct->ascii[i];
668 assert(!(CHAR_TABLE_ENTRYP(new)));
670 ctnew->ascii[i] = new;
675 for (i = 0; i < NUM_LEADING_BYTES; i++) {
676 Lisp_Object new = ct->level1[i];
677 if (CHAR_TABLE_ENTRYP(new))
678 ctnew->level1[i] = copy_char_table_entry(new);
680 ctnew->level1[i] = new;
685 if (CHAR_TABLEP(ct->mirror_table))
686 ctnew->mirror_table = Fcopy_char_table(ct->mirror_table);
688 ctnew->mirror_table = ct->mirror_table;
689 ctnew->next_table = Qnil;
690 XSETCHAR_TABLE(obj, ctnew);
691 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX) {
692 ctnew->next_table = Vall_syntax_tables;
693 Vall_syntax_tables = obj;
699 decode_char_table_range(Lisp_Object range, struct chartab_range *outrange)
702 outrange->type = CHARTAB_RANGE_ALL;
703 else if (CHAR_OR_CHAR_INTP(range)) {
704 outrange->type = CHARTAB_RANGE_CHAR;
705 outrange->ch = XCHAR_OR_CHAR_INT(range);
709 signal_simple_error("Range must be t or a character", range);
711 else if (VECTORP(range)) {
712 Lisp_Vector *vec = XVECTOR(range);
713 Lisp_Object *elts = vector_data(vec);
714 if (vector_length(vec) != 2)
716 ("Length of charset row vector must be 2", range);
717 outrange->type = CHARTAB_RANGE_ROW;
718 outrange->charset = Fget_charset(elts[0]);
720 outrange->row = XINT(elts[1]);
721 switch (XCHARSET_TYPE(outrange->charset)) {
722 case CHARSET_TYPE_94:
723 case CHARSET_TYPE_96:
725 ("Charset in row vector must be multi-byte",
727 case CHARSET_TYPE_94X94:
728 check_int_range(outrange->row, 33, 126);
730 case CHARSET_TYPE_96X96:
731 check_int_range(outrange->row, 32, 127);
737 if (!CHARSETP(range) && !SYMBOLP(range))
739 ("Char table range must be t, charset, char, or vector",
741 outrange->type = CHARTAB_RANGE_CHARSET;
742 outrange->charset = Fget_charset(range);
749 /* called from CHAR_TABLE_VALUE(). */
751 get_non_ascii_char_table_value(Lisp_Char_Table * ct, int leading_byte, Emchar c)
754 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(leading_byte);
757 BREAKUP_CHAR_1_UNSAFE(c, charset, byte1, byte2);
758 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
759 if (CHAR_TABLE_ENTRYP(val)) {
760 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(val);
761 val = cte->level2[byte1 - 32];
762 if (CHAR_TABLE_ENTRYP(val)) {
763 cte = XCHAR_TABLE_ENTRY(val);
765 val = cte->level2[byte2 - 32];
766 assert(!CHAR_TABLE_ENTRYP(val));
775 Lisp_Object get_char_table(Emchar ch, Lisp_Char_Table * ct)
783 BREAKUP_CHAR(ch, charset, byte1, byte2);
785 if (EQ(charset, Vcharset_ascii))
786 val = ct->ascii[byte1];
787 else if (EQ(charset, Vcharset_control_1))
788 val = ct->ascii[byte1 + 128];
791 XCHARSET_LEADING_BYTE(charset) - MIN_LEADING_BYTE;
792 val = ct->level1[lb];
793 if (CHAR_TABLE_ENTRYP(val)) {
794 Lisp_Char_Table_Entry *cte =
795 XCHAR_TABLE_ENTRY(val);
796 val = cte->level2[byte1 - 32];
797 if (CHAR_TABLE_ENTRYP(val)) {
798 cte = XCHAR_TABLE_ENTRY(val);
800 val = cte->level2[byte2 - 32];
801 assert(!CHAR_TABLE_ENTRYP(val));
809 return ct->ascii[(unsigned char)ch];
810 #endif /* not MULE */
813 DEFUN("get-char-table", Fget_char_table, 2, 2, 0, /*
814 Find value for CHARACTER in CHAR-TABLE.
816 (character, char_table))
818 CHECK_CHAR_TABLE(char_table);
819 CHECK_CHAR_COERCE_INT(character);
821 return get_char_table(XCHAR(character), XCHAR_TABLE(char_table));
824 DEFUN("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
825 Find value for a range in CHAR-TABLE.
826 If there is more than one value, return MULTI (defaults to nil).
828 (range, char_table, multi))
831 struct chartab_range rainj;
833 if (CHAR_OR_CHAR_INTP(range))
834 return Fget_char_table(range, char_table);
835 CHECK_CHAR_TABLE(char_table);
836 ct = XCHAR_TABLE(char_table);
838 decode_char_table_range(range, &rainj);
839 switch (rainj.type) {
840 case CHARTAB_RANGE_ALL:
843 Lisp_Object first = ct->ascii[0];
845 for (i = 1; i < NUM_ASCII_CHARS; i++)
846 if (!EQ(first, ct->ascii[i]))
850 for (i = MIN_LEADING_BYTE;
851 i < MIN_LEADING_BYTE + NUM_LEADING_BYTES; i++) {
852 Lisp_Object foo = CHARSET_BY_LEADING_BYTE(i);
854 || i == LEADING_BYTE_ASCII
855 || i == LEADING_BYTE_CONTROL_1) {
859 (first, ct->level1[i - MIN_LEADING_BYTE])) {
869 case CHARTAB_RANGE_CHARSET:
870 if (EQ(rainj.charset, Vcharset_ascii)) {
872 Lisp_Object first = ct->ascii[0];
874 for (i = 1; i < 128; i++)
875 if (!EQ(first, ct->ascii[i]))
880 if (EQ(rainj.charset, Vcharset_control_1)) {
882 Lisp_Object first = ct->ascii[128];
884 for (i = 129; i < 160; i++)
885 if (!EQ(first, ct->ascii[i]))
892 ct->level1[XCHARSET_LEADING_BYTE(rainj.charset) -
894 if (CHAR_TABLE_ENTRYP(val))
899 case CHARTAB_RANGE_ROW:
902 ct->level1[XCHARSET_LEADING_BYTE(rainj.charset) -
904 if (!CHAR_TABLE_ENTRYP(val))
906 val = XCHAR_TABLE_ENTRY(val)->level2[rainj.row - 32];
907 if (CHAR_TABLE_ENTRYP(val))
913 case CHARTAB_RANGE_CHAR:
914 #endif /* not MULE */
920 return Qnil; /* not reached */
924 check_valid_char_table_value(Lisp_Object value, enum char_table_type type,
928 case CHAR_TABLE_TYPE_SYNTAX:
929 if (!ERRB_EQ(errb, ERROR_ME))
930 return INTP(value) || (CONSP(value) && INTP(XCAR(value))
932 CHAR_OR_CHAR_INTP(XCDR(value)));
934 Lisp_Object cdr = XCDR(value);
935 CHECK_INT(XCAR(value));
936 CHECK_CHAR_COERCE_INT(cdr);
942 case CHAR_TABLE_TYPE_CATEGORY:
943 if (!ERRB_EQ(errb, ERROR_ME))
944 return CATEGORY_TABLE_VALUEP(value);
945 CHECK_CATEGORY_TABLE_VALUE(value);
949 case CHAR_TABLE_TYPE_GENERIC:
952 case CHAR_TABLE_TYPE_DISPLAY:
954 maybe_signal_simple_error
955 ("Display char tables not yet implemented", value,
959 case CHAR_TABLE_TYPE_CHAR:
960 if (!ERRB_EQ(errb, ERROR_ME))
961 return CHAR_OR_CHAR_INTP(value);
962 CHECK_CHAR_COERCE_INT(value);
969 return 0; /* not reached */
973 canonicalize_char_table_value(Lisp_Object value, enum char_table_type type)
976 case CHAR_TABLE_TYPE_SYNTAX:
978 Lisp_Object car = XCAR(value);
979 Lisp_Object cdr = XCDR(value);
980 CHECK_CHAR_COERCE_INT(cdr);
981 return Fcons(car, cdr);
984 case CHAR_TABLE_TYPE_CHAR:
985 CHECK_CHAR_COERCE_INT(value);
988 case CHAR_TABLE_TYPE_GENERIC:
990 case CHAR_TABLE_TYPE_CATEGORY:
992 case CHAR_TABLE_TYPE_DISPLAY:
999 DEFUN("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
1000 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
1002 (value, char_table_type))
1004 enum char_table_type type = symbol_to_char_table_type(char_table_type);
1006 return check_valid_char_table_value(value, type,
1007 ERROR_ME_NOT) ? Qt : Qnil;
1010 DEFUN("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
1011 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
1013 (value, char_table_type))
1015 enum char_table_type type = symbol_to_char_table_type(char_table_type);
1017 check_valid_char_table_value(value, type, ERROR_ME);
1021 /* Assign VAL to all characters in RANGE in char table CT. */
1024 put_char_table(Lisp_Char_Table * ct, struct chartab_range *range,
1027 switch (range->type) {
1028 case CHARTAB_RANGE_ALL:
1029 fill_char_table(ct, val);
1030 /* avoid the duplicate call to update_syntax_table() below,
1031 since fill_char_table() also did that. */
1035 case CHARTAB_RANGE_CHARSET:
1036 if (EQ(range->charset, Vcharset_ascii)) {
1038 for (i = 0; i < 128; i++)
1040 } else if (EQ(range->charset, Vcharset_control_1)) {
1042 for (i = 128; i < 160; i++)
1046 XCHARSET_LEADING_BYTE(range->charset) -
1048 ct->level1[lb] = val;
1052 case CHARTAB_RANGE_ROW:
1054 Lisp_Char_Table_Entry *cte;
1056 XCHARSET_LEADING_BYTE(range->charset) -
1058 /* make sure that there is a separate entry for the
1060 if (!CHAR_TABLE_ENTRYP(ct->level1[lb]))
1062 make_char_table_entry(ct->level1[lb]);
1063 cte = XCHAR_TABLE_ENTRY(ct->level1[lb]);
1064 cte->level2[range->row - 32] = val;
1069 case CHARTAB_RANGE_CHAR: {
1071 Lisp_Object charset;
1074 BREAKUP_CHAR(range->ch, charset, byte1, byte2);
1075 if (EQ(charset, Vcharset_ascii))
1076 ct->ascii[byte1] = val;
1077 else if (EQ(charset, Vcharset_control_1))
1078 ct->ascii[byte1 + 128] = val;
1080 Lisp_Char_Table_Entry *cte;
1082 XCHARSET_LEADING_BYTE(charset) -
1084 /* make sure that there is a separate entry for the
1086 if (!CHAR_TABLE_ENTRYP(ct->level1[lb]))
1088 make_char_table_entry(ct->
1090 cte = XCHAR_TABLE_ENTRY(ct->level1[lb]);
1091 /* now CTE is a char table entry for the charset;
1092 each entry is for a single row (or character of
1093 a one-octet charset). */
1094 if (XCHARSET_DIMENSION(charset) == 1)
1095 cte->level2[byte1 - 32] = val;
1097 /* assigning to one character in a two-octet
1099 /* make sure that the charset row contains a
1100 separate entry for each character. */
1101 if (!CHAR_TABLE_ENTRYP
1102 (cte->level2[byte1 - 32]))
1103 cte->level2[byte1 - 32] =
1104 make_char_table_entry(cte->
1109 cte = XCHAR_TABLE_ENTRY(cte->
1110 level2[byte1 - 32]);
1111 cte->level2[byte2 - 32] = val;
1114 #else /* not MULE */
1115 ct->ascii[(unsigned char)(range->ch)] = val;
1117 #endif /* not MULE */
1120 /* shouldnt happen should it? */
1124 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) {
1125 update_syntax_table(ct);
1130 DEFUN("put-char-table", Fput_char_table, 3, 3, 0, /*
1131 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
1133 RANGE specifies one or more characters to be affected and should be
1134 one of the following:
1136 -- t (all characters are affected)
1137 -- A charset (only allowed when Mule support is present)
1138 -- A vector of two elements: a two-octet charset and a row number
1139 (only allowed when Mule support is present)
1140 -- A single character
1142 VALUE must be a value appropriate for the type of CHAR-TABLE.
1143 See `valid-char-table-type-p'.
1145 (range, value, char_table))
1147 Lisp_Char_Table *ct;
1148 struct chartab_range rainj;
1150 CHECK_CHAR_TABLE(char_table);
1151 ct = XCHAR_TABLE(char_table);
1152 check_valid_char_table_value(value, ct->type, ERROR_ME);
1153 decode_char_table_range(range, &rainj);
1154 value = canonicalize_char_table_value(value, ct->type);
1155 put_char_table(ct, &rainj, value);
1159 /* Map FN over the ASCII chars in CT. */
1162 map_over_charset_ascii(Lisp_Char_Table * ct,
1163 int (*fn) (struct chartab_range * range,
1164 Lisp_Object val, void *arg), void *arg)
1166 struct chartab_range rainj;
1175 rainj.type = CHARTAB_RANGE_CHAR;
1177 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1178 rainj.ch = (Emchar) i;
1179 retval = (fn) (&rainj, ct->ascii[i], arg);
1187 /* Map FN over the Control-1 chars in CT. */
1190 map_over_charset_control_1(Lisp_Char_Table * ct,
1191 int (*fn) (struct chartab_range * range,
1192 Lisp_Object val, void *arg), void *arg)
1194 struct chartab_range rainj;
1197 int stop = start + 32;
1199 rainj.type = CHARTAB_RANGE_CHAR;
1201 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1202 rainj.ch = (Emchar) (i);
1203 retval = (fn) (&rainj, ct->ascii[i], arg);
1209 /* Map FN over the row ROW of two-byte charset CHARSET.
1210 There must be a separate value for that row in the char table.
1211 CTE specifies the char table entry for CHARSET. */
1214 map_over_charset_row(Lisp_Char_Table_Entry * cte,
1215 Lisp_Object charset, int row,
1216 int (*fn) (struct chartab_range * range,
1217 Lisp_Object val, void *arg), void *arg)
1219 Lisp_Object val = cte->level2[row - 32];
1221 if (!CHAR_TABLE_ENTRYP(val)) {
1222 struct chartab_range rainj;
1224 rainj.type = CHARTAB_RANGE_ROW;
1225 rainj.charset = charset;
1227 return (fn) (&rainj, val, arg);
1229 struct chartab_range rainj;
1231 int charset94_p = (XCHARSET_CHARS(charset) == 94);
1232 int start = charset94_p ? 33 : 32;
1233 int stop = charset94_p ? 127 : 128;
1235 cte = XCHAR_TABLE_ENTRY(val);
1237 rainj.type = CHARTAB_RANGE_CHAR;
1239 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1240 rainj.ch = MAKE_CHAR(charset, row, i);
1241 retval = (fn) (&rainj, cte->level2[i - 32], arg);
1248 map_over_other_charset(Lisp_Char_Table * ct, int lb,
1249 int (*fn) (struct chartab_range * range,
1250 Lisp_Object val, void *arg), void *arg)
1252 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
1253 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(lb);
1255 if (!CHARSETP(charset)
1256 || lb == LEADING_BYTE_ASCII || lb == LEADING_BYTE_CONTROL_1)
1259 if (!CHAR_TABLE_ENTRYP(val)) {
1260 struct chartab_range rainj;
1262 rainj.type = CHARTAB_RANGE_CHARSET;
1263 rainj.charset = charset;
1264 return (fn) (&rainj, val, arg);
1268 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(val);
1269 int charset94_p = (XCHARSET_CHARS(charset) == 94);
1270 int start = charset94_p ? 33 : 32;
1271 int stop = charset94_p ? 127 : 128;
1274 if (XCHARSET_DIMENSION(charset) == 1) {
1275 struct chartab_range rainj;
1276 rainj.type = CHARTAB_RANGE_CHAR;
1278 for (i = start, retval = 0; i < stop && retval == 0;
1280 rainj.ch = MAKE_CHAR(charset, i, 0);
1282 (fn) (&rainj, cte->level2[i - 32], arg);
1285 for (i = start, retval = 0; i < stop && retval == 0;
1288 map_over_charset_row(cte, charset, i, fn,
1298 /* Map FN (with client data ARG) over range RANGE in char table CT.
1299 Mapping stops the first time FN returns non-zero, and that value
1300 becomes the return value of map_char_table(). */
1303 map_char_table(Lisp_Char_Table * ct,
1304 struct chartab_range *range,
1305 int (*fn) (struct chartab_range * range,
1306 Lisp_Object val, void *arg), void *arg)
1308 switch (range->type) {
1309 case CHARTAB_RANGE_ALL:
1313 retval = map_over_charset_ascii(ct, fn, arg);
1317 retval = map_over_charset_control_1(ct, fn, arg);
1322 int start = MIN_LEADING_BYTE;
1323 int stop = start + NUM_LEADING_BYTES;
1325 for (i = start, retval = 0;
1326 i < stop && retval == 0; i++) {
1328 map_over_other_charset(ct, i, fn,
1337 case CHARTAB_RANGE_CHARSET:
1338 return map_over_other_charset(ct,
1339 XCHARSET_LEADING_BYTE(range->
1343 case CHARTAB_RANGE_ROW:
1346 ct->level1[XCHARSET_LEADING_BYTE(range->charset) -
1348 if (!CHAR_TABLE_ENTRYP(val)) {
1349 struct chartab_range rainj;
1351 rainj.type = CHARTAB_RANGE_ROW;
1352 rainj.charset = range->charset;
1353 rainj.row = range->row;
1354 return (fn) (&rainj, val, arg);
1357 map_over_charset_row(XCHAR_TABLE_ENTRY(val),
1359 range->row, fn, arg);
1363 case CHARTAB_RANGE_CHAR:
1365 Emchar ch = range->ch;
1366 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE(ct, ch);
1367 struct chartab_range rainj;
1369 rainj.type = CHARTAB_RANGE_CHAR;
1371 return (fn) (&rainj, val, arg);
1381 struct slow_map_char_table_arg {
1382 Lisp_Object function;
1387 slow_map_char_table_fun(struct chartab_range *range, Lisp_Object val, void *arg)
1389 Lisp_Object ranjarg = Qnil;
1390 struct slow_map_char_table_arg *closure =
1391 (struct slow_map_char_table_arg *)arg;
1393 switch (range->type) {
1394 case CHARTAB_RANGE_ALL:
1399 case CHARTAB_RANGE_CHARSET:
1400 ranjarg = XCHARSET_NAME(range->charset);
1403 case CHARTAB_RANGE_ROW:
1404 ranjarg = vector2(XCHARSET_NAME(range->charset),
1405 make_int(range->row));
1408 case CHARTAB_RANGE_CHAR:
1409 ranjarg = make_char(range->ch);
1415 closure->retval = call2(closure->function, ranjarg, val);
1416 return !NILP(closure->retval);
1419 DEFUN("map-char-table", Fmap_char_table, 2, 3, 0, /*
1420 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
1421 each key and value in the table.
1423 RANGE specifies a subrange to map over and is in the same format as
1424 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
1427 (function, char_table, range))
1429 Lisp_Char_Table *ct;
1430 struct slow_map_char_table_arg slarg;
1431 struct gcpro gcpro1, gcpro2;
1432 struct chartab_range rainj;
1434 CHECK_CHAR_TABLE(char_table);
1435 ct = XCHAR_TABLE(char_table);
1438 decode_char_table_range(range, &rainj);
1439 slarg.function = function;
1440 slarg.retval = Qnil;
1441 GCPRO2(slarg.function, slarg.retval);
1442 map_char_table(ct, &rainj, slow_map_char_table_fun, &slarg);
1445 return slarg.retval;
1448 /************************************************************************/
1449 /* Char table read syntax */
1450 /************************************************************************/
1453 chartab_type_validate(Lisp_Object keyword, Lisp_Object value,
1454 Error_behavior errb)
1456 /* #### should deal with ERRB */
1457 symbol_to_char_table_type(value);
1462 chartab_data_validate(Lisp_Object keyword, Lisp_Object value,
1463 Error_behavior errb)
1467 /* #### should deal with ERRB */
1468 EXTERNAL_LIST_LOOP(rest, value) {
1469 Lisp_Object range = XCAR(rest);
1470 struct chartab_range dummy;
1474 signal_simple_error("Invalid list format", value);
1476 if (!CONSP(XCDR(range))
1477 || !NILP(XCDR(XCDR(range))))
1478 signal_simple_error("Invalid range format",
1480 decode_char_table_range(XCAR(range), &dummy);
1481 decode_char_table_range(XCAR(XCDR(range)), &dummy);
1483 decode_char_table_range(range, &dummy);
1489 static Lisp_Object chartab_instantiate(Lisp_Object data)
1491 Lisp_Object chartab;
1492 Lisp_Object type = Qgeneric;
1493 Lisp_Object dataval = Qnil;
1495 while (!NILP(data)) {
1496 Lisp_Object keyw = Fcar(data);
1502 if (EQ(keyw, Qtype))
1504 else if (EQ(keyw, Qdata))
1508 chartab = Fmake_char_table(type);
1511 while (!NILP(data)) {
1512 Lisp_Object range = Fcar(data);
1513 Lisp_Object val = Fcar(Fcdr(data));
1515 data = Fcdr(Fcdr(data));
1517 if (CHAR_OR_CHAR_INTP(XCAR(range))) {
1518 Emchar first = XCHAR_OR_CHAR_INT(Fcar(range));
1520 XCHAR_OR_CHAR_INT(Fcar(Fcdr(range)));
1523 for (i = first; i <= last; i++)
1524 Fput_char_table(make_char(i), val,
1529 Fput_char_table(range, val, chartab);
1537 /************************************************************************/
1538 /* Category Tables, specifically */
1539 /************************************************************************/
1541 DEFUN("category-table-p", Fcategory_table_p, 1, 1, 0, /*
1542 Return t if OBJECT is a category table.
1543 A category table is a type of char table used for keeping track of
1544 categories. Categories are used for classifying characters for use
1545 in regexps -- you can refer to a category rather than having to use
1546 a complicated [] expression (and category lookups are significantly
1549 There are 95 different categories available, one for each printable
1550 character (including space) in the ASCII charset. Each category
1551 is designated by one such character, called a "category designator".
1552 They are specified in a regexp using the syntax "\\cX", where X is
1553 a category designator.
1555 A category table specifies, for each character, the categories that
1556 the character is in. Note that a character can be in more than one
1557 category. More specifically, a category table maps from a character
1558 to either the value nil (meaning the character is in no categories)
1559 or a 95-element bit vector, specifying for each of the 95 categories
1560 whether the character is in that category.
1562 Special Lisp functions are provided that abstract this, so you do not
1563 have to directly manipulate bit vectors.
1567 return (CHAR_TABLEP(object) &&
1568 XCHAR_TABLE_TYPE(object) == CHAR_TABLE_TYPE_CATEGORY) ?
1573 check_category_table(Lisp_Object object, Lisp_Object default_)
1577 while (NILP(Fcategory_table_p(object)))
1578 object = wrong_type_argument(Qcategory_table_p, object);
1583 check_category_char(Emchar ch, Lisp_Object table,
1584 unsigned int designator, unsigned int not_p)
1586 REGISTER Lisp_Object temp;
1587 Lisp_Char_Table *ctbl;
1588 #ifdef ERROR_CHECK_TYPECHECK
1589 if (NILP(Fcategory_table_p(table)))
1590 signal_simple_error("Expected category table", table);
1592 ctbl = XCHAR_TABLE(table);
1593 temp = get_char_table(ch, ctbl);
1598 return bit_vector_bit(XBIT_VECTOR(temp), designator) ? !not_p : not_p;
1601 DEFUN("check-category-at", Fcheck_category_at, 2, 4, 0, /*
1602 Return t if category of the character at POSITION includes DESIGNATOR.
1603 Optional third arg BUFFER specifies which buffer to use, and defaults
1604 to the current buffer.
1605 Optional fourth arg CATEGORY-TABLE specifies the category table to
1606 use, and defaults to BUFFER's category table.
1608 (position, designator, buffer, category_table))
1613 struct buffer *buf = decode_buffer(buffer, 0);
1615 CHECK_INT(position);
1616 CHECK_CATEGORY_DESIGNATOR(designator);
1617 des = XCHAR(designator);
1618 ctbl = check_category_table(category_table, Vstandard_category_table);
1619 ch = BUF_FETCH_CHAR(buf, XINT(position));
1620 return check_category_char(ch, ctbl, des, 0) ? Qt : Qnil;
1623 DEFUN("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
1624 Return t if category of CHARACTER includes DESIGNATOR, else nil.
1625 Optional third arg CATEGORY-TABLE specifies the category table to use,
1626 and defaults to the standard category table.
1628 (character, designator, category_table))
1634 CHECK_CATEGORY_DESIGNATOR(designator);
1635 des = XCHAR(designator);
1636 CHECK_CHAR(character);
1637 ch = XCHAR(character);
1638 ctbl = check_category_table(category_table, Vstandard_category_table);
1639 return check_category_char(ch, ctbl, des, 0) ? Qt : Qnil;
1642 DEFUN("category-table", Fcategory_table, 0, 1, 0, /*
1643 Return BUFFER's current category table.
1644 BUFFER defaults to the current buffer.
1648 return decode_buffer(buffer, 0)->category_table;
1651 DEFUN("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
1652 Return the standard category table.
1653 This is the one used for new buffers.
1657 return Vstandard_category_table;
1660 DEFUN("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
1661 Return a new category table which is a copy of CATEGORY-TABLE.
1662 CATEGORY-TABLE defaults to the standard category table.
1666 if (NILP(Vstandard_category_table))
1667 return Fmake_char_table(Qcategory);
1670 check_category_table(category_table, Vstandard_category_table);
1671 return Fcopy_char_table(category_table);
1674 DEFUN("set-category-table", Fset_category_table, 1, 2, 0, /*
1675 Select CATEGORY-TABLE as the new category table for BUFFER.
1676 BUFFER defaults to the current buffer if omitted.
1678 (category_table, buffer))
1680 struct buffer *buf = decode_buffer(buffer, 0);
1681 category_table = check_category_table(category_table, Qnil);
1682 buf->category_table = category_table;
1683 /* Indicate that this buffer now has a specified category table. */
1684 buf->local_var_flags |= XINT(buffer_local_flags.category_table);
1685 return category_table;
1688 DEFUN("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
1689 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
1693 return CATEGORY_DESIGNATORP(object) ? Qt : Qnil;
1696 DEFUN("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
1697 Return t if OBJECT is a category table value.
1698 Valid values are nil or a bit vector of size 95.
1702 return CATEGORY_TABLE_VALUEP(object) ? Qt : Qnil;
1705 #define CATEGORYP(x) \
1706 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
1708 #define CATEGORY_SET(c) \
1709 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
1711 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
1712 The faster version of `!NILP (Faref (category_set, category))'. */
1713 #define CATEGORY_MEMBER(category, category_set) \
1714 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
1716 /* Return 1 if there is a word boundary between two word-constituent
1717 characters C1 and C2 if they appear in this order, else return 0.
1718 Use the macro WORD_BOUNDARY_P instead of calling this function
1721 int word_boundary_p(Emchar c1, Emchar c2);
1722 int word_boundary_p(Emchar c1, Emchar c2)
1724 Lisp_Object category_set1, category_set2;
1729 if (COMPOSITE_CHAR_P(c1))
1730 c1 = cmpchar_component(c1, 0, 1);
1731 if (COMPOSITE_CHAR_P(c2))
1732 c2 = cmpchar_component(c2, 0, 1);
1735 if (EQ(CHAR_CHARSET(c1), CHAR_CHARSET(c2))) {
1736 tail = Vword_separating_categories;
1739 tail = Vword_combining_categories;
1743 category_set1 = CATEGORY_SET(c1);
1744 if (NILP(category_set1))
1745 return default_result;
1746 category_set2 = CATEGORY_SET(c2);
1747 if (NILP(category_set2))
1748 return default_result;
1750 for (; CONSP(tail); tail = XCONS(tail)->cdr) {
1751 Lisp_Object elt = XCONS(tail)->car;
1754 && CATEGORYP(XCONS(elt)->car)
1755 && CATEGORYP(XCONS(elt)->cdr)
1756 && CATEGORY_MEMBER(XCHAR(XCONS(elt)->car), category_set1)
1757 && CATEGORY_MEMBER(XCHAR(XCONS(elt)->cdr), category_set2))
1758 return !default_result;
1760 return default_result;
1764 void syms_of_chartab(void)
1766 INIT_LRECORD_IMPLEMENTATION(char_table);
1769 INIT_LRECORD_IMPLEMENTATION(char_table_entry);
1771 defsymbol(&Qcategory_table_p, "category-table-p");
1772 defsymbol(&Qcategory_designator_p, "category-designator-p");
1773 defsymbol(&Qcategory_table_value_p, "category-table-value-p");
1776 defsymbol(&Qchar_table, "char-table");
1777 defsymbol(&Qchar_tablep, "char-table-p");
1779 DEFSUBR(Fchar_table_p);
1780 DEFSUBR(Fchar_table_type_list);
1781 DEFSUBR(Fvalid_char_table_type_p);
1782 DEFSUBR(Fchar_table_type);
1783 DEFSUBR(Freset_char_table);
1784 DEFSUBR(Fmake_char_table);
1785 DEFSUBR(Fcopy_char_table);
1786 DEFSUBR(Fget_char_table);
1787 DEFSUBR(Fget_range_char_table);
1788 DEFSUBR(Fvalid_char_table_value_p);
1789 DEFSUBR(Fcheck_valid_char_table_value);
1790 DEFSUBR(Fput_char_table);
1791 DEFSUBR(Fmap_char_table);
1794 DEFSUBR(Fcategory_table_p);
1795 DEFSUBR(Fcategory_table);
1796 DEFSUBR(Fstandard_category_table);
1797 DEFSUBR(Fcopy_category_table);
1798 DEFSUBR(Fset_category_table);
1799 DEFSUBR(Fcheck_category_at);
1800 DEFSUBR(Fchar_in_category_p);
1801 DEFSUBR(Fcategory_designator_p);
1802 DEFSUBR(Fcategory_table_value_p);
1807 void vars_of_chartab(void)
1809 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
1810 Vall_syntax_tables = Qnil;
1811 dump_add_weak_object_chain(&Vall_syntax_tables);
1814 void structure_type_create_chartab(void)
1816 struct structure_type *st;
1818 st = define_structure_type(Qchar_table, 0, chartab_instantiate);
1820 define_structure_type_keyword(st, Qtype, chartab_type_validate);
1821 define_structure_type_keyword(st, Qdata, chartab_data_validate);
1824 void complex_vars_of_chartab(void)
1827 /* Set this now, so first buffer creation can refer to it. */
1828 /* Make it nil before calling copy-category-table
1829 so that copy-category-table will know not to try to copy from garbage */
1830 Vstandard_category_table = Qnil;
1831 Vstandard_category_table = Fcopy_category_table(Qnil);
1832 staticpro(&Vstandard_category_table);
1834 DEFVAR_LISP("word-combining-categories", &Vword_combining_categories /*
1835 List of pair (cons) of categories to determine word boundary.
1837 Emacs treats a sequence of word constituent characters as a single
1838 word (i.e. finds no word boundary between them) iff they belongs to
1839 the same charset. But, exceptions are allowed in the following cases.
1841 \(1) The case that characters are in different charsets is controlled
1842 by the variable `word-combining-categories'.
1844 Emacs finds no word boundary between characters of different charsets
1845 if they have categories matching some element of this list.
1847 More precisely, if an element of this list is a cons of category CAT1
1848 and CAT2, and a multibyte character C1 which has CAT1 is followed by
1849 C2 which has CAT2, there's no word boundary between C1 and C2.
1851 For instance, to tell that ASCII characters and Latin-1 characters can
1852 form a single word, the element `(?l . ?l)' should be in this list
1853 because both characters have the category `l' (Latin characters).
1855 \(2) The case that character are in the same charset is controlled by
1856 the variable `word-separating-categories'.
1858 Emacs find a word boundary between characters of the same charset
1859 if they have categories matching some element of this list.
1861 More precisely, if an element of this list is a cons of category CAT1
1862 and CAT2, and a multibyte character C1 which has CAT1 is followed by
1863 C2 which has CAT2, there's a word boundary between C1 and C2.
1865 For instance, to tell that there's a word boundary between Japanese
1866 Hiragana and Japanese Kanji (both are in the same charset), the
1867 element `(?H . ?C) should be in this list.
1870 Vword_combining_categories = Qnil;
1872 DEFVAR_LISP("word-separating-categories", &Vword_separating_categories /*
1873 List of pair (cons) of categories to determine word boundary.
1874 See the documentation of the variable `word-combining-categories'.
1877 Vword_separating_categories = Qnil;