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
37 MORIOKA Tomohiko: Rewritten for XEmacs UTF-2000
50 Lisp_Object Qchar_tablep, Qchar_table;
52 Lisp_Object Vall_syntax_tables;
55 Lisp_Object Qcategory_table_p;
56 Lisp_Object Qcategory_designator_p;
57 Lisp_Object Qcategory_table_value_p;
59 Lisp_Object Vstandard_category_table;
61 /* Variables to determine word boundary. */
62 Lisp_Object Vword_combining_categories, Vword_separating_categories;
68 #if defined(HAVE_DATABASE)
69 EXFUN (Fload_char_attribute_table, 1);
70 EXFUN (Fmap_char_attribute, 3);
72 Lisp_Object Vchar_db_stingy_mode;
75 #define BT_UINT8_MIN 0
76 #define BT_UINT8_MAX (UCHAR_MAX - 4)
77 #define BT_UINT8_t (UCHAR_MAX - 3)
78 #define BT_UINT8_nil (UCHAR_MAX - 2)
79 #define BT_UINT8_unbound (UCHAR_MAX - 1)
80 #define BT_UINT8_unloaded UCHAR_MAX
82 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
83 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
84 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
85 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
86 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
89 INT_UINT8_P (Lisp_Object obj)
95 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
102 UINT8_VALUE_P (Lisp_Object obj)
104 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
105 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
108 INLINE_HEADER unsigned char
109 UINT8_ENCODE (Lisp_Object obj)
111 if (EQ (obj, Qunloaded))
112 return BT_UINT8_unloaded;
113 else if (EQ (obj, Qunbound))
114 return BT_UINT8_unbound;
115 else if (EQ (obj, Qnil))
117 else if (EQ (obj, Qt))
123 INLINE_HEADER Lisp_Object
124 UINT8_DECODE (unsigned char n)
126 if (n == BT_UINT8_unloaded)
128 else if (n == BT_UINT8_unbound)
130 else if (n == BT_UINT8_nil)
132 else if (n == BT_UINT8_t)
139 mark_uint8_byte_table (Lisp_Object obj)
145 print_uint8_byte_table (Lisp_Object obj,
146 Lisp_Object printcharfun, int escapeflag)
148 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
150 struct gcpro gcpro1, gcpro2;
151 GCPRO2 (obj, printcharfun);
153 write_c_string ("\n#<uint8-byte-table", printcharfun);
154 for (i = 0; i < 256; i++)
156 unsigned char n = bte->property[i];
158 write_c_string ("\n ", printcharfun);
159 write_c_string (" ", printcharfun);
160 if (n == BT_UINT8_unbound)
161 write_c_string ("void", printcharfun);
162 else if (n == BT_UINT8_nil)
163 write_c_string ("nil", printcharfun);
164 else if (n == BT_UINT8_t)
165 write_c_string ("t", printcharfun);
170 sprintf (buf, "%hd", n);
171 write_c_string (buf, printcharfun);
175 write_c_string (">", printcharfun);
179 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
181 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
182 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
185 for (i = 0; i < 256; i++)
186 if (te1->property[i] != te2->property[i])
192 uint8_byte_table_hash (Lisp_Object obj, int depth)
194 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
198 for (i = 0; i < 256; i++)
199 hash = HASH2 (hash, te->property[i]);
203 static const struct lrecord_description uint8_byte_table_description[] = {
207 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
208 mark_uint8_byte_table,
209 print_uint8_byte_table,
210 0, uint8_byte_table_equal,
211 uint8_byte_table_hash,
212 uint8_byte_table_description,
213 Lisp_Uint8_Byte_Table);
216 make_uint8_byte_table (unsigned char initval)
220 Lisp_Uint8_Byte_Table *cte;
222 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
223 &lrecord_uint8_byte_table);
225 for (i = 0; i < 256; i++)
226 cte->property[i] = initval;
228 XSETUINT8_BYTE_TABLE (obj, cte);
233 copy_uint8_byte_table (Lisp_Object entry)
235 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
238 Lisp_Uint8_Byte_Table *ctenew
239 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
240 &lrecord_uint8_byte_table);
242 for (i = 0; i < 256; i++)
244 ctenew->property[i] = cte->property[i];
247 XSETUINT8_BYTE_TABLE (obj, ctenew);
252 uint8_byte_table_same_value_p (Lisp_Object obj)
254 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
255 unsigned char v0 = bte->property[0];
258 for (i = 1; i < 256; i++)
260 if (bte->property[i] != v0)
267 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
268 Emchar ofs, int place,
269 int (*fn) (struct chartab_range *range,
270 Lisp_Object val, void *arg),
273 struct chartab_range rainj;
275 int unit = 1 << (8 * place);
279 rainj.type = CHARTAB_RANGE_CHAR;
281 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
283 if (ct->property[i] == BT_UINT8_unloaded)
287 for (; c < c1 && retval == 0; c++)
289 Lisp_Object ret = get_char_id_table (root, c);
294 retval = (fn) (&rainj, ret, arg);
298 ct->property[i] = BT_UINT8_unbound;
302 else if (ct->property[i] != BT_UINT8_unbound)
305 for (; c < c1 && retval == 0; c++)
308 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
319 save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
321 Emchar ofs, int place)
323 struct chartab_range rainj;
325 int unit = 1 << (8 * place);
329 rainj.type = CHARTAB_RANGE_CHAR;
331 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
333 if (ct->property[i] == BT_UINT8_unloaded)
337 else if (ct->property[i] != BT_UINT8_unbound)
340 for (; c < c1 && retval == 0; c++)
342 Fput_database (Fprin1_to_string (make_char (c), Qnil),
343 Fprin1_to_string (UINT8_DECODE (ct->property[i]),
354 #define BT_UINT16_MIN 0
355 #define BT_UINT16_MAX (USHRT_MAX - 4)
356 #define BT_UINT16_t (USHRT_MAX - 3)
357 #define BT_UINT16_nil (USHRT_MAX - 2)
358 #define BT_UINT16_unbound (USHRT_MAX - 1)
359 #define BT_UINT16_unloaded USHRT_MAX
361 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
362 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
363 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
364 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
367 INT_UINT16_P (Lisp_Object obj)
371 int num = XINT (obj);
373 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
380 UINT16_VALUE_P (Lisp_Object obj)
382 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
383 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
386 INLINE_HEADER unsigned short
387 UINT16_ENCODE (Lisp_Object obj)
389 if (EQ (obj, Qunloaded))
390 return BT_UINT16_unloaded;
391 else if (EQ (obj, Qunbound))
392 return BT_UINT16_unbound;
393 else if (EQ (obj, Qnil))
394 return BT_UINT16_nil;
395 else if (EQ (obj, Qt))
401 INLINE_HEADER Lisp_Object
402 UINT16_DECODE (unsigned short n)
404 if (n == BT_UINT16_unloaded)
406 else if (n == BT_UINT16_unbound)
408 else if (n == BT_UINT16_nil)
410 else if (n == BT_UINT16_t)
416 INLINE_HEADER unsigned short
417 UINT8_TO_UINT16 (unsigned char n)
419 if (n == BT_UINT8_unloaded)
420 return BT_UINT16_unloaded;
421 else if (n == BT_UINT8_unbound)
422 return BT_UINT16_unbound;
423 else if (n == BT_UINT8_nil)
424 return BT_UINT16_nil;
425 else if (n == BT_UINT8_t)
432 mark_uint16_byte_table (Lisp_Object obj)
438 print_uint16_byte_table (Lisp_Object obj,
439 Lisp_Object printcharfun, int escapeflag)
441 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
443 struct gcpro gcpro1, gcpro2;
444 GCPRO2 (obj, printcharfun);
446 write_c_string ("\n#<uint16-byte-table", printcharfun);
447 for (i = 0; i < 256; i++)
449 unsigned short n = bte->property[i];
451 write_c_string ("\n ", printcharfun);
452 write_c_string (" ", printcharfun);
453 if (n == BT_UINT16_unbound)
454 write_c_string ("void", printcharfun);
455 else if (n == BT_UINT16_nil)
456 write_c_string ("nil", printcharfun);
457 else if (n == BT_UINT16_t)
458 write_c_string ("t", printcharfun);
463 sprintf (buf, "%hd", n);
464 write_c_string (buf, printcharfun);
468 write_c_string (">", printcharfun);
472 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
474 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
475 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
478 for (i = 0; i < 256; i++)
479 if (te1->property[i] != te2->property[i])
485 uint16_byte_table_hash (Lisp_Object obj, int depth)
487 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
491 for (i = 0; i < 256; i++)
492 hash = HASH2 (hash, te->property[i]);
496 static const struct lrecord_description uint16_byte_table_description[] = {
500 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
501 mark_uint16_byte_table,
502 print_uint16_byte_table,
503 0, uint16_byte_table_equal,
504 uint16_byte_table_hash,
505 uint16_byte_table_description,
506 Lisp_Uint16_Byte_Table);
509 make_uint16_byte_table (unsigned short initval)
513 Lisp_Uint16_Byte_Table *cte;
515 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
516 &lrecord_uint16_byte_table);
518 for (i = 0; i < 256; i++)
519 cte->property[i] = initval;
521 XSETUINT16_BYTE_TABLE (obj, cte);
526 copy_uint16_byte_table (Lisp_Object entry)
528 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
531 Lisp_Uint16_Byte_Table *ctenew
532 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
533 &lrecord_uint16_byte_table);
535 for (i = 0; i < 256; i++)
537 ctenew->property[i] = cte->property[i];
540 XSETUINT16_BYTE_TABLE (obj, ctenew);
545 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
549 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
550 Lisp_Uint16_Byte_Table* cte;
552 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
553 &lrecord_uint16_byte_table);
554 for (i = 0; i < 256; i++)
556 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
558 XSETUINT16_BYTE_TABLE (obj, cte);
563 uint16_byte_table_same_value_p (Lisp_Object obj)
565 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
566 unsigned short v0 = bte->property[0];
569 for (i = 1; i < 256; i++)
571 if (bte->property[i] != v0)
578 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
579 Emchar ofs, int place,
580 int (*fn) (struct chartab_range *range,
581 Lisp_Object val, void *arg),
584 struct chartab_range rainj;
586 int unit = 1 << (8 * place);
590 rainj.type = CHARTAB_RANGE_CHAR;
592 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
594 if (ct->property[i] == BT_UINT16_unloaded)
598 for (; c < c1 && retval == 0; c++)
600 Lisp_Object ret = get_char_id_table (root, c);
605 retval = (fn) (&rainj, ret, arg);
609 ct->property[i] = BT_UINT16_unbound;
613 else if (ct->property[i] != BT_UINT16_unbound)
616 for (; c < c1 && retval == 0; c++)
619 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
630 save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
632 Emchar ofs, int place)
634 struct chartab_range rainj;
636 int unit = 1 << (8 * place);
640 rainj.type = CHARTAB_RANGE_CHAR;
642 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
644 if (ct->property[i] == BT_UINT16_unloaded)
648 else if (ct->property[i] != BT_UINT16_unbound)
651 for (; c < c1 && retval == 0; c++)
653 Fput_database (Fprin1_to_string (make_char (c), Qnil),
654 Fprin1_to_string (UINT16_DECODE (ct->property[i]),
667 mark_byte_table (Lisp_Object obj)
669 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
672 for (i = 0; i < 256; i++)
674 mark_object (cte->property[i]);
680 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
682 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
684 struct gcpro gcpro1, gcpro2;
685 GCPRO2 (obj, printcharfun);
687 write_c_string ("\n#<byte-table", printcharfun);
688 for (i = 0; i < 256; i++)
690 Lisp_Object elt = bte->property[i];
692 write_c_string ("\n ", printcharfun);
693 write_c_string (" ", printcharfun);
694 if (EQ (elt, Qunbound))
695 write_c_string ("void", printcharfun);
697 print_internal (elt, printcharfun, escapeflag);
700 write_c_string (">", printcharfun);
704 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
706 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
707 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
710 for (i = 0; i < 256; i++)
711 if (BYTE_TABLE_P (cte1->property[i]))
713 if (BYTE_TABLE_P (cte2->property[i]))
715 if (!byte_table_equal (cte1->property[i],
716 cte2->property[i], depth + 1))
723 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
729 byte_table_hash (Lisp_Object obj, int depth)
731 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
733 return internal_array_hash (cte->property, 256, depth);
736 static const struct lrecord_description byte_table_description[] = {
737 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
741 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
746 byte_table_description,
750 make_byte_table (Lisp_Object initval)
754 Lisp_Byte_Table *cte;
756 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
758 for (i = 0; i < 256; i++)
759 cte->property[i] = initval;
761 XSETBYTE_TABLE (obj, cte);
766 copy_byte_table (Lisp_Object entry)
768 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
771 Lisp_Byte_Table *ctnew
772 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
774 for (i = 0; i < 256; i++)
776 if (UINT8_BYTE_TABLE_P (cte->property[i]))
778 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
780 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
782 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
784 else if (BYTE_TABLE_P (cte->property[i]))
786 ctnew->property[i] = copy_byte_table (cte->property[i]);
789 ctnew->property[i] = cte->property[i];
792 XSETBYTE_TABLE (obj, ctnew);
797 byte_table_same_value_p (Lisp_Object obj)
799 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
800 Lisp_Object v0 = bte->property[0];
803 for (i = 1; i < 256; i++)
805 if (!internal_equal (bte->property[i], v0, 0))
812 map_over_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
813 Emchar ofs, int place,
814 int (*fn) (struct chartab_range *range,
815 Lisp_Object val, void *arg),
820 int unit = 1 << (8 * place);
823 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
826 if (UINT8_BYTE_TABLE_P (v))
829 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
830 c, place - 1, fn, arg);
833 else if (UINT16_BYTE_TABLE_P (v))
836 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
837 c, place - 1, fn, arg);
840 else if (BYTE_TABLE_P (v))
842 retval = map_over_byte_table (XBYTE_TABLE(v), root,
843 c, place - 1, fn, arg);
846 else if (EQ (v, Qunloaded))
849 struct chartab_range rainj;
850 Emchar c1 = c + unit;
852 rainj.type = CHARTAB_RANGE_CHAR;
854 for (; c < c1 && retval == 0; c++)
856 Lisp_Object ret = get_char_id_table (root, c);
861 retval = (fn) (&rainj, ret, arg);
865 ct->property[i] = Qunbound;
869 else if (!UNBOUNDP (v))
871 struct chartab_range rainj;
872 Emchar c1 = c + unit;
874 rainj.type = CHARTAB_RANGE_CHAR;
876 for (; c < c1 && retval == 0; c++)
879 retval = (fn) (&rainj, v, arg);
890 save_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
892 Emchar ofs, int place)
896 int unit = 1 << (8 * place);
899 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
902 if (UINT8_BYTE_TABLE_P (v))
904 save_uint8_byte_table (XUINT8_BYTE_TABLE(v), root, db,
908 else if (UINT16_BYTE_TABLE_P (v))
910 save_uint16_byte_table (XUINT16_BYTE_TABLE(v), root, db,
914 else if (BYTE_TABLE_P (v))
916 save_byte_table (XBYTE_TABLE(v), root, db,
920 else if (EQ (v, Qunloaded))
924 else if (!UNBOUNDP (v))
926 struct chartab_range rainj;
927 Emchar c1 = c + unit;
929 rainj.type = CHARTAB_RANGE_CHAR;
931 for (; c < c1 && retval == 0; c++)
933 Fput_database (Fprin1_to_string (make_char (c), Qnil),
934 Fprin1_to_string (v, Qnil),
945 get_byte_table (Lisp_Object table, unsigned char idx)
947 if (UINT8_BYTE_TABLE_P (table))
948 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
949 else if (UINT16_BYTE_TABLE_P (table))
950 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
951 else if (BYTE_TABLE_P (table))
952 return XBYTE_TABLE(table)->property[idx];
958 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
960 if (UINT8_BYTE_TABLE_P (table))
962 if (UINT8_VALUE_P (value))
964 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
965 if (!UINT8_BYTE_TABLE_P (value) &&
966 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
967 && uint8_byte_table_same_value_p (table))
972 else if (UINT16_VALUE_P (value))
974 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
976 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
981 Lisp_Object new = make_byte_table (Qnil);
984 for (i = 0; i < 256; i++)
986 XBYTE_TABLE(new)->property[i]
987 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
989 XBYTE_TABLE(new)->property[idx] = value;
993 else if (UINT16_BYTE_TABLE_P (table))
995 if (UINT16_VALUE_P (value))
997 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
998 if (!UINT8_BYTE_TABLE_P (value) &&
999 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1000 && uint16_byte_table_same_value_p (table))
1007 Lisp_Object new = make_byte_table (Qnil);
1010 for (i = 0; i < 256; i++)
1012 XBYTE_TABLE(new)->property[i]
1013 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
1015 XBYTE_TABLE(new)->property[idx] = value;
1019 else if (BYTE_TABLE_P (table))
1021 XBYTE_TABLE(table)->property[idx] = value;
1022 if (!UINT8_BYTE_TABLE_P (value) &&
1023 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1024 && byte_table_same_value_p (table))
1029 else if (!internal_equal (table, value, 0))
1031 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
1033 table = make_uint8_byte_table (UINT8_ENCODE (table));
1034 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1036 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
1038 table = make_uint16_byte_table (UINT16_ENCODE (table));
1039 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1043 table = make_byte_table (table);
1044 XBYTE_TABLE(table)->property[idx] = value;
1052 make_char_id_table (Lisp_Object initval)
1055 obj = Fmake_char_table (Qgeneric);
1056 fill_char_table (XCHAR_TABLE (obj), initval);
1061 #ifndef HAVE_DATABASE
1062 Lisp_Object Vcharacter_composition_table;
1064 Lisp_Object Vcharacter_variant_table;
1066 Lisp_Object Qsystem_char_id;
1068 Lisp_Object Qcomposition;
1069 Lisp_Object Q_decomposition;
1070 Lisp_Object Qto_ucs;
1072 Lisp_Object Q_ucs_variants;
1073 Lisp_Object Qcompat;
1074 Lisp_Object Qisolated;
1075 Lisp_Object Qinitial;
1076 Lisp_Object Qmedial;
1078 Lisp_Object Qvertical;
1079 Lisp_Object QnoBreak;
1080 Lisp_Object Qfraction;
1083 Lisp_Object Qcircle;
1084 Lisp_Object Qsquare;
1086 Lisp_Object Qnarrow;
1090 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
1093 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
1099 else if (EQ (v, Qcompat))
1101 else if (EQ (v, Qisolated))
1103 else if (EQ (v, Qinitial))
1105 else if (EQ (v, Qmedial))
1107 else if (EQ (v, Qfinal))
1109 else if (EQ (v, Qvertical))
1111 else if (EQ (v, QnoBreak))
1113 else if (EQ (v, Qfraction))
1115 else if (EQ (v, Qsuper))
1117 else if (EQ (v, Qsub))
1119 else if (EQ (v, Qcircle))
1121 else if (EQ (v, Qsquare))
1123 else if (EQ (v, Qwide))
1125 else if (EQ (v, Qnarrow))
1127 else if (EQ (v, Qsmall))
1129 else if (EQ (v, Qfont))
1132 signal_simple_error (err_msg, err_arg);
1135 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
1136 Return character corresponding with list.
1140 #ifdef HAVE_DATABASE
1141 Lisp_Object base, modifier;
1145 signal_simple_error ("Invalid value for composition", list);
1148 while (!NILP (rest))
1151 signal_simple_error ("Invalid value for composition", list);
1153 signal_simple_error ("Invalid value for composition", list);
1154 modifier = Fcar (rest);
1156 base = Fcdr (Fassq (modifier,
1157 Fget_char_attribute (base, Qcomposition, Qnil)));
1161 Lisp_Object table = Vcharacter_composition_table;
1162 Lisp_Object rest = list;
1164 while (CONSP (rest))
1166 Lisp_Object v = Fcar (rest);
1168 Emchar c = to_char_id (v, "Invalid value for composition", list);
1170 ret = get_char_id_table (XCHAR_TABLE(table), c);
1175 if (!CHAR_TABLEP (ret))
1180 else if (!CONSP (rest))
1182 else if (CHAR_TABLEP (ret))
1185 signal_simple_error ("Invalid table is found with", list);
1187 signal_simple_error ("Invalid value for composition", list);
1191 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
1192 Return variants of CHARACTER.
1198 CHECK_CHAR (character);
1199 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
1202 return Fcopy_list (ret);
1210 /* A char table maps from ranges of characters to values.
1212 Implementing a general data structure that maps from arbitrary
1213 ranges of numbers to values is tricky to do efficiently. As it
1214 happens, it should suffice (and is usually more convenient, anyway)
1215 when dealing with characters to restrict the sorts of ranges that
1216 can be assigned values, as follows:
1219 2) All characters in a charset.
1220 3) All characters in a particular row of a charset, where a "row"
1221 means all characters with the same first byte.
1222 4) A particular character in a charset.
1224 We use char tables to generalize the 256-element vectors now
1225 littering the Emacs code.
1227 Possible uses (all should be converted at some point):
1233 5) keyboard-translate-table?
1236 abstract type to generalize the Emacs vectors and Mule
1237 vectors-of-vectors goo.
1240 /************************************************************************/
1241 /* Char Table object */
1242 /************************************************************************/
1244 #if defined(MULE)&&!defined(UTF2000)
1247 mark_char_table_entry (Lisp_Object obj)
1249 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1252 for (i = 0; i < 96; i++)
1254 mark_object (cte->level2[i]);
1260 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1262 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1263 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1266 for (i = 0; i < 96; i++)
1267 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1273 static unsigned long
1274 char_table_entry_hash (Lisp_Object obj, int depth)
1276 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1278 return internal_array_hash (cte->level2, 96, depth);
1281 static const struct lrecord_description char_table_entry_description[] = {
1282 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1286 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1287 mark_char_table_entry, internal_object_printer,
1288 0, char_table_entry_equal,
1289 char_table_entry_hash,
1290 char_table_entry_description,
1291 Lisp_Char_Table_Entry);
1295 mark_char_table (Lisp_Object obj)
1297 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1300 mark_object (ct->table);
1301 mark_object (ct->name);
1302 mark_object (ct->db);
1306 for (i = 0; i < NUM_ASCII_CHARS; i++)
1307 mark_object (ct->ascii[i]);
1309 for (i = 0; i < NUM_LEADING_BYTES; i++)
1310 mark_object (ct->level1[i]);
1314 return ct->default_value;
1316 return ct->mirror_table;
1320 /* WARNING: All functions of this nature need to be written extremely
1321 carefully to avoid crashes during GC. Cf. prune_specifiers()
1322 and prune_weak_hash_tables(). */
1325 prune_syntax_tables (void)
1327 Lisp_Object rest, prev = Qnil;
1329 for (rest = Vall_syntax_tables;
1331 rest = XCHAR_TABLE (rest)->next_table)
1333 if (! marked_p (rest))
1335 /* This table is garbage. Remove it from the list. */
1337 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1339 XCHAR_TABLE (prev)->next_table =
1340 XCHAR_TABLE (rest)->next_table;
1346 char_table_type_to_symbol (enum char_table_type type)
1351 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1352 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1353 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1354 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1356 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1361 static enum char_table_type
1362 symbol_to_char_table_type (Lisp_Object symbol)
1364 CHECK_SYMBOL (symbol);
1366 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1367 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1368 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1369 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1371 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1374 signal_simple_error ("Unrecognized char table type", symbol);
1375 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1379 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1380 Lisp_Object printcharfun)
1384 write_c_string (" (", printcharfun);
1385 print_internal (make_char (first), printcharfun, 0);
1386 write_c_string (" ", printcharfun);
1387 print_internal (make_char (last), printcharfun, 0);
1388 write_c_string (") ", printcharfun);
1392 write_c_string (" ", printcharfun);
1393 print_internal (make_char (first), printcharfun, 0);
1394 write_c_string (" ", printcharfun);
1396 print_internal (val, printcharfun, 1);
1399 #if defined(MULE)&&!defined(UTF2000)
1402 print_chartab_charset_row (Lisp_Object charset,
1404 Lisp_Char_Table_Entry *cte,
1405 Lisp_Object printcharfun)
1408 Lisp_Object cat = Qunbound;
1411 for (i = 32; i < 128; i++)
1413 Lisp_Object pam = cte->level2[i - 32];
1425 print_chartab_range (MAKE_CHAR (charset, first, 0),
1426 MAKE_CHAR (charset, i - 1, 0),
1429 print_chartab_range (MAKE_CHAR (charset, row, first),
1430 MAKE_CHAR (charset, row, i - 1),
1440 print_chartab_range (MAKE_CHAR (charset, first, 0),
1441 MAKE_CHAR (charset, i - 1, 0),
1444 print_chartab_range (MAKE_CHAR (charset, row, first),
1445 MAKE_CHAR (charset, row, i - 1),
1451 print_chartab_two_byte_charset (Lisp_Object charset,
1452 Lisp_Char_Table_Entry *cte,
1453 Lisp_Object printcharfun)
1457 for (i = 32; i < 128; i++)
1459 Lisp_Object jen = cte->level2[i - 32];
1461 if (!CHAR_TABLE_ENTRYP (jen))
1465 write_c_string (" [", printcharfun);
1466 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1467 sprintf (buf, " %d] ", i);
1468 write_c_string (buf, printcharfun);
1469 print_internal (jen, printcharfun, 0);
1472 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1480 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1482 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1485 struct gcpro gcpro1, gcpro2;
1486 GCPRO2 (obj, printcharfun);
1488 write_c_string ("#s(char-table ", printcharfun);
1489 write_c_string (" ", printcharfun);
1490 write_c_string (string_data
1492 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1494 write_c_string ("\n ", printcharfun);
1495 print_internal (ct->default_value, printcharfun, escapeflag);
1496 for (i = 0; i < 256; i++)
1498 Lisp_Object elt = get_byte_table (ct->table, i);
1499 if (i != 0) write_c_string ("\n ", printcharfun);
1500 if (EQ (elt, Qunbound))
1501 write_c_string ("void", printcharfun);
1503 print_internal (elt, printcharfun, escapeflag);
1506 #else /* non UTF2000 */
1509 sprintf (buf, "#s(char-table type %s data (",
1510 string_data (symbol_name (XSYMBOL
1511 (char_table_type_to_symbol (ct->type)))));
1512 write_c_string (buf, printcharfun);
1514 /* Now write out the ASCII/Control-1 stuff. */
1518 Lisp_Object val = Qunbound;
1520 for (i = 0; i < NUM_ASCII_CHARS; i++)
1529 if (!EQ (ct->ascii[i], val))
1531 print_chartab_range (first, i - 1, val, printcharfun);
1538 print_chartab_range (first, i - 1, val, printcharfun);
1545 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1548 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1549 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1551 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1552 || i == LEADING_BYTE_CONTROL_1)
1554 if (!CHAR_TABLE_ENTRYP (ann))
1556 write_c_string (" ", printcharfun);
1557 print_internal (XCHARSET_NAME (charset),
1559 write_c_string (" ", printcharfun);
1560 print_internal (ann, printcharfun, 0);
1564 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1565 if (XCHARSET_DIMENSION (charset) == 1)
1566 print_chartab_charset_row (charset, -1, cte, printcharfun);
1568 print_chartab_two_byte_charset (charset, cte, printcharfun);
1573 #endif /* non UTF2000 */
1575 write_c_string ("))", printcharfun);
1579 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1581 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1582 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1585 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1589 for (i = 0; i < 256; i++)
1591 if (!internal_equal (get_byte_table (ct1->table, i),
1592 get_byte_table (ct2->table, i), 0))
1596 for (i = 0; i < NUM_ASCII_CHARS; i++)
1597 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1601 for (i = 0; i < NUM_LEADING_BYTES; i++)
1602 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1605 #endif /* non UTF2000 */
1610 static unsigned long
1611 char_table_hash (Lisp_Object obj, int depth)
1613 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1615 return byte_table_hash (ct->table, depth + 1);
1617 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1620 hashval = HASH2 (hashval,
1621 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1627 static const struct lrecord_description char_table_description[] = {
1629 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1630 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1631 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, name) },
1632 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, db) },
1634 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1636 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1640 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1642 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1646 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1647 mark_char_table, print_char_table, 0,
1648 char_table_equal, char_table_hash,
1649 char_table_description,
1652 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1653 Return non-nil if OBJECT is a char table.
1655 A char table is a table that maps characters (or ranges of characters)
1656 to values. Char tables are specialized for characters, only allowing
1657 particular sorts of ranges to be assigned values. Although this
1658 loses in generality, it makes for extremely fast (constant-time)
1659 lookups, and thus is feasible for applications that do an extremely
1660 large number of lookups (e.g. scanning a buffer for a character in
1661 a particular syntax, where a lookup in the syntax table must occur
1662 once per character).
1664 When Mule support exists, the types of ranges that can be assigned
1668 -- an entire charset
1669 -- a single row in a two-octet charset
1670 -- a single character
1672 When Mule support is not present, the types of ranges that can be
1676 -- a single character
1678 To create a char table, use `make-char-table'.
1679 To modify a char table, use `put-char-table' or `remove-char-table'.
1680 To retrieve the value for a particular character, use `get-char-table'.
1681 See also `map-char-table', `clear-char-table', `copy-char-table',
1682 `valid-char-table-type-p', `char-table-type-list',
1683 `valid-char-table-value-p', and `check-char-table-value'.
1687 return CHAR_TABLEP (object) ? Qt : Qnil;
1690 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1691 Return a list of the recognized char table types.
1692 See `valid-char-table-type-p'.
1697 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1699 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1703 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1704 Return t if TYPE if a recognized char table type.
1706 Each char table type is used for a different purpose and allows different
1707 sorts of values. The different char table types are
1710 Used for category tables, which specify the regexp categories
1711 that a character is in. The valid values are nil or a
1712 bit vector of 95 elements. Higher-level Lisp functions are
1713 provided for working with category tables. Currently categories
1714 and category tables only exist when Mule support is present.
1716 A generalized char table, for mapping from one character to
1717 another. Used for case tables, syntax matching tables,
1718 `keyboard-translate-table', etc. The valid values are characters.
1720 An even more generalized char table, for mapping from a
1721 character to anything.
1723 Used for display tables, which specify how a particular character
1724 is to appear when displayed. #### Not yet implemented.
1726 Used for syntax tables, which specify the syntax of a particular
1727 character. Higher-level Lisp functions are provided for
1728 working with syntax tables. The valid values are integers.
1733 return (EQ (type, Qchar) ||
1735 EQ (type, Qcategory) ||
1737 EQ (type, Qdisplay) ||
1738 EQ (type, Qgeneric) ||
1739 EQ (type, Qsyntax)) ? Qt : Qnil;
1742 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1743 Return the type of CHAR-TABLE.
1744 See `valid-char-table-type-p'.
1748 CHECK_CHAR_TABLE (char_table);
1749 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1753 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1756 ct->table = Qunbound;
1757 ct->default_value = value;
1762 for (i = 0; i < NUM_ASCII_CHARS; i++)
1763 ct->ascii[i] = value;
1765 for (i = 0; i < NUM_LEADING_BYTES; i++)
1766 ct->level1[i] = value;
1771 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1772 update_syntax_table (ct);
1776 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1777 Reset CHAR-TABLE to its default state.
1781 Lisp_Char_Table *ct;
1783 CHECK_CHAR_TABLE (char_table);
1784 ct = XCHAR_TABLE (char_table);
1788 case CHAR_TABLE_TYPE_CHAR:
1789 fill_char_table (ct, make_char (0));
1791 case CHAR_TABLE_TYPE_DISPLAY:
1792 case CHAR_TABLE_TYPE_GENERIC:
1794 case CHAR_TABLE_TYPE_CATEGORY:
1796 fill_char_table (ct, Qnil);
1799 case CHAR_TABLE_TYPE_SYNTAX:
1800 fill_char_table (ct, make_int (Sinherit));
1810 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1811 Return a new, empty char table of type TYPE.
1812 Currently recognized types are 'char, 'category, 'display, 'generic,
1813 and 'syntax. See `valid-char-table-type-p'.
1817 Lisp_Char_Table *ct;
1819 enum char_table_type ty = symbol_to_char_table_type (type);
1821 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1824 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1826 ct->mirror_table = Fmake_char_table (Qgeneric);
1827 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1831 ct->mirror_table = Qnil;
1836 ct->next_table = Qnil;
1837 XSETCHAR_TABLE (obj, ct);
1838 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1840 ct->next_table = Vall_syntax_tables;
1841 Vall_syntax_tables = obj;
1843 Freset_char_table (obj);
1847 #if defined(MULE)&&!defined(UTF2000)
1850 make_char_table_entry (Lisp_Object initval)
1854 Lisp_Char_Table_Entry *cte =
1855 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1857 for (i = 0; i < 96; i++)
1858 cte->level2[i] = initval;
1860 XSETCHAR_TABLE_ENTRY (obj, cte);
1865 copy_char_table_entry (Lisp_Object entry)
1867 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1870 Lisp_Char_Table_Entry *ctenew =
1871 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1873 for (i = 0; i < 96; i++)
1875 Lisp_Object new = cte->level2[i];
1876 if (CHAR_TABLE_ENTRYP (new))
1877 ctenew->level2[i] = copy_char_table_entry (new);
1879 ctenew->level2[i] = new;
1882 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1888 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1889 Return a new char table which is a copy of CHAR-TABLE.
1890 It will contain the same values for the same characters and ranges
1891 as CHAR-TABLE. The values will not themselves be copied.
1895 Lisp_Char_Table *ct, *ctnew;
1901 CHECK_CHAR_TABLE (char_table);
1902 ct = XCHAR_TABLE (char_table);
1903 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1904 ctnew->type = ct->type;
1906 ctnew->default_value = ct->default_value;
1907 /* [tomo:2002-01-21] Perhaps this code seems wrong */
1908 ctnew->name = ct->name;
1911 if (UINT8_BYTE_TABLE_P (ct->table))
1913 ctnew->table = copy_uint8_byte_table (ct->table);
1915 else if (UINT16_BYTE_TABLE_P (ct->table))
1917 ctnew->table = copy_uint16_byte_table (ct->table);
1919 else if (BYTE_TABLE_P (ct->table))
1921 ctnew->table = copy_byte_table (ct->table);
1923 else if (!UNBOUNDP (ct->table))
1924 ctnew->table = ct->table;
1925 #else /* non UTF2000 */
1927 for (i = 0; i < NUM_ASCII_CHARS; i++)
1929 Lisp_Object new = ct->ascii[i];
1931 assert (! (CHAR_TABLE_ENTRYP (new)));
1933 ctnew->ascii[i] = new;
1938 for (i = 0; i < NUM_LEADING_BYTES; i++)
1940 Lisp_Object new = ct->level1[i];
1941 if (CHAR_TABLE_ENTRYP (new))
1942 ctnew->level1[i] = copy_char_table_entry (new);
1944 ctnew->level1[i] = new;
1948 #endif /* non UTF2000 */
1951 if (CHAR_TABLEP (ct->mirror_table))
1952 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
1954 ctnew->mirror_table = ct->mirror_table;
1956 ctnew->next_table = Qnil;
1957 XSETCHAR_TABLE (obj, ctnew);
1958 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
1960 ctnew->next_table = Vall_syntax_tables;
1961 Vall_syntax_tables = obj;
1966 INLINE_HEADER int XCHARSET_CELL_RANGE (Lisp_Object ccs);
1968 XCHARSET_CELL_RANGE (Lisp_Object ccs)
1970 switch (XCHARSET_CHARS (ccs))
1973 return (33 << 8) | 126;
1975 return (32 << 8) | 127;
1978 return (0 << 8) | 127;
1980 return (0 << 8) | 255;
1992 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
1995 outrange->type = CHARTAB_RANGE_ALL;
1996 else if (EQ (range, Qnil))
1997 outrange->type = CHARTAB_RANGE_DEFAULT;
1998 else if (CHAR_OR_CHAR_INTP (range))
2000 outrange->type = CHARTAB_RANGE_CHAR;
2001 outrange->ch = XCHAR_OR_CHAR_INT (range);
2005 signal_simple_error ("Range must be t or a character", range);
2007 else if (VECTORP (range))
2009 Lisp_Vector *vec = XVECTOR (range);
2010 Lisp_Object *elts = vector_data (vec);
2011 int cell_min, cell_max;
2013 outrange->type = CHARTAB_RANGE_ROW;
2014 outrange->charset = Fget_charset (elts[0]);
2015 CHECK_INT (elts[1]);
2016 outrange->row = XINT (elts[1]);
2017 if (XCHARSET_DIMENSION (outrange->charset) < 2)
2018 signal_simple_error ("Charset in row vector must be multi-byte",
2022 int ret = XCHARSET_CELL_RANGE (outrange->charset);
2024 cell_min = ret >> 8;
2025 cell_max = ret & 0xFF;
2027 if (XCHARSET_DIMENSION (outrange->charset) == 2)
2028 check_int_range (outrange->row, cell_min, cell_max);
2030 else if (XCHARSET_DIMENSION (outrange->charset) == 3)
2032 check_int_range (outrange->row >> 8 , cell_min, cell_max);
2033 check_int_range (outrange->row & 0xFF, cell_min, cell_max);
2035 else if (XCHARSET_DIMENSION (outrange->charset) == 4)
2037 check_int_range ( outrange->row >> 16 , cell_min, cell_max);
2038 check_int_range ((outrange->row >> 8) & 0xFF, cell_min, cell_max);
2039 check_int_range ( outrange->row & 0xFF, cell_min, cell_max);
2047 if (!CHARSETP (range) && !SYMBOLP (range))
2049 ("Char table range must be t, charset, char, or vector", range);
2050 outrange->type = CHARTAB_RANGE_CHARSET;
2051 outrange->charset = Fget_charset (range);
2056 #if defined(MULE)&&!defined(UTF2000)
2058 /* called from CHAR_TABLE_VALUE(). */
2060 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
2065 Lisp_Object charset;
2067 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
2072 BREAKUP_CHAR (c, charset, byte1, byte2);
2074 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
2076 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
2077 if (CHAR_TABLE_ENTRYP (val))
2079 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2080 val = cte->level2[byte1 - 32];
2081 if (CHAR_TABLE_ENTRYP (val))
2083 cte = XCHAR_TABLE_ENTRY (val);
2084 assert (byte2 >= 32);
2085 val = cte->level2[byte2 - 32];
2086 assert (!CHAR_TABLE_ENTRYP (val));
2096 get_char_table (Emchar ch, Lisp_Char_Table *ct)
2099 return get_char_id_table (ct, ch);
2102 Lisp_Object charset;
2106 BREAKUP_CHAR (ch, charset, byte1, byte2);
2108 if (EQ (charset, Vcharset_ascii))
2109 val = ct->ascii[byte1];
2110 else if (EQ (charset, Vcharset_control_1))
2111 val = ct->ascii[byte1 + 128];
2114 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2115 val = ct->level1[lb];
2116 if (CHAR_TABLE_ENTRYP (val))
2118 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2119 val = cte->level2[byte1 - 32];
2120 if (CHAR_TABLE_ENTRYP (val))
2122 cte = XCHAR_TABLE_ENTRY (val);
2123 assert (byte2 >= 32);
2124 val = cte->level2[byte2 - 32];
2125 assert (!CHAR_TABLE_ENTRYP (val));
2132 #else /* not MULE */
2133 return ct->ascii[(unsigned char)ch];
2134 #endif /* not MULE */
2138 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
2139 Find value for CHARACTER in CHAR-TABLE.
2141 (character, char_table))
2143 CHECK_CHAR_TABLE (char_table);
2144 CHECK_CHAR_COERCE_INT (character);
2146 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
2149 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
2150 Find value for a range in CHAR-TABLE.
2151 If there is more than one value, return MULTI (defaults to nil).
2153 (range, char_table, multi))
2155 Lisp_Char_Table *ct;
2156 struct chartab_range rainj;
2158 if (CHAR_OR_CHAR_INTP (range))
2159 return Fget_char_table (range, char_table);
2160 CHECK_CHAR_TABLE (char_table);
2161 ct = XCHAR_TABLE (char_table);
2163 decode_char_table_range (range, &rainj);
2166 case CHARTAB_RANGE_ALL:
2169 if (UINT8_BYTE_TABLE_P (ct->table))
2171 else if (UINT16_BYTE_TABLE_P (ct->table))
2173 else if (BYTE_TABLE_P (ct->table))
2177 #else /* non UTF2000 */
2179 Lisp_Object first = ct->ascii[0];
2181 for (i = 1; i < NUM_ASCII_CHARS; i++)
2182 if (!EQ (first, ct->ascii[i]))
2186 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
2189 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
2190 || i == LEADING_BYTE_ASCII
2191 || i == LEADING_BYTE_CONTROL_1)
2193 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
2199 #endif /* non UTF2000 */
2203 case CHARTAB_RANGE_CHARSET:
2207 if (EQ (rainj.charset, Vcharset_ascii))
2210 Lisp_Object first = ct->ascii[0];
2212 for (i = 1; i < 128; i++)
2213 if (!EQ (first, ct->ascii[i]))
2218 if (EQ (rainj.charset, Vcharset_control_1))
2221 Lisp_Object first = ct->ascii[128];
2223 for (i = 129; i < 160; i++)
2224 if (!EQ (first, ct->ascii[i]))
2230 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2232 if (CHAR_TABLE_ENTRYP (val))
2238 case CHARTAB_RANGE_ROW:
2243 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2245 if (!CHAR_TABLE_ENTRYP (val))
2247 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
2248 if (CHAR_TABLE_ENTRYP (val))
2252 #endif /* not UTF2000 */
2253 #endif /* not MULE */
2259 return Qnil; /* not reached */
2263 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2264 Error_behavior errb)
2268 case CHAR_TABLE_TYPE_SYNTAX:
2269 if (!ERRB_EQ (errb, ERROR_ME))
2270 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2271 && CHAR_OR_CHAR_INTP (XCDR (value)));
2274 Lisp_Object cdr = XCDR (value);
2275 CHECK_INT (XCAR (value));
2276 CHECK_CHAR_COERCE_INT (cdr);
2283 case CHAR_TABLE_TYPE_CATEGORY:
2284 if (!ERRB_EQ (errb, ERROR_ME))
2285 return CATEGORY_TABLE_VALUEP (value);
2286 CHECK_CATEGORY_TABLE_VALUE (value);
2290 case CHAR_TABLE_TYPE_GENERIC:
2293 case CHAR_TABLE_TYPE_DISPLAY:
2295 maybe_signal_simple_error ("Display char tables not yet implemented",
2296 value, Qchar_table, errb);
2299 case CHAR_TABLE_TYPE_CHAR:
2300 if (!ERRB_EQ (errb, ERROR_ME))
2301 return CHAR_OR_CHAR_INTP (value);
2302 CHECK_CHAR_COERCE_INT (value);
2309 return 0; /* not reached */
2313 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2317 case CHAR_TABLE_TYPE_SYNTAX:
2320 Lisp_Object car = XCAR (value);
2321 Lisp_Object cdr = XCDR (value);
2322 CHECK_CHAR_COERCE_INT (cdr);
2323 return Fcons (car, cdr);
2326 case CHAR_TABLE_TYPE_CHAR:
2327 CHECK_CHAR_COERCE_INT (value);
2335 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2336 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2338 (value, char_table_type))
2340 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2342 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2345 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2346 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2348 (value, char_table_type))
2350 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2352 check_valid_char_table_value (value, type, ERROR_ME);
2357 Lisp_Char_Table* char_attribute_table_to_put;
2358 Lisp_Object Qput_char_table_map_function;
2359 Lisp_Object value_to_put;
2361 DEFUN ("put-char-table-map-function",
2362 Fput_char_table_map_function, 2, 2, 0, /*
2363 For internal use. Don't use it.
2367 put_char_id_table_0 (char_attribute_table_to_put, c, value_to_put);
2372 /* Assign VAL to all characters in RANGE in char table CT. */
2375 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2378 switch (range->type)
2380 case CHARTAB_RANGE_ALL:
2381 /* printf ("put-char-table: range = all\n"); */
2382 fill_char_table (ct, val);
2383 return; /* avoid the duplicate call to update_syntax_table() below,
2384 since fill_char_table() also did that. */
2387 case CHARTAB_RANGE_DEFAULT:
2388 ct->default_value = val;
2393 case CHARTAB_RANGE_CHARSET:
2397 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2399 /* printf ("put-char-table: range = charset: %d\n",
2400 XCHARSET_LEADING_BYTE (range->charset));
2402 if ( CHAR_TABLEP (encoding_table) )
2405 char_attribute_table_to_put = ct;
2407 Fmap_char_attribute (Qput_char_table_map_function,
2408 XCHAR_TABLE_NAME (encoding_table),
2411 for (c = 0; c < 1 << 24; c++)
2413 if ( INTP (get_char_id_table (XCHAR_TABLE(encoding_table),
2415 put_char_id_table_0 (ct, c, val);
2421 for (c = 0; c < 1 << 24; c++)
2423 if ( charset_code_point (range->charset, c) >= 0 )
2424 put_char_id_table_0 (ct, c, val);
2429 if (EQ (range->charset, Vcharset_ascii))
2432 for (i = 0; i < 128; i++)
2435 else if (EQ (range->charset, Vcharset_control_1))
2438 for (i = 128; i < 160; i++)
2443 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2444 ct->level1[lb] = val;
2449 case CHARTAB_RANGE_ROW:
2452 int cell_min, cell_max, i;
2454 i = XCHARSET_CELL_RANGE (range->charset);
2456 cell_max = i & 0xFF;
2457 for (i = cell_min; i <= cell_max; i++)
2459 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2461 if ( charset_code_point (range->charset, ch) >= 0 )
2462 put_char_id_table_0 (ct, ch, val);
2467 Lisp_Char_Table_Entry *cte;
2468 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2469 /* make sure that there is a separate entry for the row. */
2470 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2471 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2472 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2473 cte->level2[range->row - 32] = val;
2475 #endif /* not UTF2000 */
2479 case CHARTAB_RANGE_CHAR:
2481 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2482 put_char_id_table_0 (ct, range->ch, val);
2486 Lisp_Object charset;
2489 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2490 if (EQ (charset, Vcharset_ascii))
2491 ct->ascii[byte1] = val;
2492 else if (EQ (charset, Vcharset_control_1))
2493 ct->ascii[byte1 + 128] = val;
2496 Lisp_Char_Table_Entry *cte;
2497 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2498 /* make sure that there is a separate entry for the row. */
2499 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2500 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2501 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2502 /* now CTE is a char table entry for the charset;
2503 each entry is for a single row (or character of
2504 a one-octet charset). */
2505 if (XCHARSET_DIMENSION (charset) == 1)
2506 cte->level2[byte1 - 32] = val;
2509 /* assigning to one character in a two-octet charset. */
2510 /* make sure that the charset row contains a separate
2511 entry for each character. */
2512 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2513 cte->level2[byte1 - 32] =
2514 make_char_table_entry (cte->level2[byte1 - 32]);
2515 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2516 cte->level2[byte2 - 32] = val;
2520 #else /* not MULE */
2521 ct->ascii[(unsigned char) (range->ch)] = val;
2523 #endif /* not MULE */
2527 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2528 update_syntax_table (ct);
2532 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2533 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2535 RANGE specifies one or more characters to be affected and should be
2536 one of the following:
2538 -- t (all characters are affected)
2539 -- A charset (only allowed when Mule support is present)
2540 -- A vector of two elements: a two-octet charset and a row number
2541 (only allowed when Mule support is present)
2542 -- A single character
2544 VALUE must be a value appropriate for the type of CHAR-TABLE.
2545 See `valid-char-table-type-p'.
2547 (range, value, char_table))
2549 Lisp_Char_Table *ct;
2550 struct chartab_range rainj;
2552 CHECK_CHAR_TABLE (char_table);
2553 ct = XCHAR_TABLE (char_table);
2554 check_valid_char_table_value (value, ct->type, ERROR_ME);
2555 decode_char_table_range (range, &rainj);
2556 value = canonicalize_char_table_value (value, ct->type);
2557 put_char_table (ct, &rainj, value);
2562 /* Map FN over the ASCII chars in CT. */
2565 map_over_charset_ascii (Lisp_Char_Table *ct,
2566 int (*fn) (struct chartab_range *range,
2567 Lisp_Object val, void *arg),
2570 struct chartab_range rainj;
2579 rainj.type = CHARTAB_RANGE_CHAR;
2581 for (i = start, retval = 0; i < stop && retval == 0; i++)
2583 rainj.ch = (Emchar) i;
2584 retval = (fn) (&rainj, ct->ascii[i], arg);
2592 /* Map FN over the Control-1 chars in CT. */
2595 map_over_charset_control_1 (Lisp_Char_Table *ct,
2596 int (*fn) (struct chartab_range *range,
2597 Lisp_Object val, void *arg),
2600 struct chartab_range rainj;
2603 int stop = start + 32;
2605 rainj.type = CHARTAB_RANGE_CHAR;
2607 for (i = start, retval = 0; i < stop && retval == 0; i++)
2609 rainj.ch = (Emchar) (i);
2610 retval = (fn) (&rainj, ct->ascii[i], arg);
2616 /* Map FN over the row ROW of two-byte charset CHARSET.
2617 There must be a separate value for that row in the char table.
2618 CTE specifies the char table entry for CHARSET. */
2621 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2622 Lisp_Object charset, int row,
2623 int (*fn) (struct chartab_range *range,
2624 Lisp_Object val, void *arg),
2627 Lisp_Object val = cte->level2[row - 32];
2629 if (!CHAR_TABLE_ENTRYP (val))
2631 struct chartab_range rainj;
2633 rainj.type = CHARTAB_RANGE_ROW;
2634 rainj.charset = charset;
2636 return (fn) (&rainj, val, arg);
2640 struct chartab_range rainj;
2642 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2643 int start = charset94_p ? 33 : 32;
2644 int stop = charset94_p ? 127 : 128;
2646 cte = XCHAR_TABLE_ENTRY (val);
2648 rainj.type = CHARTAB_RANGE_CHAR;
2650 for (i = start, retval = 0; i < stop && retval == 0; i++)
2652 rainj.ch = MAKE_CHAR (charset, row, i);
2653 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2661 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2662 int (*fn) (struct chartab_range *range,
2663 Lisp_Object val, void *arg),
2666 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2667 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2669 if (!CHARSETP (charset)
2670 || lb == LEADING_BYTE_ASCII
2671 || lb == LEADING_BYTE_CONTROL_1)
2674 if (!CHAR_TABLE_ENTRYP (val))
2676 struct chartab_range rainj;
2678 rainj.type = CHARTAB_RANGE_CHARSET;
2679 rainj.charset = charset;
2680 return (fn) (&rainj, val, arg);
2684 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2685 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2686 int start = charset94_p ? 33 : 32;
2687 int stop = charset94_p ? 127 : 128;
2690 if (XCHARSET_DIMENSION (charset) == 1)
2692 struct chartab_range rainj;
2693 rainj.type = CHARTAB_RANGE_CHAR;
2695 for (i = start, retval = 0; i < stop && retval == 0; i++)
2697 rainj.ch = MAKE_CHAR (charset, i, 0);
2698 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2703 for (i = start, retval = 0; i < stop && retval == 0; i++)
2704 retval = map_over_charset_row (cte, charset, i, fn, arg);
2712 #endif /* not UTF2000 */
2715 struct map_char_table_for_charset_arg
2717 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2718 Lisp_Char_Table *ct;
2723 map_char_table_for_charset_fun (struct chartab_range *range,
2724 Lisp_Object val, void *arg)
2726 struct map_char_table_for_charset_arg *closure =
2727 (struct map_char_table_for_charset_arg *) arg;
2730 switch (range->type)
2732 case CHARTAB_RANGE_ALL:
2735 case CHARTAB_RANGE_DEFAULT:
2738 case CHARTAB_RANGE_CHARSET:
2741 case CHARTAB_RANGE_ROW:
2744 case CHARTAB_RANGE_CHAR:
2745 ret = get_char_table (range->ch, closure->ct);
2746 if (!UNBOUNDP (ret))
2747 return (closure->fn) (range, ret, closure->arg);
2759 /* Map FN (with client data ARG) over range RANGE in char table CT.
2760 Mapping stops the first time FN returns non-zero, and that value
2761 becomes the return value of map_char_table(). */
2764 map_char_table (Lisp_Char_Table *ct,
2765 struct chartab_range *range,
2766 int (*fn) (struct chartab_range *range,
2767 Lisp_Object val, void *arg),
2770 switch (range->type)
2772 case CHARTAB_RANGE_ALL:
2774 if (!UNBOUNDP (ct->default_value))
2776 struct chartab_range rainj;
2779 rainj.type = CHARTAB_RANGE_DEFAULT;
2780 retval = (fn) (&rainj, ct->default_value, arg);
2784 if (UINT8_BYTE_TABLE_P (ct->table))
2785 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
2787 else if (UINT16_BYTE_TABLE_P (ct->table))
2788 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
2790 else if (BYTE_TABLE_P (ct->table))
2791 return map_over_byte_table (XBYTE_TABLE(ct->table), ct,
2793 else if (EQ (ct->table, Qunloaded))
2796 struct chartab_range rainj;
2799 Emchar c1 = c + unit;
2802 rainj.type = CHARTAB_RANGE_CHAR;
2804 for (retval = 0; c < c1 && retval == 0; c++)
2806 Lisp_Object ret = get_char_id_table (ct, c);
2808 if (!UNBOUNDP (ret))
2811 retval = (fn) (&rainj, ct->table, arg);
2816 ct->table = Qunbound;
2819 else if (!UNBOUNDP (ct->table))
2820 return (fn) (range, ct->table, arg);
2826 retval = map_over_charset_ascii (ct, fn, arg);
2830 retval = map_over_charset_control_1 (ct, fn, arg);
2835 Charset_ID start = MIN_LEADING_BYTE;
2836 Charset_ID stop = start + NUM_LEADING_BYTES;
2838 for (i = start, retval = 0; i < stop && retval == 0; i++)
2840 retval = map_over_other_charset (ct, i, fn, arg);
2849 case CHARTAB_RANGE_DEFAULT:
2850 if (!UNBOUNDP (ct->default_value))
2851 return (fn) (range, ct->default_value, arg);
2856 case CHARTAB_RANGE_CHARSET:
2859 Lisp_Object encoding_table
2860 = XCHARSET_ENCODING_TABLE (range->charset);
2862 if (!NILP (encoding_table))
2864 struct chartab_range rainj;
2865 struct map_char_table_for_charset_arg mcarg;
2867 #ifdef HAVE_DATABASE
2868 if (XCHAR_TABLE_UNLOADED(encoding_table))
2869 Fload_char_attribute_table (XCHAR_TABLE_NAME (encoding_table));
2874 rainj.type = CHARTAB_RANGE_ALL;
2875 return map_char_table (XCHAR_TABLE(encoding_table),
2877 &map_char_table_for_charset_fun,
2883 return map_over_other_charset (ct,
2884 XCHARSET_LEADING_BYTE (range->charset),
2888 case CHARTAB_RANGE_ROW:
2891 int cell_min, cell_max, i;
2893 struct chartab_range rainj;
2895 i = XCHARSET_CELL_RANGE (range->charset);
2897 cell_max = i & 0xFF;
2898 rainj.type = CHARTAB_RANGE_CHAR;
2899 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2901 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2903 if ( charset_code_point (range->charset, ch) >= 0 )
2906 = get_byte_table (get_byte_table
2910 (unsigned char)(ch >> 24)),
2911 (unsigned char) (ch >> 16)),
2912 (unsigned char) (ch >> 8)),
2913 (unsigned char) ch);
2916 val = ct->default_value;
2918 retval = (fn) (&rainj, val, arg);
2925 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
2926 - MIN_LEADING_BYTE];
2927 if (!CHAR_TABLE_ENTRYP (val))
2929 struct chartab_range rainj;
2931 rainj.type = CHARTAB_RANGE_ROW;
2932 rainj.charset = range->charset;
2933 rainj.row = range->row;
2934 return (fn) (&rainj, val, arg);
2937 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
2938 range->charset, range->row,
2941 #endif /* not UTF2000 */
2944 case CHARTAB_RANGE_CHAR:
2946 Emchar ch = range->ch;
2947 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
2949 if (!UNBOUNDP (val))
2951 struct chartab_range rainj;
2953 rainj.type = CHARTAB_RANGE_CHAR;
2955 return (fn) (&rainj, val, arg);
2967 struct slow_map_char_table_arg
2969 Lisp_Object function;
2974 slow_map_char_table_fun (struct chartab_range *range,
2975 Lisp_Object val, void *arg)
2977 Lisp_Object ranjarg = Qnil;
2978 struct slow_map_char_table_arg *closure =
2979 (struct slow_map_char_table_arg *) arg;
2981 switch (range->type)
2983 case CHARTAB_RANGE_ALL:
2988 case CHARTAB_RANGE_DEFAULT:
2994 case CHARTAB_RANGE_CHARSET:
2995 ranjarg = XCHARSET_NAME (range->charset);
2998 case CHARTAB_RANGE_ROW:
2999 ranjarg = vector2 (XCHARSET_NAME (range->charset),
3000 make_int (range->row));
3003 case CHARTAB_RANGE_CHAR:
3004 ranjarg = make_char (range->ch);
3010 closure->retval = call2 (closure->function, ranjarg, val);
3011 return !NILP (closure->retval);
3014 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
3015 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
3016 each key and value in the table.
3018 RANGE specifies a subrange to map over and is in the same format as
3019 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3022 (function, char_table, range))
3024 Lisp_Char_Table *ct;
3025 struct slow_map_char_table_arg slarg;
3026 struct gcpro gcpro1, gcpro2;
3027 struct chartab_range rainj;
3029 CHECK_CHAR_TABLE (char_table);
3030 ct = XCHAR_TABLE (char_table);
3033 decode_char_table_range (range, &rainj);
3034 slarg.function = function;
3035 slarg.retval = Qnil;
3036 GCPRO2 (slarg.function, slarg.retval);
3037 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3040 return slarg.retval;
3044 /************************************************************************/
3045 /* Character Attributes */
3046 /************************************************************************/
3050 Lisp_Object Vchar_attribute_hash_table;
3052 /* We store the char-attributes in hash tables with the names as the
3053 key and the actual char-id-table object as the value. Occasionally
3054 we need to use them in a list format. These routines provide us
3056 struct char_attribute_list_closure
3058 Lisp_Object *char_attribute_list;
3062 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
3063 void *char_attribute_list_closure)
3065 /* This function can GC */
3066 struct char_attribute_list_closure *calcl
3067 = (struct char_attribute_list_closure*) char_attribute_list_closure;
3068 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
3070 *char_attribute_list = Fcons (key, *char_attribute_list);
3074 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
3075 Return the list of all existing character attributes except coded-charsets.
3079 Lisp_Object char_attribute_list = Qnil;
3080 struct gcpro gcpro1;
3081 struct char_attribute_list_closure char_attribute_list_closure;
3083 GCPRO1 (char_attribute_list);
3084 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
3085 elisp_maphash (add_char_attribute_to_list_mapper,
3086 Vchar_attribute_hash_table,
3087 &char_attribute_list_closure);
3089 return char_attribute_list;
3092 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
3093 Return char-id-table corresponding to ATTRIBUTE.
3097 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
3101 /* We store the char-id-tables in hash tables with the attributes as
3102 the key and the actual char-id-table object as the value. Each
3103 char-id-table stores values of an attribute corresponding with
3104 characters. Occasionally we need to get attributes of a character
3105 in a association-list format. These routines provide us with
3107 struct char_attribute_alist_closure
3110 Lisp_Object *char_attribute_alist;
3114 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
3115 void *char_attribute_alist_closure)
3117 /* This function can GC */
3118 struct char_attribute_alist_closure *caacl =
3119 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
3121 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
3122 if (!UNBOUNDP (ret))
3124 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
3125 *char_attribute_alist
3126 = Fcons (Fcons (key, ret), *char_attribute_alist);
3131 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
3132 Return the alist of attributes of CHARACTER.
3136 struct gcpro gcpro1;
3137 struct char_attribute_alist_closure char_attribute_alist_closure;
3138 Lisp_Object alist = Qnil;
3140 CHECK_CHAR (character);
3143 char_attribute_alist_closure.char_id = XCHAR (character);
3144 char_attribute_alist_closure.char_attribute_alist = &alist;
3145 elisp_maphash (add_char_attribute_alist_mapper,
3146 Vchar_attribute_hash_table,
3147 &char_attribute_alist_closure);
3153 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
3154 Return the value of CHARACTER's ATTRIBUTE.
3155 Return DEFAULT-VALUE if the value is not exist.
3157 (character, attribute, default_value))
3161 CHECK_CHAR (character);
3163 if (CHARSETP (attribute))
3164 attribute = XCHARSET_NAME (attribute);
3166 table = Fgethash (attribute, Vchar_attribute_hash_table,
3168 if (!UNBOUNDP (table))
3170 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
3172 if (!UNBOUNDP (ret))
3175 return default_value;
3178 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
3179 Store CHARACTER's ATTRIBUTE with VALUE.
3181 (character, attribute, value))
3183 Lisp_Object ccs = Ffind_charset (attribute);
3187 CHECK_CHAR (character);
3188 value = put_char_ccs_code_point (character, ccs, value);
3190 else if (EQ (attribute, Q_decomposition))
3192 #ifndef HAVE_DATABASE
3196 CHECK_CHAR (character);
3198 signal_simple_error ("Invalid value for ->decomposition",
3201 if (CONSP (Fcdr (value)))
3203 #ifdef HAVE_DATABASE
3204 if (NILP (Fcdr (Fcdr (value))))
3206 Lisp_Object base = Fcar (value);
3207 Lisp_Object modifier = Fcar (Fcdr (value));
3211 base = make_char (XINT (base));
3212 Fsetcar (value, base);
3214 if (INTP (modifier))
3216 modifier = make_char (XINT (modifier));
3217 Fsetcar (Fcdr (value), modifier);
3221 Lisp_Object alist = Fget_char_attribute (base, Qcomposition, Qnil);
3222 Lisp_Object ret = Fassq (modifier, alist);
3225 Fput_char_attribute (base, Qcomposition,
3226 Fcons (Fcons (modifier, character), alist));
3228 Fsetcdr (ret, character);
3232 Lisp_Object rest = value;
3233 Lisp_Object table = Vcharacter_composition_table;
3237 GET_EXTERNAL_LIST_LENGTH (rest, len);
3238 seq = make_vector (len, Qnil);
3240 while (CONSP (rest))
3242 Lisp_Object v = Fcar (rest);
3245 = to_char_id (v, "Invalid value for ->decomposition", value);
3248 XVECTOR_DATA(seq)[i++] = v;
3250 XVECTOR_DATA(seq)[i++] = make_char (c);
3254 put_char_id_table (XCHAR_TABLE(table),
3255 make_char (c), character);
3260 ntable = get_char_id_table (XCHAR_TABLE(table), c);
3261 if (!CHAR_TABLEP (ntable))
3263 ntable = make_char_id_table (Qnil);
3264 put_char_id_table (XCHAR_TABLE(table),
3265 make_char (c), ntable);
3274 Lisp_Object v = Fcar (value);
3278 Emchar c = XINT (v);
3280 = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3285 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3286 make_char (c), Fcons (character, Qnil));
3288 else if (NILP (Fmemq (v, ret)))
3290 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3291 make_char (c), Fcons (character, ret));
3294 #ifndef HAVE_DATABASE
3295 seq = make_vector (1, v);
3298 #ifndef HAVE_DATABASE
3302 else if (EQ (attribute, Qto_ucs) || EQ (attribute, Q_ucs))
3307 CHECK_CHAR (character);
3309 signal_simple_error ("Invalid value for ->ucs", value);
3313 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table), c);
3316 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3317 make_char (c), Fcons (character, Qnil));
3319 else if (NILP (Fmemq (character, ret)))
3321 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3322 make_char (c), Fcons (character, ret));
3325 if (EQ (attribute, Q_ucs))
3326 attribute = Qto_ucs;
3330 Lisp_Object table = Fgethash (attribute,
3331 Vchar_attribute_hash_table,
3336 table = make_char_id_table (Qunbound);
3337 Fputhash (attribute, table, Vchar_attribute_hash_table);
3338 #ifdef HAVE_DATABASE
3339 XCHAR_TABLE_NAME (table) = attribute;
3342 put_char_id_table (XCHAR_TABLE(table), character, value);
3347 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3348 Remove CHARACTER's ATTRIBUTE.
3350 (character, attribute))
3354 CHECK_CHAR (character);
3355 ccs = Ffind_charset (attribute);
3358 return remove_char_ccs (character, ccs);
3362 Lisp_Object table = Fgethash (attribute,
3363 Vchar_attribute_hash_table,
3365 if (!UNBOUNDP (table))
3367 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3375 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
3378 Lisp_Object db_dir = Vexec_directory;
3381 db_dir = build_string ("../lib-src");
3383 db_dir = Fexpand_file_name (build_string ("char-db"), db_dir);
3384 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3385 Fmake_directory_internal (db_dir);
3387 db_dir = Fexpand_file_name (Fsymbol_name (key_type), db_dir);
3388 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3389 Fmake_directory_internal (db_dir);
3392 Lisp_Object attribute_name = Fsymbol_name (attribute);
3393 Lisp_Object dest = Qnil, ret;
3395 struct gcpro gcpro1, gcpro2;
3396 int len = XSTRING_CHAR_LENGTH (attribute_name);
3400 for (i = 0; i < len; i++)
3402 Emchar c = string_char (XSTRING (attribute_name), i);
3404 if ( (c == '/') || (c == '%') )
3408 sprintf (str, "%%%02X", c);
3409 dest = concat3 (dest,
3410 Fsubstring (attribute_name,
3411 make_int (base), make_int (i)),
3412 build_string (str));
3416 ret = Fsubstring (attribute_name, make_int (base), make_int (len));
3417 dest = concat2 (dest, ret);
3419 return Fexpand_file_name (dest, db_dir);
3422 return Fexpand_file_name (Fsymbol_name (attribute), db_dir);
3426 DEFUN ("save-char-attribute-table", Fsave_char_attribute_table, 1, 1, 0, /*
3427 Save values of ATTRIBUTE into database file.
3431 #ifdef HAVE_DATABASE
3432 Lisp_Object table = Fgethash (attribute,
3433 Vchar_attribute_hash_table, Qunbound);
3434 Lisp_Char_Table *ct;
3435 Lisp_Object db_file;
3438 if (CHAR_TABLEP (table))
3439 ct = XCHAR_TABLE (table);
3443 db_file = char_attribute_system_db_file (Qsystem_char_id, attribute, 1);
3444 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
3447 if (UINT8_BYTE_TABLE_P (ct->table))
3448 save_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct, db, 0, 3);
3449 else if (UINT16_BYTE_TABLE_P (ct->table))
3450 save_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct, db, 0, 3);
3451 else if (BYTE_TABLE_P (ct->table))
3452 save_byte_table (XBYTE_TABLE(ct->table), ct, db, 0, 3);
3453 Fclose_database (db);
3463 DEFUN ("mount-char-attribute-table", Fmount_char_attribute_table, 1, 1, 0, /*
3464 Mount database file on char-attribute-table ATTRIBUTE.
3468 #ifdef HAVE_DATABASE
3469 Lisp_Object table = Fgethash (attribute,
3470 Vchar_attribute_hash_table, Qunbound);
3472 if (UNBOUNDP (table))
3474 Lisp_Char_Table *ct;
3476 table = make_char_id_table (Qunbound);
3477 Fputhash (attribute, table, Vchar_attribute_hash_table);
3478 XCHAR_TABLE_NAME(table) = attribute;
3479 ct = XCHAR_TABLE (table);
3480 ct->table = Qunloaded;
3481 XCHAR_TABLE_UNLOADED(table) = 1;
3489 DEFUN ("close-char-attribute-table", Fclose_char_attribute_table, 1, 1, 0, /*
3490 Close database of ATTRIBUTE.
3494 #ifdef HAVE_DATABASE
3495 Lisp_Object table = Fgethash (attribute,
3496 Vchar_attribute_hash_table, Qunbound);
3497 Lisp_Char_Table *ct;
3499 if (CHAR_TABLEP (table))
3500 ct = XCHAR_TABLE (table);
3506 if (!NILP (Fdatabase_live_p (ct->db)))
3507 Fclose_database (ct->db);
3514 DEFUN ("reset-char-attribute-table", Freset_char_attribute_table, 1, 1, 0, /*
3515 Reset values of ATTRIBUTE with database file.
3519 #ifdef HAVE_DATABASE
3520 Lisp_Object table = Fgethash (attribute,
3521 Vchar_attribute_hash_table, Qunbound);
3522 Lisp_Char_Table *ct;
3524 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3526 if (!NILP (Ffile_exists_p (db_file)))
3528 if (UNBOUNDP (table))
3530 table = make_char_id_table (Qunbound);
3531 Fputhash (attribute, table, Vchar_attribute_hash_table);
3532 XCHAR_TABLE_NAME(table) = attribute;
3534 ct = XCHAR_TABLE (table);
3535 ct->table = Qunloaded;
3536 if (!NILP (Fdatabase_live_p (ct->db)))
3537 Fclose_database (ct->db);
3539 XCHAR_TABLE_UNLOADED(table) = 1;
3546 #ifdef HAVE_DATABASE
3548 load_char_attribute_maybe (Lisp_Char_Table* cit, Emchar ch)
3550 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3552 if (!NILP (attribute))
3554 if (NILP (Fdatabase_live_p (cit->db)))
3557 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3559 cit->db = Fopen_database (db_file, Qnil, Qnil,
3560 build_string ("r"), Qnil);
3562 if (!NILP (cit->db))
3565 = Fget_database (Fprin1_to_string (make_char (ch), Qnil),
3567 if (!UNBOUNDP (val))
3571 if (!NILP (Vchar_db_stingy_mode))
3573 Fclose_database (cit->db);
3582 Lisp_Char_Table* char_attribute_table_to_load;
3584 Lisp_Object Qload_char_attribute_table_map_function;
3586 DEFUN ("load-char-attribute-table-map-function",
3587 Fload_char_attribute_table_map_function, 2, 2, 0, /*
3588 For internal use. Don't use it.
3592 Lisp_Object c = Fread (key);
3593 Emchar code = XCHAR (c);
3594 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3596 if (EQ (ret, Qunloaded))
3597 put_char_id_table_0 (char_attribute_table_to_load, code, Fread (value));
3602 DEFUN ("load-char-attribute-table", Fload_char_attribute_table, 1, 1, 0, /*
3603 Load values of ATTRIBUTE into database file.
3607 #ifdef HAVE_DATABASE
3608 Lisp_Object table = Fgethash (attribute,
3609 Vchar_attribute_hash_table,
3611 if (CHAR_TABLEP (table))
3613 Lisp_Char_Table *ct = XCHAR_TABLE (table);
3615 if (NILP (Fdatabase_live_p (ct->db)))
3618 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3620 ct->db = Fopen_database (db_file, Qnil, Qnil,
3621 build_string ("r"), Qnil);
3625 struct gcpro gcpro1;
3627 char_attribute_table_to_load = XCHAR_TABLE (table);
3629 Fmap_database (Qload_char_attribute_table_map_function, ct->db);
3631 Fclose_database (ct->db);
3633 XCHAR_TABLE_UNLOADED(table) = 0;
3641 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3642 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3643 each key and value in the table.
3645 RANGE specifies a subrange to map over and is in the same format as
3646 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3649 (function, attribute, range))
3652 Lisp_Char_Table *ct;
3653 struct slow_map_char_table_arg slarg;
3654 struct gcpro gcpro1, gcpro2;
3655 struct chartab_range rainj;
3657 if (!NILP (ccs = Ffind_charset (attribute)))
3659 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3661 if (CHAR_TABLEP (encoding_table))
3662 ct = XCHAR_TABLE (encoding_table);
3668 Lisp_Object table = Fgethash (attribute,
3669 Vchar_attribute_hash_table,
3671 if (CHAR_TABLEP (table))
3672 ct = XCHAR_TABLE (table);
3678 decode_char_table_range (range, &rainj);
3679 #ifdef HAVE_DATABASE
3680 if (CHAR_TABLE_UNLOADED(ct))
3681 Fload_char_attribute_table (attribute);
3683 slarg.function = function;
3684 slarg.retval = Qnil;
3685 GCPRO2 (slarg.function, slarg.retval);
3686 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3689 return slarg.retval;
3692 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3693 Store character's ATTRIBUTES.
3697 Lisp_Object rest = attributes;
3698 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
3699 Lisp_Object character;
3703 while (CONSP (rest))
3705 Lisp_Object cell = Fcar (rest);
3709 signal_simple_error ("Invalid argument", attributes);
3710 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3711 && ((XCHARSET_FINAL (ccs) != 0) ||
3712 (XCHARSET_MAX_CODE (ccs) > 0) ||
3713 (EQ (ccs, Vcharset_chinese_big5))) )
3717 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3719 character = Fdecode_char (ccs, cell, Qnil);
3720 if (!NILP (character))
3721 goto setup_attributes;
3725 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3726 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3730 signal_simple_error ("Invalid argument", attributes);
3732 character = make_char (XINT (code) + 0x100000);
3733 goto setup_attributes;
3737 else if (!INTP (code))
3738 signal_simple_error ("Invalid argument", attributes);
3740 character = make_char (XINT (code));
3744 while (CONSP (rest))
3746 Lisp_Object cell = Fcar (rest);
3749 signal_simple_error ("Invalid argument", attributes);
3751 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
3757 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
3758 Retrieve the character of the given ATTRIBUTES.
3762 Lisp_Object rest = attributes;
3765 while (CONSP (rest))
3767 Lisp_Object cell = Fcar (rest);
3771 signal_simple_error ("Invalid argument", attributes);
3772 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
3776 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3778 return Fdecode_char (ccs, cell, Qnil);
3782 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3783 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3786 signal_simple_error ("Invalid argument", attributes);
3788 return make_char (XINT (code) + 0x100000);
3796 /************************************************************************/
3797 /* Char table read syntax */
3798 /************************************************************************/
3801 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
3802 Error_behavior errb)
3804 /* #### should deal with ERRB */
3805 symbol_to_char_table_type (value);
3810 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
3811 Error_behavior errb)
3815 /* #### should deal with ERRB */
3816 EXTERNAL_LIST_LOOP (rest, value)
3818 Lisp_Object range = XCAR (rest);
3819 struct chartab_range dummy;
3823 signal_simple_error ("Invalid list format", value);
3826 if (!CONSP (XCDR (range))
3827 || !NILP (XCDR (XCDR (range))))
3828 signal_simple_error ("Invalid range format", range);
3829 decode_char_table_range (XCAR (range), &dummy);
3830 decode_char_table_range (XCAR (XCDR (range)), &dummy);
3833 decode_char_table_range (range, &dummy);
3840 chartab_instantiate (Lisp_Object data)
3842 Lisp_Object chartab;
3843 Lisp_Object type = Qgeneric;
3844 Lisp_Object dataval = Qnil;
3846 while (!NILP (data))
3848 Lisp_Object keyw = Fcar (data);
3854 if (EQ (keyw, Qtype))
3856 else if (EQ (keyw, Qdata))
3860 chartab = Fmake_char_table (type);
3863 while (!NILP (data))
3865 Lisp_Object range = Fcar (data);
3866 Lisp_Object val = Fcar (Fcdr (data));
3868 data = Fcdr (Fcdr (data));
3871 if (CHAR_OR_CHAR_INTP (XCAR (range)))
3873 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
3874 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
3877 for (i = first; i <= last; i++)
3878 Fput_char_table (make_char (i), val, chartab);
3884 Fput_char_table (range, val, chartab);
3893 /************************************************************************/
3894 /* Category Tables, specifically */
3895 /************************************************************************/
3897 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
3898 Return t if OBJECT is a category table.
3899 A category table is a type of char table used for keeping track of
3900 categories. Categories are used for classifying characters for use
3901 in regexps -- you can refer to a category rather than having to use
3902 a complicated [] expression (and category lookups are significantly
3905 There are 95 different categories available, one for each printable
3906 character (including space) in the ASCII charset. Each category
3907 is designated by one such character, called a "category designator".
3908 They are specified in a regexp using the syntax "\\cX", where X is
3909 a category designator.
3911 A category table specifies, for each character, the categories that
3912 the character is in. Note that a character can be in more than one
3913 category. More specifically, a category table maps from a character
3914 to either the value nil (meaning the character is in no categories)
3915 or a 95-element bit vector, specifying for each of the 95 categories
3916 whether the character is in that category.
3918 Special Lisp functions are provided that abstract this, so you do not
3919 have to directly manipulate bit vectors.
3923 return (CHAR_TABLEP (object) &&
3924 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
3929 check_category_table (Lisp_Object object, Lisp_Object default_)
3933 while (NILP (Fcategory_table_p (object)))
3934 object = wrong_type_argument (Qcategory_table_p, object);
3939 check_category_char (Emchar ch, Lisp_Object table,
3940 unsigned int designator, unsigned int not_p)
3942 REGISTER Lisp_Object temp;
3943 Lisp_Char_Table *ctbl;
3944 #ifdef ERROR_CHECK_TYPECHECK
3945 if (NILP (Fcategory_table_p (table)))
3946 signal_simple_error ("Expected category table", table);
3948 ctbl = XCHAR_TABLE (table);
3949 temp = get_char_table (ch, ctbl);
3954 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
3957 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
3958 Return t if category of the character at POSITION includes DESIGNATOR.
3959 Optional third arg BUFFER specifies which buffer to use, and defaults
3960 to the current buffer.
3961 Optional fourth arg CATEGORY-TABLE specifies the category table to
3962 use, and defaults to BUFFER's category table.
3964 (position, designator, buffer, category_table))
3969 struct buffer *buf = decode_buffer (buffer, 0);
3971 CHECK_INT (position);
3972 CHECK_CATEGORY_DESIGNATOR (designator);
3973 des = XCHAR (designator);
3974 ctbl = check_category_table (category_table, Vstandard_category_table);
3975 ch = BUF_FETCH_CHAR (buf, XINT (position));
3976 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3979 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
3980 Return t if category of CHARACTER includes DESIGNATOR, else nil.
3981 Optional third arg CATEGORY-TABLE specifies the category table to use,
3982 and defaults to the standard category table.
3984 (character, designator, category_table))
3990 CHECK_CATEGORY_DESIGNATOR (designator);
3991 des = XCHAR (designator);
3992 CHECK_CHAR (character);
3993 ch = XCHAR (character);
3994 ctbl = check_category_table (category_table, Vstandard_category_table);
3995 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3998 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
3999 Return BUFFER's current category table.
4000 BUFFER defaults to the current buffer.
4004 return decode_buffer (buffer, 0)->category_table;
4007 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
4008 Return the standard category table.
4009 This is the one used for new buffers.
4013 return Vstandard_category_table;
4016 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
4017 Return a new category table which is a copy of CATEGORY-TABLE.
4018 CATEGORY-TABLE defaults to the standard category table.
4022 if (NILP (Vstandard_category_table))
4023 return Fmake_char_table (Qcategory);
4026 check_category_table (category_table, Vstandard_category_table);
4027 return Fcopy_char_table (category_table);
4030 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
4031 Select CATEGORY-TABLE as the new category table for BUFFER.
4032 BUFFER defaults to the current buffer if omitted.
4034 (category_table, buffer))
4036 struct buffer *buf = decode_buffer (buffer, 0);
4037 category_table = check_category_table (category_table, Qnil);
4038 buf->category_table = category_table;
4039 /* Indicate that this buffer now has a specified category table. */
4040 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
4041 return category_table;
4044 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
4045 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
4049 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
4052 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
4053 Return t if OBJECT is a category table value.
4054 Valid values are nil or a bit vector of size 95.
4058 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
4062 #define CATEGORYP(x) \
4063 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
4065 #define CATEGORY_SET(c) \
4066 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
4068 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
4069 The faster version of `!NILP (Faref (category_set, category))'. */
4070 #define CATEGORY_MEMBER(category, category_set) \
4071 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
4073 /* Return 1 if there is a word boundary between two word-constituent
4074 characters C1 and C2 if they appear in this order, else return 0.
4075 Use the macro WORD_BOUNDARY_P instead of calling this function
4078 int word_boundary_p (Emchar c1, Emchar c2);
4080 word_boundary_p (Emchar c1, Emchar c2)
4082 Lisp_Object category_set1, category_set2;
4087 if (COMPOSITE_CHAR_P (c1))
4088 c1 = cmpchar_component (c1, 0, 1);
4089 if (COMPOSITE_CHAR_P (c2))
4090 c2 = cmpchar_component (c2, 0, 1);
4093 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
4095 tail = Vword_separating_categories;
4100 tail = Vword_combining_categories;
4104 category_set1 = CATEGORY_SET (c1);
4105 if (NILP (category_set1))
4106 return default_result;
4107 category_set2 = CATEGORY_SET (c2);
4108 if (NILP (category_set2))
4109 return default_result;
4111 for (; CONSP (tail); tail = XCONS (tail)->cdr)
4113 Lisp_Object elt = XCONS(tail)->car;
4116 && CATEGORYP (XCONS (elt)->car)
4117 && CATEGORYP (XCONS (elt)->cdr)
4118 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
4119 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
4120 return !default_result;
4122 return default_result;
4128 syms_of_chartab (void)
4131 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
4132 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
4133 INIT_LRECORD_IMPLEMENTATION (byte_table);
4135 defsymbol (&Qsystem_char_id, "system-char-id");
4137 defsymbol (&Qto_ucs, "=>ucs");
4138 defsymbol (&Q_ucs, "->ucs");
4139 defsymbol (&Q_ucs_variants, "->ucs-variants");
4140 defsymbol (&Qcomposition, "composition");
4141 defsymbol (&Q_decomposition, "->decomposition");
4142 defsymbol (&Qcompat, "compat");
4143 defsymbol (&Qisolated, "isolated");
4144 defsymbol (&Qinitial, "initial");
4145 defsymbol (&Qmedial, "medial");
4146 defsymbol (&Qfinal, "final");
4147 defsymbol (&Qvertical, "vertical");
4148 defsymbol (&QnoBreak, "noBreak");
4149 defsymbol (&Qfraction, "fraction");
4150 defsymbol (&Qsuper, "super");
4151 defsymbol (&Qsub, "sub");
4152 defsymbol (&Qcircle, "circle");
4153 defsymbol (&Qsquare, "square");
4154 defsymbol (&Qwide, "wide");
4155 defsymbol (&Qnarrow, "narrow");
4156 defsymbol (&Qsmall, "small");
4157 defsymbol (&Qfont, "font");
4159 DEFSUBR (Fchar_attribute_list);
4160 DEFSUBR (Ffind_char_attribute_table);
4161 defsymbol (&Qput_char_table_map_function, "put-char-table-map-function");
4162 DEFSUBR (Fput_char_table_map_function);
4163 DEFSUBR (Fsave_char_attribute_table);
4164 DEFSUBR (Fmount_char_attribute_table);
4165 DEFSUBR (Freset_char_attribute_table);
4166 DEFSUBR (Fclose_char_attribute_table);
4167 #ifdef HAVE_DATABASE
4168 defsymbol (&Qload_char_attribute_table_map_function,
4169 "load-char-attribute-table-map-function");
4170 DEFSUBR (Fload_char_attribute_table_map_function);
4172 DEFSUBR (Fload_char_attribute_table);
4173 DEFSUBR (Fchar_attribute_alist);
4174 DEFSUBR (Fget_char_attribute);
4175 DEFSUBR (Fput_char_attribute);
4176 DEFSUBR (Fremove_char_attribute);
4177 DEFSUBR (Fmap_char_attribute);
4178 DEFSUBR (Fdefine_char);
4179 DEFSUBR (Ffind_char);
4180 DEFSUBR (Fchar_variants);
4182 DEFSUBR (Fget_composite_char);
4185 INIT_LRECORD_IMPLEMENTATION (char_table);
4189 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
4192 defsymbol (&Qcategory_table_p, "category-table-p");
4193 defsymbol (&Qcategory_designator_p, "category-designator-p");
4194 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
4197 defsymbol (&Qchar_table, "char-table");
4198 defsymbol (&Qchar_tablep, "char-table-p");
4200 DEFSUBR (Fchar_table_p);
4201 DEFSUBR (Fchar_table_type_list);
4202 DEFSUBR (Fvalid_char_table_type_p);
4203 DEFSUBR (Fchar_table_type);
4204 DEFSUBR (Freset_char_table);
4205 DEFSUBR (Fmake_char_table);
4206 DEFSUBR (Fcopy_char_table);
4207 DEFSUBR (Fget_char_table);
4208 DEFSUBR (Fget_range_char_table);
4209 DEFSUBR (Fvalid_char_table_value_p);
4210 DEFSUBR (Fcheck_valid_char_table_value);
4211 DEFSUBR (Fput_char_table);
4212 DEFSUBR (Fmap_char_table);
4215 DEFSUBR (Fcategory_table_p);
4216 DEFSUBR (Fcategory_table);
4217 DEFSUBR (Fstandard_category_table);
4218 DEFSUBR (Fcopy_category_table);
4219 DEFSUBR (Fset_category_table);
4220 DEFSUBR (Fcheck_category_at);
4221 DEFSUBR (Fchar_in_category_p);
4222 DEFSUBR (Fcategory_designator_p);
4223 DEFSUBR (Fcategory_table_value_p);
4229 vars_of_chartab (void)
4232 #ifndef HAVE_DATABASE
4233 staticpro (&Vcharacter_composition_table);
4234 Vcharacter_composition_table = make_char_id_table (Qnil);
4237 staticpro (&Vcharacter_variant_table);
4238 Vcharacter_variant_table = make_char_id_table (Qunbound);
4240 #ifdef HAVE_DATABASE
4241 DEFVAR_LISP ("char-db-stingy-mode", &Vchar_db_stingy_mode /*
4243 Vchar_db_stingy_mode = Qt;
4244 #endif /* HAVE_DATABASE */
4246 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
4247 Vall_syntax_tables = Qnil;
4248 dump_add_weak_object_chain (&Vall_syntax_tables);
4252 structure_type_create_chartab (void)
4254 struct structure_type *st;
4256 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
4258 define_structure_type_keyword (st, Qtype, chartab_type_validate);
4259 define_structure_type_keyword (st, Qdata, chartab_data_validate);
4263 complex_vars_of_chartab (void)
4266 staticpro (&Vchar_attribute_hash_table);
4267 Vchar_attribute_hash_table
4268 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
4269 #ifdef HAVE_DATABASE
4270 Fputhash (Q_ucs_variants, Vcharacter_variant_table,
4271 Vchar_attribute_hash_table);
4272 XCHAR_TABLE_NAME (Vcharacter_variant_table) = Q_ucs_variants;
4273 #endif /* HAVE_DATABASE */
4274 #endif /* UTF2000 */
4276 /* Set this now, so first buffer creation can refer to it. */
4277 /* Make it nil before calling copy-category-table
4278 so that copy-category-table will know not to try to copy from garbage */
4279 Vstandard_category_table = Qnil;
4280 Vstandard_category_table = Fcopy_category_table (Qnil);
4281 staticpro (&Vstandard_category_table);
4283 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
4284 List of pair (cons) of categories to determine word boundary.
4286 Emacs treats a sequence of word constituent characters as a single
4287 word (i.e. finds no word boundary between them) iff they belongs to
4288 the same charset. But, exceptions are allowed in the following cases.
4290 \(1) The case that characters are in different charsets is controlled
4291 by the variable `word-combining-categories'.
4293 Emacs finds no word boundary between characters of different charsets
4294 if they have categories matching some element of this list.
4296 More precisely, if an element of this list is a cons of category CAT1
4297 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4298 C2 which has CAT2, there's no word boundary between C1 and C2.
4300 For instance, to tell that ASCII characters and Latin-1 characters can
4301 form a single word, the element `(?l . ?l)' should be in this list
4302 because both characters have the category `l' (Latin characters).
4304 \(2) The case that character are in the same charset is controlled by
4305 the variable `word-separating-categories'.
4307 Emacs find a word boundary between characters of the same charset
4308 if they have categories matching some element of this list.
4310 More precisely, if an element of this list is a cons of category CAT1
4311 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4312 C2 which has CAT2, there's a word boundary between C1 and C2.
4314 For instance, to tell that there's a word boundary between Japanese
4315 Hiragana and Japanese Kanji (both are in the same charset), the
4316 element `(?H . ?C) should be in this list.
4319 Vword_combining_categories = Qnil;
4321 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
4322 List of pair (cons) of categories to determine word boundary.
4323 See the documentation of the variable `word-combining-categories'.
4326 Vword_separating_categories = Qnil;