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)
181 case CHAR_TABLE_TYPE_GENERIC:
183 case CHAR_TABLE_TYPE_SYNTAX:
185 case CHAR_TABLE_TYPE_DISPLAY:
187 case CHAR_TABLE_TYPE_CHAR:
190 case CHAR_TABLE_TYPE_CATEGORY:
196 static enum char_table_type symbol_to_char_table_type(Lisp_Object symbol)
198 CHECK_SYMBOL(symbol);
200 if (EQ(symbol, Qgeneric))
201 return CHAR_TABLE_TYPE_GENERIC;
202 if (EQ(symbol, Qsyntax))
203 return CHAR_TABLE_TYPE_SYNTAX;
204 if (EQ(symbol, Qdisplay))
205 return CHAR_TABLE_TYPE_DISPLAY;
206 if (EQ(symbol, Qchar))
207 return CHAR_TABLE_TYPE_CHAR;
209 if (EQ(symbol, Qcategory))
210 return CHAR_TABLE_TYPE_CATEGORY;
213 signal_simple_error("Unrecognized char table type", symbol);
214 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
218 print_chartab_range(Emchar first, Emchar last, Lisp_Object val,
219 Lisp_Object printcharfun)
222 write_c_string(" (", printcharfun);
223 print_internal(make_char(first), printcharfun, 0);
224 write_c_string(" ", printcharfun);
225 print_internal(make_char(last), printcharfun, 0);
226 write_c_string(") ", printcharfun);
228 write_c_string(" ", printcharfun);
229 print_internal(make_char(first), printcharfun, 0);
230 write_c_string(" ", printcharfun);
232 print_internal(val, printcharfun, 1);
238 print_chartab_charset_row(Lisp_Object charset,
240 Lisp_Char_Table_Entry * cte, Lisp_Object printcharfun)
243 Lisp_Object cat = Qunbound;
246 for (i = 32; i < 128; i++) {
247 Lisp_Object pam = cte->level2[i - 32];
257 print_chartab_range(MAKE_CHAR
259 MAKE_CHAR(charset, i - 1,
263 print_chartab_range(MAKE_CHAR
264 (charset, row, first),
265 MAKE_CHAR(charset, row,
275 print_chartab_range(MAKE_CHAR(charset, first, 0),
276 MAKE_CHAR(charset, i - 1, 0),
279 print_chartab_range(MAKE_CHAR(charset, row, first),
280 MAKE_CHAR(charset, row, i - 1),
286 print_chartab_two_byte_charset(Lisp_Object charset,
287 Lisp_Char_Table_Entry * cte,
288 Lisp_Object printcharfun)
292 for (i = 32; i < 128; i++) {
293 Lisp_Object jen = cte->level2[i - 32];
295 if (!CHAR_TABLE_ENTRYP(jen)) {
298 write_c_string(" [", printcharfun);
299 print_internal(XCHARSET_NAME(charset), printcharfun, 0);
300 sprintf(buf, " %d] ", i);
301 write_c_string(buf, printcharfun);
302 print_internal(jen, printcharfun, 0);
304 print_chartab_charset_row(charset, i,
305 XCHAR_TABLE_ENTRY(jen),
313 print_char_table(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
315 Lisp_Char_Table *ct = XCHAR_TABLE(obj);
317 Lisp_Object tmp_sym = char_table_type_to_symbol(ct->type);
319 snprintf(buf, countof(buf)-1, "#s(char-table type %s data (",
320 string_data(symbol_name(XSYMBOL(tmp_sym))));
321 write_c_string(buf, printcharfun);
323 /* Now write out the ASCII/Control-1 stuff. */
327 Lisp_Object val = Qunbound;
329 for (i = 0; i < NUM_ASCII_CHARS; i++) {
336 if (!EQ(ct->ascii[i], val)) {
337 print_chartab_range(first, i - 1, val,
345 print_chartab_range(first, i - 1, val, printcharfun);
352 for (i = MIN_LEADING_BYTE;
353 i < MIN_LEADING_BYTE + NUM_LEADING_BYTES; i++) {
354 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
355 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(i);
357 if (!CHARSETP(charset) || i == LEADING_BYTE_ASCII
358 || i == LEADING_BYTE_CONTROL_1)
360 if (!CHAR_TABLE_ENTRYP(ann)) {
361 write_c_string(" ", printcharfun);
362 print_internal(XCHARSET_NAME(charset),
364 write_c_string(" ", printcharfun);
365 print_internal(ann, printcharfun, 0);
367 Lisp_Char_Table_Entry *cte =
368 XCHAR_TABLE_ENTRY(ann);
369 if (XCHARSET_DIMENSION(charset) == 1)
370 print_chartab_charset_row(charset, -1,
374 print_chartab_two_byte_charset(charset,
382 write_c_string("))", printcharfun);
385 static int char_table_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
387 Lisp_Char_Table *ct1 = XCHAR_TABLE(obj1);
388 Lisp_Char_Table *ct2 = XCHAR_TABLE(obj2);
391 if (CHAR_TABLE_TYPE(ct1) != CHAR_TABLE_TYPE(ct2))
394 for (i = 0; i < NUM_ASCII_CHARS; i++)
395 if (!internal_equal(ct1->ascii[i], ct2->ascii[i], depth + 1))
399 for (i = 0; i < NUM_LEADING_BYTES; i++)
400 if (!internal_equal(ct1->level1[i], ct2->level1[i], depth + 1))
407 static unsigned long char_table_hash(Lisp_Object obj, int depth)
409 Lisp_Char_Table *ct = XCHAR_TABLE(obj);
410 unsigned long hashval = internal_array_hash(ct->ascii, NUM_ASCII_CHARS,
413 hashval = HASH2(hashval,
414 internal_array_hash(ct->level1, NUM_LEADING_BYTES,
420 static const struct lrecord_description char_table_description[] = {
421 {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Char_Table, ascii),
424 {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Char_Table, level1),
427 {XD_LISP_OBJECT, offsetof(Lisp_Char_Table, mirror_table)},
428 {XD_LO_LINK, offsetof(Lisp_Char_Table, next_table)},
432 DEFINE_LRECORD_IMPLEMENTATION("char-table", char_table,
433 mark_char_table, print_char_table, 0,
434 char_table_equal, char_table_hash,
435 char_table_description, Lisp_Char_Table);
437 DEFUN("char-table-p", Fchar_table_p, 1, 1, 0, /*
438 Return non-nil if OBJECT is a char table.
440 A char table is a table that maps characters (or ranges of characters)
441 to values. Char tables are specialized for characters, only allowing
442 particular sorts of ranges to be assigned values. Although this
443 loses in generality, it makes for extremely fast (constant-time)
444 lookups, and thus is feasible for applications that do an extremely
445 large number of lookups (e.g. scanning a buffer for a character in
446 a particular syntax, where a lookup in the syntax table must occur
449 When Mule support exists, the types of ranges that can be assigned
454 -- a single row in a two-octet charset
455 -- a single character
457 When Mule support is not present, the types of ranges that can be
461 -- a single character
463 To create a char table, use `make-char-table'.
464 To modify a char table, use `put-char-table' or `remove-char-table'.
465 To retrieve the value for a particular character, use `get-char-table'.
466 See also `map-char-table', `clear-char-table', `copy-char-table',
467 `valid-char-table-type-p', `char-table-type-list',
468 `valid-char-table-value-p', and `check-char-table-value'.
472 return CHAR_TABLEP(object) ? Qt : Qnil;
475 DEFUN("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
476 Return a list of the recognized char table types.
477 See `valid-char-table-type-p'.
482 return list5(Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
484 return list4(Qchar, Qdisplay, Qgeneric, Qsyntax);
488 DEFUN("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
489 Return t if TYPE if a recognized char table type.
491 Each char table type is used for a different purpose and allows different
492 sorts of values. The different char table types are
495 Used for category tables, which specify the regexp categories
496 that a character is in. The valid values are nil or a
497 bit vector of 95 elements. Higher-level Lisp functions are
498 provided for working with category tables. Currently categories
499 and category tables only exist when Mule support is present.
501 A generalized char table, for mapping from one character to
502 another. Used for case tables, syntax matching tables,
503 `keyboard-translate-table', etc. The valid values are characters.
505 An even more generalized char table, for mapping from a
506 character to anything.
508 Used for display tables, which specify how a particular character
509 is to appear when displayed. #### Not yet implemented.
511 Used for syntax tables, which specify the syntax of a particular
512 character. Higher-level Lisp functions are provided for
513 working with syntax tables. The valid values are integers.
518 return (EQ(type, Qchar) ||
520 EQ(type, Qcategory) ||
522 EQ(type, Qdisplay) ||
523 EQ(type, Qgeneric) || EQ(type, Qsyntax)) ? Qt : Qnil;
526 DEFUN("char-table-type", Fchar_table_type, 1, 1, 0, /*
527 Return the type of CHAR-TABLE.
528 See `valid-char-table-type-p'.
532 CHECK_CHAR_TABLE(char_table);
533 return char_table_type_to_symbol(XCHAR_TABLE(char_table)->type);
536 void fill_char_table(Lisp_Char_Table * ct, Lisp_Object value)
540 for (i = 0; i < NUM_ASCII_CHARS; i++)
541 ct->ascii[i] = value;
543 for (i = 0; i < NUM_LEADING_BYTES; i++)
544 ct->level1[i] = value;
547 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
548 update_syntax_table(ct);
551 DEFUN("reset-char-table", Freset_char_table, 1, 1, 0, /*
552 Reset CHAR-TABLE to its default state.
558 CHECK_CHAR_TABLE(char_table);
559 ct = XCHAR_TABLE(char_table);
562 case CHAR_TABLE_TYPE_CHAR:
563 fill_char_table(ct, make_char(0));
565 case CHAR_TABLE_TYPE_DISPLAY:
566 case CHAR_TABLE_TYPE_GENERIC:
568 case CHAR_TABLE_TYPE_CATEGORY:
570 fill_char_table(ct, Qnil);
573 case CHAR_TABLE_TYPE_SYNTAX:
574 fill_char_table(ct, make_int(Sinherit));
584 DEFUN("make-char-table", Fmake_char_table, 1, 1, 0, /*
585 Return a new, empty char table of type TYPE.
586 Currently recognized types are 'char, 'category, 'display, 'generic,
587 and 'syntax. See `valid-char-table-type-p'.
593 enum char_table_type ty = symbol_to_char_table_type(type);
595 ct = alloc_lcrecord_type(Lisp_Char_Table, &lrecord_char_table);
597 if (ty == CHAR_TABLE_TYPE_SYNTAX) {
598 ct->mirror_table = Fmake_char_table(Qgeneric);
599 fill_char_table(XCHAR_TABLE(ct->mirror_table),
602 ct->mirror_table = Qnil;
603 ct->next_table = Qnil;
604 XSETCHAR_TABLE(obj, ct);
605 if (ty == CHAR_TABLE_TYPE_SYNTAX) {
606 ct->next_table = Vall_syntax_tables;
607 Vall_syntax_tables = obj;
609 Freset_char_table(obj);
615 static Lisp_Object make_char_table_entry(Lisp_Object initval)
619 Lisp_Char_Table_Entry *cte =
620 alloc_lcrecord_type(Lisp_Char_Table_Entry,
621 &lrecord_char_table_entry);
623 for (i = 0; i < 96; i++)
624 cte->level2[i] = initval;
626 XSETCHAR_TABLE_ENTRY(obj, cte);
630 static Lisp_Object copy_char_table_entry(Lisp_Object entry)
632 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(entry);
635 Lisp_Char_Table_Entry *ctenew =
636 alloc_lcrecord_type(Lisp_Char_Table_Entry,
637 &lrecord_char_table_entry);
639 for (i = 0; i < 96; i++) {
640 Lisp_Object new = cte->level2[i];
641 if (CHAR_TABLE_ENTRYP(new))
642 ctenew->level2[i] = copy_char_table_entry(new);
644 ctenew->level2[i] = new;
647 XSETCHAR_TABLE_ENTRY(obj, ctenew);
653 DEFUN("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
654 Return a new char table which is a copy of CHAR-TABLE.
655 It will contain the same values for the same characters and ranges
656 as CHAR-TABLE. The values will not themselves be copied.
660 Lisp_Char_Table *ct, *ctnew;
664 CHECK_CHAR_TABLE(char_table);
665 ct = XCHAR_TABLE(char_table);
666 ctnew = alloc_lcrecord_type(Lisp_Char_Table, &lrecord_char_table);
667 ctnew->type = ct->type;
669 for (i = 0; i < NUM_ASCII_CHARS; i++) {
670 Lisp_Object new = ct->ascii[i];
672 assert(!(CHAR_TABLE_ENTRYP(new)));
674 ctnew->ascii[i] = new;
679 for (i = 0; i < NUM_LEADING_BYTES; i++) {
680 Lisp_Object new = ct->level1[i];
681 if (CHAR_TABLE_ENTRYP(new))
682 ctnew->level1[i] = copy_char_table_entry(new);
684 ctnew->level1[i] = new;
689 if (CHAR_TABLEP(ct->mirror_table))
690 ctnew->mirror_table = Fcopy_char_table(ct->mirror_table);
692 ctnew->mirror_table = ct->mirror_table;
693 ctnew->next_table = Qnil;
694 XSETCHAR_TABLE(obj, ctnew);
695 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX) {
696 ctnew->next_table = Vall_syntax_tables;
697 Vall_syntax_tables = obj;
703 decode_char_table_range(Lisp_Object range, struct chartab_range *outrange)
706 outrange->type = CHARTAB_RANGE_ALL;
707 else if (CHAR_OR_CHAR_INTP(range)) {
708 outrange->type = CHARTAB_RANGE_CHAR;
709 outrange->ch = XCHAR_OR_CHAR_INT(range);
713 signal_simple_error("Range must be t or a character", range);
715 else if (VECTORP(range)) {
716 Lisp_Vector *vec = XVECTOR(range);
717 Lisp_Object *elts = vector_data(vec);
718 if (vector_length(vec) != 2)
720 ("Length of charset row vector must be 2", range);
721 outrange->type = CHARTAB_RANGE_ROW;
722 outrange->charset = Fget_charset(elts[0]);
724 outrange->row = XINT(elts[1]);
725 switch (XCHARSET_TYPE(outrange->charset)) {
726 case CHARSET_TYPE_94:
727 case CHARSET_TYPE_96:
729 ("Charset in row vector must be multi-byte",
731 case CHARSET_TYPE_94X94:
732 check_int_range(outrange->row, 33, 126);
734 case CHARSET_TYPE_96X96:
735 check_int_range(outrange->row, 32, 127);
741 if (!CHARSETP(range) && !SYMBOLP(range))
743 ("Char table range must be t, charset, char, or vector",
745 outrange->type = CHARTAB_RANGE_CHARSET;
746 outrange->charset = Fget_charset(range);
753 /* called from CHAR_TABLE_VALUE(). */
755 get_non_ascii_char_table_value(Lisp_Char_Table * ct, int leading_byte, Emchar c)
758 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(leading_byte);
761 BREAKUP_CHAR_1_UNSAFE(c, charset, byte1, byte2);
762 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
763 if (CHAR_TABLE_ENTRYP(val)) {
764 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(val);
765 val = cte->level2[byte1 - 32];
766 if (CHAR_TABLE_ENTRYP(val)) {
767 cte = XCHAR_TABLE_ENTRY(val);
769 val = cte->level2[byte2 - 32];
770 assert(!CHAR_TABLE_ENTRYP(val));
779 Lisp_Object get_char_table(Emchar ch, Lisp_Char_Table * ct)
787 BREAKUP_CHAR(ch, charset, byte1, byte2);
789 if (EQ(charset, Vcharset_ascii))
790 val = ct->ascii[byte1];
791 else if (EQ(charset, Vcharset_control_1))
792 val = ct->ascii[byte1 + 128];
795 XCHARSET_LEADING_BYTE(charset) - MIN_LEADING_BYTE;
796 val = ct->level1[lb];
797 if (CHAR_TABLE_ENTRYP(val)) {
798 Lisp_Char_Table_Entry *cte =
799 XCHAR_TABLE_ENTRY(val);
800 val = cte->level2[byte1 - 32];
801 if (CHAR_TABLE_ENTRYP(val)) {
802 cte = XCHAR_TABLE_ENTRY(val);
804 val = cte->level2[byte2 - 32];
805 assert(!CHAR_TABLE_ENTRYP(val));
813 return ct->ascii[(unsigned char)ch];
814 #endif /* not MULE */
817 DEFUN("get-char-table", Fget_char_table, 2, 2, 0, /*
818 Find value for CHARACTER in CHAR-TABLE.
820 (character, char_table))
822 CHECK_CHAR_TABLE(char_table);
823 CHECK_CHAR_COERCE_INT(character);
825 return get_char_table(XCHAR(character), XCHAR_TABLE(char_table));
828 DEFUN("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
829 Find value for a range in CHAR-TABLE.
830 If there is more than one value, return MULTI (defaults to nil).
832 (range, char_table, multi))
835 struct chartab_range rainj;
837 if (CHAR_OR_CHAR_INTP(range))
838 return Fget_char_table(range, char_table);
839 CHECK_CHAR_TABLE(char_table);
840 ct = XCHAR_TABLE(char_table);
842 decode_char_table_range(range, &rainj);
843 switch (rainj.type) {
844 case CHARTAB_RANGE_ALL:
847 Lisp_Object first = ct->ascii[0];
849 for (i = 1; i < NUM_ASCII_CHARS; i++)
850 if (!EQ(first, ct->ascii[i]))
854 for (i = MIN_LEADING_BYTE;
855 i < MIN_LEADING_BYTE + NUM_LEADING_BYTES; i++) {
856 Lisp_Object foo = CHARSET_BY_LEADING_BYTE(i);
858 || i == LEADING_BYTE_ASCII
859 || i == LEADING_BYTE_CONTROL_1) {
863 (first, ct->level1[i - MIN_LEADING_BYTE])) {
873 case CHARTAB_RANGE_CHARSET:
874 if (EQ(rainj.charset, Vcharset_ascii)) {
876 Lisp_Object first = ct->ascii[0];
878 for (i = 1; i < 128; i++)
879 if (!EQ(first, ct->ascii[i]))
884 if (EQ(rainj.charset, Vcharset_control_1)) {
886 Lisp_Object first = ct->ascii[128];
888 for (i = 129; i < 160; i++)
889 if (!EQ(first, ct->ascii[i]))
896 ct->level1[XCHARSET_LEADING_BYTE(rainj.charset) -
898 if (CHAR_TABLE_ENTRYP(val))
903 case CHARTAB_RANGE_ROW:
906 ct->level1[XCHARSET_LEADING_BYTE(rainj.charset) -
908 if (!CHAR_TABLE_ENTRYP(val))
910 val = XCHAR_TABLE_ENTRY(val)->level2[rainj.row - 32];
911 if (CHAR_TABLE_ENTRYP(val))
917 case CHARTAB_RANGE_CHAR:
918 #endif /* not MULE */
924 return Qnil; /* not reached */
928 check_valid_char_table_value(Lisp_Object value, enum char_table_type type,
932 case CHAR_TABLE_TYPE_SYNTAX:
933 if (!ERRB_EQ(errb, ERROR_ME))
934 return INTP(value) || (CONSP(value) && INTP(XCAR(value))
936 CHAR_OR_CHAR_INTP(XCDR(value)));
938 Lisp_Object cdr = XCDR(value);
939 CHECK_INT(XCAR(value));
940 CHECK_CHAR_COERCE_INT(cdr);
946 case CHAR_TABLE_TYPE_CATEGORY:
947 if (!ERRB_EQ(errb, ERROR_ME))
948 return CATEGORY_TABLE_VALUEP(value);
949 CHECK_CATEGORY_TABLE_VALUE(value);
953 case CHAR_TABLE_TYPE_GENERIC:
956 case CHAR_TABLE_TYPE_DISPLAY:
958 maybe_signal_simple_error
959 ("Display char tables not yet implemented", value,
963 case CHAR_TABLE_TYPE_CHAR:
964 if (!ERRB_EQ(errb, ERROR_ME))
965 return CHAR_OR_CHAR_INTP(value);
966 CHECK_CHAR_COERCE_INT(value);
973 return 0; /* not reached */
977 canonicalize_char_table_value(Lisp_Object value, enum char_table_type type)
980 case CHAR_TABLE_TYPE_SYNTAX:
982 Lisp_Object car = XCAR(value);
983 Lisp_Object cdr = XCDR(value);
984 CHECK_CHAR_COERCE_INT(cdr);
985 return Fcons(car, cdr);
988 case CHAR_TABLE_TYPE_CHAR:
989 CHECK_CHAR_COERCE_INT(value);
992 case CHAR_TABLE_TYPE_GENERIC:
993 case CHAR_TABLE_TYPE_CATEGORY:
994 case CHAR_TABLE_TYPE_DISPLAY:
1001 DEFUN("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
1002 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
1004 (value, char_table_type))
1006 enum char_table_type type = symbol_to_char_table_type(char_table_type);
1008 return check_valid_char_table_value(value, type,
1009 ERROR_ME_NOT) ? Qt : Qnil;
1012 DEFUN("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
1013 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
1015 (value, char_table_type))
1017 enum char_table_type type = symbol_to_char_table_type(char_table_type);
1019 check_valid_char_table_value(value, type, ERROR_ME);
1023 /* Assign VAL to all characters in RANGE in char table CT. */
1026 put_char_table(Lisp_Char_Table * ct, struct chartab_range *range,
1029 switch (range->type) {
1030 case CHARTAB_RANGE_ALL:
1031 fill_char_table(ct, val);
1032 /* avoid the duplicate call to update_syntax_table() below,
1033 since fill_char_table() also did that. */
1037 case CHARTAB_RANGE_CHARSET:
1038 if (EQ(range->charset, Vcharset_ascii)) {
1040 for (i = 0; i < 128; i++)
1042 } else if (EQ(range->charset, Vcharset_control_1)) {
1044 for (i = 128; i < 160; i++)
1048 XCHARSET_LEADING_BYTE(range->charset) -
1050 ct->level1[lb] = val;
1054 case CHARTAB_RANGE_ROW:
1056 Lisp_Char_Table_Entry *cte;
1058 XCHARSET_LEADING_BYTE(range->charset) -
1060 /* make sure that there is a separate entry for the
1062 if (!CHAR_TABLE_ENTRYP(ct->level1[lb]))
1064 make_char_table_entry(ct->level1[lb]);
1065 cte = XCHAR_TABLE_ENTRY(ct->level1[lb]);
1066 cte->level2[range->row - 32] = val;
1071 case CHARTAB_RANGE_CHAR: {
1073 Lisp_Object charset;
1076 BREAKUP_CHAR(range->ch, charset, byte1, byte2);
1077 if (EQ(charset, Vcharset_ascii))
1078 ct->ascii[byte1] = val;
1079 else if (EQ(charset, Vcharset_control_1))
1080 ct->ascii[byte1 + 128] = val;
1082 Lisp_Char_Table_Entry *cte;
1084 XCHARSET_LEADING_BYTE(charset) -
1086 /* make sure that there is a separate entry for the
1088 if (!CHAR_TABLE_ENTRYP(ct->level1[lb]))
1090 make_char_table_entry(ct->
1092 cte = XCHAR_TABLE_ENTRY(ct->level1[lb]);
1093 /* now CTE is a char table entry for the charset;
1094 each entry is for a single row (or character of
1095 a one-octet charset). */
1096 if (XCHARSET_DIMENSION(charset) == 1)
1097 cte->level2[byte1 - 32] = val;
1099 /* assigning to one character in a two-octet
1101 /* make sure that the charset row contains a
1102 separate entry for each character. */
1103 if (!CHAR_TABLE_ENTRYP
1104 (cte->level2[byte1 - 32]))
1105 cte->level2[byte1 - 32] =
1106 make_char_table_entry(cte->
1111 cte = XCHAR_TABLE_ENTRY(cte->
1112 level2[byte1 - 32]);
1113 cte->level2[byte2 - 32] = val;
1116 #else /* not MULE */
1117 ct->ascii[(unsigned char)(range->ch)] = val;
1119 #endif /* not MULE */
1122 /* shouldnt happen should it? */
1126 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) {
1127 update_syntax_table(ct);
1132 DEFUN("put-char-table", Fput_char_table, 3, 3, 0, /*
1133 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
1135 RANGE specifies one or more characters to be affected and should be
1136 one of the following:
1138 -- t (all characters are affected)
1139 -- A charset (only allowed when Mule support is present)
1140 -- A vector of two elements: a two-octet charset and a row number
1141 (only allowed when Mule support is present)
1142 -- A single character
1144 VALUE must be a value appropriate for the type of CHAR-TABLE.
1145 See `valid-char-table-type-p'.
1147 (range, value, char_table))
1149 Lisp_Char_Table *ct;
1150 struct chartab_range rainj;
1152 CHECK_CHAR_TABLE(char_table);
1153 ct = XCHAR_TABLE(char_table);
1154 check_valid_char_table_value(value, ct->type, ERROR_ME);
1155 decode_char_table_range(range, &rainj);
1156 value = canonicalize_char_table_value(value, ct->type);
1157 put_char_table(ct, &rainj, value);
1161 /* Map FN over the ASCII chars in CT. */
1164 map_over_charset_ascii(Lisp_Char_Table * ct,
1165 int (*fn) (struct chartab_range * range,
1166 Lisp_Object val, void *arg), void *arg)
1168 struct chartab_range rainj;
1177 rainj.type = CHARTAB_RANGE_CHAR;
1179 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1180 rainj.ch = (Emchar) i;
1181 retval = (fn) (&rainj, ct->ascii[i], arg);
1189 /* Map FN over the Control-1 chars in CT. */
1192 map_over_charset_control_1(Lisp_Char_Table * ct,
1193 int (*fn) (struct chartab_range * range,
1194 Lisp_Object val, void *arg), void *arg)
1196 struct chartab_range rainj;
1199 int stop = start + 32;
1201 rainj.type = CHARTAB_RANGE_CHAR;
1203 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1204 rainj.ch = (Emchar) (i);
1205 retval = (fn) (&rainj, ct->ascii[i], arg);
1211 /* Map FN over the row ROW of two-byte charset CHARSET.
1212 There must be a separate value for that row in the char table.
1213 CTE specifies the char table entry for CHARSET. */
1216 map_over_charset_row(Lisp_Char_Table_Entry * cte,
1217 Lisp_Object charset, int row,
1218 int (*fn) (struct chartab_range * range,
1219 Lisp_Object val, void *arg), void *arg)
1221 Lisp_Object val = cte->level2[row - 32];
1223 if (!CHAR_TABLE_ENTRYP(val)) {
1224 struct chartab_range rainj;
1226 rainj.type = CHARTAB_RANGE_ROW;
1227 rainj.charset = charset;
1229 return (fn) (&rainj, val, arg);
1231 struct chartab_range rainj;
1233 int charset94_p = (XCHARSET_CHARS(charset) == 94);
1234 int start = charset94_p ? 33 : 32;
1235 int stop = charset94_p ? 127 : 128;
1237 cte = XCHAR_TABLE_ENTRY(val);
1239 rainj.type = CHARTAB_RANGE_CHAR;
1241 for (i = start, retval = 0; i < stop && retval == 0; i++) {
1242 rainj.ch = MAKE_CHAR(charset, row, i);
1243 retval = (fn) (&rainj, cte->level2[i - 32], arg);
1250 map_over_other_charset(Lisp_Char_Table * ct, int lb,
1251 int (*fn) (struct chartab_range * range,
1252 Lisp_Object val, void *arg), void *arg)
1254 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
1255 Lisp_Object charset = CHARSET_BY_LEADING_BYTE(lb);
1257 if (!CHARSETP(charset)
1258 || lb == LEADING_BYTE_ASCII || lb == LEADING_BYTE_CONTROL_1)
1261 if (!CHAR_TABLE_ENTRYP(val)) {
1262 struct chartab_range rainj;
1264 rainj.type = CHARTAB_RANGE_CHARSET;
1265 rainj.charset = charset;
1266 return (fn) (&rainj, val, arg);
1270 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY(val);
1271 int charset94_p = (XCHARSET_CHARS(charset) == 94);
1272 int start = charset94_p ? 33 : 32;
1273 int stop = charset94_p ? 127 : 128;
1276 if (XCHARSET_DIMENSION(charset) == 1) {
1277 struct chartab_range rainj;
1278 rainj.type = CHARTAB_RANGE_CHAR;
1280 for (i = start, retval = 0; i < stop && retval == 0;
1282 rainj.ch = MAKE_CHAR(charset, i, 0);
1284 (fn) (&rainj, cte->level2[i - 32], arg);
1287 for (i = start, retval = 0; i < stop && retval == 0;
1290 map_over_charset_row(cte, charset, i, fn,
1300 /* Map FN (with client data ARG) over range RANGE in char table CT.
1301 Mapping stops the first time FN returns non-zero, and that value
1302 becomes the return value of map_char_table(). */
1305 map_char_table(Lisp_Char_Table * ct,
1306 struct chartab_range *range,
1307 int (*fn) (struct chartab_range * range,
1308 Lisp_Object val, void *arg), void *arg)
1310 switch (range->type) {
1311 case CHARTAB_RANGE_ALL:
1315 retval = map_over_charset_ascii(ct, fn, arg);
1319 retval = map_over_charset_control_1(ct, fn, arg);
1324 int start = MIN_LEADING_BYTE;
1325 int stop = start + NUM_LEADING_BYTES;
1327 for (i = start, retval = 0;
1328 i < stop && retval == 0; i++) {
1330 map_over_other_charset(ct, i, fn,
1339 case CHARTAB_RANGE_CHARSET:
1340 return map_over_other_charset(ct,
1341 XCHARSET_LEADING_BYTE(range->
1345 case CHARTAB_RANGE_ROW:
1348 ct->level1[XCHARSET_LEADING_BYTE(range->charset) -
1350 if (!CHAR_TABLE_ENTRYP(val)) {
1351 struct chartab_range rainj;
1353 rainj.type = CHARTAB_RANGE_ROW;
1354 rainj.charset = range->charset;
1355 rainj.row = range->row;
1356 return (fn) (&rainj, val, arg);
1359 map_over_charset_row(XCHAR_TABLE_ENTRY(val),
1361 range->row, fn, arg);
1365 case CHARTAB_RANGE_CHAR:
1367 Emchar ch = range->ch;
1368 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE(ct, ch);
1369 struct chartab_range rainj;
1371 rainj.type = CHARTAB_RANGE_CHAR;
1373 return (fn) (&rainj, val, arg);
1383 struct slow_map_char_table_arg {
1384 Lisp_Object function;
1389 slow_map_char_table_fun(struct chartab_range *range, Lisp_Object val, void *arg)
1391 Lisp_Object ranjarg = Qnil;
1392 struct slow_map_char_table_arg *closure =
1393 (struct slow_map_char_table_arg *)arg;
1395 switch (range->type) {
1396 case CHARTAB_RANGE_ALL:
1401 case CHARTAB_RANGE_CHARSET:
1402 ranjarg = XCHARSET_NAME(range->charset);
1405 case CHARTAB_RANGE_ROW:
1406 ranjarg = vector2(XCHARSET_NAME(range->charset),
1407 make_int(range->row));
1410 case CHARTAB_RANGE_CHAR:
1411 ranjarg = make_char(range->ch);
1417 closure->retval = call2(closure->function, ranjarg, val);
1418 return !NILP(closure->retval);
1421 DEFUN("map-char-table", Fmap_char_table, 2, 3, 0, /*
1422 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
1423 each key and value in the table.
1425 RANGE specifies a subrange to map over and is in the same format as
1426 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
1429 (function, char_table, range))
1431 Lisp_Char_Table *ct;
1432 struct slow_map_char_table_arg slarg;
1433 struct gcpro gcpro1, gcpro2;
1434 struct chartab_range rainj;
1436 CHECK_CHAR_TABLE(char_table);
1437 ct = XCHAR_TABLE(char_table);
1440 decode_char_table_range(range, &rainj);
1441 slarg.function = function;
1442 slarg.retval = Qnil;
1443 GCPRO2(slarg.function, slarg.retval);
1444 map_char_table(ct, &rainj, slow_map_char_table_fun, &slarg);
1447 return slarg.retval;
1450 /************************************************************************/
1451 /* Char table read syntax */
1452 /************************************************************************/
1455 chartab_type_validate(Lisp_Object keyword, Lisp_Object value,
1456 Error_behavior errb)
1458 /* #### should deal with ERRB */
1459 symbol_to_char_table_type(value);
1464 chartab_data_validate(Lisp_Object keyword, Lisp_Object value,
1465 Error_behavior errb)
1469 /* #### should deal with ERRB */
1470 EXTERNAL_LIST_LOOP(rest, value) {
1471 Lisp_Object range = XCAR(rest);
1472 struct chartab_range dummy;
1476 signal_simple_error("Invalid list format", value);
1478 if (!CONSP(XCDR(range))
1479 || !NILP(XCDR(XCDR(range))))
1480 signal_simple_error("Invalid range format",
1482 decode_char_table_range(XCAR(range), &dummy);
1483 decode_char_table_range(XCAR(XCDR(range)), &dummy);
1485 decode_char_table_range(range, &dummy);
1491 static Lisp_Object chartab_instantiate(Lisp_Object data)
1493 Lisp_Object chartab;
1494 Lisp_Object type = Qgeneric;
1495 Lisp_Object dataval = Qnil;
1497 while (!NILP(data)) {
1498 Lisp_Object keyw = Fcar(data);
1504 if (EQ(keyw, Qtype))
1506 else if (EQ(keyw, Qdata))
1510 chartab = Fmake_char_table(type);
1513 while (!NILP(data)) {
1514 Lisp_Object range = Fcar(data);
1515 Lisp_Object val = Fcar(Fcdr(data));
1517 data = Fcdr(Fcdr(data));
1519 if (CHAR_OR_CHAR_INTP(XCAR(range))) {
1520 Emchar first = XCHAR_OR_CHAR_INT(Fcar(range));
1522 XCHAR_OR_CHAR_INT(Fcar(Fcdr(range)));
1525 for (i = first; i <= last; i++)
1526 Fput_char_table(make_char(i), val,
1531 Fput_char_table(range, val, chartab);
1539 /************************************************************************/
1540 /* Category Tables, specifically */
1541 /************************************************************************/
1543 DEFUN("category-table-p", Fcategory_table_p, 1, 1, 0, /*
1544 Return t if OBJECT is a category table.
1545 A category table is a type of char table used for keeping track of
1546 categories. Categories are used for classifying characters for use
1547 in regexps -- you can refer to a category rather than having to use
1548 a complicated [] expression (and category lookups are significantly
1551 There are 95 different categories available, one for each printable
1552 character (including space) in the ASCII charset. Each category
1553 is designated by one such character, called a "category designator".
1554 They are specified in a regexp using the syntax "\\cX", where X is
1555 a category designator.
1557 A category table specifies, for each character, the categories that
1558 the character is in. Note that a character can be in more than one
1559 category. More specifically, a category table maps from a character
1560 to either the value nil (meaning the character is in no categories)
1561 or a 95-element bit vector, specifying for each of the 95 categories
1562 whether the character is in that category.
1564 Special Lisp functions are provided that abstract this, so you do not
1565 have to directly manipulate bit vectors.
1569 return (CHAR_TABLEP(object) &&
1570 XCHAR_TABLE_TYPE(object) == CHAR_TABLE_TYPE_CATEGORY) ?
1575 check_category_table(Lisp_Object object, Lisp_Object default_)
1579 while (NILP(Fcategory_table_p(object)))
1580 object = wrong_type_argument(Qcategory_table_p, object);
1585 check_category_char(Emchar ch, Lisp_Object table,
1586 unsigned int designator, unsigned int not_p)
1588 REGISTER Lisp_Object temp;
1589 Lisp_Char_Table *ctbl;
1590 #ifdef ERROR_CHECK_TYPECHECK
1591 if (NILP(Fcategory_table_p(table)))
1592 signal_simple_error("Expected category table", table);
1594 ctbl = XCHAR_TABLE(table);
1595 temp = get_char_table(ch, ctbl);
1600 return bit_vector_bit(XBIT_VECTOR(temp), designator) ? !not_p : not_p;
1603 DEFUN("check-category-at", Fcheck_category_at, 2, 4, 0, /*
1604 Return t if category of the character at POSITION includes DESIGNATOR.
1605 Optional third arg BUFFER specifies which buffer to use, and defaults
1606 to the current buffer.
1607 Optional fourth arg CATEGORY-TABLE specifies the category table to
1608 use, and defaults to BUFFER's category table.
1610 (position, designator, buffer, category_table))
1615 struct buffer *buf = decode_buffer(buffer, 0);
1617 CHECK_INT(position);
1618 CHECK_CATEGORY_DESIGNATOR(designator);
1619 des = XCHAR(designator);
1620 ctbl = check_category_table(category_table, Vstandard_category_table);
1621 ch = BUF_FETCH_CHAR(buf, XINT(position));
1622 return check_category_char(ch, ctbl, des, 0) ? Qt : Qnil;
1625 DEFUN("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
1626 Return t if category of CHARACTER includes DESIGNATOR, else nil.
1627 Optional third arg CATEGORY-TABLE specifies the category table to use,
1628 and defaults to the standard category table.
1630 (character, designator, category_table))
1636 CHECK_CATEGORY_DESIGNATOR(designator);
1637 des = XCHAR(designator);
1638 CHECK_CHAR(character);
1639 ch = XCHAR(character);
1640 ctbl = check_category_table(category_table, Vstandard_category_table);
1641 return check_category_char(ch, ctbl, des, 0) ? Qt : Qnil;
1644 DEFUN("category-table", Fcategory_table, 0, 1, 0, /*
1645 Return BUFFER's current category table.
1646 BUFFER defaults to the current buffer.
1650 return decode_buffer(buffer, 0)->category_table;
1653 DEFUN("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
1654 Return the standard category table.
1655 This is the one used for new buffers.
1659 return Vstandard_category_table;
1662 DEFUN("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
1663 Return a new category table which is a copy of CATEGORY-TABLE.
1664 CATEGORY-TABLE defaults to the standard category table.
1668 if (NILP(Vstandard_category_table))
1669 return Fmake_char_table(Qcategory);
1672 check_category_table(category_table, Vstandard_category_table);
1673 return Fcopy_char_table(category_table);
1676 DEFUN("set-category-table", Fset_category_table, 1, 2, 0, /*
1677 Select CATEGORY-TABLE as the new category table for BUFFER.
1678 BUFFER defaults to the current buffer if omitted.
1680 (category_table, buffer))
1682 struct buffer *buf = decode_buffer(buffer, 0);
1683 category_table = check_category_table(category_table, Qnil);
1684 buf->category_table = category_table;
1685 /* Indicate that this buffer now has a specified category table. */
1686 buf->local_var_flags |= XINT(buffer_local_flags.category_table);
1687 return category_table;
1690 DEFUN("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
1691 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
1695 return CATEGORY_DESIGNATORP(object) ? Qt : Qnil;
1698 DEFUN("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
1699 Return t if OBJECT is a category table value.
1700 Valid values are nil or a bit vector of size 95.
1704 return CATEGORY_TABLE_VALUEP(object) ? Qt : Qnil;
1707 #define CATEGORYP(x) \
1708 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
1710 #define CATEGORY_SET(c) \
1711 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
1713 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
1714 The faster version of `!NILP (Faref (category_set, category))'. */
1715 #define CATEGORY_MEMBER(category, category_set) \
1716 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
1718 /* Return 1 if there is a word boundary between two word-constituent
1719 characters C1 and C2 if they appear in this order, else return 0.
1720 Use the macro WORD_BOUNDARY_P instead of calling this function
1723 int word_boundary_p(Emchar c1, Emchar c2);
1724 int word_boundary_p(Emchar c1, Emchar c2)
1726 Lisp_Object category_set1, category_set2;
1731 if (COMPOSITE_CHAR_P(c1))
1732 c1 = cmpchar_component(c1, 0, 1);
1733 if (COMPOSITE_CHAR_P(c2))
1734 c2 = cmpchar_component(c2, 0, 1);
1737 if (EQ(CHAR_CHARSET(c1), CHAR_CHARSET(c2))) {
1738 tail = Vword_separating_categories;
1741 tail = Vword_combining_categories;
1745 category_set1 = CATEGORY_SET(c1);
1746 if (NILP(category_set1))
1747 return default_result;
1748 category_set2 = CATEGORY_SET(c2);
1749 if (NILP(category_set2))
1750 return default_result;
1752 for (; CONSP(tail); tail = XCONS(tail)->cdr) {
1753 Lisp_Object elt = XCONS(tail)->car;
1756 && CATEGORYP(XCONS(elt)->car)
1757 && CATEGORYP(XCONS(elt)->cdr)
1758 && CATEGORY_MEMBER(XCHAR(XCONS(elt)->car), category_set1)
1759 && CATEGORY_MEMBER(XCHAR(XCONS(elt)->cdr), category_set2))
1760 return !default_result;
1762 return default_result;
1766 void syms_of_chartab(void)
1768 INIT_LRECORD_IMPLEMENTATION(char_table);
1771 INIT_LRECORD_IMPLEMENTATION(char_table_entry);
1773 defsymbol(&Qcategory_table_p, "category-table-p");
1774 defsymbol(&Qcategory_designator_p, "category-designator-p");
1775 defsymbol(&Qcategory_table_value_p, "category-table-value-p");
1778 defsymbol(&Qchar_table, "char-table");
1779 defsymbol(&Qchar_tablep, "char-table-p");
1781 DEFSUBR(Fchar_table_p);
1782 DEFSUBR(Fchar_table_type_list);
1783 DEFSUBR(Fvalid_char_table_type_p);
1784 DEFSUBR(Fchar_table_type);
1785 DEFSUBR(Freset_char_table);
1786 DEFSUBR(Fmake_char_table);
1787 DEFSUBR(Fcopy_char_table);
1788 DEFSUBR(Fget_char_table);
1789 DEFSUBR(Fget_range_char_table);
1790 DEFSUBR(Fvalid_char_table_value_p);
1791 DEFSUBR(Fcheck_valid_char_table_value);
1792 DEFSUBR(Fput_char_table);
1793 DEFSUBR(Fmap_char_table);
1796 DEFSUBR(Fcategory_table_p);
1797 DEFSUBR(Fcategory_table);
1798 DEFSUBR(Fstandard_category_table);
1799 DEFSUBR(Fcopy_category_table);
1800 DEFSUBR(Fset_category_table);
1801 DEFSUBR(Fcheck_category_at);
1802 DEFSUBR(Fchar_in_category_p);
1803 DEFSUBR(Fcategory_designator_p);
1804 DEFSUBR(Fcategory_table_value_p);
1809 void vars_of_chartab(void)
1811 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
1812 Vall_syntax_tables = Qnil;
1813 dump_add_weak_object_chain(&Vall_syntax_tables);
1816 void structure_type_create_chartab(void)
1818 struct structure_type *st;
1820 st = define_structure_type(Qchar_table, 0, chartab_instantiate);
1822 define_structure_type_keyword(st, Qtype, chartab_type_validate);
1823 define_structure_type_keyword(st, Qdata, chartab_data_validate);
1826 void complex_vars_of_chartab(void)
1829 /* Set this now, so first buffer creation can refer to it. */
1830 /* Make it nil before calling copy-category-table
1831 so that copy-category-table will know not to try to copy from garbage */
1832 Vstandard_category_table = Qnil;
1833 Vstandard_category_table = Fcopy_category_table(Qnil);
1834 staticpro(&Vstandard_category_table);
1836 DEFVAR_LISP("word-combining-categories", &Vword_combining_categories /*
1837 List of pair (cons) of categories to determine word boundary.
1839 Emacs treats a sequence of word constituent characters as a single
1840 word (i.e. finds no word boundary between them) iff they belongs to
1841 the same charset. But, exceptions are allowed in the following cases.
1843 \(1) The case that characters are in different charsets is controlled
1844 by the variable `word-combining-categories'.
1846 Emacs finds no word boundary between characters of different charsets
1847 if they have categories matching some element of this list.
1849 More precisely, if an element of this list is a cons of category CAT1
1850 and CAT2, and a multibyte character C1 which has CAT1 is followed by
1851 C2 which has CAT2, there's no word boundary between C1 and C2.
1853 For instance, to tell that ASCII characters and Latin-1 characters can
1854 form a single word, the element `(?l . ?l)' should be in this list
1855 because both characters have the category `l' (Latin characters).
1857 \(2) The case that character are in the same charset is controlled by
1858 the variable `word-separating-categories'.
1860 Emacs find a word boundary between characters of the same charset
1861 if they have categories matching some element of this list.
1863 More precisely, if an element of this list is a cons of category CAT1
1864 and CAT2, and a multibyte character C1 which has CAT1 is followed by
1865 C2 which has CAT2, there's a word boundary between C1 and C2.
1867 For instance, to tell that there's a word boundary between Japanese
1868 Hiragana and Japanese Kanji (both are in the same charset), the
1869 element `(?H . ?C) should be in this list.
1872 Vword_combining_categories = Qnil;
1874 DEFVAR_LISP("word-separating-categories", &Vword_separating_categories /*
1875 List of pair (cons) of categories to determine word boundary.
1876 See the documentation of the variable `word-combining-categories'.
1879 Vword_separating_categories = Qnil;