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,2002 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;
70 #define BT_UINT8_MIN 0
71 #define BT_UINT8_MAX (UCHAR_MAX - 4)
72 #define BT_UINT8_t (UCHAR_MAX - 3)
73 #define BT_UINT8_nil (UCHAR_MAX - 2)
74 #define BT_UINT8_unbound (UCHAR_MAX - 1)
75 #define BT_UINT8_unloaded UCHAR_MAX
77 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
78 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
79 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
80 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
81 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
84 INT_UINT8_P (Lisp_Object obj)
90 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
97 UINT8_VALUE_P (Lisp_Object obj)
99 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
100 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
103 INLINE_HEADER unsigned char
104 UINT8_ENCODE (Lisp_Object obj)
106 if (EQ (obj, Qunloaded))
107 return BT_UINT8_unloaded;
108 else 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_unloaded)
123 else if (n == BT_UINT8_unbound)
125 else if (n == BT_UINT8_nil)
127 else if (n == BT_UINT8_t)
134 mark_uint8_byte_table (Lisp_Object obj)
140 print_uint8_byte_table (Lisp_Object obj,
141 Lisp_Object printcharfun, int escapeflag)
143 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
145 struct gcpro gcpro1, gcpro2;
146 GCPRO2 (obj, printcharfun);
148 write_c_string ("\n#<uint8-byte-table", printcharfun);
149 for (i = 0; i < 256; i++)
151 unsigned char n = bte->property[i];
153 write_c_string ("\n ", printcharfun);
154 write_c_string (" ", printcharfun);
155 if (n == BT_UINT8_unbound)
156 write_c_string ("void", printcharfun);
157 else if (n == BT_UINT8_nil)
158 write_c_string ("nil", printcharfun);
159 else if (n == BT_UINT8_t)
160 write_c_string ("t", printcharfun);
165 sprintf (buf, "%hd", n);
166 write_c_string (buf, printcharfun);
170 write_c_string (">", printcharfun);
174 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
176 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
177 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
180 for (i = 0; i < 256; i++)
181 if (te1->property[i] != te2->property[i])
187 uint8_byte_table_hash (Lisp_Object obj, int depth)
189 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
193 for (i = 0; i < 256; i++)
194 hash = HASH2 (hash, te->property[i]);
198 static const struct lrecord_description uint8_byte_table_description[] = {
202 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
203 mark_uint8_byte_table,
204 print_uint8_byte_table,
205 0, uint8_byte_table_equal,
206 uint8_byte_table_hash,
207 uint8_byte_table_description,
208 Lisp_Uint8_Byte_Table);
211 make_uint8_byte_table (unsigned char initval)
215 Lisp_Uint8_Byte_Table *cte;
217 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
218 &lrecord_uint8_byte_table);
220 for (i = 0; i < 256; i++)
221 cte->property[i] = initval;
223 XSETUINT8_BYTE_TABLE (obj, cte);
228 copy_uint8_byte_table (Lisp_Object entry)
230 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
233 Lisp_Uint8_Byte_Table *ctenew
234 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
235 &lrecord_uint8_byte_table);
237 for (i = 0; i < 256; i++)
239 ctenew->property[i] = cte->property[i];
242 XSETUINT8_BYTE_TABLE (obj, ctenew);
247 uint8_byte_table_same_value_p (Lisp_Object obj)
249 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
250 unsigned char v0 = bte->property[0];
253 for (i = 1; i < 256; i++)
255 if (bte->property[i] != v0)
262 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
263 Emchar ofs, int place,
264 int (*fn) (struct chartab_range *range,
265 Lisp_Object val, void *arg),
268 struct chartab_range rainj;
270 int unit = 1 << (8 * place);
274 rainj.type = CHARTAB_RANGE_CHAR;
276 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
278 if (ct->property[i] == BT_UINT8_unloaded)
282 for (; c < c1 && retval == 0; c++)
284 Lisp_Object ret = get_char_id_table (root, c);
289 retval = (fn) (&rainj, ret, arg);
293 ct->property[i] = BT_UINT8_unbound;
297 else if (ct->property[i] != BT_UINT8_unbound)
300 for (; c < c1 && retval == 0; c++)
303 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
314 save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
316 Emchar ofs, int place)
318 struct chartab_range rainj;
320 int unit = 1 << (8 * place);
324 rainj.type = CHARTAB_RANGE_CHAR;
326 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
328 if (ct->property[i] == BT_UINT8_unloaded)
332 else if (ct->property[i] != BT_UINT8_unbound)
335 for (; c < c1 && retval == 0; c++)
337 Fput_database (Fprin1_to_string (make_char (c), Qnil),
338 Fprin1_to_string (UINT8_DECODE (ct->property[i]),
341 put_char_id_table (root, make_char (c), Qunloaded);
350 #define BT_UINT16_MIN 0
351 #define BT_UINT16_MAX (USHRT_MAX - 4)
352 #define BT_UINT16_t (USHRT_MAX - 3)
353 #define BT_UINT16_nil (USHRT_MAX - 2)
354 #define BT_UINT16_unbound (USHRT_MAX - 1)
355 #define BT_UINT16_unloaded USHRT_MAX
357 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
358 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
359 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
360 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
363 INT_UINT16_P (Lisp_Object obj)
367 int num = XINT (obj);
369 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
376 UINT16_VALUE_P (Lisp_Object obj)
378 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
379 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
382 INLINE_HEADER unsigned short
383 UINT16_ENCODE (Lisp_Object obj)
385 if (EQ (obj, Qunloaded))
386 return BT_UINT16_unloaded;
387 else if (EQ (obj, Qunbound))
388 return BT_UINT16_unbound;
389 else if (EQ (obj, Qnil))
390 return BT_UINT16_nil;
391 else if (EQ (obj, Qt))
397 INLINE_HEADER Lisp_Object
398 UINT16_DECODE (unsigned short n)
400 if (n == BT_UINT16_unloaded)
402 else if (n == BT_UINT16_unbound)
404 else if (n == BT_UINT16_nil)
406 else if (n == BT_UINT16_t)
412 INLINE_HEADER unsigned short
413 UINT8_TO_UINT16 (unsigned char n)
415 if (n == BT_UINT8_unloaded)
416 return BT_UINT16_unloaded;
417 else if (n == BT_UINT8_unbound)
418 return BT_UINT16_unbound;
419 else if (n == BT_UINT8_nil)
420 return BT_UINT16_nil;
421 else if (n == BT_UINT8_t)
428 mark_uint16_byte_table (Lisp_Object obj)
434 print_uint16_byte_table (Lisp_Object obj,
435 Lisp_Object printcharfun, int escapeflag)
437 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
439 struct gcpro gcpro1, gcpro2;
440 GCPRO2 (obj, printcharfun);
442 write_c_string ("\n#<uint16-byte-table", printcharfun);
443 for (i = 0; i < 256; i++)
445 unsigned short n = bte->property[i];
447 write_c_string ("\n ", printcharfun);
448 write_c_string (" ", printcharfun);
449 if (n == BT_UINT16_unbound)
450 write_c_string ("void", printcharfun);
451 else if (n == BT_UINT16_nil)
452 write_c_string ("nil", printcharfun);
453 else if (n == BT_UINT16_t)
454 write_c_string ("t", printcharfun);
459 sprintf (buf, "%hd", n);
460 write_c_string (buf, printcharfun);
464 write_c_string (">", printcharfun);
468 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
470 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
471 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
474 for (i = 0; i < 256; i++)
475 if (te1->property[i] != te2->property[i])
481 uint16_byte_table_hash (Lisp_Object obj, int depth)
483 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
487 for (i = 0; i < 256; i++)
488 hash = HASH2 (hash, te->property[i]);
492 static const struct lrecord_description uint16_byte_table_description[] = {
496 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
497 mark_uint16_byte_table,
498 print_uint16_byte_table,
499 0, uint16_byte_table_equal,
500 uint16_byte_table_hash,
501 uint16_byte_table_description,
502 Lisp_Uint16_Byte_Table);
505 make_uint16_byte_table (unsigned short initval)
509 Lisp_Uint16_Byte_Table *cte;
511 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
512 &lrecord_uint16_byte_table);
514 for (i = 0; i < 256; i++)
515 cte->property[i] = initval;
517 XSETUINT16_BYTE_TABLE (obj, cte);
522 copy_uint16_byte_table (Lisp_Object entry)
524 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
527 Lisp_Uint16_Byte_Table *ctenew
528 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
529 &lrecord_uint16_byte_table);
531 for (i = 0; i < 256; i++)
533 ctenew->property[i] = cte->property[i];
536 XSETUINT16_BYTE_TABLE (obj, ctenew);
541 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
545 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
546 Lisp_Uint16_Byte_Table* cte;
548 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
549 &lrecord_uint16_byte_table);
550 for (i = 0; i < 256; i++)
552 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
554 XSETUINT16_BYTE_TABLE (obj, cte);
559 uint16_byte_table_same_value_p (Lisp_Object obj)
561 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
562 unsigned short v0 = bte->property[0];
565 for (i = 1; i < 256; i++)
567 if (bte->property[i] != v0)
574 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
575 Emchar ofs, int place,
576 int (*fn) (struct chartab_range *range,
577 Lisp_Object val, void *arg),
580 struct chartab_range rainj;
582 int unit = 1 << (8 * place);
586 rainj.type = CHARTAB_RANGE_CHAR;
588 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
590 if (ct->property[i] == BT_UINT16_unloaded)
594 for (; c < c1 && retval == 0; c++)
596 Lisp_Object ret = get_char_id_table (root, c);
601 retval = (fn) (&rainj, ret, arg);
605 ct->property[i] = BT_UINT16_unbound;
609 else if (ct->property[i] != BT_UINT16_unbound)
612 for (; c < c1 && retval == 0; c++)
615 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
626 save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
628 Emchar ofs, int place)
630 struct chartab_range rainj;
632 int unit = 1 << (8 * place);
636 rainj.type = CHARTAB_RANGE_CHAR;
638 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
640 if (ct->property[i] == BT_UINT16_unloaded)
644 else if (ct->property[i] != BT_UINT16_unbound)
647 for (; c < c1 && retval == 0; c++)
649 Fput_database (Fprin1_to_string (make_char (c), Qnil),
650 Fprin1_to_string (UINT16_DECODE (ct->property[i]),
653 put_char_id_table (root, make_char (c), Qunloaded);
664 mark_byte_table (Lisp_Object obj)
666 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
669 for (i = 0; i < 256; i++)
671 mark_object (cte->property[i]);
677 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
679 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
681 struct gcpro gcpro1, gcpro2;
682 GCPRO2 (obj, printcharfun);
684 write_c_string ("\n#<byte-table", printcharfun);
685 for (i = 0; i < 256; i++)
687 Lisp_Object elt = bte->property[i];
689 write_c_string ("\n ", printcharfun);
690 write_c_string (" ", printcharfun);
691 if (EQ (elt, Qunbound))
692 write_c_string ("void", printcharfun);
694 print_internal (elt, printcharfun, escapeflag);
697 write_c_string (">", printcharfun);
701 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
703 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
704 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
707 for (i = 0; i < 256; i++)
708 if (BYTE_TABLE_P (cte1->property[i]))
710 if (BYTE_TABLE_P (cte2->property[i]))
712 if (!byte_table_equal (cte1->property[i],
713 cte2->property[i], depth + 1))
720 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
726 byte_table_hash (Lisp_Object obj, int depth)
728 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
730 return internal_array_hash (cte->property, 256, depth);
733 static const struct lrecord_description byte_table_description[] = {
734 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
738 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
743 byte_table_description,
747 make_byte_table (Lisp_Object initval)
751 Lisp_Byte_Table *cte;
753 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
755 for (i = 0; i < 256; i++)
756 cte->property[i] = initval;
758 XSETBYTE_TABLE (obj, cte);
763 copy_byte_table (Lisp_Object entry)
765 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
768 Lisp_Byte_Table *ctnew
769 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
771 for (i = 0; i < 256; i++)
773 if (UINT8_BYTE_TABLE_P (cte->property[i]))
775 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
777 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
779 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
781 else if (BYTE_TABLE_P (cte->property[i]))
783 ctnew->property[i] = copy_byte_table (cte->property[i]);
786 ctnew->property[i] = cte->property[i];
789 XSETBYTE_TABLE (obj, ctnew);
794 byte_table_same_value_p (Lisp_Object obj)
796 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
797 Lisp_Object v0 = bte->property[0];
800 for (i = 1; i < 256; i++)
802 if (!internal_equal (bte->property[i], v0, 0))
809 map_over_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
810 Emchar ofs, int place,
811 int (*fn) (struct chartab_range *range,
812 Lisp_Object val, void *arg),
817 int unit = 1 << (8 * place);
820 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
823 if (UINT8_BYTE_TABLE_P (v))
826 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
827 c, place - 1, fn, arg);
830 else if (UINT16_BYTE_TABLE_P (v))
833 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
834 c, place - 1, fn, arg);
837 else if (BYTE_TABLE_P (v))
839 retval = map_over_byte_table (XBYTE_TABLE(v), root,
840 c, place - 1, fn, arg);
843 else if (EQ (v, Qunloaded))
846 struct chartab_range rainj;
847 Emchar c1 = c + unit;
849 rainj.type = CHARTAB_RANGE_CHAR;
851 for (; c < c1 && retval == 0; c++)
853 Lisp_Object ret = get_char_id_table (root, c);
858 retval = (fn) (&rainj, ret, arg);
862 ct->property[i] = Qunbound;
866 else if (!UNBOUNDP (v))
868 struct chartab_range rainj;
869 Emchar c1 = c + unit;
871 rainj.type = CHARTAB_RANGE_CHAR;
873 for (; c < c1 && retval == 0; c++)
876 retval = (fn) (&rainj, v, arg);
887 save_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
889 Emchar ofs, int place)
893 int unit = 1 << (8 * place);
896 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
899 if (UINT8_BYTE_TABLE_P (v))
901 save_uint8_byte_table (XUINT8_BYTE_TABLE(v), root, db,
905 else if (UINT16_BYTE_TABLE_P (v))
907 save_uint16_byte_table (XUINT16_BYTE_TABLE(v), root, db,
911 else if (BYTE_TABLE_P (v))
913 save_byte_table (XBYTE_TABLE(v), root, db,
917 else if (EQ (v, Qunloaded))
921 else if (!UNBOUNDP (v))
923 struct chartab_range rainj;
924 Emchar c1 = c + unit;
926 rainj.type = CHARTAB_RANGE_CHAR;
928 for (; c < c1 && retval == 0; c++)
930 Fput_database (Fprin1_to_string (make_char (c), Qnil),
931 Fprin1_to_string (v, Qnil),
933 put_char_id_table (root, make_char (c), Qunloaded);
943 get_byte_table (Lisp_Object table, unsigned char idx)
945 if (UINT8_BYTE_TABLE_P (table))
946 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
947 else if (UINT16_BYTE_TABLE_P (table))
948 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
949 else if (BYTE_TABLE_P (table))
950 return XBYTE_TABLE(table)->property[idx];
956 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
958 if (UINT8_BYTE_TABLE_P (table))
960 if (UINT8_VALUE_P (value))
962 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
963 if (!UINT8_BYTE_TABLE_P (value) &&
964 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
965 && uint8_byte_table_same_value_p (table))
970 else if (UINT16_VALUE_P (value))
972 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
974 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
979 Lisp_Object new = make_byte_table (Qnil);
982 for (i = 0; i < 256; i++)
984 XBYTE_TABLE(new)->property[i]
985 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
987 XBYTE_TABLE(new)->property[idx] = value;
991 else if (UINT16_BYTE_TABLE_P (table))
993 if (UINT16_VALUE_P (value))
995 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
996 if (!UINT8_BYTE_TABLE_P (value) &&
997 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
998 && uint16_byte_table_same_value_p (table))
1005 Lisp_Object new = make_byte_table (Qnil);
1008 for (i = 0; i < 256; i++)
1010 XBYTE_TABLE(new)->property[i]
1011 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
1013 XBYTE_TABLE(new)->property[idx] = value;
1017 else if (BYTE_TABLE_P (table))
1019 XBYTE_TABLE(table)->property[idx] = value;
1020 if (!UINT8_BYTE_TABLE_P (value) &&
1021 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1022 && byte_table_same_value_p (table))
1027 else if (!internal_equal (table, value, 0))
1029 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
1031 table = make_uint8_byte_table (UINT8_ENCODE (table));
1032 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1034 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
1036 table = make_uint16_byte_table (UINT16_ENCODE (table));
1037 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1041 table = make_byte_table (table);
1042 XBYTE_TABLE(table)->property[idx] = value;
1050 make_char_id_table (Lisp_Object initval)
1053 obj = Fmake_char_table (Qgeneric);
1054 fill_char_table (XCHAR_TABLE (obj), initval);
1059 Lisp_Object Vcharacter_composition_table;
1060 Lisp_Object Vcharacter_variant_table;
1063 Lisp_Object Qsystem_char_id;
1065 Lisp_Object Q_decomposition;
1066 Lisp_Object Qto_ucs;
1068 Lisp_Object Q_ucs_variants;
1069 Lisp_Object Qcompat;
1070 Lisp_Object Qisolated;
1071 Lisp_Object Qinitial;
1072 Lisp_Object Qmedial;
1074 Lisp_Object Qvertical;
1075 Lisp_Object QnoBreak;
1076 Lisp_Object Qfraction;
1079 Lisp_Object Qcircle;
1080 Lisp_Object Qsquare;
1082 Lisp_Object Qnarrow;
1086 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
1089 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
1095 else if (EQ (v, Qcompat))
1097 else if (EQ (v, Qisolated))
1099 else if (EQ (v, Qinitial))
1101 else if (EQ (v, Qmedial))
1103 else if (EQ (v, Qfinal))
1105 else if (EQ (v, Qvertical))
1107 else if (EQ (v, QnoBreak))
1109 else if (EQ (v, Qfraction))
1111 else if (EQ (v, Qsuper))
1113 else if (EQ (v, Qsub))
1115 else if (EQ (v, Qcircle))
1117 else if (EQ (v, Qsquare))
1119 else if (EQ (v, Qwide))
1121 else if (EQ (v, Qnarrow))
1123 else if (EQ (v, Qsmall))
1125 else if (EQ (v, Qfont))
1128 signal_simple_error (err_msg, err_arg);
1131 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
1132 Return character corresponding with list.
1136 Lisp_Object table = Vcharacter_composition_table;
1137 Lisp_Object rest = list;
1139 while (CONSP (rest))
1141 Lisp_Object v = Fcar (rest);
1143 Emchar c = to_char_id (v, "Invalid value for composition", list);
1145 ret = get_char_id_table (XCHAR_TABLE(table), c);
1150 if (!CHAR_TABLEP (ret))
1155 else if (!CONSP (rest))
1157 else if (CHAR_TABLEP (ret))
1160 signal_simple_error ("Invalid table is found with", list);
1162 signal_simple_error ("Invalid value for composition", list);
1165 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
1166 Return variants of CHARACTER.
1172 CHECK_CHAR (character);
1173 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
1176 return Fcopy_list (ret);
1184 /* A char table maps from ranges of characters to values.
1186 Implementing a general data structure that maps from arbitrary
1187 ranges of numbers to values is tricky to do efficiently. As it
1188 happens, it should suffice (and is usually more convenient, anyway)
1189 when dealing with characters to restrict the sorts of ranges that
1190 can be assigned values, as follows:
1193 2) All characters in a charset.
1194 3) All characters in a particular row of a charset, where a "row"
1195 means all characters with the same first byte.
1196 4) A particular character in a charset.
1198 We use char tables to generalize the 256-element vectors now
1199 littering the Emacs code.
1201 Possible uses (all should be converted at some point):
1207 5) keyboard-translate-table?
1210 abstract type to generalize the Emacs vectors and Mule
1211 vectors-of-vectors goo.
1214 /************************************************************************/
1215 /* Char Table object */
1216 /************************************************************************/
1218 #if defined(MULE)&&!defined(UTF2000)
1221 mark_char_table_entry (Lisp_Object obj)
1223 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1226 for (i = 0; i < 96; i++)
1228 mark_object (cte->level2[i]);
1234 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1236 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1237 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1240 for (i = 0; i < 96; i++)
1241 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1247 static unsigned long
1248 char_table_entry_hash (Lisp_Object obj, int depth)
1250 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1252 return internal_array_hash (cte->level2, 96, depth);
1255 static const struct lrecord_description char_table_entry_description[] = {
1256 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1260 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1261 mark_char_table_entry, internal_object_printer,
1262 0, char_table_entry_equal,
1263 char_table_entry_hash,
1264 char_table_entry_description,
1265 Lisp_Char_Table_Entry);
1269 mark_char_table (Lisp_Object obj)
1271 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1274 mark_object (ct->table);
1275 mark_object (ct->name);
1279 for (i = 0; i < NUM_ASCII_CHARS; i++)
1280 mark_object (ct->ascii[i]);
1282 for (i = 0; i < NUM_LEADING_BYTES; i++)
1283 mark_object (ct->level1[i]);
1287 return ct->default_value;
1289 return ct->mirror_table;
1293 /* WARNING: All functions of this nature need to be written extremely
1294 carefully to avoid crashes during GC. Cf. prune_specifiers()
1295 and prune_weak_hash_tables(). */
1298 prune_syntax_tables (void)
1300 Lisp_Object rest, prev = Qnil;
1302 for (rest = Vall_syntax_tables;
1304 rest = XCHAR_TABLE (rest)->next_table)
1306 if (! marked_p (rest))
1308 /* This table is garbage. Remove it from the list. */
1310 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1312 XCHAR_TABLE (prev)->next_table =
1313 XCHAR_TABLE (rest)->next_table;
1319 char_table_type_to_symbol (enum char_table_type type)
1324 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1325 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1326 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1327 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1329 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1334 static enum char_table_type
1335 symbol_to_char_table_type (Lisp_Object symbol)
1337 CHECK_SYMBOL (symbol);
1339 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1340 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1341 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1342 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1344 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1347 signal_simple_error ("Unrecognized char table type", symbol);
1348 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1352 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1353 Lisp_Object printcharfun)
1357 write_c_string (" (", printcharfun);
1358 print_internal (make_char (first), printcharfun, 0);
1359 write_c_string (" ", printcharfun);
1360 print_internal (make_char (last), printcharfun, 0);
1361 write_c_string (") ", printcharfun);
1365 write_c_string (" ", printcharfun);
1366 print_internal (make_char (first), printcharfun, 0);
1367 write_c_string (" ", printcharfun);
1369 print_internal (val, printcharfun, 1);
1372 #if defined(MULE)&&!defined(UTF2000)
1375 print_chartab_charset_row (Lisp_Object charset,
1377 Lisp_Char_Table_Entry *cte,
1378 Lisp_Object printcharfun)
1381 Lisp_Object cat = Qunbound;
1384 for (i = 32; i < 128; i++)
1386 Lisp_Object pam = cte->level2[i - 32];
1398 print_chartab_range (MAKE_CHAR (charset, first, 0),
1399 MAKE_CHAR (charset, i - 1, 0),
1402 print_chartab_range (MAKE_CHAR (charset, row, first),
1403 MAKE_CHAR (charset, row, i - 1),
1413 print_chartab_range (MAKE_CHAR (charset, first, 0),
1414 MAKE_CHAR (charset, i - 1, 0),
1417 print_chartab_range (MAKE_CHAR (charset, row, first),
1418 MAKE_CHAR (charset, row, i - 1),
1424 print_chartab_two_byte_charset (Lisp_Object charset,
1425 Lisp_Char_Table_Entry *cte,
1426 Lisp_Object printcharfun)
1430 for (i = 32; i < 128; i++)
1432 Lisp_Object jen = cte->level2[i - 32];
1434 if (!CHAR_TABLE_ENTRYP (jen))
1438 write_c_string (" [", printcharfun);
1439 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1440 sprintf (buf, " %d] ", i);
1441 write_c_string (buf, printcharfun);
1442 print_internal (jen, printcharfun, 0);
1445 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1453 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1455 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1458 struct gcpro gcpro1, gcpro2;
1459 GCPRO2 (obj, printcharfun);
1461 write_c_string ("#s(char-table ", printcharfun);
1462 write_c_string (" ", printcharfun);
1463 write_c_string (string_data
1465 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1467 write_c_string ("\n ", printcharfun);
1468 print_internal (ct->default_value, printcharfun, escapeflag);
1469 for (i = 0; i < 256; i++)
1471 Lisp_Object elt = get_byte_table (ct->table, i);
1472 if (i != 0) write_c_string ("\n ", printcharfun);
1473 if (EQ (elt, Qunbound))
1474 write_c_string ("void", printcharfun);
1476 print_internal (elt, printcharfun, escapeflag);
1479 #else /* non UTF2000 */
1482 sprintf (buf, "#s(char-table type %s data (",
1483 string_data (symbol_name (XSYMBOL
1484 (char_table_type_to_symbol (ct->type)))));
1485 write_c_string (buf, printcharfun);
1487 /* Now write out the ASCII/Control-1 stuff. */
1491 Lisp_Object val = Qunbound;
1493 for (i = 0; i < NUM_ASCII_CHARS; i++)
1502 if (!EQ (ct->ascii[i], val))
1504 print_chartab_range (first, i - 1, val, printcharfun);
1511 print_chartab_range (first, i - 1, val, printcharfun);
1518 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1521 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1522 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1524 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1525 || i == LEADING_BYTE_CONTROL_1)
1527 if (!CHAR_TABLE_ENTRYP (ann))
1529 write_c_string (" ", printcharfun);
1530 print_internal (XCHARSET_NAME (charset),
1532 write_c_string (" ", printcharfun);
1533 print_internal (ann, printcharfun, 0);
1537 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1538 if (XCHARSET_DIMENSION (charset) == 1)
1539 print_chartab_charset_row (charset, -1, cte, printcharfun);
1541 print_chartab_two_byte_charset (charset, cte, printcharfun);
1546 #endif /* non UTF2000 */
1548 write_c_string ("))", printcharfun);
1552 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1554 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1555 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1558 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1562 for (i = 0; i < 256; i++)
1564 if (!internal_equal (get_byte_table (ct1->table, i),
1565 get_byte_table (ct2->table, i), 0))
1569 for (i = 0; i < NUM_ASCII_CHARS; i++)
1570 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1574 for (i = 0; i < NUM_LEADING_BYTES; i++)
1575 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1578 #endif /* non UTF2000 */
1583 static unsigned long
1584 char_table_hash (Lisp_Object obj, int depth)
1586 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1588 return byte_table_hash (ct->table, depth + 1);
1590 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1593 hashval = HASH2 (hashval,
1594 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1600 static const struct lrecord_description char_table_description[] = {
1602 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1603 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1604 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, name) },
1606 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1608 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1612 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1614 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1618 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1619 mark_char_table, print_char_table, 0,
1620 char_table_equal, char_table_hash,
1621 char_table_description,
1624 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1625 Return non-nil if OBJECT is a char table.
1627 A char table is a table that maps characters (or ranges of characters)
1628 to values. Char tables are specialized for characters, only allowing
1629 particular sorts of ranges to be assigned values. Although this
1630 loses in generality, it makes for extremely fast (constant-time)
1631 lookups, and thus is feasible for applications that do an extremely
1632 large number of lookups (e.g. scanning a buffer for a character in
1633 a particular syntax, where a lookup in the syntax table must occur
1634 once per character).
1636 When Mule support exists, the types of ranges that can be assigned
1640 -- an entire charset
1641 -- a single row in a two-octet charset
1642 -- a single character
1644 When Mule support is not present, the types of ranges that can be
1648 -- a single character
1650 To create a char table, use `make-char-table'.
1651 To modify a char table, use `put-char-table' or `remove-char-table'.
1652 To retrieve the value for a particular character, use `get-char-table'.
1653 See also `map-char-table', `clear-char-table', `copy-char-table',
1654 `valid-char-table-type-p', `char-table-type-list',
1655 `valid-char-table-value-p', and `check-char-table-value'.
1659 return CHAR_TABLEP (object) ? Qt : Qnil;
1662 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1663 Return a list of the recognized char table types.
1664 See `valid-char-table-type-p'.
1669 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1671 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1675 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1676 Return t if TYPE if a recognized char table type.
1678 Each char table type is used for a different purpose and allows different
1679 sorts of values. The different char table types are
1682 Used for category tables, which specify the regexp categories
1683 that a character is in. The valid values are nil or a
1684 bit vector of 95 elements. Higher-level Lisp functions are
1685 provided for working with category tables. Currently categories
1686 and category tables only exist when Mule support is present.
1688 A generalized char table, for mapping from one character to
1689 another. Used for case tables, syntax matching tables,
1690 `keyboard-translate-table', etc. The valid values are characters.
1692 An even more generalized char table, for mapping from a
1693 character to anything.
1695 Used for display tables, which specify how a particular character
1696 is to appear when displayed. #### Not yet implemented.
1698 Used for syntax tables, which specify the syntax of a particular
1699 character. Higher-level Lisp functions are provided for
1700 working with syntax tables. The valid values are integers.
1705 return (EQ (type, Qchar) ||
1707 EQ (type, Qcategory) ||
1709 EQ (type, Qdisplay) ||
1710 EQ (type, Qgeneric) ||
1711 EQ (type, Qsyntax)) ? Qt : Qnil;
1714 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1715 Return the type of CHAR-TABLE.
1716 See `valid-char-table-type-p'.
1720 CHECK_CHAR_TABLE (char_table);
1721 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1725 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1728 ct->table = Qunbound;
1729 ct->default_value = value;
1734 for (i = 0; i < NUM_ASCII_CHARS; i++)
1735 ct->ascii[i] = value;
1737 for (i = 0; i < NUM_LEADING_BYTES; i++)
1738 ct->level1[i] = value;
1743 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1744 update_syntax_table (ct);
1748 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1749 Reset CHAR-TABLE to its default state.
1753 Lisp_Char_Table *ct;
1755 CHECK_CHAR_TABLE (char_table);
1756 ct = XCHAR_TABLE (char_table);
1760 case CHAR_TABLE_TYPE_CHAR:
1761 fill_char_table (ct, make_char (0));
1763 case CHAR_TABLE_TYPE_DISPLAY:
1764 case CHAR_TABLE_TYPE_GENERIC:
1766 case CHAR_TABLE_TYPE_CATEGORY:
1768 fill_char_table (ct, Qnil);
1771 case CHAR_TABLE_TYPE_SYNTAX:
1772 fill_char_table (ct, make_int (Sinherit));
1782 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1783 Return a new, empty char table of type TYPE.
1784 Currently recognized types are 'char, 'category, 'display, 'generic,
1785 and 'syntax. See `valid-char-table-type-p'.
1789 Lisp_Char_Table *ct;
1791 enum char_table_type ty = symbol_to_char_table_type (type);
1793 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1796 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1798 ct->mirror_table = Fmake_char_table (Qgeneric);
1799 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1803 ct->mirror_table = Qnil;
1807 ct->next_table = Qnil;
1808 XSETCHAR_TABLE (obj, ct);
1809 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1811 ct->next_table = Vall_syntax_tables;
1812 Vall_syntax_tables = obj;
1814 Freset_char_table (obj);
1818 #if defined(MULE)&&!defined(UTF2000)
1821 make_char_table_entry (Lisp_Object initval)
1825 Lisp_Char_Table_Entry *cte =
1826 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1828 for (i = 0; i < 96; i++)
1829 cte->level2[i] = initval;
1831 XSETCHAR_TABLE_ENTRY (obj, cte);
1836 copy_char_table_entry (Lisp_Object entry)
1838 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1841 Lisp_Char_Table_Entry *ctenew =
1842 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1844 for (i = 0; i < 96; i++)
1846 Lisp_Object new = cte->level2[i];
1847 if (CHAR_TABLE_ENTRYP (new))
1848 ctenew->level2[i] = copy_char_table_entry (new);
1850 ctenew->level2[i] = new;
1853 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1859 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1860 Return a new char table which is a copy of CHAR-TABLE.
1861 It will contain the same values for the same characters and ranges
1862 as CHAR-TABLE. The values will not themselves be copied.
1866 Lisp_Char_Table *ct, *ctnew;
1872 CHECK_CHAR_TABLE (char_table);
1873 ct = XCHAR_TABLE (char_table);
1874 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1875 ctnew->type = ct->type;
1877 ctnew->default_value = ct->default_value;
1878 /* [tomo:2002-01-21] Perhaps this code seems wrong */
1879 ctnew->name = ct->name;
1881 if (UINT8_BYTE_TABLE_P (ct->table))
1883 ctnew->table = copy_uint8_byte_table (ct->table);
1885 else if (UINT16_BYTE_TABLE_P (ct->table))
1887 ctnew->table = copy_uint16_byte_table (ct->table);
1889 else if (BYTE_TABLE_P (ct->table))
1891 ctnew->table = copy_byte_table (ct->table);
1893 else if (!UNBOUNDP (ct->table))
1894 ctnew->table = ct->table;
1895 #else /* non UTF2000 */
1897 for (i = 0; i < NUM_ASCII_CHARS; i++)
1899 Lisp_Object new = ct->ascii[i];
1901 assert (! (CHAR_TABLE_ENTRYP (new)));
1903 ctnew->ascii[i] = new;
1908 for (i = 0; i < NUM_LEADING_BYTES; i++)
1910 Lisp_Object new = ct->level1[i];
1911 if (CHAR_TABLE_ENTRYP (new))
1912 ctnew->level1[i] = copy_char_table_entry (new);
1914 ctnew->level1[i] = new;
1918 #endif /* non UTF2000 */
1921 if (CHAR_TABLEP (ct->mirror_table))
1922 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
1924 ctnew->mirror_table = ct->mirror_table;
1926 ctnew->next_table = Qnil;
1927 XSETCHAR_TABLE (obj, ctnew);
1928 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
1930 ctnew->next_table = Vall_syntax_tables;
1931 Vall_syntax_tables = obj;
1936 INLINE_HEADER int XCHARSET_CELL_RANGE (Lisp_Object ccs);
1938 XCHARSET_CELL_RANGE (Lisp_Object ccs)
1940 switch (XCHARSET_CHARS (ccs))
1943 return (33 << 8) | 126;
1945 return (32 << 8) | 127;
1948 return (0 << 8) | 127;
1950 return (0 << 8) | 255;
1962 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
1965 outrange->type = CHARTAB_RANGE_ALL;
1966 else if (EQ (range, Qnil))
1967 outrange->type = CHARTAB_RANGE_DEFAULT;
1968 else if (CHAR_OR_CHAR_INTP (range))
1970 outrange->type = CHARTAB_RANGE_CHAR;
1971 outrange->ch = XCHAR_OR_CHAR_INT (range);
1975 signal_simple_error ("Range must be t or a character", range);
1977 else if (VECTORP (range))
1979 Lisp_Vector *vec = XVECTOR (range);
1980 Lisp_Object *elts = vector_data (vec);
1981 int cell_min, cell_max;
1983 outrange->type = CHARTAB_RANGE_ROW;
1984 outrange->charset = Fget_charset (elts[0]);
1985 CHECK_INT (elts[1]);
1986 outrange->row = XINT (elts[1]);
1987 if (XCHARSET_DIMENSION (outrange->charset) < 2)
1988 signal_simple_error ("Charset in row vector must be multi-byte",
1992 int ret = XCHARSET_CELL_RANGE (outrange->charset);
1994 cell_min = ret >> 8;
1995 cell_max = ret & 0xFF;
1997 if (XCHARSET_DIMENSION (outrange->charset) == 2)
1998 check_int_range (outrange->row, cell_min, cell_max);
2000 else if (XCHARSET_DIMENSION (outrange->charset) == 3)
2002 check_int_range (outrange->row >> 8 , cell_min, cell_max);
2003 check_int_range (outrange->row & 0xFF, cell_min, cell_max);
2005 else if (XCHARSET_DIMENSION (outrange->charset) == 4)
2007 check_int_range ( outrange->row >> 16 , cell_min, cell_max);
2008 check_int_range ((outrange->row >> 8) & 0xFF, cell_min, cell_max);
2009 check_int_range ( outrange->row & 0xFF, cell_min, cell_max);
2017 if (!CHARSETP (range) && !SYMBOLP (range))
2019 ("Char table range must be t, charset, char, or vector", range);
2020 outrange->type = CHARTAB_RANGE_CHARSET;
2021 outrange->charset = Fget_charset (range);
2026 #if defined(MULE)&&!defined(UTF2000)
2028 /* called from CHAR_TABLE_VALUE(). */
2030 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
2035 Lisp_Object charset;
2037 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
2042 BREAKUP_CHAR (c, charset, byte1, byte2);
2044 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
2046 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
2047 if (CHAR_TABLE_ENTRYP (val))
2049 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2050 val = cte->level2[byte1 - 32];
2051 if (CHAR_TABLE_ENTRYP (val))
2053 cte = XCHAR_TABLE_ENTRY (val);
2054 assert (byte2 >= 32);
2055 val = cte->level2[byte2 - 32];
2056 assert (!CHAR_TABLE_ENTRYP (val));
2066 get_char_table (Emchar ch, Lisp_Char_Table *ct)
2069 return get_char_id_table (ct, ch);
2072 Lisp_Object charset;
2076 BREAKUP_CHAR (ch, charset, byte1, byte2);
2078 if (EQ (charset, Vcharset_ascii))
2079 val = ct->ascii[byte1];
2080 else if (EQ (charset, Vcharset_control_1))
2081 val = ct->ascii[byte1 + 128];
2084 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2085 val = ct->level1[lb];
2086 if (CHAR_TABLE_ENTRYP (val))
2088 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2089 val = cte->level2[byte1 - 32];
2090 if (CHAR_TABLE_ENTRYP (val))
2092 cte = XCHAR_TABLE_ENTRY (val);
2093 assert (byte2 >= 32);
2094 val = cte->level2[byte2 - 32];
2095 assert (!CHAR_TABLE_ENTRYP (val));
2102 #else /* not MULE */
2103 return ct->ascii[(unsigned char)ch];
2104 #endif /* not MULE */
2108 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
2109 Find value for CHARACTER in CHAR-TABLE.
2111 (character, char_table))
2113 CHECK_CHAR_TABLE (char_table);
2114 CHECK_CHAR_COERCE_INT (character);
2116 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
2119 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
2120 Find value for a range in CHAR-TABLE.
2121 If there is more than one value, return MULTI (defaults to nil).
2123 (range, char_table, multi))
2125 Lisp_Char_Table *ct;
2126 struct chartab_range rainj;
2128 if (CHAR_OR_CHAR_INTP (range))
2129 return Fget_char_table (range, char_table);
2130 CHECK_CHAR_TABLE (char_table);
2131 ct = XCHAR_TABLE (char_table);
2133 decode_char_table_range (range, &rainj);
2136 case CHARTAB_RANGE_ALL:
2139 if (UINT8_BYTE_TABLE_P (ct->table))
2141 else if (UINT16_BYTE_TABLE_P (ct->table))
2143 else if (BYTE_TABLE_P (ct->table))
2147 #else /* non UTF2000 */
2149 Lisp_Object first = ct->ascii[0];
2151 for (i = 1; i < NUM_ASCII_CHARS; i++)
2152 if (!EQ (first, ct->ascii[i]))
2156 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
2159 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
2160 || i == LEADING_BYTE_ASCII
2161 || i == LEADING_BYTE_CONTROL_1)
2163 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
2169 #endif /* non UTF2000 */
2173 case CHARTAB_RANGE_CHARSET:
2177 if (EQ (rainj.charset, Vcharset_ascii))
2180 Lisp_Object first = ct->ascii[0];
2182 for (i = 1; i < 128; i++)
2183 if (!EQ (first, ct->ascii[i]))
2188 if (EQ (rainj.charset, Vcharset_control_1))
2191 Lisp_Object first = ct->ascii[128];
2193 for (i = 129; i < 160; i++)
2194 if (!EQ (first, ct->ascii[i]))
2200 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2202 if (CHAR_TABLE_ENTRYP (val))
2208 case CHARTAB_RANGE_ROW:
2213 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2215 if (!CHAR_TABLE_ENTRYP (val))
2217 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
2218 if (CHAR_TABLE_ENTRYP (val))
2222 #endif /* not UTF2000 */
2223 #endif /* not MULE */
2229 return Qnil; /* not reached */
2233 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2234 Error_behavior errb)
2238 case CHAR_TABLE_TYPE_SYNTAX:
2239 if (!ERRB_EQ (errb, ERROR_ME))
2240 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2241 && CHAR_OR_CHAR_INTP (XCDR (value)));
2244 Lisp_Object cdr = XCDR (value);
2245 CHECK_INT (XCAR (value));
2246 CHECK_CHAR_COERCE_INT (cdr);
2253 case CHAR_TABLE_TYPE_CATEGORY:
2254 if (!ERRB_EQ (errb, ERROR_ME))
2255 return CATEGORY_TABLE_VALUEP (value);
2256 CHECK_CATEGORY_TABLE_VALUE (value);
2260 case CHAR_TABLE_TYPE_GENERIC:
2263 case CHAR_TABLE_TYPE_DISPLAY:
2265 maybe_signal_simple_error ("Display char tables not yet implemented",
2266 value, Qchar_table, errb);
2269 case CHAR_TABLE_TYPE_CHAR:
2270 if (!ERRB_EQ (errb, ERROR_ME))
2271 return CHAR_OR_CHAR_INTP (value);
2272 CHECK_CHAR_COERCE_INT (value);
2279 return 0; /* not reached */
2283 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2287 case CHAR_TABLE_TYPE_SYNTAX:
2290 Lisp_Object car = XCAR (value);
2291 Lisp_Object cdr = XCDR (value);
2292 CHECK_CHAR_COERCE_INT (cdr);
2293 return Fcons (car, cdr);
2296 case CHAR_TABLE_TYPE_CHAR:
2297 CHECK_CHAR_COERCE_INT (value);
2305 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2306 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2308 (value, char_table_type))
2310 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2312 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2315 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2316 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2318 (value, char_table_type))
2320 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2322 check_valid_char_table_value (value, type, ERROR_ME);
2327 Lisp_Char_Table* char_attribute_table_to_put;
2328 Lisp_Object Qput_char_table_map_function;
2329 Lisp_Object value_to_put;
2331 DEFUN ("put-char-table-map-function",
2332 Fput_char_table_map_function, 2, 2, 0, /*
2333 For internal use. Don't use it.
2337 put_char_id_table_0 (char_attribute_table_to_put, c, value_to_put);
2342 /* Assign VAL to all characters in RANGE in char table CT. */
2345 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2348 switch (range->type)
2350 case CHARTAB_RANGE_ALL:
2351 /* printf ("put-char-table: range = all\n"); */
2352 fill_char_table (ct, val);
2353 return; /* avoid the duplicate call to update_syntax_table() below,
2354 since fill_char_table() also did that. */
2357 case CHARTAB_RANGE_DEFAULT:
2358 ct->default_value = val;
2363 case CHARTAB_RANGE_CHARSET:
2367 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2369 /* printf ("put-char-table: range = charset: %d\n",
2370 XCHARSET_LEADING_BYTE (range->charset));
2372 if ( CHAR_TABLEP (encoding_table) )
2375 char_attribute_table_to_put = ct;
2377 Fmap_char_attribute (Qput_char_table_map_function,
2378 XCHAR_TABLE_NAME (encoding_table),
2381 for (c = 0; c < 1 << 24; c++)
2383 if ( INTP (get_char_id_table (XCHAR_TABLE(encoding_table),
2385 put_char_id_table_0 (ct, c, val);
2391 for (c = 0; c < 1 << 24; c++)
2393 if ( charset_code_point (range->charset, c) >= 0 )
2394 put_char_id_table_0 (ct, c, val);
2399 if (EQ (range->charset, Vcharset_ascii))
2402 for (i = 0; i < 128; i++)
2405 else if (EQ (range->charset, Vcharset_control_1))
2408 for (i = 128; i < 160; i++)
2413 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2414 ct->level1[lb] = val;
2419 case CHARTAB_RANGE_ROW:
2422 int cell_min, cell_max, i;
2424 i = XCHARSET_CELL_RANGE (range->charset);
2426 cell_max = i & 0xFF;
2427 for (i = cell_min; i <= cell_max; i++)
2429 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2431 if ( charset_code_point (range->charset, ch) >= 0 )
2432 put_char_id_table_0 (ct, ch, val);
2437 Lisp_Char_Table_Entry *cte;
2438 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2439 /* make sure that there is a separate entry for the row. */
2440 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2441 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2442 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2443 cte->level2[range->row - 32] = val;
2445 #endif /* not UTF2000 */
2449 case CHARTAB_RANGE_CHAR:
2451 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2452 put_char_id_table_0 (ct, range->ch, val);
2456 Lisp_Object charset;
2459 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2460 if (EQ (charset, Vcharset_ascii))
2461 ct->ascii[byte1] = val;
2462 else if (EQ (charset, Vcharset_control_1))
2463 ct->ascii[byte1 + 128] = val;
2466 Lisp_Char_Table_Entry *cte;
2467 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2468 /* make sure that there is a separate entry for the row. */
2469 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2470 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2471 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2472 /* now CTE is a char table entry for the charset;
2473 each entry is for a single row (or character of
2474 a one-octet charset). */
2475 if (XCHARSET_DIMENSION (charset) == 1)
2476 cte->level2[byte1 - 32] = val;
2479 /* assigning to one character in a two-octet charset. */
2480 /* make sure that the charset row contains a separate
2481 entry for each character. */
2482 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2483 cte->level2[byte1 - 32] =
2484 make_char_table_entry (cte->level2[byte1 - 32]);
2485 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2486 cte->level2[byte2 - 32] = val;
2490 #else /* not MULE */
2491 ct->ascii[(unsigned char) (range->ch)] = val;
2493 #endif /* not MULE */
2497 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2498 update_syntax_table (ct);
2502 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2503 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2505 RANGE specifies one or more characters to be affected and should be
2506 one of the following:
2508 -- t (all characters are affected)
2509 -- A charset (only allowed when Mule support is present)
2510 -- A vector of two elements: a two-octet charset and a row number
2511 (only allowed when Mule support is present)
2512 -- A single character
2514 VALUE must be a value appropriate for the type of CHAR-TABLE.
2515 See `valid-char-table-type-p'.
2517 (range, value, char_table))
2519 Lisp_Char_Table *ct;
2520 struct chartab_range rainj;
2522 CHECK_CHAR_TABLE (char_table);
2523 ct = XCHAR_TABLE (char_table);
2524 check_valid_char_table_value (value, ct->type, ERROR_ME);
2525 decode_char_table_range (range, &rainj);
2526 value = canonicalize_char_table_value (value, ct->type);
2527 put_char_table (ct, &rainj, value);
2532 /* Map FN over the ASCII chars in CT. */
2535 map_over_charset_ascii (Lisp_Char_Table *ct,
2536 int (*fn) (struct chartab_range *range,
2537 Lisp_Object val, void *arg),
2540 struct chartab_range rainj;
2549 rainj.type = CHARTAB_RANGE_CHAR;
2551 for (i = start, retval = 0; i < stop && retval == 0; i++)
2553 rainj.ch = (Emchar) i;
2554 retval = (fn) (&rainj, ct->ascii[i], arg);
2562 /* Map FN over the Control-1 chars in CT. */
2565 map_over_charset_control_1 (Lisp_Char_Table *ct,
2566 int (*fn) (struct chartab_range *range,
2567 Lisp_Object val, void *arg),
2570 struct chartab_range rainj;
2573 int stop = start + 32;
2575 rainj.type = CHARTAB_RANGE_CHAR;
2577 for (i = start, retval = 0; i < stop && retval == 0; i++)
2579 rainj.ch = (Emchar) (i);
2580 retval = (fn) (&rainj, ct->ascii[i], arg);
2586 /* Map FN over the row ROW of two-byte charset CHARSET.
2587 There must be a separate value for that row in the char table.
2588 CTE specifies the char table entry for CHARSET. */
2591 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2592 Lisp_Object charset, int row,
2593 int (*fn) (struct chartab_range *range,
2594 Lisp_Object val, void *arg),
2597 Lisp_Object val = cte->level2[row - 32];
2599 if (!CHAR_TABLE_ENTRYP (val))
2601 struct chartab_range rainj;
2603 rainj.type = CHARTAB_RANGE_ROW;
2604 rainj.charset = charset;
2606 return (fn) (&rainj, val, arg);
2610 struct chartab_range rainj;
2612 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2613 int start = charset94_p ? 33 : 32;
2614 int stop = charset94_p ? 127 : 128;
2616 cte = XCHAR_TABLE_ENTRY (val);
2618 rainj.type = CHARTAB_RANGE_CHAR;
2620 for (i = start, retval = 0; i < stop && retval == 0; i++)
2622 rainj.ch = MAKE_CHAR (charset, row, i);
2623 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2631 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2632 int (*fn) (struct chartab_range *range,
2633 Lisp_Object val, void *arg),
2636 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2637 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2639 if (!CHARSETP (charset)
2640 || lb == LEADING_BYTE_ASCII
2641 || lb == LEADING_BYTE_CONTROL_1)
2644 if (!CHAR_TABLE_ENTRYP (val))
2646 struct chartab_range rainj;
2648 rainj.type = CHARTAB_RANGE_CHARSET;
2649 rainj.charset = charset;
2650 return (fn) (&rainj, val, arg);
2654 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2655 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2656 int start = charset94_p ? 33 : 32;
2657 int stop = charset94_p ? 127 : 128;
2660 if (XCHARSET_DIMENSION (charset) == 1)
2662 struct chartab_range rainj;
2663 rainj.type = CHARTAB_RANGE_CHAR;
2665 for (i = start, retval = 0; i < stop && retval == 0; i++)
2667 rainj.ch = MAKE_CHAR (charset, i, 0);
2668 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2673 for (i = start, retval = 0; i < stop && retval == 0; i++)
2674 retval = map_over_charset_row (cte, charset, i, fn, arg);
2682 #endif /* not UTF2000 */
2685 struct map_char_table_for_charset_arg
2687 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2688 Lisp_Char_Table *ct;
2693 map_char_table_for_charset_fun (struct chartab_range *range,
2694 Lisp_Object val, void *arg)
2696 struct map_char_table_for_charset_arg *closure =
2697 (struct map_char_table_for_charset_arg *) arg;
2700 switch (range->type)
2702 case CHARTAB_RANGE_ALL:
2705 case CHARTAB_RANGE_DEFAULT:
2708 case CHARTAB_RANGE_CHARSET:
2711 case CHARTAB_RANGE_ROW:
2714 case CHARTAB_RANGE_CHAR:
2715 ret = get_char_table (range->ch, closure->ct);
2716 if (!UNBOUNDP (ret))
2717 return (closure->fn) (range, ret, closure->arg);
2727 #if defined(HAVE_DATABASE)
2728 EXFUN (Fload_char_attribute_table, 1);
2733 /* Map FN (with client data ARG) over range RANGE in char table CT.
2734 Mapping stops the first time FN returns non-zero, and that value
2735 becomes the return value of map_char_table(). */
2738 map_char_table (Lisp_Char_Table *ct,
2739 struct chartab_range *range,
2740 int (*fn) (struct chartab_range *range,
2741 Lisp_Object val, void *arg),
2744 switch (range->type)
2746 case CHARTAB_RANGE_ALL:
2748 if (!UNBOUNDP (ct->default_value))
2750 struct chartab_range rainj;
2753 rainj.type = CHARTAB_RANGE_DEFAULT;
2754 retval = (fn) (&rainj, ct->default_value, arg);
2758 if (UINT8_BYTE_TABLE_P (ct->table))
2759 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
2761 else if (UINT16_BYTE_TABLE_P (ct->table))
2762 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
2764 else if (BYTE_TABLE_P (ct->table))
2765 return map_over_byte_table (XBYTE_TABLE(ct->table), ct,
2767 else if (EQ (ct->table, Qunloaded))
2770 struct chartab_range rainj;
2773 Emchar c1 = c + unit;
2776 rainj.type = CHARTAB_RANGE_CHAR;
2778 for (retval = 0; c < c1 && retval == 0; c++)
2780 Lisp_Object ret = get_char_id_table (ct, c);
2782 if (!UNBOUNDP (ret))
2785 retval = (fn) (&rainj, ct->table, arg);
2790 ct->table = Qunbound;
2793 else if (!UNBOUNDP (ct->table))
2794 return (fn) (range, ct->table, arg);
2800 retval = map_over_charset_ascii (ct, fn, arg);
2804 retval = map_over_charset_control_1 (ct, fn, arg);
2809 Charset_ID start = MIN_LEADING_BYTE;
2810 Charset_ID stop = start + NUM_LEADING_BYTES;
2812 for (i = start, retval = 0; i < stop && retval == 0; i++)
2814 retval = map_over_other_charset (ct, i, fn, arg);
2823 case CHARTAB_RANGE_DEFAULT:
2824 if (!UNBOUNDP (ct->default_value))
2825 return (fn) (range, ct->default_value, arg);
2830 case CHARTAB_RANGE_CHARSET:
2833 Lisp_Object encoding_table
2834 = XCHARSET_ENCODING_TABLE (range->charset);
2836 if (!NILP (encoding_table))
2838 struct chartab_range rainj;
2839 struct map_char_table_for_charset_arg mcarg;
2841 #ifdef HAVE_DATABASE
2842 if (XCHAR_TABLE_UNLOADED(encoding_table))
2843 Fload_char_attribute_table (XCHAR_TABLE_NAME (encoding_table));
2848 rainj.type = CHARTAB_RANGE_ALL;
2849 return map_char_table (XCHAR_TABLE(encoding_table),
2851 &map_char_table_for_charset_fun,
2857 return map_over_other_charset (ct,
2858 XCHARSET_LEADING_BYTE (range->charset),
2862 case CHARTAB_RANGE_ROW:
2865 int cell_min, cell_max, i;
2867 struct chartab_range rainj;
2869 i = XCHARSET_CELL_RANGE (range->charset);
2871 cell_max = i & 0xFF;
2872 rainj.type = CHARTAB_RANGE_CHAR;
2873 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2875 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2877 if ( charset_code_point (range->charset, ch) >= 0 )
2880 = get_byte_table (get_byte_table
2884 (unsigned char)(ch >> 24)),
2885 (unsigned char) (ch >> 16)),
2886 (unsigned char) (ch >> 8)),
2887 (unsigned char) ch);
2890 val = ct->default_value;
2892 retval = (fn) (&rainj, val, arg);
2899 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
2900 - MIN_LEADING_BYTE];
2901 if (!CHAR_TABLE_ENTRYP (val))
2903 struct chartab_range rainj;
2905 rainj.type = CHARTAB_RANGE_ROW;
2906 rainj.charset = range->charset;
2907 rainj.row = range->row;
2908 return (fn) (&rainj, val, arg);
2911 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
2912 range->charset, range->row,
2915 #endif /* not UTF2000 */
2918 case CHARTAB_RANGE_CHAR:
2920 Emchar ch = range->ch;
2921 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
2923 if (!UNBOUNDP (val))
2925 struct chartab_range rainj;
2927 rainj.type = CHARTAB_RANGE_CHAR;
2929 return (fn) (&rainj, val, arg);
2941 struct slow_map_char_table_arg
2943 Lisp_Object function;
2948 slow_map_char_table_fun (struct chartab_range *range,
2949 Lisp_Object val, void *arg)
2951 Lisp_Object ranjarg = Qnil;
2952 struct slow_map_char_table_arg *closure =
2953 (struct slow_map_char_table_arg *) arg;
2955 switch (range->type)
2957 case CHARTAB_RANGE_ALL:
2962 case CHARTAB_RANGE_DEFAULT:
2968 case CHARTAB_RANGE_CHARSET:
2969 ranjarg = XCHARSET_NAME (range->charset);
2972 case CHARTAB_RANGE_ROW:
2973 ranjarg = vector2 (XCHARSET_NAME (range->charset),
2974 make_int (range->row));
2977 case CHARTAB_RANGE_CHAR:
2978 ranjarg = make_char (range->ch);
2984 closure->retval = call2 (closure->function, ranjarg, val);
2985 return !NILP (closure->retval);
2988 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
2989 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
2990 each key and value in the table.
2992 RANGE specifies a subrange to map over and is in the same format as
2993 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
2996 (function, char_table, range))
2998 Lisp_Char_Table *ct;
2999 struct slow_map_char_table_arg slarg;
3000 struct gcpro gcpro1, gcpro2;
3001 struct chartab_range rainj;
3003 CHECK_CHAR_TABLE (char_table);
3004 ct = XCHAR_TABLE (char_table);
3007 decode_char_table_range (range, &rainj);
3008 slarg.function = function;
3009 slarg.retval = Qnil;
3010 GCPRO2 (slarg.function, slarg.retval);
3011 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3014 return slarg.retval;
3018 /************************************************************************/
3019 /* Character Attributes */
3020 /************************************************************************/
3024 Lisp_Object Vchar_attribute_hash_table;
3026 /* We store the char-attributes in hash tables with the names as the
3027 key and the actual char-id-table object as the value. Occasionally
3028 we need to use them in a list format. These routines provide us
3030 struct char_attribute_list_closure
3032 Lisp_Object *char_attribute_list;
3036 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
3037 void *char_attribute_list_closure)
3039 /* This function can GC */
3040 struct char_attribute_list_closure *calcl
3041 = (struct char_attribute_list_closure*) char_attribute_list_closure;
3042 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
3044 *char_attribute_list = Fcons (key, *char_attribute_list);
3048 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
3049 Return the list of all existing character attributes except coded-charsets.
3053 Lisp_Object char_attribute_list = Qnil;
3054 struct gcpro gcpro1;
3055 struct char_attribute_list_closure char_attribute_list_closure;
3057 GCPRO1 (char_attribute_list);
3058 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
3059 elisp_maphash (add_char_attribute_to_list_mapper,
3060 Vchar_attribute_hash_table,
3061 &char_attribute_list_closure);
3063 return char_attribute_list;
3066 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
3067 Return char-id-table corresponding to ATTRIBUTE.
3071 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
3075 /* We store the char-id-tables in hash tables with the attributes as
3076 the key and the actual char-id-table object as the value. Each
3077 char-id-table stores values of an attribute corresponding with
3078 characters. Occasionally we need to get attributes of a character
3079 in a association-list format. These routines provide us with
3081 struct char_attribute_alist_closure
3084 Lisp_Object *char_attribute_alist;
3088 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
3089 void *char_attribute_alist_closure)
3091 /* This function can GC */
3092 struct char_attribute_alist_closure *caacl =
3093 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
3095 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
3096 if (!UNBOUNDP (ret))
3098 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
3099 *char_attribute_alist
3100 = Fcons (Fcons (key, ret), *char_attribute_alist);
3105 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
3106 Return the alist of attributes of CHARACTER.
3110 struct gcpro gcpro1;
3111 struct char_attribute_alist_closure char_attribute_alist_closure;
3112 Lisp_Object alist = Qnil;
3114 CHECK_CHAR (character);
3117 char_attribute_alist_closure.char_id = XCHAR (character);
3118 char_attribute_alist_closure.char_attribute_alist = &alist;
3119 elisp_maphash (add_char_attribute_alist_mapper,
3120 Vchar_attribute_hash_table,
3121 &char_attribute_alist_closure);
3127 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
3128 Return the value of CHARACTER's ATTRIBUTE.
3129 Return DEFAULT-VALUE if the value is not exist.
3131 (character, attribute, default_value))
3135 CHECK_CHAR (character);
3137 if (CHARSETP (attribute))
3138 attribute = XCHARSET_NAME (attribute);
3140 table = Fgethash (attribute, Vchar_attribute_hash_table,
3142 if (!UNBOUNDP (table))
3144 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
3146 if (!UNBOUNDP (ret))
3149 return default_value;
3152 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
3153 Store CHARACTER's ATTRIBUTE with VALUE.
3155 (character, attribute, value))
3157 Lisp_Object ccs = Ffind_charset (attribute);
3161 CHECK_CHAR (character);
3162 value = put_char_ccs_code_point (character, ccs, value);
3164 else if (EQ (attribute, Q_decomposition))
3168 CHECK_CHAR (character);
3170 signal_simple_error ("Invalid value for ->decomposition",
3173 if (CONSP (Fcdr (value)))
3175 Lisp_Object rest = value;
3176 Lisp_Object table = Vcharacter_composition_table;
3180 GET_EXTERNAL_LIST_LENGTH (rest, len);
3181 seq = make_vector (len, Qnil);
3183 while (CONSP (rest))
3185 Lisp_Object v = Fcar (rest);
3188 = to_char_id (v, "Invalid value for ->decomposition", value);
3191 XVECTOR_DATA(seq)[i++] = v;
3193 XVECTOR_DATA(seq)[i++] = make_char (c);
3197 put_char_id_table (XCHAR_TABLE(table),
3198 make_char (c), character);
3203 ntable = get_char_id_table (XCHAR_TABLE(table), c);
3204 if (!CHAR_TABLEP (ntable))
3206 ntable = make_char_id_table (Qnil);
3207 put_char_id_table (XCHAR_TABLE(table),
3208 make_char (c), ntable);
3216 Lisp_Object v = Fcar (value);
3220 Emchar c = XINT (v);
3222 = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3227 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3228 make_char (c), Fcons (character, Qnil));
3230 else if (NILP (Fmemq (v, ret)))
3232 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3233 make_char (c), Fcons (character, ret));
3236 seq = make_vector (1, v);
3240 else if (EQ (attribute, Qto_ucs) || EQ (attribute, Q_ucs))
3245 CHECK_CHAR (character);
3247 signal_simple_error ("Invalid value for ->ucs", value);
3251 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table), c);
3254 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3255 make_char (c), Fcons (character, Qnil));
3257 else if (NILP (Fmemq (character, ret)))
3259 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3260 make_char (c), Fcons (character, ret));
3263 if (EQ (attribute, Q_ucs))
3264 attribute = Qto_ucs;
3268 Lisp_Object table = Fgethash (attribute,
3269 Vchar_attribute_hash_table,
3274 table = make_char_id_table (Qunbound);
3275 Fputhash (attribute, table, Vchar_attribute_hash_table);
3276 #ifdef HAVE_DATABASE
3277 XCHAR_TABLE_NAME (table) = attribute;
3280 put_char_id_table (XCHAR_TABLE(table), character, value);
3285 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3286 Remove CHARACTER's ATTRIBUTE.
3288 (character, attribute))
3292 CHECK_CHAR (character);
3293 ccs = Ffind_charset (attribute);
3296 return remove_char_ccs (character, ccs);
3300 Lisp_Object table = Fgethash (attribute,
3301 Vchar_attribute_hash_table,
3303 if (!UNBOUNDP (table))
3305 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3313 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
3316 Lisp_Object db_dir = Vexec_directory;
3319 db_dir = build_string ("../lib-src");
3321 db_dir = Fexpand_file_name (build_string ("char-db"), db_dir);
3322 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3323 Fmake_directory_internal (db_dir);
3325 db_dir = Fexpand_file_name (Fsymbol_name (key_type), db_dir);
3326 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3327 Fmake_directory_internal (db_dir);
3330 Lisp_Object attribute_name = Fsymbol_name (attribute);
3331 Lisp_Object dest = Qnil, ret;
3333 struct gcpro gcpro1, gcpro2;
3334 int len = XSTRING_CHAR_LENGTH (attribute_name);
3338 for (i = 0; i < len; i++)
3340 Emchar c = string_char (XSTRING (attribute_name), i);
3342 if ( (c == '/') || (c == '%') )
3346 sprintf (str, "%%%02X", c);
3347 dest = concat3 (dest,
3348 Fsubstring (attribute_name,
3349 make_int (base), make_int (i)),
3350 build_string (str));
3354 ret = Fsubstring (attribute_name, make_int (base), make_int (len));
3355 dest = concat2 (dest, ret);
3357 return Fexpand_file_name (dest, db_dir);
3360 return Fexpand_file_name (Fsymbol_name (attribute), db_dir);
3364 DEFUN ("save-char-attribute-table", Fsave_char_attribute_table, 1, 1, 0, /*
3365 Save values of ATTRIBUTE into database file.
3369 #ifdef HAVE_DATABASE
3370 Lisp_Object table = Fgethash (attribute,
3371 Vchar_attribute_hash_table, Qunbound);
3372 Lisp_Char_Table *ct;
3374 Lisp_Object db_file;
3376 if (CHAR_TABLEP (table))
3377 ct = XCHAR_TABLE (table);
3381 db_file = char_attribute_system_db_file (Qsystem_char_id, attribute, 1);
3382 db = Fopen_database (db_file, Qnil, Qnil, Qnil, Qnil);
3385 if (UINT8_BYTE_TABLE_P (ct->table))
3386 save_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct, db, 0, 3);
3387 else if (UINT16_BYTE_TABLE_P (ct->table))
3388 save_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct, db, 0, 3);
3389 else if (BYTE_TABLE_P (ct->table))
3390 save_byte_table (XBYTE_TABLE(ct->table), ct, db, 0, 3);
3391 Fclose_database (db);
3401 DEFUN ("reset-char-attribute-table", Freset_char_attribute_table, 1, 1, 0, /*
3402 Reset values of ATTRIBUTE with database file.
3406 #ifdef HAVE_DATABASE
3407 Lisp_Object table = Fgethash (attribute,
3408 Vchar_attribute_hash_table, Qunbound);
3409 Lisp_Char_Table *ct;
3411 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3413 if (!NILP (Ffile_exists_p (db_file)))
3415 if (UNBOUNDP (table))
3417 table = make_char_id_table (Qunbound);
3418 Fputhash (attribute, table, Vchar_attribute_hash_table);
3419 XCHAR_TABLE_NAME(table) = attribute;
3421 ct = XCHAR_TABLE (table);
3422 ct->table = Qunloaded;
3423 XCHAR_TABLE_UNLOADED(table) = 1;
3430 #ifdef HAVE_DATABASE
3432 load_char_attribute_maybe (Emchar ch, Lisp_Object attribute)
3436 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3438 db = Fopen_database (db_file, Qnil, Qnil, Qnil, Qnil);
3442 = Fget_database (Fprin1_to_string (make_char (ch), Qnil),
3444 if (!UNBOUNDP (val))
3448 Fclose_database (db);
3455 Lisp_Char_Table* char_attribute_table_to_load;
3457 Lisp_Object Qload_char_attribute_table_map_function;
3459 DEFUN ("load-char-attribute-table-map-function",
3460 Fload_char_attribute_table_map_function, 2, 2, 0, /*
3461 For internal use. Don't use it.
3465 Lisp_Object c = Fread (key);
3466 Emchar code = XCHAR (c);
3467 Lisp_Object ret = get_char_id_table (char_attribute_table_to_load, code);
3469 if (EQ (ret, Qunloaded))
3470 put_char_id_table_0 (char_attribute_table_to_load, code, Fread (value));
3475 DEFUN ("load-char-attribute-table", Fload_char_attribute_table, 1, 1, 0, /*
3476 Load values of ATTRIBUTE into database file.
3480 #ifdef HAVE_DATABASE
3483 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3485 db = Fopen_database (db_file, Qnil, Qnil, Qnil, Qnil);
3488 Lisp_Object table = Fgethash (attribute,
3489 Vchar_attribute_hash_table,
3491 struct gcpro gcpro1, gcpro2;
3493 if (CHAR_TABLEP (table))
3494 char_attribute_table_to_load = XCHAR_TABLE (table);
3497 Fclose_database (db);
3501 Fmap_database (Qload_char_attribute_table_map_function, db);
3503 Fclose_database (db);
3504 XCHAR_TABLE_UNLOADED(table) = 0;
3512 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3513 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3514 each key and value in the table.
3516 RANGE specifies a subrange to map over and is in the same format as
3517 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3520 (function, attribute, range))
3523 Lisp_Char_Table *ct;
3524 struct slow_map_char_table_arg slarg;
3525 struct gcpro gcpro1, gcpro2;
3526 struct chartab_range rainj;
3528 if (!NILP (ccs = Ffind_charset (attribute)))
3530 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3532 if (CHAR_TABLEP (encoding_table))
3533 ct = XCHAR_TABLE (encoding_table);
3539 Lisp_Object table = Fgethash (attribute,
3540 Vchar_attribute_hash_table,
3542 if (CHAR_TABLEP (table))
3543 ct = XCHAR_TABLE (table);
3549 decode_char_table_range (range, &rainj);
3550 #ifdef HAVE_DATABASE
3551 if (CHAR_TABLE_UNLOADED(ct))
3552 Fload_char_attribute_table (attribute);
3554 slarg.function = function;
3555 slarg.retval = Qnil;
3556 GCPRO2 (slarg.function, slarg.retval);
3557 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3560 return slarg.retval;
3563 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3564 Store character's ATTRIBUTES.
3568 Lisp_Object rest = attributes;
3569 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
3570 Lisp_Object character;
3574 while (CONSP (rest))
3576 Lisp_Object cell = Fcar (rest);
3580 signal_simple_error ("Invalid argument", attributes);
3581 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3582 && ((XCHARSET_FINAL (ccs) != 0) ||
3583 (XCHARSET_MAX_CODE (ccs) > 0) ||
3584 (EQ (ccs, Vcharset_chinese_big5))) )
3588 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3590 character = Fdecode_char (ccs, cell, Qnil);
3591 if (!NILP (character))
3592 goto setup_attributes;
3596 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3597 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3601 signal_simple_error ("Invalid argument", attributes);
3603 character = make_char (XINT (code) + 0x100000);
3604 goto setup_attributes;
3608 else if (!INTP (code))
3609 signal_simple_error ("Invalid argument", attributes);
3611 character = make_char (XINT (code));
3615 while (CONSP (rest))
3617 Lisp_Object cell = Fcar (rest);
3620 signal_simple_error ("Invalid argument", attributes);
3622 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
3628 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
3629 Retrieve the character of the given ATTRIBUTES.
3633 Lisp_Object rest = attributes;
3636 while (CONSP (rest))
3638 Lisp_Object cell = Fcar (rest);
3642 signal_simple_error ("Invalid argument", attributes);
3643 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
3647 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3649 return Fdecode_char (ccs, cell, Qnil);
3653 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3654 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3657 signal_simple_error ("Invalid argument", attributes);
3659 return make_char (XINT (code) + 0x100000);
3667 /************************************************************************/
3668 /* Char table read syntax */
3669 /************************************************************************/
3672 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
3673 Error_behavior errb)
3675 /* #### should deal with ERRB */
3676 symbol_to_char_table_type (value);
3681 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
3682 Error_behavior errb)
3686 /* #### should deal with ERRB */
3687 EXTERNAL_LIST_LOOP (rest, value)
3689 Lisp_Object range = XCAR (rest);
3690 struct chartab_range dummy;
3694 signal_simple_error ("Invalid list format", value);
3697 if (!CONSP (XCDR (range))
3698 || !NILP (XCDR (XCDR (range))))
3699 signal_simple_error ("Invalid range format", range);
3700 decode_char_table_range (XCAR (range), &dummy);
3701 decode_char_table_range (XCAR (XCDR (range)), &dummy);
3704 decode_char_table_range (range, &dummy);
3711 chartab_instantiate (Lisp_Object data)
3713 Lisp_Object chartab;
3714 Lisp_Object type = Qgeneric;
3715 Lisp_Object dataval = Qnil;
3717 while (!NILP (data))
3719 Lisp_Object keyw = Fcar (data);
3725 if (EQ (keyw, Qtype))
3727 else if (EQ (keyw, Qdata))
3731 chartab = Fmake_char_table (type);
3734 while (!NILP (data))
3736 Lisp_Object range = Fcar (data);
3737 Lisp_Object val = Fcar (Fcdr (data));
3739 data = Fcdr (Fcdr (data));
3742 if (CHAR_OR_CHAR_INTP (XCAR (range)))
3744 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
3745 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
3748 for (i = first; i <= last; i++)
3749 Fput_char_table (make_char (i), val, chartab);
3755 Fput_char_table (range, val, chartab);
3764 /************************************************************************/
3765 /* Category Tables, specifically */
3766 /************************************************************************/
3768 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
3769 Return t if OBJECT is a category table.
3770 A category table is a type of char table used for keeping track of
3771 categories. Categories are used for classifying characters for use
3772 in regexps -- you can refer to a category rather than having to use
3773 a complicated [] expression (and category lookups are significantly
3776 There are 95 different categories available, one for each printable
3777 character (including space) in the ASCII charset. Each category
3778 is designated by one such character, called a "category designator".
3779 They are specified in a regexp using the syntax "\\cX", where X is
3780 a category designator.
3782 A category table specifies, for each character, the categories that
3783 the character is in. Note that a character can be in more than one
3784 category. More specifically, a category table maps from a character
3785 to either the value nil (meaning the character is in no categories)
3786 or a 95-element bit vector, specifying for each of the 95 categories
3787 whether the character is in that category.
3789 Special Lisp functions are provided that abstract this, so you do not
3790 have to directly manipulate bit vectors.
3794 return (CHAR_TABLEP (object) &&
3795 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
3800 check_category_table (Lisp_Object object, Lisp_Object default_)
3804 while (NILP (Fcategory_table_p (object)))
3805 object = wrong_type_argument (Qcategory_table_p, object);
3810 check_category_char (Emchar ch, Lisp_Object table,
3811 unsigned int designator, unsigned int not_p)
3813 REGISTER Lisp_Object temp;
3814 Lisp_Char_Table *ctbl;
3815 #ifdef ERROR_CHECK_TYPECHECK
3816 if (NILP (Fcategory_table_p (table)))
3817 signal_simple_error ("Expected category table", table);
3819 ctbl = XCHAR_TABLE (table);
3820 temp = get_char_table (ch, ctbl);
3825 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
3828 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
3829 Return t if category of the character at POSITION includes DESIGNATOR.
3830 Optional third arg BUFFER specifies which buffer to use, and defaults
3831 to the current buffer.
3832 Optional fourth arg CATEGORY-TABLE specifies the category table to
3833 use, and defaults to BUFFER's category table.
3835 (position, designator, buffer, category_table))
3840 struct buffer *buf = decode_buffer (buffer, 0);
3842 CHECK_INT (position);
3843 CHECK_CATEGORY_DESIGNATOR (designator);
3844 des = XCHAR (designator);
3845 ctbl = check_category_table (category_table, Vstandard_category_table);
3846 ch = BUF_FETCH_CHAR (buf, XINT (position));
3847 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3850 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
3851 Return t if category of CHARACTER includes DESIGNATOR, else nil.
3852 Optional third arg CATEGORY-TABLE specifies the category table to use,
3853 and defaults to the standard category table.
3855 (character, designator, category_table))
3861 CHECK_CATEGORY_DESIGNATOR (designator);
3862 des = XCHAR (designator);
3863 CHECK_CHAR (character);
3864 ch = XCHAR (character);
3865 ctbl = check_category_table (category_table, Vstandard_category_table);
3866 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3869 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
3870 Return BUFFER's current category table.
3871 BUFFER defaults to the current buffer.
3875 return decode_buffer (buffer, 0)->category_table;
3878 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
3879 Return the standard category table.
3880 This is the one used for new buffers.
3884 return Vstandard_category_table;
3887 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
3888 Return a new category table which is a copy of CATEGORY-TABLE.
3889 CATEGORY-TABLE defaults to the standard category table.
3893 if (NILP (Vstandard_category_table))
3894 return Fmake_char_table (Qcategory);
3897 check_category_table (category_table, Vstandard_category_table);
3898 return Fcopy_char_table (category_table);
3901 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
3902 Select CATEGORY-TABLE as the new category table for BUFFER.
3903 BUFFER defaults to the current buffer if omitted.
3905 (category_table, buffer))
3907 struct buffer *buf = decode_buffer (buffer, 0);
3908 category_table = check_category_table (category_table, Qnil);
3909 buf->category_table = category_table;
3910 /* Indicate that this buffer now has a specified category table. */
3911 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
3912 return category_table;
3915 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
3916 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
3920 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
3923 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
3924 Return t if OBJECT is a category table value.
3925 Valid values are nil or a bit vector of size 95.
3929 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
3933 #define CATEGORYP(x) \
3934 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
3936 #define CATEGORY_SET(c) \
3937 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
3939 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
3940 The faster version of `!NILP (Faref (category_set, category))'. */
3941 #define CATEGORY_MEMBER(category, category_set) \
3942 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
3944 /* Return 1 if there is a word boundary between two word-constituent
3945 characters C1 and C2 if they appear in this order, else return 0.
3946 Use the macro WORD_BOUNDARY_P instead of calling this function
3949 int word_boundary_p (Emchar c1, Emchar c2);
3951 word_boundary_p (Emchar c1, Emchar c2)
3953 Lisp_Object category_set1, category_set2;
3958 if (COMPOSITE_CHAR_P (c1))
3959 c1 = cmpchar_component (c1, 0, 1);
3960 if (COMPOSITE_CHAR_P (c2))
3961 c2 = cmpchar_component (c2, 0, 1);
3964 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
3966 tail = Vword_separating_categories;
3971 tail = Vword_combining_categories;
3975 category_set1 = CATEGORY_SET (c1);
3976 if (NILP (category_set1))
3977 return default_result;
3978 category_set2 = CATEGORY_SET (c2);
3979 if (NILP (category_set2))
3980 return default_result;
3982 for (; CONSP (tail); tail = XCONS (tail)->cdr)
3984 Lisp_Object elt = XCONS(tail)->car;
3987 && CATEGORYP (XCONS (elt)->car)
3988 && CATEGORYP (XCONS (elt)->cdr)
3989 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
3990 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
3991 return !default_result;
3993 return default_result;
3999 syms_of_chartab (void)
4002 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
4003 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
4004 INIT_LRECORD_IMPLEMENTATION (byte_table);
4006 defsymbol (&Qsystem_char_id, "system-char-id");
4008 defsymbol (&Qto_ucs, "=>ucs");
4009 defsymbol (&Q_ucs, "->ucs");
4010 defsymbol (&Q_ucs_variants, "->ucs-variants");
4011 defsymbol (&Q_decomposition, "->decomposition");
4012 defsymbol (&Qcompat, "compat");
4013 defsymbol (&Qisolated, "isolated");
4014 defsymbol (&Qinitial, "initial");
4015 defsymbol (&Qmedial, "medial");
4016 defsymbol (&Qfinal, "final");
4017 defsymbol (&Qvertical, "vertical");
4018 defsymbol (&QnoBreak, "noBreak");
4019 defsymbol (&Qfraction, "fraction");
4020 defsymbol (&Qsuper, "super");
4021 defsymbol (&Qsub, "sub");
4022 defsymbol (&Qcircle, "circle");
4023 defsymbol (&Qsquare, "square");
4024 defsymbol (&Qwide, "wide");
4025 defsymbol (&Qnarrow, "narrow");
4026 defsymbol (&Qsmall, "small");
4027 defsymbol (&Qfont, "font");
4029 DEFSUBR (Fchar_attribute_list);
4030 DEFSUBR (Ffind_char_attribute_table);
4031 defsymbol (&Qput_char_table_map_function, "put-char-table-map-function");
4032 DEFSUBR (Fput_char_table_map_function);
4033 DEFSUBR (Fsave_char_attribute_table);
4034 DEFSUBR (Freset_char_attribute_table);
4035 #ifdef HAVE_DATABASE
4036 defsymbol (&Qload_char_attribute_table_map_function,
4037 "load-char-attribute-table-map-function");
4038 DEFSUBR (Fload_char_attribute_table_map_function);
4040 DEFSUBR (Fload_char_attribute_table);
4041 DEFSUBR (Fchar_attribute_alist);
4042 DEFSUBR (Fget_char_attribute);
4043 DEFSUBR (Fput_char_attribute);
4044 DEFSUBR (Fremove_char_attribute);
4045 DEFSUBR (Fmap_char_attribute);
4046 DEFSUBR (Fdefine_char);
4047 DEFSUBR (Ffind_char);
4048 DEFSUBR (Fchar_variants);
4050 DEFSUBR (Fget_composite_char);
4053 INIT_LRECORD_IMPLEMENTATION (char_table);
4057 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
4060 defsymbol (&Qcategory_table_p, "category-table-p");
4061 defsymbol (&Qcategory_designator_p, "category-designator-p");
4062 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
4065 defsymbol (&Qchar_table, "char-table");
4066 defsymbol (&Qchar_tablep, "char-table-p");
4068 DEFSUBR (Fchar_table_p);
4069 DEFSUBR (Fchar_table_type_list);
4070 DEFSUBR (Fvalid_char_table_type_p);
4071 DEFSUBR (Fchar_table_type);
4072 DEFSUBR (Freset_char_table);
4073 DEFSUBR (Fmake_char_table);
4074 DEFSUBR (Fcopy_char_table);
4075 DEFSUBR (Fget_char_table);
4076 DEFSUBR (Fget_range_char_table);
4077 DEFSUBR (Fvalid_char_table_value_p);
4078 DEFSUBR (Fcheck_valid_char_table_value);
4079 DEFSUBR (Fput_char_table);
4080 DEFSUBR (Fmap_char_table);
4083 DEFSUBR (Fcategory_table_p);
4084 DEFSUBR (Fcategory_table);
4085 DEFSUBR (Fstandard_category_table);
4086 DEFSUBR (Fcopy_category_table);
4087 DEFSUBR (Fset_category_table);
4088 DEFSUBR (Fcheck_category_at);
4089 DEFSUBR (Fchar_in_category_p);
4090 DEFSUBR (Fcategory_designator_p);
4091 DEFSUBR (Fcategory_table_value_p);
4097 vars_of_chartab (void)
4100 Vutf_2000_version = build_string("0.18 (Yamato-Koizumi)");
4101 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
4102 Version number of XEmacs UTF-2000.
4105 staticpro (&Vcharacter_composition_table);
4106 Vcharacter_composition_table = make_char_id_table (Qnil);
4108 staticpro (&Vcharacter_variant_table);
4109 Vcharacter_variant_table = make_char_id_table (Qunbound);
4111 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
4112 Vall_syntax_tables = Qnil;
4113 dump_add_weak_object_chain (&Vall_syntax_tables);
4117 structure_type_create_chartab (void)
4119 struct structure_type *st;
4121 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
4123 define_structure_type_keyword (st, Qtype, chartab_type_validate);
4124 define_structure_type_keyword (st, Qdata, chartab_data_validate);
4128 complex_vars_of_chartab (void)
4131 staticpro (&Vchar_attribute_hash_table);
4132 Vchar_attribute_hash_table
4133 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
4134 #ifdef HAVE_DATABASE
4135 Fputhash (Q_ucs_variants, Vcharacter_variant_table,
4136 Vchar_attribute_hash_table);
4137 XCHAR_TABLE_NAME (Vcharacter_variant_table) = Q_ucs_variants;
4138 #endif /* HAVE_DATABASE */
4139 #endif /* UTF2000 */
4141 /* Set this now, so first buffer creation can refer to it. */
4142 /* Make it nil before calling copy-category-table
4143 so that copy-category-table will know not to try to copy from garbage */
4144 Vstandard_category_table = Qnil;
4145 Vstandard_category_table = Fcopy_category_table (Qnil);
4146 staticpro (&Vstandard_category_table);
4148 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
4149 List of pair (cons) of categories to determine word boundary.
4151 Emacs treats a sequence of word constituent characters as a single
4152 word (i.e. finds no word boundary between them) iff they belongs to
4153 the same charset. But, exceptions are allowed in the following cases.
4155 \(1) The case that characters are in different charsets is controlled
4156 by the variable `word-combining-categories'.
4158 Emacs finds no word boundary between characters of different charsets
4159 if they have categories matching some element of this list.
4161 More precisely, if an element of this list is a cons of category CAT1
4162 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4163 C2 which has CAT2, there's no word boundary between C1 and C2.
4165 For instance, to tell that ASCII characters and Latin-1 characters can
4166 form a single word, the element `(?l . ?l)' should be in this list
4167 because both characters have the category `l' (Latin characters).
4169 \(2) The case that character are in the same charset is controlled by
4170 the variable `word-separating-categories'.
4172 Emacs find a word boundary between characters of the same charset
4173 if they have categories matching some element of this list.
4175 More precisely, if an element of this list is a cons of category CAT1
4176 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4177 C2 which has CAT2, there's a word boundary between C1 and C2.
4179 For instance, to tell that there's a word boundary between Japanese
4180 Hiragana and Japanese Kanji (both are in the same charset), the
4181 element `(?H . ?C) should be in this list.
4184 Vword_combining_categories = Qnil;
4186 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
4187 List of pair (cons) of categories to determine word boundary.
4188 See the documentation of the variable `word-combining-categories'.
4191 Vword_separating_categories = Qnil;