1 /* XEmacs 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.
7 Copyright (C) 1999,2000,2001 MORIOKA Tomohiko
9 This file is part of XEmacs.
11 XEmacs is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 XEmacs is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with XEmacs; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */
26 /* Synched up with: Mule 2.3. Not synched with FSF.
28 This file was written independently of the FSF implementation,
29 and is not compatible. */
33 Ben Wing: wrote, for 19.13 (Mule). Some category table stuff
34 loosely based on the original Mule.
35 Jareth Hein: fixed a couple of bugs in the implementation, and
36 added regex support for categories with check_category_at
49 Lisp_Object Vutf_2000_version;
52 Lisp_Object Qchar_tablep, Qchar_table;
54 Lisp_Object Vall_syntax_tables;
57 Lisp_Object Qcategory_table_p;
58 Lisp_Object Qcategory_designator_p;
59 Lisp_Object Qcategory_table_value_p;
61 Lisp_Object Vstandard_category_table;
63 /* Variables to determine word boundary. */
64 Lisp_Object Vword_combining_categories, Vword_separating_categories;
71 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange);
73 #define BT_UINT8_MIN 0
74 #define BT_UINT8_MAX (UCHAR_MAX - 3)
75 #define BT_UINT8_t (UCHAR_MAX - 2)
76 #define BT_UINT8_nil (UCHAR_MAX - 1)
77 #define BT_UINT8_unbound UCHAR_MAX
79 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
80 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
81 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
82 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
83 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
86 INT_UINT8_P (Lisp_Object obj)
92 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
99 UINT8_VALUE_P (Lisp_Object obj)
101 return EQ (obj, Qunbound)
102 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
105 INLINE_HEADER unsigned char
106 UINT8_ENCODE (Lisp_Object obj)
108 if (EQ (obj, Qunbound))
109 return BT_UINT8_unbound;
110 else if (EQ (obj, Qnil))
112 else if (EQ (obj, Qt))
118 INLINE_HEADER Lisp_Object
119 UINT8_DECODE (unsigned char n)
121 if (n == BT_UINT8_unbound)
123 else if (n == BT_UINT8_nil)
125 else if (n == BT_UINT8_t)
132 mark_uint8_byte_table (Lisp_Object obj)
138 print_uint8_byte_table (Lisp_Object obj,
139 Lisp_Object printcharfun, int escapeflag)
141 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
143 struct gcpro gcpro1, gcpro2;
144 GCPRO2 (obj, printcharfun);
146 write_c_string ("\n#<uint8-byte-table", printcharfun);
147 for (i = 0; i < 256; i++)
149 unsigned char n = bte->property[i];
151 write_c_string ("\n ", printcharfun);
152 write_c_string (" ", printcharfun);
153 if (n == BT_UINT8_unbound)
154 write_c_string ("void", printcharfun);
155 else if (n == BT_UINT8_nil)
156 write_c_string ("nil", printcharfun);
157 else if (n == BT_UINT8_t)
158 write_c_string ("t", printcharfun);
163 sprintf (buf, "%hd", n);
164 write_c_string (buf, printcharfun);
168 write_c_string (">", printcharfun);
172 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
174 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
175 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
178 for (i = 0; i < 256; i++)
179 if (te1->property[i] != te2->property[i])
185 uint8_byte_table_hash (Lisp_Object obj, int depth)
187 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
191 for (i = 0; i < 256; i++)
192 hash = HASH2 (hash, te->property[i]);
196 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
197 mark_uint8_byte_table,
198 print_uint8_byte_table,
199 0, uint8_byte_table_equal,
200 uint8_byte_table_hash,
201 0 /* uint8_byte_table_description */,
202 Lisp_Uint8_Byte_Table);
205 make_uint8_byte_table (unsigned char initval)
209 Lisp_Uint8_Byte_Table *cte;
211 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
212 &lrecord_uint8_byte_table);
214 for (i = 0; i < 256; i++)
215 cte->property[i] = initval;
217 XSETUINT8_BYTE_TABLE (obj, cte);
222 copy_uint8_byte_table (Lisp_Object entry)
224 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
227 Lisp_Uint8_Byte_Table *ctenew
228 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
229 &lrecord_uint8_byte_table);
231 for (i = 0; i < 256; i++)
233 ctenew->property[i] = cte->property[i];
236 XSETUINT8_BYTE_TABLE (obj, ctenew);
241 uint8_byte_table_same_value_p (Lisp_Object obj)
243 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
244 unsigned char v0 = bte->property[0];
247 for (i = 1; i < 256; i++)
249 if (bte->property[i] != v0)
256 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Emchar ofs, int place,
257 int (*fn) (struct chartab_range *range,
258 Lisp_Object val, void *arg),
261 struct chartab_range rainj;
263 int unit = 1 << (8 * place);
267 rainj.type = CHARTAB_RANGE_CHAR;
269 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
271 if (ct->property[i] != BT_UINT8_unbound)
274 for (; c < c1 && retval == 0; c++)
277 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
286 #define BT_UINT16_MIN 0
287 #define BT_UINT16_MAX (USHRT_MAX - 3)
288 #define BT_UINT16_t (USHRT_MAX - 2)
289 #define BT_UINT16_nil (USHRT_MAX - 1)
290 #define BT_UINT16_unbound USHRT_MAX
292 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
293 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
294 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
295 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
298 INT_UINT16_P (Lisp_Object obj)
302 int num = XINT (obj);
304 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
311 UINT16_VALUE_P (Lisp_Object obj)
313 return EQ (obj, Qunbound)
314 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
317 INLINE_HEADER unsigned short
318 UINT16_ENCODE (Lisp_Object obj)
320 if (EQ (obj, Qunbound))
321 return BT_UINT16_unbound;
322 else if (EQ (obj, Qnil))
323 return BT_UINT16_nil;
324 else if (EQ (obj, Qt))
330 INLINE_HEADER Lisp_Object
331 UINT16_DECODE (unsigned short n)
333 if (n == BT_UINT16_unbound)
335 else if (n == BT_UINT16_nil)
337 else if (n == BT_UINT16_t)
343 INLINE_HEADER unsigned short
344 UINT8_TO_UINT16 (unsigned char n)
346 if (n == BT_UINT8_unbound)
347 return BT_UINT16_unbound;
348 else if (n == BT_UINT8_nil)
349 return BT_UINT16_nil;
350 else if (n == BT_UINT8_t)
357 mark_uint16_byte_table (Lisp_Object obj)
363 print_uint16_byte_table (Lisp_Object obj,
364 Lisp_Object printcharfun, int escapeflag)
366 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
368 struct gcpro gcpro1, gcpro2;
369 GCPRO2 (obj, printcharfun);
371 write_c_string ("\n#<uint16-byte-table", printcharfun);
372 for (i = 0; i < 256; i++)
374 unsigned short n = bte->property[i];
376 write_c_string ("\n ", printcharfun);
377 write_c_string (" ", printcharfun);
378 if (n == BT_UINT16_unbound)
379 write_c_string ("void", printcharfun);
380 else if (n == BT_UINT16_nil)
381 write_c_string ("nil", printcharfun);
382 else if (n == BT_UINT16_t)
383 write_c_string ("t", printcharfun);
388 sprintf (buf, "%hd", n);
389 write_c_string (buf, printcharfun);
393 write_c_string (">", printcharfun);
397 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
399 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
400 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
403 for (i = 0; i < 256; i++)
404 if (te1->property[i] != te2->property[i])
410 uint16_byte_table_hash (Lisp_Object obj, int depth)
412 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
416 for (i = 0; i < 256; i++)
417 hash = HASH2 (hash, te->property[i]);
421 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
422 mark_uint16_byte_table,
423 print_uint16_byte_table,
424 0, uint16_byte_table_equal,
425 uint16_byte_table_hash,
426 0 /* uint16_byte_table_description */,
427 Lisp_Uint16_Byte_Table);
430 make_uint16_byte_table (unsigned short initval)
434 Lisp_Uint16_Byte_Table *cte;
436 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
437 &lrecord_uint16_byte_table);
439 for (i = 0; i < 256; i++)
440 cte->property[i] = initval;
442 XSETUINT16_BYTE_TABLE (obj, cte);
447 copy_uint16_byte_table (Lisp_Object entry)
449 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
452 Lisp_Uint16_Byte_Table *ctenew
453 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
454 &lrecord_uint16_byte_table);
456 for (i = 0; i < 256; i++)
458 ctenew->property[i] = cte->property[i];
461 XSETUINT16_BYTE_TABLE (obj, ctenew);
466 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
470 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
471 Lisp_Uint16_Byte_Table* cte;
473 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
474 &lrecord_uint16_byte_table);
475 for (i = 0; i < 256; i++)
477 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
479 XSETUINT16_BYTE_TABLE (obj, cte);
484 uint16_byte_table_same_value_p (Lisp_Object obj)
486 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
487 unsigned short v0 = bte->property[0];
490 for (i = 1; i < 256; i++)
492 if (bte->property[i] != v0)
499 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Emchar ofs, int place,
500 int (*fn) (struct chartab_range *range,
501 Lisp_Object val, void *arg),
504 struct chartab_range rainj;
506 int unit = 1 << (8 * place);
510 rainj.type = CHARTAB_RANGE_CHAR;
512 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
514 if (ct->property[i] != BT_UINT16_unbound)
517 for (; c < c1 && retval == 0; c++)
520 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
531 mark_byte_table (Lisp_Object obj)
533 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
536 for (i = 0; i < 256; i++)
538 mark_object (cte->property[i]);
544 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
546 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
548 struct gcpro gcpro1, gcpro2;
549 GCPRO2 (obj, printcharfun);
551 write_c_string ("\n#<byte-table", printcharfun);
552 for (i = 0; i < 256; i++)
554 Lisp_Object elt = bte->property[i];
556 write_c_string ("\n ", printcharfun);
557 write_c_string (" ", printcharfun);
558 if (EQ (elt, Qunbound))
559 write_c_string ("void", printcharfun);
561 print_internal (elt, printcharfun, escapeflag);
564 write_c_string (">", printcharfun);
568 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
570 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
571 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
574 for (i = 0; i < 256; i++)
575 if (BYTE_TABLE_P (cte1->property[i]))
577 if (BYTE_TABLE_P (cte2->property[i]))
579 if (!byte_table_equal (cte1->property[i],
580 cte2->property[i], depth + 1))
587 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
593 byte_table_hash (Lisp_Object obj, int depth)
595 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
597 return internal_array_hash (cte->property, 256, depth);
600 static const struct lrecord_description byte_table_description[] = {
601 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
605 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
610 byte_table_description,
614 make_byte_table (Lisp_Object initval)
618 Lisp_Byte_Table *cte;
620 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
622 for (i = 0; i < 256; i++)
623 cte->property[i] = initval;
625 XSETBYTE_TABLE (obj, cte);
630 copy_byte_table (Lisp_Object entry)
632 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
635 Lisp_Byte_Table *ctnew
636 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
638 for (i = 0; i < 256; i++)
640 if (UINT8_BYTE_TABLE_P (cte->property[i]))
642 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
644 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
646 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
648 else if (BYTE_TABLE_P (cte->property[i]))
650 ctnew->property[i] = copy_byte_table (cte->property[i]);
653 ctnew->property[i] = cte->property[i];
656 XSETBYTE_TABLE (obj, ctnew);
661 byte_table_same_value_p (Lisp_Object obj)
663 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
664 Lisp_Object v0 = bte->property[0];
667 for (i = 1; i < 256; i++)
669 if (!internal_equal (bte->property[i], v0, 0))
676 map_over_byte_table (Lisp_Byte_Table *ct, Emchar ofs, int place,
677 int (*fn) (struct chartab_range *range,
678 Lisp_Object val, void *arg),
683 int unit = 1 << (8 * place);
686 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
689 if (UINT8_BYTE_TABLE_P (v))
692 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v),
693 c, place - 1, fn, arg);
696 else if (UINT16_BYTE_TABLE_P (v))
699 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v),
700 c, place - 1, fn, arg);
703 else if (BYTE_TABLE_P (v))
705 retval = map_over_byte_table (XBYTE_TABLE(v),
706 c, place - 1, fn, arg);
709 else if (!UNBOUNDP (v))
711 struct chartab_range rainj;
712 Emchar c1 = c + unit;
714 rainj.type = CHARTAB_RANGE_CHAR;
716 for (; c < c1 && retval == 0; c++)
719 retval = (fn) (&rainj, v, arg);
730 get_byte_table (Lisp_Object table, unsigned char idx)
732 if (UINT8_BYTE_TABLE_P (table))
733 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
734 else if (UINT16_BYTE_TABLE_P (table))
735 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
736 else if (BYTE_TABLE_P (table))
737 return XBYTE_TABLE(table)->property[idx];
743 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
745 if (UINT8_BYTE_TABLE_P (table))
747 if (UINT8_VALUE_P (value))
749 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
750 if (!UINT8_BYTE_TABLE_P (value) &&
751 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
752 && uint8_byte_table_same_value_p (table))
757 else if (UINT16_VALUE_P (value))
759 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
761 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
766 Lisp_Object new = make_byte_table (Qnil);
769 for (i = 0; i < 256; i++)
771 XBYTE_TABLE(new)->property[i]
772 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
774 XBYTE_TABLE(new)->property[idx] = value;
778 else if (UINT16_BYTE_TABLE_P (table))
780 if (UINT16_VALUE_P (value))
782 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
783 if (!UINT8_BYTE_TABLE_P (value) &&
784 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
785 && uint16_byte_table_same_value_p (table))
792 Lisp_Object new = make_byte_table (Qnil);
795 for (i = 0; i < 256; i++)
797 XBYTE_TABLE(new)->property[i]
798 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
800 XBYTE_TABLE(new)->property[idx] = value;
804 else if (BYTE_TABLE_P (table))
806 XBYTE_TABLE(table)->property[idx] = value;
807 if (!UINT8_BYTE_TABLE_P (value) &&
808 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
809 && byte_table_same_value_p (table))
814 else if (!internal_equal (table, value, 0))
816 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
818 table = make_uint8_byte_table (UINT8_ENCODE (table));
819 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
821 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
823 table = make_uint16_byte_table (UINT16_ENCODE (table));
824 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
828 table = make_byte_table (table);
829 XBYTE_TABLE(table)->property[idx] = value;
837 make_char_id_table (Lisp_Object initval)
840 obj = Fmake_char_table (Qgeneric);
841 fill_char_table (XCHAR_TABLE (obj), initval);
846 get_char_id_table (Lisp_Char_Table* cit, Emchar ch)
848 Lisp_Object val = get_byte_table (get_byte_table
852 (unsigned char)(ch >> 24)),
853 (unsigned char) (ch >> 16)),
854 (unsigned char) (ch >> 8)),
857 return cit->default_value;
863 put_char_id_table (Lisp_Char_Table* cit,
864 Lisp_Object character, Lisp_Object value)
866 struct chartab_range range;
868 decode_char_table_range (character, &range);
869 put_char_table (cit, &range, value);
873 Lisp_Object Vcharacter_composition_table;
874 Lisp_Object Vcharacter_variant_table;
877 Lisp_Object Q_decomposition;
881 Lisp_Object Qisolated;
882 Lisp_Object Qinitial;
885 Lisp_Object Qvertical;
886 Lisp_Object QnoBreak;
887 Lisp_Object Qfraction;
897 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
900 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
906 else if (EQ (v, Qcompat))
908 else if (EQ (v, Qisolated))
910 else if (EQ (v, Qinitial))
912 else if (EQ (v, Qmedial))
914 else if (EQ (v, Qfinal))
916 else if (EQ (v, Qvertical))
918 else if (EQ (v, QnoBreak))
920 else if (EQ (v, Qfraction))
922 else if (EQ (v, Qsuper))
924 else if (EQ (v, Qsub))
926 else if (EQ (v, Qcircle))
928 else if (EQ (v, Qsquare))
930 else if (EQ (v, Qwide))
932 else if (EQ (v, Qnarrow))
934 else if (EQ (v, Qsmall))
936 else if (EQ (v, Qfont))
939 signal_simple_error (err_msg, err_arg);
942 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
943 Return character corresponding with list.
947 Lisp_Object table = Vcharacter_composition_table;
948 Lisp_Object rest = list;
952 Lisp_Object v = Fcar (rest);
954 Emchar c = to_char_id (v, "Invalid value for composition", list);
956 ret = get_char_id_table (XCHAR_TABLE(table), c);
961 if (!CHAR_TABLEP (ret))
966 else if (!CONSP (rest))
968 else if (CHAR_TABLEP (ret))
971 signal_simple_error ("Invalid table is found with", list);
973 signal_simple_error ("Invalid value for composition", list);
976 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
977 Return variants of CHARACTER.
981 CHECK_CHAR (character);
982 return Fcopy_list (get_char_id_table
983 (XCHAR_TABLE(Vcharacter_variant_table),
990 /* A char table maps from ranges of characters to values.
992 Implementing a general data structure that maps from arbitrary
993 ranges of numbers to values is tricky to do efficiently. As it
994 happens, it should suffice (and is usually more convenient, anyway)
995 when dealing with characters to restrict the sorts of ranges that
996 can be assigned values, as follows:
999 2) All characters in a charset.
1000 3) All characters in a particular row of a charset, where a "row"
1001 means all characters with the same first byte.
1002 4) A particular character in a charset.
1004 We use char tables to generalize the 256-element vectors now
1005 littering the Emacs code.
1007 Possible uses (all should be converted at some point):
1013 5) keyboard-translate-table?
1016 abstract type to generalize the Emacs vectors and Mule
1017 vectors-of-vectors goo.
1020 /************************************************************************/
1021 /* Char Table object */
1022 /************************************************************************/
1024 #if defined(MULE)&&!defined(UTF2000)
1027 mark_char_table_entry (Lisp_Object obj)
1029 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1032 for (i = 0; i < 96; i++)
1034 mark_object (cte->level2[i]);
1040 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1042 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1043 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1046 for (i = 0; i < 96; i++)
1047 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1053 static unsigned long
1054 char_table_entry_hash (Lisp_Object obj, int depth)
1056 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1058 return internal_array_hash (cte->level2, 96, depth);
1061 static const struct lrecord_description char_table_entry_description[] = {
1062 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1066 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1067 mark_char_table_entry, internal_object_printer,
1068 0, char_table_entry_equal,
1069 char_table_entry_hash,
1070 char_table_entry_description,
1071 Lisp_Char_Table_Entry);
1075 mark_char_table (Lisp_Object obj)
1077 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1080 mark_object (ct->table);
1084 for (i = 0; i < NUM_ASCII_CHARS; i++)
1085 mark_object (ct->ascii[i]);
1087 for (i = 0; i < NUM_LEADING_BYTES; i++)
1088 mark_object (ct->level1[i]);
1092 return ct->default_value;
1094 return ct->mirror_table;
1098 /* WARNING: All functions of this nature need to be written extremely
1099 carefully to avoid crashes during GC. Cf. prune_specifiers()
1100 and prune_weak_hash_tables(). */
1103 prune_syntax_tables (void)
1105 Lisp_Object rest, prev = Qnil;
1107 for (rest = Vall_syntax_tables;
1109 rest = XCHAR_TABLE (rest)->next_table)
1111 if (! marked_p (rest))
1113 /* This table is garbage. Remove it from the list. */
1115 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1117 XCHAR_TABLE (prev)->next_table =
1118 XCHAR_TABLE (rest)->next_table;
1124 char_table_type_to_symbol (enum char_table_type type)
1129 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1130 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1131 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1132 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1134 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1139 static enum char_table_type
1140 symbol_to_char_table_type (Lisp_Object symbol)
1142 CHECK_SYMBOL (symbol);
1144 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1145 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1146 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1147 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1149 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1152 signal_simple_error ("Unrecognized char table type", symbol);
1153 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1157 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1158 Lisp_Object printcharfun)
1162 write_c_string (" (", printcharfun);
1163 print_internal (make_char (first), printcharfun, 0);
1164 write_c_string (" ", printcharfun);
1165 print_internal (make_char (last), printcharfun, 0);
1166 write_c_string (") ", printcharfun);
1170 write_c_string (" ", printcharfun);
1171 print_internal (make_char (first), printcharfun, 0);
1172 write_c_string (" ", printcharfun);
1174 print_internal (val, printcharfun, 1);
1177 #if defined(MULE)&&!defined(UTF2000)
1180 print_chartab_charset_row (Lisp_Object charset,
1182 Lisp_Char_Table_Entry *cte,
1183 Lisp_Object printcharfun)
1186 Lisp_Object cat = Qunbound;
1189 for (i = 32; i < 128; i++)
1191 Lisp_Object pam = cte->level2[i - 32];
1203 print_chartab_range (MAKE_CHAR (charset, first, 0),
1204 MAKE_CHAR (charset, i - 1, 0),
1207 print_chartab_range (MAKE_CHAR (charset, row, first),
1208 MAKE_CHAR (charset, row, i - 1),
1218 print_chartab_range (MAKE_CHAR (charset, first, 0),
1219 MAKE_CHAR (charset, i - 1, 0),
1222 print_chartab_range (MAKE_CHAR (charset, row, first),
1223 MAKE_CHAR (charset, row, i - 1),
1229 print_chartab_two_byte_charset (Lisp_Object charset,
1230 Lisp_Char_Table_Entry *cte,
1231 Lisp_Object printcharfun)
1235 for (i = 32; i < 128; i++)
1237 Lisp_Object jen = cte->level2[i - 32];
1239 if (!CHAR_TABLE_ENTRYP (jen))
1243 write_c_string (" [", printcharfun);
1244 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1245 sprintf (buf, " %d] ", i);
1246 write_c_string (buf, printcharfun);
1247 print_internal (jen, printcharfun, 0);
1250 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1258 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1260 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1263 struct gcpro gcpro1, gcpro2;
1264 GCPRO2 (obj, printcharfun);
1266 write_c_string ("#s(char-table ", printcharfun);
1267 write_c_string (" ", printcharfun);
1268 write_c_string (string_data
1270 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1272 write_c_string ("\n ", printcharfun);
1273 print_internal (ct->default_value, printcharfun, escapeflag);
1274 for (i = 0; i < 256; i++)
1276 Lisp_Object elt = get_byte_table (ct->table, i);
1277 if (i != 0) write_c_string ("\n ", printcharfun);
1278 if (EQ (elt, Qunbound))
1279 write_c_string ("void", printcharfun);
1281 print_internal (elt, printcharfun, escapeflag);
1284 #else /* non UTF2000 */
1287 sprintf (buf, "#s(char-table type %s data (",
1288 string_data (symbol_name (XSYMBOL
1289 (char_table_type_to_symbol (ct->type)))));
1290 write_c_string (buf, printcharfun);
1292 /* Now write out the ASCII/Control-1 stuff. */
1296 Lisp_Object val = Qunbound;
1298 for (i = 0; i < NUM_ASCII_CHARS; i++)
1307 if (!EQ (ct->ascii[i], val))
1309 print_chartab_range (first, i - 1, val, printcharfun);
1316 print_chartab_range (first, i - 1, val, printcharfun);
1323 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1326 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1327 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1329 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1330 || i == LEADING_BYTE_CONTROL_1)
1332 if (!CHAR_TABLE_ENTRYP (ann))
1334 write_c_string (" ", printcharfun);
1335 print_internal (XCHARSET_NAME (charset),
1337 write_c_string (" ", printcharfun);
1338 print_internal (ann, printcharfun, 0);
1342 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1343 if (XCHARSET_DIMENSION (charset) == 1)
1344 print_chartab_charset_row (charset, -1, cte, printcharfun);
1346 print_chartab_two_byte_charset (charset, cte, printcharfun);
1351 #endif /* non UTF2000 */
1353 write_c_string ("))", printcharfun);
1357 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1359 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1360 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1363 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1367 for (i = 0; i < 256; i++)
1369 if (!internal_equal (get_byte_table (ct1->table, i),
1370 get_byte_table (ct2->table, i), 0))
1374 for (i = 0; i < NUM_ASCII_CHARS; i++)
1375 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1379 for (i = 0; i < NUM_LEADING_BYTES; i++)
1380 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1383 #endif /* non UTF2000 */
1388 static unsigned long
1389 char_table_hash (Lisp_Object obj, int depth)
1391 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1393 return byte_table_hash (ct->table, depth + 1);
1395 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1398 hashval = HASH2 (hashval,
1399 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1405 static const struct lrecord_description char_table_description[] = {
1407 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1408 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1410 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1412 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1416 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1418 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1422 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1423 mark_char_table, print_char_table, 0,
1424 char_table_equal, char_table_hash,
1425 char_table_description,
1428 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1429 Return non-nil if OBJECT is a char table.
1431 A char table is a table that maps characters (or ranges of characters)
1432 to values. Char tables are specialized for characters, only allowing
1433 particular sorts of ranges to be assigned values. Although this
1434 loses in generality, it makes for extremely fast (constant-time)
1435 lookups, and thus is feasible for applications that do an extremely
1436 large number of lookups (e.g. scanning a buffer for a character in
1437 a particular syntax, where a lookup in the syntax table must occur
1438 once per character).
1440 When Mule support exists, the types of ranges that can be assigned
1444 -- an entire charset
1445 -- a single row in a two-octet charset
1446 -- a single character
1448 When Mule support is not present, the types of ranges that can be
1452 -- a single character
1454 To create a char table, use `make-char-table'.
1455 To modify a char table, use `put-char-table' or `remove-char-table'.
1456 To retrieve the value for a particular character, use `get-char-table'.
1457 See also `map-char-table', `clear-char-table', `copy-char-table',
1458 `valid-char-table-type-p', `char-table-type-list',
1459 `valid-char-table-value-p', and `check-char-table-value'.
1463 return CHAR_TABLEP (object) ? Qt : Qnil;
1466 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1467 Return a list of the recognized char table types.
1468 See `valid-char-table-type-p'.
1473 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1475 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1479 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1480 Return t if TYPE if a recognized char table type.
1482 Each char table type is used for a different purpose and allows different
1483 sorts of values. The different char table types are
1486 Used for category tables, which specify the regexp categories
1487 that a character is in. The valid values are nil or a
1488 bit vector of 95 elements. Higher-level Lisp functions are
1489 provided for working with category tables. Currently categories
1490 and category tables only exist when Mule support is present.
1492 A generalized char table, for mapping from one character to
1493 another. Used for case tables, syntax matching tables,
1494 `keyboard-translate-table', etc. The valid values are characters.
1496 An even more generalized char table, for mapping from a
1497 character to anything.
1499 Used for display tables, which specify how a particular character
1500 is to appear when displayed. #### Not yet implemented.
1502 Used for syntax tables, which specify the syntax of a particular
1503 character. Higher-level Lisp functions are provided for
1504 working with syntax tables. The valid values are integers.
1509 return (EQ (type, Qchar) ||
1511 EQ (type, Qcategory) ||
1513 EQ (type, Qdisplay) ||
1514 EQ (type, Qgeneric) ||
1515 EQ (type, Qsyntax)) ? Qt : Qnil;
1518 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1519 Return the type of CHAR-TABLE.
1520 See `valid-char-table-type-p'.
1524 CHECK_CHAR_TABLE (char_table);
1525 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1529 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1532 ct->table = Qunbound;
1533 ct->default_value = value;
1537 for (i = 0; i < NUM_ASCII_CHARS; i++)
1538 ct->ascii[i] = value;
1540 for (i = 0; i < NUM_LEADING_BYTES; i++)
1541 ct->level1[i] = value;
1546 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1547 update_syntax_table (ct);
1551 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1552 Reset CHAR-TABLE to its default state.
1556 Lisp_Char_Table *ct;
1558 CHECK_CHAR_TABLE (char_table);
1559 ct = XCHAR_TABLE (char_table);
1563 case CHAR_TABLE_TYPE_CHAR:
1564 fill_char_table (ct, make_char (0));
1566 case CHAR_TABLE_TYPE_DISPLAY:
1567 case CHAR_TABLE_TYPE_GENERIC:
1569 case CHAR_TABLE_TYPE_CATEGORY:
1571 fill_char_table (ct, Qnil);
1574 case CHAR_TABLE_TYPE_SYNTAX:
1575 fill_char_table (ct, make_int (Sinherit));
1585 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1586 Return a new, empty char table of type TYPE.
1587 Currently recognized types are 'char, 'category, 'display, 'generic,
1588 and 'syntax. See `valid-char-table-type-p'.
1592 Lisp_Char_Table *ct;
1594 enum char_table_type ty = symbol_to_char_table_type (type);
1596 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1599 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1601 ct->mirror_table = Fmake_char_table (Qgeneric);
1602 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1606 ct->mirror_table = Qnil;
1608 ct->next_table = Qnil;
1609 XSETCHAR_TABLE (obj, ct);
1610 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1612 ct->next_table = Vall_syntax_tables;
1613 Vall_syntax_tables = obj;
1615 Freset_char_table (obj);
1619 #if defined(MULE)&&!defined(UTF2000)
1622 make_char_table_entry (Lisp_Object initval)
1626 Lisp_Char_Table_Entry *cte =
1627 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1629 for (i = 0; i < 96; i++)
1630 cte->level2[i] = initval;
1632 XSETCHAR_TABLE_ENTRY (obj, cte);
1637 copy_char_table_entry (Lisp_Object entry)
1639 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1642 Lisp_Char_Table_Entry *ctenew =
1643 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1645 for (i = 0; i < 96; i++)
1647 Lisp_Object new = cte->level2[i];
1648 if (CHAR_TABLE_ENTRYP (new))
1649 ctenew->level2[i] = copy_char_table_entry (new);
1651 ctenew->level2[i] = new;
1654 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1660 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1661 Return a new char table which is a copy of CHAR-TABLE.
1662 It will contain the same values for the same characters and ranges
1663 as CHAR-TABLE. The values will not themselves be copied.
1667 Lisp_Char_Table *ct, *ctnew;
1673 CHECK_CHAR_TABLE (char_table);
1674 ct = XCHAR_TABLE (char_table);
1675 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1676 ctnew->type = ct->type;
1678 ctnew->default_value = ct->default_value;
1680 if (UINT8_BYTE_TABLE_P (ct->table))
1682 ctnew->table = copy_uint8_byte_table (ct->table);
1684 else if (UINT16_BYTE_TABLE_P (ct->table))
1686 ctnew->table = copy_uint16_byte_table (ct->table);
1688 else if (BYTE_TABLE_P (ct->table))
1690 ctnew->table = copy_byte_table (ct->table);
1692 else if (!UNBOUNDP (ct->table))
1693 ctnew->table = ct->table;
1694 #else /* non UTF2000 */
1696 for (i = 0; i < NUM_ASCII_CHARS; i++)
1698 Lisp_Object new = ct->ascii[i];
1700 assert (! (CHAR_TABLE_ENTRYP (new)));
1702 ctnew->ascii[i] = new;
1707 for (i = 0; i < NUM_LEADING_BYTES; i++)
1709 Lisp_Object new = ct->level1[i];
1710 if (CHAR_TABLE_ENTRYP (new))
1711 ctnew->level1[i] = copy_char_table_entry (new);
1713 ctnew->level1[i] = new;
1717 #endif /* non UTF2000 */
1720 if (CHAR_TABLEP (ct->mirror_table))
1721 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
1723 ctnew->mirror_table = ct->mirror_table;
1725 ctnew->next_table = Qnil;
1726 XSETCHAR_TABLE (obj, ctnew);
1727 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
1729 ctnew->next_table = Vall_syntax_tables;
1730 Vall_syntax_tables = obj;
1736 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
1739 outrange->type = CHARTAB_RANGE_ALL;
1740 else if (EQ (range, Qnil))
1741 outrange->type = CHARTAB_RANGE_DEFAULT;
1742 else if (CHAR_OR_CHAR_INTP (range))
1744 outrange->type = CHARTAB_RANGE_CHAR;
1745 outrange->ch = XCHAR_OR_CHAR_INT (range);
1749 signal_simple_error ("Range must be t or a character", range);
1751 else if (VECTORP (range))
1753 Lisp_Vector *vec = XVECTOR (range);
1754 Lisp_Object *elts = vector_data (vec);
1755 if (vector_length (vec) != 2)
1756 signal_simple_error ("Length of charset row vector must be 2",
1758 outrange->type = CHARTAB_RANGE_ROW;
1759 outrange->charset = Fget_charset (elts[0]);
1760 CHECK_INT (elts[1]);
1761 outrange->row = XINT (elts[1]);
1762 if (XCHARSET_DIMENSION (outrange->charset) >= 2)
1764 switch (XCHARSET_CHARS (outrange->charset))
1767 check_int_range (outrange->row, 33, 126);
1770 check_int_range (outrange->row, 32, 127);
1777 signal_simple_error ("Charset in row vector must be multi-byte",
1782 if (!CHARSETP (range) && !SYMBOLP (range))
1784 ("Char table range must be t, charset, char, or vector", range);
1785 outrange->type = CHARTAB_RANGE_CHARSET;
1786 outrange->charset = Fget_charset (range);
1791 #if defined(MULE)&&!defined(UTF2000)
1793 /* called from CHAR_TABLE_VALUE(). */
1795 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
1800 Lisp_Object charset;
1802 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
1807 BREAKUP_CHAR (c, charset, byte1, byte2);
1809 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
1811 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
1812 if (CHAR_TABLE_ENTRYP (val))
1814 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
1815 val = cte->level2[byte1 - 32];
1816 if (CHAR_TABLE_ENTRYP (val))
1818 cte = XCHAR_TABLE_ENTRY (val);
1819 assert (byte2 >= 32);
1820 val = cte->level2[byte2 - 32];
1821 assert (!CHAR_TABLE_ENTRYP (val));
1831 get_char_table (Emchar ch, Lisp_Char_Table *ct)
1834 Lisp_Object val = get_byte_table (get_byte_table
1838 (unsigned char)(ch >> 24)),
1839 (unsigned char) (ch >> 16)),
1840 (unsigned char) (ch >> 8)),
1841 (unsigned char) ch);
1843 return ct->default_value;
1848 Lisp_Object charset;
1852 BREAKUP_CHAR (ch, charset, byte1, byte2);
1854 if (EQ (charset, Vcharset_ascii))
1855 val = ct->ascii[byte1];
1856 else if (EQ (charset, Vcharset_control_1))
1857 val = ct->ascii[byte1 + 128];
1860 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
1861 val = ct->level1[lb];
1862 if (CHAR_TABLE_ENTRYP (val))
1864 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
1865 val = cte->level2[byte1 - 32];
1866 if (CHAR_TABLE_ENTRYP (val))
1868 cte = XCHAR_TABLE_ENTRY (val);
1869 assert (byte2 >= 32);
1870 val = cte->level2[byte2 - 32];
1871 assert (!CHAR_TABLE_ENTRYP (val));
1878 #else /* not MULE */
1879 return ct->ascii[(unsigned char)ch];
1880 #endif /* not MULE */
1884 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
1885 Find value for CHARACTER in CHAR-TABLE.
1887 (character, char_table))
1889 CHECK_CHAR_TABLE (char_table);
1890 CHECK_CHAR_COERCE_INT (character);
1892 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
1895 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
1896 Find value for a range in CHAR-TABLE.
1897 If there is more than one value, return MULTI (defaults to nil).
1899 (range, char_table, multi))
1901 Lisp_Char_Table *ct;
1902 struct chartab_range rainj;
1904 if (CHAR_OR_CHAR_INTP (range))
1905 return Fget_char_table (range, char_table);
1906 CHECK_CHAR_TABLE (char_table);
1907 ct = XCHAR_TABLE (char_table);
1909 decode_char_table_range (range, &rainj);
1912 case CHARTAB_RANGE_ALL:
1915 if (UINT8_BYTE_TABLE_P (ct->table))
1917 else if (UINT16_BYTE_TABLE_P (ct->table))
1919 else if (BYTE_TABLE_P (ct->table))
1923 #else /* non UTF2000 */
1925 Lisp_Object first = ct->ascii[0];
1927 for (i = 1; i < NUM_ASCII_CHARS; i++)
1928 if (!EQ (first, ct->ascii[i]))
1932 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1935 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
1936 || i == LEADING_BYTE_ASCII
1937 || i == LEADING_BYTE_CONTROL_1)
1939 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
1945 #endif /* non UTF2000 */
1949 case CHARTAB_RANGE_CHARSET:
1953 if (EQ (rainj.charset, Vcharset_ascii))
1956 Lisp_Object first = ct->ascii[0];
1958 for (i = 1; i < 128; i++)
1959 if (!EQ (first, ct->ascii[i]))
1964 if (EQ (rainj.charset, Vcharset_control_1))
1967 Lisp_Object first = ct->ascii[128];
1969 for (i = 129; i < 160; i++)
1970 if (!EQ (first, ct->ascii[i]))
1976 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
1978 if (CHAR_TABLE_ENTRYP (val))
1984 case CHARTAB_RANGE_ROW:
1989 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
1991 if (!CHAR_TABLE_ENTRYP (val))
1993 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
1994 if (CHAR_TABLE_ENTRYP (val))
1998 #endif /* not UTF2000 */
1999 #endif /* not MULE */
2005 return Qnil; /* not reached */
2009 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2010 Error_behavior errb)
2014 case CHAR_TABLE_TYPE_SYNTAX:
2015 if (!ERRB_EQ (errb, ERROR_ME))
2016 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2017 && CHAR_OR_CHAR_INTP (XCDR (value)));
2020 Lisp_Object cdr = XCDR (value);
2021 CHECK_INT (XCAR (value));
2022 CHECK_CHAR_COERCE_INT (cdr);
2029 case CHAR_TABLE_TYPE_CATEGORY:
2030 if (!ERRB_EQ (errb, ERROR_ME))
2031 return CATEGORY_TABLE_VALUEP (value);
2032 CHECK_CATEGORY_TABLE_VALUE (value);
2036 case CHAR_TABLE_TYPE_GENERIC:
2039 case CHAR_TABLE_TYPE_DISPLAY:
2041 maybe_signal_simple_error ("Display char tables not yet implemented",
2042 value, Qchar_table, errb);
2045 case CHAR_TABLE_TYPE_CHAR:
2046 if (!ERRB_EQ (errb, ERROR_ME))
2047 return CHAR_OR_CHAR_INTP (value);
2048 CHECK_CHAR_COERCE_INT (value);
2055 return 0; /* not reached */
2059 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2063 case CHAR_TABLE_TYPE_SYNTAX:
2066 Lisp_Object car = XCAR (value);
2067 Lisp_Object cdr = XCDR (value);
2068 CHECK_CHAR_COERCE_INT (cdr);
2069 return Fcons (car, cdr);
2072 case CHAR_TABLE_TYPE_CHAR:
2073 CHECK_CHAR_COERCE_INT (value);
2081 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2082 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2084 (value, char_table_type))
2086 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2088 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2091 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2092 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2094 (value, char_table_type))
2096 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2098 check_valid_char_table_value (value, type, ERROR_ME);
2102 /* Assign VAL to all characters in RANGE in char table CT. */
2105 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2108 switch (range->type)
2110 case CHARTAB_RANGE_ALL:
2111 /* printf ("put-char-table: range = all\n"); */
2112 fill_char_table (ct, val);
2113 return; /* avoid the duplicate call to update_syntax_table() below,
2114 since fill_char_table() also did that. */
2117 case CHARTAB_RANGE_DEFAULT:
2118 ct->default_value = val;
2123 case CHARTAB_RANGE_CHARSET:
2127 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2129 /* printf ("put-char-table: range = charset: %d\n",
2130 XCHARSET_LEADING_BYTE (range->charset));
2132 if ( CHAR_TABLEP (encoding_table) )
2134 for (c = 0; c < 1 << 24; c++)
2136 if ( INTP (get_char_id_table (XCHAR_TABLE(encoding_table),
2138 put_char_id_table_0 (ct, c, val);
2143 for (c = 0; c < 1 << 24; c++)
2145 if ( charset_code_point (range->charset, c) >= 0 )
2146 put_char_id_table_0 (ct, c, val);
2151 if (EQ (range->charset, Vcharset_ascii))
2154 for (i = 0; i < 128; i++)
2157 else if (EQ (range->charset, Vcharset_control_1))
2160 for (i = 128; i < 160; i++)
2165 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2166 ct->level1[lb] = val;
2171 case CHARTAB_RANGE_ROW:
2174 int cell_min, cell_max, i;
2176 /* printf ("put-char-table: range = charset-row: %d, 0x%x\n",
2177 XCHARSET_LEADING_BYTE (range->charset), range->row); */
2178 if (XCHARSET_DIMENSION (range->charset) < 2)
2179 signal_simple_error ("Charset in row vector must be multi-byte",
2183 switch (XCHARSET_CHARS (range->charset))
2186 cell_min = 33; cell_max = 126;
2189 cell_min = 32; cell_max = 127;
2192 cell_min = 0; cell_max = 127;
2195 cell_min = 0; cell_max = 255;
2201 if (XCHARSET_DIMENSION (range->charset) == 2)
2202 check_int_range (range->row, cell_min, cell_max);
2203 else if (XCHARSET_DIMENSION (range->charset) == 3)
2205 check_int_range (range->row >> 8 , cell_min, cell_max);
2206 check_int_range (range->row & 0xFF, cell_min, cell_max);
2208 else if (XCHARSET_DIMENSION (range->charset) == 4)
2210 check_int_range ( range->row >> 16 , cell_min, cell_max);
2211 check_int_range ((range->row >> 8) & 0xFF, cell_min, cell_max);
2212 check_int_range ( range->row & 0xFF, cell_min, cell_max);
2217 for (i = cell_min; i <= cell_max; i++)
2219 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2220 if ( charset_code_point (range->charset, ch) >= 0 )
2221 put_char_id_table_0 (ct, ch, val);
2226 Lisp_Char_Table_Entry *cte;
2227 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2228 /* make sure that there is a separate entry for the row. */
2229 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2230 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2231 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2232 cte->level2[range->row - 32] = val;
2234 #endif /* not UTF2000 */
2238 case CHARTAB_RANGE_CHAR:
2240 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2241 put_char_id_table_0 (ct, range->ch, val);
2245 Lisp_Object charset;
2248 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2249 if (EQ (charset, Vcharset_ascii))
2250 ct->ascii[byte1] = val;
2251 else if (EQ (charset, Vcharset_control_1))
2252 ct->ascii[byte1 + 128] = val;
2255 Lisp_Char_Table_Entry *cte;
2256 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2257 /* make sure that there is a separate entry for the row. */
2258 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2259 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2260 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2261 /* now CTE is a char table entry for the charset;
2262 each entry is for a single row (or character of
2263 a one-octet charset). */
2264 if (XCHARSET_DIMENSION (charset) == 1)
2265 cte->level2[byte1 - 32] = val;
2268 /* assigning to one character in a two-octet charset. */
2269 /* make sure that the charset row contains a separate
2270 entry for each character. */
2271 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2272 cte->level2[byte1 - 32] =
2273 make_char_table_entry (cte->level2[byte1 - 32]);
2274 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2275 cte->level2[byte2 - 32] = val;
2279 #else /* not MULE */
2280 ct->ascii[(unsigned char) (range->ch)] = val;
2282 #endif /* not MULE */
2286 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2287 update_syntax_table (ct);
2291 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2292 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2294 RANGE specifies one or more characters to be affected and should be
2295 one of the following:
2297 -- t (all characters are affected)
2298 -- A charset (only allowed when Mule support is present)
2299 -- A vector of two elements: a two-octet charset and a row number
2300 (only allowed when Mule support is present)
2301 -- A single character
2303 VALUE must be a value appropriate for the type of CHAR-TABLE.
2304 See `valid-char-table-type-p'.
2306 (range, value, char_table))
2308 Lisp_Char_Table *ct;
2309 struct chartab_range rainj;
2311 CHECK_CHAR_TABLE (char_table);
2312 ct = XCHAR_TABLE (char_table);
2313 check_valid_char_table_value (value, ct->type, ERROR_ME);
2314 decode_char_table_range (range, &rainj);
2315 value = canonicalize_char_table_value (value, ct->type);
2316 put_char_table (ct, &rainj, value);
2321 /* Map FN over the ASCII chars in CT. */
2324 map_over_charset_ascii (Lisp_Char_Table *ct,
2325 int (*fn) (struct chartab_range *range,
2326 Lisp_Object val, void *arg),
2329 struct chartab_range rainj;
2338 rainj.type = CHARTAB_RANGE_CHAR;
2340 for (i = start, retval = 0; i < stop && retval == 0; i++)
2342 rainj.ch = (Emchar) i;
2343 retval = (fn) (&rainj, ct->ascii[i], arg);
2351 /* Map FN over the Control-1 chars in CT. */
2354 map_over_charset_control_1 (Lisp_Char_Table *ct,
2355 int (*fn) (struct chartab_range *range,
2356 Lisp_Object val, void *arg),
2359 struct chartab_range rainj;
2362 int stop = start + 32;
2364 rainj.type = CHARTAB_RANGE_CHAR;
2366 for (i = start, retval = 0; i < stop && retval == 0; i++)
2368 rainj.ch = (Emchar) (i);
2369 retval = (fn) (&rainj, ct->ascii[i], arg);
2375 /* Map FN over the row ROW of two-byte charset CHARSET.
2376 There must be a separate value for that row in the char table.
2377 CTE specifies the char table entry for CHARSET. */
2380 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2381 Lisp_Object charset, int row,
2382 int (*fn) (struct chartab_range *range,
2383 Lisp_Object val, void *arg),
2386 Lisp_Object val = cte->level2[row - 32];
2388 if (!CHAR_TABLE_ENTRYP (val))
2390 struct chartab_range rainj;
2392 rainj.type = CHARTAB_RANGE_ROW;
2393 rainj.charset = charset;
2395 return (fn) (&rainj, val, arg);
2399 struct chartab_range rainj;
2401 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2402 int start = charset94_p ? 33 : 32;
2403 int stop = charset94_p ? 127 : 128;
2405 cte = XCHAR_TABLE_ENTRY (val);
2407 rainj.type = CHARTAB_RANGE_CHAR;
2409 for (i = start, retval = 0; i < stop && retval == 0; i++)
2411 rainj.ch = MAKE_CHAR (charset, row, i);
2412 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2420 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2421 int (*fn) (struct chartab_range *range,
2422 Lisp_Object val, void *arg),
2425 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2426 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2428 if (!CHARSETP (charset)
2429 || lb == LEADING_BYTE_ASCII
2430 || lb == LEADING_BYTE_CONTROL_1)
2433 if (!CHAR_TABLE_ENTRYP (val))
2435 struct chartab_range rainj;
2437 rainj.type = CHARTAB_RANGE_CHARSET;
2438 rainj.charset = charset;
2439 return (fn) (&rainj, val, arg);
2443 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2444 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2445 int start = charset94_p ? 33 : 32;
2446 int stop = charset94_p ? 127 : 128;
2449 if (XCHARSET_DIMENSION (charset) == 1)
2451 struct chartab_range rainj;
2452 rainj.type = CHARTAB_RANGE_CHAR;
2454 for (i = start, retval = 0; i < stop && retval == 0; i++)
2456 rainj.ch = MAKE_CHAR (charset, i, 0);
2457 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2462 for (i = start, retval = 0; i < stop && retval == 0; i++)
2463 retval = map_over_charset_row (cte, charset, i, fn, arg);
2471 #endif /* not UTF2000 */
2474 struct map_char_table_for_charset_arg
2476 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2477 Lisp_Char_Table *ct;
2482 map_char_table_for_charset_fun (struct chartab_range *range,
2483 Lisp_Object val, void *arg)
2485 struct map_char_table_for_charset_arg *closure =
2486 (struct map_char_table_for_charset_arg *) arg;
2489 switch (range->type)
2491 case CHARTAB_RANGE_ALL:
2494 case CHARTAB_RANGE_DEFAULT:
2497 case CHARTAB_RANGE_CHARSET:
2500 case CHARTAB_RANGE_ROW:
2503 case CHARTAB_RANGE_CHAR:
2504 ret = get_char_table (range->ch, closure->ct);
2505 if (!UNBOUNDP (ret))
2506 return (closure->fn) (range, ret, closure->arg);
2517 /* Map FN (with client data ARG) over range RANGE in char table CT.
2518 Mapping stops the first time FN returns non-zero, and that value
2519 becomes the return value of map_char_table(). */
2522 map_char_table (Lisp_Char_Table *ct,
2523 struct chartab_range *range,
2524 int (*fn) (struct chartab_range *range,
2525 Lisp_Object val, void *arg),
2528 switch (range->type)
2530 case CHARTAB_RANGE_ALL:
2532 if (!UNBOUNDP (ct->default_value))
2534 struct chartab_range rainj;
2537 rainj.type = CHARTAB_RANGE_DEFAULT;
2538 retval = (fn) (&rainj, ct->default_value, arg);
2542 if (UINT8_BYTE_TABLE_P (ct->table))
2543 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table),
2545 else if (UINT16_BYTE_TABLE_P (ct->table))
2546 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table),
2548 else if (BYTE_TABLE_P (ct->table))
2549 return map_over_byte_table (XBYTE_TABLE(ct->table),
2551 else if (!UNBOUNDP (ct->table))
2554 struct chartab_range rainj;
2557 Emchar c1 = c + unit;
2560 rainj.type = CHARTAB_RANGE_CHAR;
2562 for (retval = 0; c < c1 && retval == 0; c++)
2565 retval = (fn) (&rainj, ct->table, arg);
2570 return (fn) (range, ct->table, arg);
2577 retval = map_over_charset_ascii (ct, fn, arg);
2581 retval = map_over_charset_control_1 (ct, fn, arg);
2586 Charset_ID start = MIN_LEADING_BYTE;
2587 Charset_ID stop = start + NUM_LEADING_BYTES;
2589 for (i = start, retval = 0; i < stop && retval == 0; i++)
2591 retval = map_over_other_charset (ct, i, fn, arg);
2600 case CHARTAB_RANGE_DEFAULT:
2601 if (!UNBOUNDP (ct->default_value))
2602 return (fn) (range, ct->default_value, arg);
2607 case CHARTAB_RANGE_CHARSET:
2610 Lisp_Object encoding_table
2611 = XCHARSET_ENCODING_TABLE (range->charset);
2613 if (!NILP (encoding_table))
2615 struct chartab_range rainj;
2616 struct map_char_table_for_charset_arg mcarg;
2621 rainj.type = CHARTAB_RANGE_ALL;
2622 return map_char_table (XCHAR_TABLE(encoding_table),
2624 &map_char_table_for_charset_fun,
2630 return map_over_other_charset (ct,
2631 XCHARSET_LEADING_BYTE (range->charset),
2635 case CHARTAB_RANGE_ROW:
2638 int cell_min, cell_max, i;
2640 struct chartab_range rainj;
2642 if (XCHARSET_DIMENSION (range->charset) < 2)
2643 signal_simple_error ("Charset in row vector must be multi-byte",
2647 switch (XCHARSET_CHARS (range->charset))
2650 cell_min = 33; cell_max = 126;
2653 cell_min = 32; cell_max = 127;
2656 cell_min = 0; cell_max = 127;
2659 cell_min = 0; cell_max = 255;
2665 if (XCHARSET_DIMENSION (range->charset) == 2)
2666 check_int_range (range->row, cell_min, cell_max);
2667 else if (XCHARSET_DIMENSION (range->charset) == 3)
2669 check_int_range (range->row >> 8 , cell_min, cell_max);
2670 check_int_range (range->row & 0xFF, cell_min, cell_max);
2672 else if (XCHARSET_DIMENSION (range->charset) == 4)
2674 check_int_range ( range->row >> 16 , cell_min, cell_max);
2675 check_int_range ((range->row >> 8) & 0xFF, cell_min, cell_max);
2676 check_int_range ( range->row & 0xFF, cell_min, cell_max);
2681 rainj.type = CHARTAB_RANGE_CHAR;
2682 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2684 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2686 if ( charset_code_point (range->charset, ch) >= 0 )
2689 = get_byte_table (get_byte_table
2693 (unsigned char)(ch >> 24)),
2694 (unsigned char) (ch >> 16)),
2695 (unsigned char) (ch >> 8)),
2696 (unsigned char) ch);
2699 val = ct->default_value;
2701 retval = (fn) (&rainj, val, arg);
2708 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
2709 - MIN_LEADING_BYTE];
2710 if (!CHAR_TABLE_ENTRYP (val))
2712 struct chartab_range rainj;
2714 rainj.type = CHARTAB_RANGE_ROW;
2715 rainj.charset = range->charset;
2716 rainj.row = range->row;
2717 return (fn) (&rainj, val, arg);
2720 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
2721 range->charset, range->row,
2724 #endif /* not UTF2000 */
2727 case CHARTAB_RANGE_CHAR:
2729 Emchar ch = range->ch;
2730 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
2732 if (!UNBOUNDP (val))
2734 struct chartab_range rainj;
2736 rainj.type = CHARTAB_RANGE_CHAR;
2738 return (fn) (&rainj, val, arg);
2750 struct slow_map_char_table_arg
2752 Lisp_Object function;
2757 slow_map_char_table_fun (struct chartab_range *range,
2758 Lisp_Object val, void *arg)
2760 Lisp_Object ranjarg = Qnil;
2761 struct slow_map_char_table_arg *closure =
2762 (struct slow_map_char_table_arg *) arg;
2764 switch (range->type)
2766 case CHARTAB_RANGE_ALL:
2771 case CHARTAB_RANGE_DEFAULT:
2777 case CHARTAB_RANGE_CHARSET:
2778 ranjarg = XCHARSET_NAME (range->charset);
2781 case CHARTAB_RANGE_ROW:
2782 ranjarg = vector2 (XCHARSET_NAME (range->charset),
2783 make_int (range->row));
2786 case CHARTAB_RANGE_CHAR:
2787 ranjarg = make_char (range->ch);
2793 closure->retval = call2 (closure->function, ranjarg, val);
2794 return !NILP (closure->retval);
2797 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
2798 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
2799 each key and value in the table.
2801 RANGE specifies a subrange to map over and is in the same format as
2802 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
2805 (function, char_table, range))
2807 Lisp_Char_Table *ct;
2808 struct slow_map_char_table_arg slarg;
2809 struct gcpro gcpro1, gcpro2;
2810 struct chartab_range rainj;
2812 CHECK_CHAR_TABLE (char_table);
2813 ct = XCHAR_TABLE (char_table);
2816 decode_char_table_range (range, &rainj);
2817 slarg.function = function;
2818 slarg.retval = Qnil;
2819 GCPRO2 (slarg.function, slarg.retval);
2820 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
2823 return slarg.retval;
2827 /************************************************************************/
2828 /* Character Attributes */
2829 /************************************************************************/
2833 Lisp_Object Vchar_attribute_hash_table;
2835 /* We store the char-attributes in hash tables with the names as the
2836 key and the actual char-id-table object as the value. Occasionally
2837 we need to use them in a list format. These routines provide us
2839 struct char_attribute_list_closure
2841 Lisp_Object *char_attribute_list;
2845 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
2846 void *char_attribute_list_closure)
2848 /* This function can GC */
2849 struct char_attribute_list_closure *calcl
2850 = (struct char_attribute_list_closure*) char_attribute_list_closure;
2851 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
2853 *char_attribute_list = Fcons (key, *char_attribute_list);
2857 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
2858 Return the list of all existing character attributes except coded-charsets.
2862 Lisp_Object char_attribute_list = Qnil;
2863 struct gcpro gcpro1;
2864 struct char_attribute_list_closure char_attribute_list_closure;
2866 GCPRO1 (char_attribute_list);
2867 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
2868 elisp_maphash (add_char_attribute_to_list_mapper,
2869 Vchar_attribute_hash_table,
2870 &char_attribute_list_closure);
2872 return char_attribute_list;
2875 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
2876 Return char-id-table corresponding to ATTRIBUTE.
2880 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
2884 /* We store the char-id-tables in hash tables with the attributes as
2885 the key and the actual char-id-table object as the value. Each
2886 char-id-table stores values of an attribute corresponding with
2887 characters. Occasionally we need to get attributes of a character
2888 in a association-list format. These routines provide us with
2890 struct char_attribute_alist_closure
2893 Lisp_Object *char_attribute_alist;
2897 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
2898 void *char_attribute_alist_closure)
2900 /* This function can GC */
2901 struct char_attribute_alist_closure *caacl =
2902 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
2904 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
2905 if (!UNBOUNDP (ret))
2907 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
2908 *char_attribute_alist
2909 = Fcons (Fcons (key, ret), *char_attribute_alist);
2914 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
2915 Return the alist of attributes of CHARACTER.
2919 Lisp_Object alist = Qnil;
2922 CHECK_CHAR (character);
2924 struct gcpro gcpro1;
2925 struct char_attribute_alist_closure char_attribute_alist_closure;
2928 char_attribute_alist_closure.char_id = XCHAR (character);
2929 char_attribute_alist_closure.char_attribute_alist = &alist;
2930 elisp_maphash (add_char_attribute_alist_mapper,
2931 Vchar_attribute_hash_table,
2932 &char_attribute_alist_closure);
2936 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
2938 Lisp_Object ccs = chlook->charset_by_leading_byte[i];
2942 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
2945 if ( CHAR_TABLEP (encoding_table)
2947 = get_char_id_table (XCHAR_TABLE(encoding_table),
2948 XCHAR (character))) )
2950 alist = Fcons (Fcons (ccs, cpos), alist);
2957 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
2958 Return the value of CHARACTER's ATTRIBUTE.
2959 Return DEFAULT-VALUE if the value is not exist.
2961 (character, attribute, default_value))
2965 CHECK_CHAR (character);
2966 if (!NILP (ccs = Ffind_charset (attribute)))
2968 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
2970 if (CHAR_TABLEP (encoding_table))
2971 return get_char_id_table (XCHAR_TABLE(encoding_table),
2976 Lisp_Object table = Fgethash (attribute,
2977 Vchar_attribute_hash_table,
2979 if (!UNBOUNDP (table))
2981 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
2983 if (!UNBOUNDP (ret))
2987 return default_value;
2990 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
2991 Store CHARACTER's ATTRIBUTE with VALUE.
2993 (character, attribute, value))
2997 ccs = Ffind_charset (attribute);
3000 CHECK_CHAR (character);
3001 return put_char_ccs_code_point (character, ccs, value);
3003 else if (EQ (attribute, Q_decomposition))
3007 CHECK_CHAR (character);
3009 signal_simple_error ("Invalid value for ->decomposition",
3012 if (CONSP (Fcdr (value)))
3014 Lisp_Object rest = value;
3015 Lisp_Object table = Vcharacter_composition_table;
3019 GET_EXTERNAL_LIST_LENGTH (rest, len);
3020 seq = make_vector (len, Qnil);
3022 while (CONSP (rest))
3024 Lisp_Object v = Fcar (rest);
3027 = to_char_id (v, "Invalid value for ->decomposition", value);
3030 XVECTOR_DATA(seq)[i++] = v;
3032 XVECTOR_DATA(seq)[i++] = make_char (c);
3036 put_char_id_table (XCHAR_TABLE(table),
3037 make_char (c), character);
3042 ntable = get_char_id_table (XCHAR_TABLE(table), c);
3043 if (!CHAR_TABLEP (ntable))
3045 ntable = make_char_id_table (Qnil);
3046 put_char_id_table (XCHAR_TABLE(table),
3047 make_char (c), ntable);
3055 Lisp_Object v = Fcar (value);
3059 Emchar c = XINT (v);
3061 = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3064 if (NILP (Fmemq (v, ret)))
3066 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3067 make_char (c), Fcons (character, ret));
3070 seq = make_vector (1, v);
3074 else if (EQ (attribute, Qto_ucs) || EQ (attribute, Q_ucs))
3079 CHECK_CHAR (character);
3081 signal_simple_error ("Invalid value for ->ucs", value);
3085 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table), c);
3086 if (NILP (Fmemq (character, ret)))
3088 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3089 make_char (c), Fcons (character, ret));
3092 if (EQ (attribute, Q_ucs))
3093 attribute = Qto_ucs;
3097 Lisp_Object table = Fgethash (attribute,
3098 Vchar_attribute_hash_table,
3103 table = make_char_id_table (Qunbound);
3104 Fputhash (attribute, table, Vchar_attribute_hash_table);
3106 put_char_id_table (XCHAR_TABLE(table), character, value);
3111 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3112 Remove CHARACTER's ATTRIBUTE.
3114 (character, attribute))
3118 CHECK_CHAR (character);
3119 ccs = Ffind_charset (attribute);
3122 return remove_char_ccs (character, ccs);
3126 Lisp_Object table = Fgethash (attribute,
3127 Vchar_attribute_hash_table,
3129 if (!UNBOUNDP (table))
3131 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3138 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3139 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3140 each key and value in the table.
3142 RANGE specifies a subrange to map over and is in the same format as
3143 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3146 (function, attribute, range))
3149 Lisp_Char_Table *ct;
3150 struct slow_map_char_table_arg slarg;
3151 struct gcpro gcpro1, gcpro2;
3152 struct chartab_range rainj;
3154 if (!NILP (ccs = Ffind_charset (attribute)))
3156 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3158 if (CHAR_TABLEP (encoding_table))
3159 ct = XCHAR_TABLE (encoding_table);
3165 Lisp_Object table = Fgethash (attribute,
3166 Vchar_attribute_hash_table,
3168 if (CHAR_TABLEP (table))
3169 ct = XCHAR_TABLE (table);
3175 decode_char_table_range (range, &rainj);
3176 slarg.function = function;
3177 slarg.retval = Qnil;
3178 GCPRO2 (slarg.function, slarg.retval);
3179 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3182 return slarg.retval;
3185 EXFUN (Fmake_char, 3);
3186 EXFUN (Fdecode_char, 2);
3188 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3189 Store character's ATTRIBUTES.
3193 Lisp_Object rest = attributes;
3194 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
3195 Lisp_Object character;
3199 while (CONSP (rest))
3201 Lisp_Object cell = Fcar (rest);
3205 signal_simple_error ("Invalid argument", attributes);
3206 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3207 && ((XCHARSET_FINAL (ccs) != 0) ||
3208 (XCHARSET_UCS_MAX (ccs) > 0)) )
3212 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3214 character = Fdecode_char (ccs, cell);
3215 if (!NILP (character))
3216 goto setup_attributes;
3220 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3221 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3225 signal_simple_error ("Invalid argument", attributes);
3227 character = make_char (XINT (code) + 0x100000);
3228 goto setup_attributes;
3232 else if (!INTP (code))
3233 signal_simple_error ("Invalid argument", attributes);
3235 character = make_char (XINT (code));
3239 while (CONSP (rest))
3241 Lisp_Object cell = Fcar (rest);
3244 signal_simple_error ("Invalid argument", attributes);
3246 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
3252 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
3253 Retrieve the character of the given ATTRIBUTES.
3257 Lisp_Object rest = attributes;
3260 while (CONSP (rest))
3262 Lisp_Object cell = Fcar (rest);
3266 signal_simple_error ("Invalid argument", attributes);
3267 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
3271 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3273 return Fdecode_char (ccs, cell);
3277 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3278 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3281 signal_simple_error ("Invalid argument", attributes);
3283 return make_char (XINT (code) + 0x100000);
3291 /************************************************************************/
3292 /* Char table read syntax */
3293 /************************************************************************/
3296 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
3297 Error_behavior errb)
3299 /* #### should deal with ERRB */
3300 symbol_to_char_table_type (value);
3305 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
3306 Error_behavior errb)
3310 /* #### should deal with ERRB */
3311 EXTERNAL_LIST_LOOP (rest, value)
3313 Lisp_Object range = XCAR (rest);
3314 struct chartab_range dummy;
3318 signal_simple_error ("Invalid list format", value);
3321 if (!CONSP (XCDR (range))
3322 || !NILP (XCDR (XCDR (range))))
3323 signal_simple_error ("Invalid range format", range);
3324 decode_char_table_range (XCAR (range), &dummy);
3325 decode_char_table_range (XCAR (XCDR (range)), &dummy);
3328 decode_char_table_range (range, &dummy);
3335 chartab_instantiate (Lisp_Object data)
3337 Lisp_Object chartab;
3338 Lisp_Object type = Qgeneric;
3339 Lisp_Object dataval = Qnil;
3341 while (!NILP (data))
3343 Lisp_Object keyw = Fcar (data);
3349 if (EQ (keyw, Qtype))
3351 else if (EQ (keyw, Qdata))
3355 chartab = Fmake_char_table (type);
3358 while (!NILP (data))
3360 Lisp_Object range = Fcar (data);
3361 Lisp_Object val = Fcar (Fcdr (data));
3363 data = Fcdr (Fcdr (data));
3366 if (CHAR_OR_CHAR_INTP (XCAR (range)))
3368 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
3369 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
3372 for (i = first; i <= last; i++)
3373 Fput_char_table (make_char (i), val, chartab);
3379 Fput_char_table (range, val, chartab);
3388 /************************************************************************/
3389 /* Category Tables, specifically */
3390 /************************************************************************/
3392 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
3393 Return t if OBJECT is a category table.
3394 A category table is a type of char table used for keeping track of
3395 categories. Categories are used for classifying characters for use
3396 in regexps -- you can refer to a category rather than having to use
3397 a complicated [] expression (and category lookups are significantly
3400 There are 95 different categories available, one for each printable
3401 character (including space) in the ASCII charset. Each category
3402 is designated by one such character, called a "category designator".
3403 They are specified in a regexp using the syntax "\\cX", where X is
3404 a category designator.
3406 A category table specifies, for each character, the categories that
3407 the character is in. Note that a character can be in more than one
3408 category. More specifically, a category table maps from a character
3409 to either the value nil (meaning the character is in no categories)
3410 or a 95-element bit vector, specifying for each of the 95 categories
3411 whether the character is in that category.
3413 Special Lisp functions are provided that abstract this, so you do not
3414 have to directly manipulate bit vectors.
3418 return (CHAR_TABLEP (object) &&
3419 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
3424 check_category_table (Lisp_Object object, Lisp_Object default_)
3428 while (NILP (Fcategory_table_p (object)))
3429 object = wrong_type_argument (Qcategory_table_p, object);
3434 check_category_char (Emchar ch, Lisp_Object table,
3435 unsigned int designator, unsigned int not)
3437 REGISTER Lisp_Object temp;
3438 Lisp_Char_Table *ctbl;
3439 #ifdef ERROR_CHECK_TYPECHECK
3440 if (NILP (Fcategory_table_p (table)))
3441 signal_simple_error ("Expected category table", table);
3443 ctbl = XCHAR_TABLE (table);
3444 temp = get_char_table (ch, ctbl);
3449 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not : not;
3452 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
3453 Return t if category of the character at POSITION includes DESIGNATOR.
3454 Optional third arg BUFFER specifies which buffer to use, and defaults
3455 to the current buffer.
3456 Optional fourth arg CATEGORY-TABLE specifies the category table to
3457 use, and defaults to BUFFER's category table.
3459 (position, designator, buffer, category_table))
3464 struct buffer *buf = decode_buffer (buffer, 0);
3466 CHECK_INT (position);
3467 CHECK_CATEGORY_DESIGNATOR (designator);
3468 des = XCHAR (designator);
3469 ctbl = check_category_table (category_table, Vstandard_category_table);
3470 ch = BUF_FETCH_CHAR (buf, XINT (position));
3471 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3474 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
3475 Return t if category of CHARACTER includes DESIGNATOR, else nil.
3476 Optional third arg CATEGORY-TABLE specifies the category table to use,
3477 and defaults to the standard category table.
3479 (character, designator, category_table))
3485 CHECK_CATEGORY_DESIGNATOR (designator);
3486 des = XCHAR (designator);
3487 CHECK_CHAR (character);
3488 ch = XCHAR (character);
3489 ctbl = check_category_table (category_table, Vstandard_category_table);
3490 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3493 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
3494 Return BUFFER's current category table.
3495 BUFFER defaults to the current buffer.
3499 return decode_buffer (buffer, 0)->category_table;
3502 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
3503 Return the standard category table.
3504 This is the one used for new buffers.
3508 return Vstandard_category_table;
3511 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
3512 Return a new category table which is a copy of CATEGORY-TABLE.
3513 CATEGORY-TABLE defaults to the standard category table.
3517 if (NILP (Vstandard_category_table))
3518 return Fmake_char_table (Qcategory);
3521 check_category_table (category_table, Vstandard_category_table);
3522 return Fcopy_char_table (category_table);
3525 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
3526 Select CATEGORY-TABLE as the new category table for BUFFER.
3527 BUFFER defaults to the current buffer if omitted.
3529 (category_table, buffer))
3531 struct buffer *buf = decode_buffer (buffer, 0);
3532 category_table = check_category_table (category_table, Qnil);
3533 buf->category_table = category_table;
3534 /* Indicate that this buffer now has a specified category table. */
3535 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
3536 return category_table;
3539 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
3540 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
3544 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
3547 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
3548 Return t if OBJECT is a category table value.
3549 Valid values are nil or a bit vector of size 95.
3553 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
3557 #define CATEGORYP(x) \
3558 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
3560 #define CATEGORY_SET(c) \
3561 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
3563 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
3564 The faster version of `!NILP (Faref (category_set, category))'. */
3565 #define CATEGORY_MEMBER(category, category_set) \
3566 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
3568 /* Return 1 if there is a word boundary between two word-constituent
3569 characters C1 and C2 if they appear in this order, else return 0.
3570 Use the macro WORD_BOUNDARY_P instead of calling this function
3573 int word_boundary_p (Emchar c1, Emchar c2);
3575 word_boundary_p (Emchar c1, Emchar c2)
3577 Lisp_Object category_set1, category_set2;
3582 if (COMPOSITE_CHAR_P (c1))
3583 c1 = cmpchar_component (c1, 0, 1);
3584 if (COMPOSITE_CHAR_P (c2))
3585 c2 = cmpchar_component (c2, 0, 1);
3588 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
3590 tail = Vword_separating_categories;
3595 tail = Vword_combining_categories;
3599 category_set1 = CATEGORY_SET (c1);
3600 if (NILP (category_set1))
3601 return default_result;
3602 category_set2 = CATEGORY_SET (c2);
3603 if (NILP (category_set2))
3604 return default_result;
3606 for (; CONSP (tail); tail = XCONS (tail)->cdr)
3608 Lisp_Object elt = XCONS(tail)->car;
3611 && CATEGORYP (XCONS (elt)->car)
3612 && CATEGORYP (XCONS (elt)->cdr)
3613 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
3614 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
3615 return !default_result;
3617 return default_result;
3623 syms_of_chartab (void)
3626 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
3627 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
3628 INIT_LRECORD_IMPLEMENTATION (byte_table);
3630 defsymbol (&Qto_ucs, "=>ucs");
3631 defsymbol (&Q_ucs, "->ucs");
3632 defsymbol (&Q_decomposition, "->decomposition");
3633 defsymbol (&Qcompat, "compat");
3634 defsymbol (&Qisolated, "isolated");
3635 defsymbol (&Qinitial, "initial");
3636 defsymbol (&Qmedial, "medial");
3637 defsymbol (&Qfinal, "final");
3638 defsymbol (&Qvertical, "vertical");
3639 defsymbol (&QnoBreak, "noBreak");
3640 defsymbol (&Qfraction, "fraction");
3641 defsymbol (&Qsuper, "super");
3642 defsymbol (&Qsub, "sub");
3643 defsymbol (&Qcircle, "circle");
3644 defsymbol (&Qsquare, "square");
3645 defsymbol (&Qwide, "wide");
3646 defsymbol (&Qnarrow, "narrow");
3647 defsymbol (&Qsmall, "small");
3648 defsymbol (&Qfont, "font");
3650 DEFSUBR (Fchar_attribute_list);
3651 DEFSUBR (Ffind_char_attribute_table);
3652 DEFSUBR (Fchar_attribute_alist);
3653 DEFSUBR (Fget_char_attribute);
3654 DEFSUBR (Fput_char_attribute);
3655 DEFSUBR (Fremove_char_attribute);
3656 DEFSUBR (Fmap_char_attribute);
3657 DEFSUBR (Fdefine_char);
3658 DEFSUBR (Ffind_char);
3659 DEFSUBR (Fchar_variants);
3661 DEFSUBR (Fget_composite_char);
3664 INIT_LRECORD_IMPLEMENTATION (char_table);
3668 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
3671 defsymbol (&Qcategory_table_p, "category-table-p");
3672 defsymbol (&Qcategory_designator_p, "category-designator-p");
3673 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
3676 defsymbol (&Qchar_table, "char-table");
3677 defsymbol (&Qchar_tablep, "char-table-p");
3679 DEFSUBR (Fchar_table_p);
3680 DEFSUBR (Fchar_table_type_list);
3681 DEFSUBR (Fvalid_char_table_type_p);
3682 DEFSUBR (Fchar_table_type);
3683 DEFSUBR (Freset_char_table);
3684 DEFSUBR (Fmake_char_table);
3685 DEFSUBR (Fcopy_char_table);
3686 DEFSUBR (Fget_char_table);
3687 DEFSUBR (Fget_range_char_table);
3688 DEFSUBR (Fvalid_char_table_value_p);
3689 DEFSUBR (Fcheck_valid_char_table_value);
3690 DEFSUBR (Fput_char_table);
3691 DEFSUBR (Fmap_char_table);
3694 DEFSUBR (Fcategory_table_p);
3695 DEFSUBR (Fcategory_table);
3696 DEFSUBR (Fstandard_category_table);
3697 DEFSUBR (Fcopy_category_table);
3698 DEFSUBR (Fset_category_table);
3699 DEFSUBR (Fcheck_category_at);
3700 DEFSUBR (Fchar_in_category_p);
3701 DEFSUBR (Fcategory_designator_p);
3702 DEFSUBR (Fcategory_table_value_p);
3708 vars_of_chartab (void)
3711 Vutf_2000_version = build_string("0.18 (Yamato-Koizumi)");
3712 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
3713 Version number of XEmacs UTF-2000.
3716 staticpro (&Vcharacter_composition_table);
3717 Vcharacter_composition_table = make_char_id_table (Qnil);
3719 staticpro (&Vcharacter_variant_table);
3720 Vcharacter_variant_table = make_char_id_table (Qnil);
3722 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
3723 Vall_syntax_tables = Qnil;
3724 dump_add_weak_object_chain (&Vall_syntax_tables);
3728 structure_type_create_chartab (void)
3730 struct structure_type *st;
3732 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
3734 define_structure_type_keyword (st, Qtype, chartab_type_validate);
3735 define_structure_type_keyword (st, Qdata, chartab_data_validate);
3739 complex_vars_of_chartab (void)
3742 staticpro (&Vchar_attribute_hash_table);
3743 Vchar_attribute_hash_table
3744 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3745 #endif /* UTF2000 */
3747 /* Set this now, so first buffer creation can refer to it. */
3748 /* Make it nil before calling copy-category-table
3749 so that copy-category-table will know not to try to copy from garbage */
3750 Vstandard_category_table = Qnil;
3751 Vstandard_category_table = Fcopy_category_table (Qnil);
3752 staticpro (&Vstandard_category_table);
3754 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
3755 List of pair (cons) of categories to determine word boundary.
3757 Emacs treats a sequence of word constituent characters as a single
3758 word (i.e. finds no word boundary between them) iff they belongs to
3759 the same charset. But, exceptions are allowed in the following cases.
3761 \(1) The case that characters are in different charsets is controlled
3762 by the variable `word-combining-categories'.
3764 Emacs finds no word boundary between characters of different charsets
3765 if they have categories matching some element of this list.
3767 More precisely, if an element of this list is a cons of category CAT1
3768 and CAT2, and a multibyte character C1 which has CAT1 is followed by
3769 C2 which has CAT2, there's no word boundary between C1 and C2.
3771 For instance, to tell that ASCII characters and Latin-1 characters can
3772 form a single word, the element `(?l . ?l)' should be in this list
3773 because both characters have the category `l' (Latin characters).
3775 \(2) The case that character are in the same charset is controlled by
3776 the variable `word-separating-categories'.
3778 Emacs find a word boundary between characters of the same charset
3779 if they have categories matching some element of this list.
3781 More precisely, if an element of this list is a cons of category CAT1
3782 and CAT2, and a multibyte character C1 which has CAT1 is followed by
3783 C2 which has CAT2, there's a word boundary between C1 and C2.
3785 For instance, to tell that there's a word boundary between Japanese
3786 Hiragana and Japanese Kanji (both are in the same charset), the
3787 element `(?H . ?C) should be in this list.
3790 Vword_combining_categories = Qnil;
3792 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
3793 List of pair (cons) of categories to determine word boundary.
3794 See the documentation of the variable `word-combining-categories'.
3797 Vword_separating_categories = Qnil;