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,2003 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;
67 CHISE_DS *default_chise_data_source = NULL;
72 EXFUN (Fchar_refs_simplify_char_specs, 1);
73 extern Lisp_Object Qideographic_structure;
75 EXFUN (Fmap_char_attribute, 3);
78 EXFUN (Fload_char_attribute_table, 1);
80 Lisp_Object Vchar_db_stingy_mode;
83 #define BT_UINT8_MIN 0
84 #define BT_UINT8_MAX (UCHAR_MAX - 4)
85 #define BT_UINT8_t (UCHAR_MAX - 3)
86 #define BT_UINT8_nil (UCHAR_MAX - 2)
87 #define BT_UINT8_unbound (UCHAR_MAX - 1)
88 #define BT_UINT8_unloaded UCHAR_MAX
90 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
91 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
92 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
93 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
94 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
97 INT_UINT8_P (Lisp_Object obj)
101 int num = XINT (obj);
103 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
110 UINT8_VALUE_P (Lisp_Object obj)
112 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
113 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
116 INLINE_HEADER unsigned char
117 UINT8_ENCODE (Lisp_Object obj)
119 if (EQ (obj, Qunloaded))
120 return BT_UINT8_unloaded;
121 else if (EQ (obj, Qunbound))
122 return BT_UINT8_unbound;
123 else if (EQ (obj, Qnil))
125 else if (EQ (obj, Qt))
131 INLINE_HEADER Lisp_Object
132 UINT8_DECODE (unsigned char n)
134 if (n == BT_UINT8_unloaded)
136 else if (n == BT_UINT8_unbound)
138 else if (n == BT_UINT8_nil)
140 else if (n == BT_UINT8_t)
147 mark_uint8_byte_table (Lisp_Object obj)
153 print_uint8_byte_table (Lisp_Object obj,
154 Lisp_Object printcharfun, int escapeflag)
156 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
158 struct gcpro gcpro1, gcpro2;
159 GCPRO2 (obj, printcharfun);
161 write_c_string ("\n#<uint8-byte-table", printcharfun);
162 for (i = 0; i < 256; i++)
164 unsigned char n = bte->property[i];
166 write_c_string ("\n ", printcharfun);
167 write_c_string (" ", printcharfun);
168 if (n == BT_UINT8_unbound)
169 write_c_string ("void", printcharfun);
170 else if (n == BT_UINT8_nil)
171 write_c_string ("nil", printcharfun);
172 else if (n == BT_UINT8_t)
173 write_c_string ("t", printcharfun);
178 sprintf (buf, "%hd", n);
179 write_c_string (buf, printcharfun);
183 write_c_string (">", printcharfun);
187 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
189 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
190 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
193 for (i = 0; i < 256; i++)
194 if (te1->property[i] != te2->property[i])
200 uint8_byte_table_hash (Lisp_Object obj, int depth)
202 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
206 for (i = 0; i < 256; i++)
207 hash = HASH2 (hash, te->property[i]);
211 static const struct lrecord_description uint8_byte_table_description[] = {
215 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
216 mark_uint8_byte_table,
217 print_uint8_byte_table,
218 0, uint8_byte_table_equal,
219 uint8_byte_table_hash,
220 uint8_byte_table_description,
221 Lisp_Uint8_Byte_Table);
224 make_uint8_byte_table (unsigned char initval)
228 Lisp_Uint8_Byte_Table *cte;
230 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
231 &lrecord_uint8_byte_table);
233 for (i = 0; i < 256; i++)
234 cte->property[i] = initval;
236 XSETUINT8_BYTE_TABLE (obj, cte);
241 copy_uint8_byte_table (Lisp_Object entry)
243 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
246 Lisp_Uint8_Byte_Table *ctenew
247 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
248 &lrecord_uint8_byte_table);
250 for (i = 0; i < 256; i++)
252 ctenew->property[i] = cte->property[i];
255 XSETUINT8_BYTE_TABLE (obj, ctenew);
260 uint8_byte_table_same_value_p (Lisp_Object obj)
262 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
263 unsigned char v0 = bte->property[0];
266 for (i = 1; i < 256; i++)
268 if (bte->property[i] != v0)
275 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
276 Emchar ofs, int place,
277 int (*fn) (struct chartab_range *range,
278 Lisp_Object val, void *arg),
281 struct chartab_range rainj;
283 int unit = 1 << (8 * place);
287 rainj.type = CHARTAB_RANGE_CHAR;
289 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
291 if (ct->property[i] == BT_UINT8_unloaded)
295 for (; c < c1 && retval == 0; c++)
297 Lisp_Object ret = get_char_id_table (root, c);
302 retval = (fn) (&rainj, ret, arg);
306 ct->property[i] = BT_UINT8_unbound;
310 else if (ct->property[i] != BT_UINT8_unbound)
313 for (; c < c1 && retval == 0; c++)
316 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
327 save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
329 CHISE_Feature feature,
333 Emchar ofs, int place,
334 Lisp_Object (*filter)(Lisp_Object value))
336 struct chartab_range rainj;
338 int unit = 1 << (8 * place);
342 rainj.type = CHARTAB_RANGE_CHAR;
344 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
346 if (ct->property[i] == BT_UINT8_unloaded)
350 else if (ct->property[i] != BT_UINT8_unbound)
353 for (; c < c1 && retval == 0; c++)
356 chise_char_set_feature_value
359 (Fprin1_to_string (UINT8_DECODE (ct->property[i]),
362 Fput_database (Fprin1_to_string (make_char (c), Qnil),
363 Fprin1_to_string (UINT8_DECODE (ct->property[i]),
375 #define BT_UINT16_MIN 0
376 #define BT_UINT16_MAX (USHRT_MAX - 4)
377 #define BT_UINT16_t (USHRT_MAX - 3)
378 #define BT_UINT16_nil (USHRT_MAX - 2)
379 #define BT_UINT16_unbound (USHRT_MAX - 1)
380 #define BT_UINT16_unloaded USHRT_MAX
382 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
383 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
384 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
385 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
388 INT_UINT16_P (Lisp_Object obj)
392 int num = XINT (obj);
394 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
401 UINT16_VALUE_P (Lisp_Object obj)
403 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
404 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
407 INLINE_HEADER unsigned short
408 UINT16_ENCODE (Lisp_Object obj)
410 if (EQ (obj, Qunloaded))
411 return BT_UINT16_unloaded;
412 else if (EQ (obj, Qunbound))
413 return BT_UINT16_unbound;
414 else if (EQ (obj, Qnil))
415 return BT_UINT16_nil;
416 else if (EQ (obj, Qt))
422 INLINE_HEADER Lisp_Object
423 UINT16_DECODE (unsigned short n)
425 if (n == BT_UINT16_unloaded)
427 else if (n == BT_UINT16_unbound)
429 else if (n == BT_UINT16_nil)
431 else if (n == BT_UINT16_t)
437 INLINE_HEADER unsigned short
438 UINT8_TO_UINT16 (unsigned char n)
440 if (n == BT_UINT8_unloaded)
441 return BT_UINT16_unloaded;
442 else if (n == BT_UINT8_unbound)
443 return BT_UINT16_unbound;
444 else if (n == BT_UINT8_nil)
445 return BT_UINT16_nil;
446 else if (n == BT_UINT8_t)
453 mark_uint16_byte_table (Lisp_Object obj)
459 print_uint16_byte_table (Lisp_Object obj,
460 Lisp_Object printcharfun, int escapeflag)
462 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
464 struct gcpro gcpro1, gcpro2;
465 GCPRO2 (obj, printcharfun);
467 write_c_string ("\n#<uint16-byte-table", printcharfun);
468 for (i = 0; i < 256; i++)
470 unsigned short n = bte->property[i];
472 write_c_string ("\n ", printcharfun);
473 write_c_string (" ", printcharfun);
474 if (n == BT_UINT16_unbound)
475 write_c_string ("void", printcharfun);
476 else if (n == BT_UINT16_nil)
477 write_c_string ("nil", printcharfun);
478 else if (n == BT_UINT16_t)
479 write_c_string ("t", printcharfun);
484 sprintf (buf, "%hd", n);
485 write_c_string (buf, printcharfun);
489 write_c_string (">", printcharfun);
493 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
495 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
496 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
499 for (i = 0; i < 256; i++)
500 if (te1->property[i] != te2->property[i])
506 uint16_byte_table_hash (Lisp_Object obj, int depth)
508 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
512 for (i = 0; i < 256; i++)
513 hash = HASH2 (hash, te->property[i]);
517 static const struct lrecord_description uint16_byte_table_description[] = {
521 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
522 mark_uint16_byte_table,
523 print_uint16_byte_table,
524 0, uint16_byte_table_equal,
525 uint16_byte_table_hash,
526 uint16_byte_table_description,
527 Lisp_Uint16_Byte_Table);
530 make_uint16_byte_table (unsigned short initval)
534 Lisp_Uint16_Byte_Table *cte;
536 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
537 &lrecord_uint16_byte_table);
539 for (i = 0; i < 256; i++)
540 cte->property[i] = initval;
542 XSETUINT16_BYTE_TABLE (obj, cte);
547 copy_uint16_byte_table (Lisp_Object entry)
549 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
552 Lisp_Uint16_Byte_Table *ctenew
553 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
554 &lrecord_uint16_byte_table);
556 for (i = 0; i < 256; i++)
558 ctenew->property[i] = cte->property[i];
561 XSETUINT16_BYTE_TABLE (obj, ctenew);
566 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
570 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
571 Lisp_Uint16_Byte_Table* cte;
573 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
574 &lrecord_uint16_byte_table);
575 for (i = 0; i < 256; i++)
577 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
579 XSETUINT16_BYTE_TABLE (obj, cte);
584 uint16_byte_table_same_value_p (Lisp_Object obj)
586 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
587 unsigned short v0 = bte->property[0];
590 for (i = 1; i < 256; i++)
592 if (bte->property[i] != v0)
599 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
600 Emchar ofs, int place,
601 int (*fn) (struct chartab_range *range,
602 Lisp_Object val, void *arg),
605 struct chartab_range rainj;
607 int unit = 1 << (8 * place);
611 rainj.type = CHARTAB_RANGE_CHAR;
613 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
615 if (ct->property[i] == BT_UINT16_unloaded)
619 for (; c < c1 && retval == 0; c++)
621 Lisp_Object ret = get_char_id_table (root, c);
626 retval = (fn) (&rainj, ret, arg);
630 ct->property[i] = BT_UINT16_unbound;
634 else if (ct->property[i] != BT_UINT16_unbound)
637 for (; c < c1 && retval == 0; c++)
640 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
651 save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
653 CHISE_Feature feature,
657 Emchar ofs, int place,
658 Lisp_Object (*filter)(Lisp_Object value))
660 struct chartab_range rainj;
662 int unit = 1 << (8 * place);
666 rainj.type = CHARTAB_RANGE_CHAR;
668 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
670 if (ct->property[i] == BT_UINT16_unloaded)
674 else if (ct->property[i] != BT_UINT16_unbound)
677 for (; c < c1 && retval == 0; c++)
680 chise_char_set_feature_value
683 (Fprin1_to_string (UINT16_DECODE (ct->property[i]),
686 Fput_database (Fprin1_to_string (make_char (c), Qnil),
687 Fprin1_to_string (UINT16_DECODE (ct->property[i]),
701 mark_byte_table (Lisp_Object obj)
703 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
706 for (i = 0; i < 256; i++)
708 mark_object (cte->property[i]);
714 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
716 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
718 struct gcpro gcpro1, gcpro2;
719 GCPRO2 (obj, printcharfun);
721 write_c_string ("\n#<byte-table", printcharfun);
722 for (i = 0; i < 256; i++)
724 Lisp_Object elt = bte->property[i];
726 write_c_string ("\n ", printcharfun);
727 write_c_string (" ", printcharfun);
728 if (EQ (elt, Qunbound))
729 write_c_string ("void", printcharfun);
731 print_internal (elt, printcharfun, escapeflag);
734 write_c_string (">", printcharfun);
738 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
740 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
741 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
744 for (i = 0; i < 256; i++)
745 if (BYTE_TABLE_P (cte1->property[i]))
747 if (BYTE_TABLE_P (cte2->property[i]))
749 if (!byte_table_equal (cte1->property[i],
750 cte2->property[i], depth + 1))
757 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
763 byte_table_hash (Lisp_Object obj, int depth)
765 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
767 return internal_array_hash (cte->property, 256, depth);
770 static const struct lrecord_description byte_table_description[] = {
771 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
775 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
780 byte_table_description,
784 make_byte_table (Lisp_Object initval)
788 Lisp_Byte_Table *cte;
790 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
792 for (i = 0; i < 256; i++)
793 cte->property[i] = initval;
795 XSETBYTE_TABLE (obj, cte);
800 copy_byte_table (Lisp_Object entry)
802 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
805 Lisp_Byte_Table *ctnew
806 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
808 for (i = 0; i < 256; i++)
810 if (UINT8_BYTE_TABLE_P (cte->property[i]))
812 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
814 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
816 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
818 else if (BYTE_TABLE_P (cte->property[i]))
820 ctnew->property[i] = copy_byte_table (cte->property[i]);
823 ctnew->property[i] = cte->property[i];
826 XSETBYTE_TABLE (obj, ctnew);
831 byte_table_same_value_p (Lisp_Object obj)
833 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
834 Lisp_Object v0 = bte->property[0];
837 for (i = 1; i < 256; i++)
839 if (!internal_equal (bte->property[i], v0, 0))
846 map_over_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
847 Emchar ofs, int place,
848 int (*fn) (struct chartab_range *range,
849 Lisp_Object val, void *arg),
854 int unit = 1 << (8 * place);
857 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
860 if (UINT8_BYTE_TABLE_P (v))
863 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
864 c, place - 1, fn, arg);
867 else if (UINT16_BYTE_TABLE_P (v))
870 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
871 c, place - 1, fn, arg);
874 else if (BYTE_TABLE_P (v))
876 retval = map_over_byte_table (XBYTE_TABLE(v), root,
877 c, place - 1, fn, arg);
880 else if (EQ (v, Qunloaded))
883 struct chartab_range rainj;
884 Emchar c1 = c + unit;
886 rainj.type = CHARTAB_RANGE_CHAR;
888 for (; c < c1 && retval == 0; c++)
890 Lisp_Object ret = get_char_id_table (root, c);
895 retval = (fn) (&rainj, ret, arg);
899 ct->property[i] = Qunbound;
903 else if (!UNBOUNDP (v))
905 struct chartab_range rainj;
906 Emchar c1 = c + unit;
908 rainj.type = CHARTAB_RANGE_CHAR;
910 for (; c < c1 && retval == 0; c++)
913 retval = (fn) (&rainj, v, arg);
924 save_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
926 CHISE_Feature feature,
930 Emchar ofs, int place,
931 Lisp_Object (*filter)(Lisp_Object value))
935 int unit = 1 << (8 * place);
938 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
941 if (UINT8_BYTE_TABLE_P (v))
943 save_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
949 c, place - 1, filter);
952 else if (UINT16_BYTE_TABLE_P (v))
954 save_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
960 c, place - 1, filter);
963 else if (BYTE_TABLE_P (v))
965 save_byte_table (XBYTE_TABLE(v), root,
971 c, place - 1, filter);
974 else if (EQ (v, Qunloaded))
978 else if (!UNBOUNDP (v))
980 struct chartab_range rainj;
981 Emchar c1 = c + unit;
986 rainj.type = CHARTAB_RANGE_CHAR;
988 for (; c < c1 && retval == 0; c++)
991 chise_char_set_feature_value
992 (c, feature, XSTRING_DATA (Fprin1_to_string (v, Qnil)));
994 Fput_database (Fprin1_to_string (make_char (c), Qnil),
995 Fprin1_to_string (v, Qnil),
1007 get_byte_table (Lisp_Object table, unsigned char idx)
1009 if (UINT8_BYTE_TABLE_P (table))
1010 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
1011 else if (UINT16_BYTE_TABLE_P (table))
1012 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
1013 else if (BYTE_TABLE_P (table))
1014 return XBYTE_TABLE(table)->property[idx];
1020 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
1022 if (UINT8_BYTE_TABLE_P (table))
1024 if (UINT8_VALUE_P (value))
1026 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1027 if (!UINT8_BYTE_TABLE_P (value) &&
1028 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1029 && uint8_byte_table_same_value_p (table))
1034 else if (UINT16_VALUE_P (value))
1036 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
1038 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
1043 Lisp_Object new = make_byte_table (Qnil);
1046 for (i = 0; i < 256; i++)
1048 XBYTE_TABLE(new)->property[i]
1049 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
1051 XBYTE_TABLE(new)->property[idx] = value;
1055 else if (UINT16_BYTE_TABLE_P (table))
1057 if (UINT16_VALUE_P (value))
1059 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1060 if (!UINT8_BYTE_TABLE_P (value) &&
1061 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1062 && uint16_byte_table_same_value_p (table))
1069 Lisp_Object new = make_byte_table (Qnil);
1072 for (i = 0; i < 256; i++)
1074 XBYTE_TABLE(new)->property[i]
1075 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
1077 XBYTE_TABLE(new)->property[idx] = value;
1081 else if (BYTE_TABLE_P (table))
1083 XBYTE_TABLE(table)->property[idx] = value;
1084 if (!UINT8_BYTE_TABLE_P (value) &&
1085 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1086 && byte_table_same_value_p (table))
1091 else if (!internal_equal (table, value, 0))
1093 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
1095 table = make_uint8_byte_table (UINT8_ENCODE (table));
1096 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1098 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
1100 table = make_uint16_byte_table (UINT16_ENCODE (table));
1101 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1105 table = make_byte_table (table);
1106 XBYTE_TABLE(table)->property[idx] = value;
1114 make_char_id_table (Lisp_Object initval)
1117 obj = Fmake_char_table (Qgeneric);
1118 fill_char_table (XCHAR_TABLE (obj), initval);
1123 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
1124 Lisp_Object Qsystem_char_id;
1127 Lisp_Object Qcomposition;
1128 Lisp_Object Q_decomposition;
1129 Lisp_Object Qto_ucs;
1130 Lisp_Object Q_ucs_unified;
1131 Lisp_Object Qcompat;
1132 Lisp_Object Qisolated;
1133 Lisp_Object Qinitial;
1134 Lisp_Object Qmedial;
1136 Lisp_Object Qvertical;
1137 Lisp_Object QnoBreak;
1138 Lisp_Object Qfraction;
1141 Lisp_Object Qcircle;
1142 Lisp_Object Qsquare;
1144 Lisp_Object Qnarrow;
1148 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
1151 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
1157 else if (EQ (v, Qcompat))
1159 else if (EQ (v, Qisolated))
1161 else if (EQ (v, Qinitial))
1163 else if (EQ (v, Qmedial))
1165 else if (EQ (v, Qfinal))
1167 else if (EQ (v, Qvertical))
1169 else if (EQ (v, QnoBreak))
1171 else if (EQ (v, Qfraction))
1173 else if (EQ (v, Qsuper))
1175 else if (EQ (v, Qsub))
1177 else if (EQ (v, Qcircle))
1179 else if (EQ (v, Qsquare))
1181 else if (EQ (v, Qwide))
1183 else if (EQ (v, Qnarrow))
1185 else if (EQ (v, Qsmall))
1187 else if (EQ (v, Qfont))
1190 signal_simple_error (err_msg, err_arg);
1193 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
1194 Return character corresponding with list.
1198 Lisp_Object base, modifier;
1202 signal_simple_error ("Invalid value for composition", list);
1205 while (!NILP (rest))
1210 signal_simple_error ("Invalid value for composition", list);
1211 modifier = Fcar (rest);
1213 base = Fcdr (Fassq (modifier,
1214 Fget_char_attribute (base, Qcomposition, Qnil)));
1219 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
1220 Return variants of CHARACTER.
1226 CHECK_CHAR (character);
1227 ret = Fget_char_attribute (character, Q_ucs_unified, Qnil);
1229 return Fcopy_list (ret);
1237 /* A char table maps from ranges of characters to values.
1239 Implementing a general data structure that maps from arbitrary
1240 ranges of numbers to values is tricky to do efficiently. As it
1241 happens, it should suffice (and is usually more convenient, anyway)
1242 when dealing with characters to restrict the sorts of ranges that
1243 can be assigned values, as follows:
1246 2) All characters in a charset.
1247 3) All characters in a particular row of a charset, where a "row"
1248 means all characters with the same first byte.
1249 4) A particular character in a charset.
1251 We use char tables to generalize the 256-element vectors now
1252 littering the Emacs code.
1254 Possible uses (all should be converted at some point):
1260 5) keyboard-translate-table?
1263 abstract type to generalize the Emacs vectors and Mule
1264 vectors-of-vectors goo.
1267 /************************************************************************/
1268 /* Char Table object */
1269 /************************************************************************/
1271 #if defined(MULE)&&!defined(UTF2000)
1274 mark_char_table_entry (Lisp_Object obj)
1276 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1279 for (i = 0; i < 96; i++)
1281 mark_object (cte->level2[i]);
1287 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1289 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1290 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1293 for (i = 0; i < 96; i++)
1294 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1300 static unsigned long
1301 char_table_entry_hash (Lisp_Object obj, int depth)
1303 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1305 return internal_array_hash (cte->level2, 96, depth);
1308 static const struct lrecord_description char_table_entry_description[] = {
1309 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1313 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1314 mark_char_table_entry, internal_object_printer,
1315 0, char_table_entry_equal,
1316 char_table_entry_hash,
1317 char_table_entry_description,
1318 Lisp_Char_Table_Entry);
1322 mark_char_table (Lisp_Object obj)
1324 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1327 mark_object (ct->table);
1328 mark_object (ct->name);
1329 #ifndef HAVE_LIBCHISE
1330 mark_object (ct->db);
1335 for (i = 0; i < NUM_ASCII_CHARS; i++)
1336 mark_object (ct->ascii[i]);
1338 for (i = 0; i < NUM_LEADING_BYTES; i++)
1339 mark_object (ct->level1[i]);
1343 return ct->default_value;
1345 return ct->mirror_table;
1349 /* WARNING: All functions of this nature need to be written extremely
1350 carefully to avoid crashes during GC. Cf. prune_specifiers()
1351 and prune_weak_hash_tables(). */
1354 prune_syntax_tables (void)
1356 Lisp_Object rest, prev = Qnil;
1358 for (rest = Vall_syntax_tables;
1360 rest = XCHAR_TABLE (rest)->next_table)
1362 if (! marked_p (rest))
1364 /* This table is garbage. Remove it from the list. */
1366 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1368 XCHAR_TABLE (prev)->next_table =
1369 XCHAR_TABLE (rest)->next_table;
1375 char_table_type_to_symbol (enum char_table_type type)
1380 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1381 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1382 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1383 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1385 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1390 static enum char_table_type
1391 symbol_to_char_table_type (Lisp_Object symbol)
1393 CHECK_SYMBOL (symbol);
1395 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1396 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1397 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1398 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1400 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1403 signal_simple_error ("Unrecognized char table type", symbol);
1404 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1408 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1409 Lisp_Object printcharfun)
1413 write_c_string (" (", printcharfun);
1414 print_internal (make_char (first), printcharfun, 0);
1415 write_c_string (" ", printcharfun);
1416 print_internal (make_char (last), printcharfun, 0);
1417 write_c_string (") ", printcharfun);
1421 write_c_string (" ", printcharfun);
1422 print_internal (make_char (first), printcharfun, 0);
1423 write_c_string (" ", printcharfun);
1425 print_internal (val, printcharfun, 1);
1428 #if defined(MULE)&&!defined(UTF2000)
1431 print_chartab_charset_row (Lisp_Object charset,
1433 Lisp_Char_Table_Entry *cte,
1434 Lisp_Object printcharfun)
1437 Lisp_Object cat = Qunbound;
1440 for (i = 32; i < 128; i++)
1442 Lisp_Object pam = cte->level2[i - 32];
1454 print_chartab_range (MAKE_CHAR (charset, first, 0),
1455 MAKE_CHAR (charset, i - 1, 0),
1458 print_chartab_range (MAKE_CHAR (charset, row, first),
1459 MAKE_CHAR (charset, row, i - 1),
1469 print_chartab_range (MAKE_CHAR (charset, first, 0),
1470 MAKE_CHAR (charset, i - 1, 0),
1473 print_chartab_range (MAKE_CHAR (charset, row, first),
1474 MAKE_CHAR (charset, row, i - 1),
1480 print_chartab_two_byte_charset (Lisp_Object charset,
1481 Lisp_Char_Table_Entry *cte,
1482 Lisp_Object printcharfun)
1486 for (i = 32; i < 128; i++)
1488 Lisp_Object jen = cte->level2[i - 32];
1490 if (!CHAR_TABLE_ENTRYP (jen))
1494 write_c_string (" [", printcharfun);
1495 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1496 sprintf (buf, " %d] ", i);
1497 write_c_string (buf, printcharfun);
1498 print_internal (jen, printcharfun, 0);
1501 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1509 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1511 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1514 struct gcpro gcpro1, gcpro2;
1515 GCPRO2 (obj, printcharfun);
1517 write_c_string ("#s(char-table ", printcharfun);
1518 write_c_string (" ", printcharfun);
1519 write_c_string (string_data
1521 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1523 write_c_string ("\n ", printcharfun);
1524 print_internal (ct->default_value, printcharfun, escapeflag);
1525 for (i = 0; i < 256; i++)
1527 Lisp_Object elt = get_byte_table (ct->table, i);
1528 if (i != 0) write_c_string ("\n ", printcharfun);
1529 if (EQ (elt, Qunbound))
1530 write_c_string ("void", printcharfun);
1532 print_internal (elt, printcharfun, escapeflag);
1535 #else /* non UTF2000 */
1538 sprintf (buf, "#s(char-table type %s data (",
1539 string_data (symbol_name (XSYMBOL
1540 (char_table_type_to_symbol (ct->type)))));
1541 write_c_string (buf, printcharfun);
1543 /* Now write out the ASCII/Control-1 stuff. */
1547 Lisp_Object val = Qunbound;
1549 for (i = 0; i < NUM_ASCII_CHARS; i++)
1558 if (!EQ (ct->ascii[i], val))
1560 print_chartab_range (first, i - 1, val, printcharfun);
1567 print_chartab_range (first, i - 1, val, printcharfun);
1574 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1577 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1578 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1580 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1581 || i == LEADING_BYTE_CONTROL_1)
1583 if (!CHAR_TABLE_ENTRYP (ann))
1585 write_c_string (" ", printcharfun);
1586 print_internal (XCHARSET_NAME (charset),
1588 write_c_string (" ", printcharfun);
1589 print_internal (ann, printcharfun, 0);
1593 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1594 if (XCHARSET_DIMENSION (charset) == 1)
1595 print_chartab_charset_row (charset, -1, cte, printcharfun);
1597 print_chartab_two_byte_charset (charset, cte, printcharfun);
1602 #endif /* non UTF2000 */
1604 write_c_string ("))", printcharfun);
1608 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1610 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1611 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1614 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1618 for (i = 0; i < 256; i++)
1620 if (!internal_equal (get_byte_table (ct1->table, i),
1621 get_byte_table (ct2->table, i), 0))
1625 for (i = 0; i < NUM_ASCII_CHARS; i++)
1626 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1630 for (i = 0; i < NUM_LEADING_BYTES; i++)
1631 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1634 #endif /* non UTF2000 */
1639 static unsigned long
1640 char_table_hash (Lisp_Object obj, int depth)
1642 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1644 return byte_table_hash (ct->table, depth + 1);
1646 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1649 hashval = HASH2 (hashval,
1650 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1656 static const struct lrecord_description char_table_description[] = {
1658 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1659 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1660 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, name) },
1661 #ifndef HAVE_LIBCHISE
1662 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, db) },
1665 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1667 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1671 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1673 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1677 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1678 mark_char_table, print_char_table, 0,
1679 char_table_equal, char_table_hash,
1680 char_table_description,
1683 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1684 Return non-nil if OBJECT is a char table.
1686 A char table is a table that maps characters (or ranges of characters)
1687 to values. Char tables are specialized for characters, only allowing
1688 particular sorts of ranges to be assigned values. Although this
1689 loses in generality, it makes for extremely fast (constant-time)
1690 lookups, and thus is feasible for applications that do an extremely
1691 large number of lookups (e.g. scanning a buffer for a character in
1692 a particular syntax, where a lookup in the syntax table must occur
1693 once per character).
1695 When Mule support exists, the types of ranges that can be assigned
1699 -- an entire charset
1700 -- a single row in a two-octet charset
1701 -- a single character
1703 When Mule support is not present, the types of ranges that can be
1707 -- a single character
1709 To create a char table, use `make-char-table'.
1710 To modify a char table, use `put-char-table' or `remove-char-table'.
1711 To retrieve the value for a particular character, use `get-char-table'.
1712 See also `map-char-table', `clear-char-table', `copy-char-table',
1713 `valid-char-table-type-p', `char-table-type-list',
1714 `valid-char-table-value-p', and `check-char-table-value'.
1718 return CHAR_TABLEP (object) ? Qt : Qnil;
1721 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1722 Return a list of the recognized char table types.
1723 See `valid-char-table-type-p'.
1728 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1730 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1734 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1735 Return t if TYPE if a recognized char table type.
1737 Each char table type is used for a different purpose and allows different
1738 sorts of values. The different char table types are
1741 Used for category tables, which specify the regexp categories
1742 that a character is in. The valid values are nil or a
1743 bit vector of 95 elements. Higher-level Lisp functions are
1744 provided for working with category tables. Currently categories
1745 and category tables only exist when Mule support is present.
1747 A generalized char table, for mapping from one character to
1748 another. Used for case tables, syntax matching tables,
1749 `keyboard-translate-table', etc. The valid values are characters.
1751 An even more generalized char table, for mapping from a
1752 character to anything.
1754 Used for display tables, which specify how a particular character
1755 is to appear when displayed. #### Not yet implemented.
1757 Used for syntax tables, which specify the syntax of a particular
1758 character. Higher-level Lisp functions are provided for
1759 working with syntax tables. The valid values are integers.
1764 return (EQ (type, Qchar) ||
1766 EQ (type, Qcategory) ||
1768 EQ (type, Qdisplay) ||
1769 EQ (type, Qgeneric) ||
1770 EQ (type, Qsyntax)) ? Qt : Qnil;
1773 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1774 Return the type of CHAR-TABLE.
1775 See `valid-char-table-type-p'.
1779 CHECK_CHAR_TABLE (char_table);
1780 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1784 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1787 ct->table = Qunbound;
1788 ct->default_value = value;
1793 for (i = 0; i < NUM_ASCII_CHARS; i++)
1794 ct->ascii[i] = value;
1796 for (i = 0; i < NUM_LEADING_BYTES; i++)
1797 ct->level1[i] = value;
1802 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1803 update_syntax_table (ct);
1807 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1808 Reset CHAR-TABLE to its default state.
1812 Lisp_Char_Table *ct;
1814 CHECK_CHAR_TABLE (char_table);
1815 ct = XCHAR_TABLE (char_table);
1819 case CHAR_TABLE_TYPE_CHAR:
1820 fill_char_table (ct, make_char (0));
1822 case CHAR_TABLE_TYPE_DISPLAY:
1823 case CHAR_TABLE_TYPE_GENERIC:
1825 case CHAR_TABLE_TYPE_CATEGORY:
1827 fill_char_table (ct, Qnil);
1830 case CHAR_TABLE_TYPE_SYNTAX:
1831 fill_char_table (ct, make_int (Sinherit));
1841 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1842 Return a new, empty char table of type TYPE.
1843 Currently recognized types are 'char, 'category, 'display, 'generic,
1844 and 'syntax. See `valid-char-table-type-p'.
1848 Lisp_Char_Table *ct;
1850 enum char_table_type ty = symbol_to_char_table_type (type);
1852 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1855 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1857 ct->mirror_table = Fmake_char_table (Qgeneric);
1858 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1862 ct->mirror_table = Qnil;
1865 #ifndef HAVE_LIBCHISE
1869 ct->next_table = Qnil;
1870 XSETCHAR_TABLE (obj, ct);
1871 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1873 ct->next_table = Vall_syntax_tables;
1874 Vall_syntax_tables = obj;
1876 Freset_char_table (obj);
1880 #if defined(MULE)&&!defined(UTF2000)
1883 make_char_table_entry (Lisp_Object initval)
1887 Lisp_Char_Table_Entry *cte =
1888 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1890 for (i = 0; i < 96; i++)
1891 cte->level2[i] = initval;
1893 XSETCHAR_TABLE_ENTRY (obj, cte);
1898 copy_char_table_entry (Lisp_Object entry)
1900 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1903 Lisp_Char_Table_Entry *ctenew =
1904 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1906 for (i = 0; i < 96; i++)
1908 Lisp_Object new = cte->level2[i];
1909 if (CHAR_TABLE_ENTRYP (new))
1910 ctenew->level2[i] = copy_char_table_entry (new);
1912 ctenew->level2[i] = new;
1915 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1921 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1922 Return a new char table which is a copy of CHAR-TABLE.
1923 It will contain the same values for the same characters and ranges
1924 as CHAR-TABLE. The values will not themselves be copied.
1928 Lisp_Char_Table *ct, *ctnew;
1934 CHECK_CHAR_TABLE (char_table);
1935 ct = XCHAR_TABLE (char_table);
1936 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1937 ctnew->type = ct->type;
1939 ctnew->default_value = ct->default_value;
1940 /* [tomo:2002-01-21] Perhaps this code seems wrong */
1941 ctnew->name = ct->name;
1942 #ifndef HAVE_LIBCHISE
1946 if (UINT8_BYTE_TABLE_P (ct->table))
1948 ctnew->table = copy_uint8_byte_table (ct->table);
1950 else if (UINT16_BYTE_TABLE_P (ct->table))
1952 ctnew->table = copy_uint16_byte_table (ct->table);
1954 else if (BYTE_TABLE_P (ct->table))
1956 ctnew->table = copy_byte_table (ct->table);
1958 else if (!UNBOUNDP (ct->table))
1959 ctnew->table = ct->table;
1960 #else /* non UTF2000 */
1962 for (i = 0; i < NUM_ASCII_CHARS; i++)
1964 Lisp_Object new = ct->ascii[i];
1966 assert (! (CHAR_TABLE_ENTRYP (new)));
1968 ctnew->ascii[i] = new;
1973 for (i = 0; i < NUM_LEADING_BYTES; i++)
1975 Lisp_Object new = ct->level1[i];
1976 if (CHAR_TABLE_ENTRYP (new))
1977 ctnew->level1[i] = copy_char_table_entry (new);
1979 ctnew->level1[i] = new;
1983 #endif /* non UTF2000 */
1986 if (CHAR_TABLEP (ct->mirror_table))
1987 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
1989 ctnew->mirror_table = ct->mirror_table;
1991 ctnew->next_table = Qnil;
1992 XSETCHAR_TABLE (obj, ctnew);
1993 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
1995 ctnew->next_table = Vall_syntax_tables;
1996 Vall_syntax_tables = obj;
2001 INLINE_HEADER int XCHARSET_CELL_RANGE (Lisp_Object ccs);
2003 XCHARSET_CELL_RANGE (Lisp_Object ccs)
2005 switch (XCHARSET_CHARS (ccs))
2008 return (33 << 8) | 126;
2010 return (32 << 8) | 127;
2013 return (0 << 8) | 127;
2015 return (0 << 8) | 255;
2027 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
2030 outrange->type = CHARTAB_RANGE_ALL;
2032 else if (EQ (range, Qnil))
2033 outrange->type = CHARTAB_RANGE_DEFAULT;
2035 else if (CHAR_OR_CHAR_INTP (range))
2037 outrange->type = CHARTAB_RANGE_CHAR;
2038 outrange->ch = XCHAR_OR_CHAR_INT (range);
2042 signal_simple_error ("Range must be t or a character", range);
2044 else if (VECTORP (range))
2046 Lisp_Vector *vec = XVECTOR (range);
2047 Lisp_Object *elts = vector_data (vec);
2048 int cell_min, cell_max;
2050 outrange->type = CHARTAB_RANGE_ROW;
2051 outrange->charset = Fget_charset (elts[0]);
2052 CHECK_INT (elts[1]);
2053 outrange->row = XINT (elts[1]);
2054 if (XCHARSET_DIMENSION (outrange->charset) < 2)
2055 signal_simple_error ("Charset in row vector must be multi-byte",
2059 int ret = XCHARSET_CELL_RANGE (outrange->charset);
2061 cell_min = ret >> 8;
2062 cell_max = ret & 0xFF;
2064 if (XCHARSET_DIMENSION (outrange->charset) == 2)
2065 check_int_range (outrange->row, cell_min, cell_max);
2067 else if (XCHARSET_DIMENSION (outrange->charset) == 3)
2069 check_int_range (outrange->row >> 8 , cell_min, cell_max);
2070 check_int_range (outrange->row & 0xFF, cell_min, cell_max);
2072 else if (XCHARSET_DIMENSION (outrange->charset) == 4)
2074 check_int_range ( outrange->row >> 16 , cell_min, cell_max);
2075 check_int_range ((outrange->row >> 8) & 0xFF, cell_min, cell_max);
2076 check_int_range ( outrange->row & 0xFF, cell_min, cell_max);
2084 if (!CHARSETP (range) && !SYMBOLP (range))
2086 ("Char table range must be t, charset, char, or vector", range);
2087 outrange->type = CHARTAB_RANGE_CHARSET;
2088 outrange->charset = Fget_charset (range);
2093 #if defined(MULE)&&!defined(UTF2000)
2095 /* called from CHAR_TABLE_VALUE(). */
2097 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
2102 Lisp_Object charset;
2104 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
2109 BREAKUP_CHAR (c, charset, byte1, byte2);
2111 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
2113 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
2114 if (CHAR_TABLE_ENTRYP (val))
2116 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2117 val = cte->level2[byte1 - 32];
2118 if (CHAR_TABLE_ENTRYP (val))
2120 cte = XCHAR_TABLE_ENTRY (val);
2121 assert (byte2 >= 32);
2122 val = cte->level2[byte2 - 32];
2123 assert (!CHAR_TABLE_ENTRYP (val));
2133 get_char_table (Emchar ch, Lisp_Char_Table *ct)
2137 Lisp_Object ret = get_char_id_table (ct, ch);
2142 if (EQ (CHAR_TABLE_NAME (ct), Qdowncase))
2143 ret = Fget_char_attribute (make_char (ch), Q_lowercase, Qnil);
2144 else if (EQ (CHAR_TABLE_NAME (ct), Qflippedcase))
2145 ret = Fget_char_attribute (make_char (ch), Q_uppercase, Qnil);
2150 ret = Ffind_char (ret);
2158 Lisp_Object charset;
2162 BREAKUP_CHAR (ch, charset, byte1, byte2);
2164 if (EQ (charset, Vcharset_ascii))
2165 val = ct->ascii[byte1];
2166 else if (EQ (charset, Vcharset_control_1))
2167 val = ct->ascii[byte1 + 128];
2170 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2171 val = ct->level1[lb];
2172 if (CHAR_TABLE_ENTRYP (val))
2174 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2175 val = cte->level2[byte1 - 32];
2176 if (CHAR_TABLE_ENTRYP (val))
2178 cte = XCHAR_TABLE_ENTRY (val);
2179 assert (byte2 >= 32);
2180 val = cte->level2[byte2 - 32];
2181 assert (!CHAR_TABLE_ENTRYP (val));
2188 #else /* not MULE */
2189 return ct->ascii[(unsigned char)ch];
2190 #endif /* not MULE */
2194 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
2195 Find value for CHARACTER in CHAR-TABLE.
2197 (character, char_table))
2199 CHECK_CHAR_TABLE (char_table);
2200 CHECK_CHAR_COERCE_INT (character);
2202 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
2205 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
2206 Find value for a range in CHAR-TABLE.
2207 If there is more than one value, return MULTI (defaults to nil).
2209 (range, char_table, multi))
2211 Lisp_Char_Table *ct;
2212 struct chartab_range rainj;
2214 if (CHAR_OR_CHAR_INTP (range))
2215 return Fget_char_table (range, char_table);
2216 CHECK_CHAR_TABLE (char_table);
2217 ct = XCHAR_TABLE (char_table);
2219 decode_char_table_range (range, &rainj);
2222 case CHARTAB_RANGE_ALL:
2225 if (UINT8_BYTE_TABLE_P (ct->table))
2227 else if (UINT16_BYTE_TABLE_P (ct->table))
2229 else if (BYTE_TABLE_P (ct->table))
2233 #else /* non UTF2000 */
2235 Lisp_Object first = ct->ascii[0];
2237 for (i = 1; i < NUM_ASCII_CHARS; i++)
2238 if (!EQ (first, ct->ascii[i]))
2242 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
2245 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
2246 || i == LEADING_BYTE_ASCII
2247 || i == LEADING_BYTE_CONTROL_1)
2249 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
2255 #endif /* non UTF2000 */
2259 case CHARTAB_RANGE_CHARSET:
2263 if (EQ (rainj.charset, Vcharset_ascii))
2266 Lisp_Object first = ct->ascii[0];
2268 for (i = 1; i < 128; i++)
2269 if (!EQ (first, ct->ascii[i]))
2274 if (EQ (rainj.charset, Vcharset_control_1))
2277 Lisp_Object first = ct->ascii[128];
2279 for (i = 129; i < 160; i++)
2280 if (!EQ (first, ct->ascii[i]))
2286 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2288 if (CHAR_TABLE_ENTRYP (val))
2294 case CHARTAB_RANGE_ROW:
2299 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2301 if (!CHAR_TABLE_ENTRYP (val))
2303 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
2304 if (CHAR_TABLE_ENTRYP (val))
2308 #endif /* not UTF2000 */
2309 #endif /* not MULE */
2315 return Qnil; /* not reached */
2319 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2320 Error_behavior errb)
2324 case CHAR_TABLE_TYPE_SYNTAX:
2325 if (!ERRB_EQ (errb, ERROR_ME))
2326 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2327 && CHAR_OR_CHAR_INTP (XCDR (value)));
2330 Lisp_Object cdr = XCDR (value);
2331 CHECK_INT (XCAR (value));
2332 CHECK_CHAR_COERCE_INT (cdr);
2339 case CHAR_TABLE_TYPE_CATEGORY:
2340 if (!ERRB_EQ (errb, ERROR_ME))
2341 return CATEGORY_TABLE_VALUEP (value);
2342 CHECK_CATEGORY_TABLE_VALUE (value);
2346 case CHAR_TABLE_TYPE_GENERIC:
2349 case CHAR_TABLE_TYPE_DISPLAY:
2351 maybe_signal_simple_error ("Display char tables not yet implemented",
2352 value, Qchar_table, errb);
2355 case CHAR_TABLE_TYPE_CHAR:
2356 if (!ERRB_EQ (errb, ERROR_ME))
2357 return CHAR_OR_CHAR_INTP (value);
2358 CHECK_CHAR_COERCE_INT (value);
2365 return 0; /* not reached */
2369 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2373 case CHAR_TABLE_TYPE_SYNTAX:
2376 Lisp_Object car = XCAR (value);
2377 Lisp_Object cdr = XCDR (value);
2378 CHECK_CHAR_COERCE_INT (cdr);
2379 return Fcons (car, cdr);
2382 case CHAR_TABLE_TYPE_CHAR:
2383 CHECK_CHAR_COERCE_INT (value);
2391 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2392 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2394 (value, char_table_type))
2396 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2398 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2401 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2402 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2404 (value, char_table_type))
2406 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2408 check_valid_char_table_value (value, type, ERROR_ME);
2413 Lisp_Char_Table* char_attribute_table_to_put;
2414 Lisp_Object Qput_char_table_map_function;
2415 Lisp_Object value_to_put;
2417 DEFUN ("put-char-table-map-function",
2418 Fput_char_table_map_function, 2, 2, 0, /*
2419 For internal use. Don't use it.
2423 put_char_id_table_0 (char_attribute_table_to_put,
2424 XCHAR (c), value_to_put);
2429 /* Assign VAL to all characters in RANGE in char table CT. */
2432 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2435 switch (range->type)
2437 case CHARTAB_RANGE_ALL:
2438 /* printf ("put-char-table: range = all\n"); */
2439 fill_char_table (ct, val);
2440 return; /* avoid the duplicate call to update_syntax_table() below,
2441 since fill_char_table() also did that. */
2444 case CHARTAB_RANGE_DEFAULT:
2445 ct->default_value = val;
2450 case CHARTAB_RANGE_CHARSET:
2453 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2455 /* printf ("put-char-table: range = charset: %d\n",
2456 XCHARSET_LEADING_BYTE (range->charset));
2458 if ( CHAR_TABLEP (encoding_table) )
2460 Lisp_Object mother = XCHARSET_MOTHER (range->charset);
2462 char_attribute_table_to_put = ct;
2464 Fmap_char_attribute (Qput_char_table_map_function,
2465 XCHAR_TABLE_NAME (encoding_table),
2467 if ( CHARSETP (mother) )
2469 struct chartab_range r;
2471 r.type = CHARTAB_RANGE_CHARSET;
2473 put_char_table (ct, &r, val);
2481 for (c = 0; c < 1 << 24; c++)
2483 if ( charset_code_point (range->charset, c) >= 0 )
2484 put_char_id_table_0 (ct, c, val);
2490 if (EQ (range->charset, Vcharset_ascii))
2493 for (i = 0; i < 128; i++)
2496 else if (EQ (range->charset, Vcharset_control_1))
2499 for (i = 128; i < 160; i++)
2504 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2505 ct->level1[lb] = val;
2510 case CHARTAB_RANGE_ROW:
2513 int cell_min, cell_max, i;
2515 i = XCHARSET_CELL_RANGE (range->charset);
2517 cell_max = i & 0xFF;
2518 for (i = cell_min; i <= cell_max; i++)
2520 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2522 if ( charset_code_point (range->charset, ch, 0) >= 0 )
2523 put_char_id_table_0 (ct, ch, val);
2528 Lisp_Char_Table_Entry *cte;
2529 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2530 /* make sure that there is a separate entry for the row. */
2531 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2532 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2533 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2534 cte->level2[range->row - 32] = val;
2536 #endif /* not UTF2000 */
2540 case CHARTAB_RANGE_CHAR:
2542 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2543 put_char_id_table_0 (ct, range->ch, val);
2547 Lisp_Object charset;
2550 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2551 if (EQ (charset, Vcharset_ascii))
2552 ct->ascii[byte1] = val;
2553 else if (EQ (charset, Vcharset_control_1))
2554 ct->ascii[byte1 + 128] = val;
2557 Lisp_Char_Table_Entry *cte;
2558 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2559 /* make sure that there is a separate entry for the row. */
2560 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2561 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2562 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2563 /* now CTE is a char table entry for the charset;
2564 each entry is for a single row (or character of
2565 a one-octet charset). */
2566 if (XCHARSET_DIMENSION (charset) == 1)
2567 cte->level2[byte1 - 32] = val;
2570 /* assigning to one character in a two-octet charset. */
2571 /* make sure that the charset row contains a separate
2572 entry for each character. */
2573 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2574 cte->level2[byte1 - 32] =
2575 make_char_table_entry (cte->level2[byte1 - 32]);
2576 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2577 cte->level2[byte2 - 32] = val;
2581 #else /* not MULE */
2582 ct->ascii[(unsigned char) (range->ch)] = val;
2584 #endif /* not MULE */
2588 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2589 update_syntax_table (ct);
2593 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2594 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2596 RANGE specifies one or more characters to be affected and should be
2597 one of the following:
2599 -- t (all characters are affected)
2600 -- A charset (only allowed when Mule support is present)
2601 -- A vector of two elements: a two-octet charset and a row number
2602 (only allowed when Mule support is present)
2603 -- A single character
2605 VALUE must be a value appropriate for the type of CHAR-TABLE.
2606 See `valid-char-table-type-p'.
2608 (range, value, char_table))
2610 Lisp_Char_Table *ct;
2611 struct chartab_range rainj;
2613 CHECK_CHAR_TABLE (char_table);
2614 ct = XCHAR_TABLE (char_table);
2615 check_valid_char_table_value (value, ct->type, ERROR_ME);
2616 decode_char_table_range (range, &rainj);
2617 value = canonicalize_char_table_value (value, ct->type);
2618 put_char_table (ct, &rainj, value);
2623 /* Map FN over the ASCII chars in CT. */
2626 map_over_charset_ascii (Lisp_Char_Table *ct,
2627 int (*fn) (struct chartab_range *range,
2628 Lisp_Object val, void *arg),
2631 struct chartab_range rainj;
2640 rainj.type = CHARTAB_RANGE_CHAR;
2642 for (i = start, retval = 0; i < stop && retval == 0; i++)
2644 rainj.ch = (Emchar) i;
2645 retval = (fn) (&rainj, ct->ascii[i], arg);
2653 /* Map FN over the Control-1 chars in CT. */
2656 map_over_charset_control_1 (Lisp_Char_Table *ct,
2657 int (*fn) (struct chartab_range *range,
2658 Lisp_Object val, void *arg),
2661 struct chartab_range rainj;
2664 int stop = start + 32;
2666 rainj.type = CHARTAB_RANGE_CHAR;
2668 for (i = start, retval = 0; i < stop && retval == 0; i++)
2670 rainj.ch = (Emchar) (i);
2671 retval = (fn) (&rainj, ct->ascii[i], arg);
2677 /* Map FN over the row ROW of two-byte charset CHARSET.
2678 There must be a separate value for that row in the char table.
2679 CTE specifies the char table entry for CHARSET. */
2682 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2683 Lisp_Object charset, int row,
2684 int (*fn) (struct chartab_range *range,
2685 Lisp_Object val, void *arg),
2688 Lisp_Object val = cte->level2[row - 32];
2690 if (!CHAR_TABLE_ENTRYP (val))
2692 struct chartab_range rainj;
2694 rainj.type = CHARTAB_RANGE_ROW;
2695 rainj.charset = charset;
2697 return (fn) (&rainj, val, arg);
2701 struct chartab_range rainj;
2703 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2704 int start = charset94_p ? 33 : 32;
2705 int stop = charset94_p ? 127 : 128;
2707 cte = XCHAR_TABLE_ENTRY (val);
2709 rainj.type = CHARTAB_RANGE_CHAR;
2711 for (i = start, retval = 0; i < stop && retval == 0; i++)
2713 rainj.ch = MAKE_CHAR (charset, row, i);
2714 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2722 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2723 int (*fn) (struct chartab_range *range,
2724 Lisp_Object val, void *arg),
2727 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2728 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2730 if (!CHARSETP (charset)
2731 || lb == LEADING_BYTE_ASCII
2732 || lb == LEADING_BYTE_CONTROL_1)
2735 if (!CHAR_TABLE_ENTRYP (val))
2737 struct chartab_range rainj;
2739 rainj.type = CHARTAB_RANGE_CHARSET;
2740 rainj.charset = charset;
2741 return (fn) (&rainj, val, arg);
2745 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2746 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2747 int start = charset94_p ? 33 : 32;
2748 int stop = charset94_p ? 127 : 128;
2751 if (XCHARSET_DIMENSION (charset) == 1)
2753 struct chartab_range rainj;
2754 rainj.type = CHARTAB_RANGE_CHAR;
2756 for (i = start, retval = 0; i < stop && retval == 0; i++)
2758 rainj.ch = MAKE_CHAR (charset, i, 0);
2759 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2764 for (i = start, retval = 0; i < stop && retval == 0; i++)
2765 retval = map_over_charset_row (cte, charset, i, fn, arg);
2773 #endif /* not UTF2000 */
2776 struct map_char_table_for_charset_arg
2778 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2779 Lisp_Char_Table *ct;
2784 map_char_table_for_charset_fun (struct chartab_range *range,
2785 Lisp_Object val, void *arg)
2787 struct map_char_table_for_charset_arg *closure =
2788 (struct map_char_table_for_charset_arg *) arg;
2791 switch (range->type)
2793 case CHARTAB_RANGE_ALL:
2796 case CHARTAB_RANGE_DEFAULT:
2799 case CHARTAB_RANGE_CHARSET:
2802 case CHARTAB_RANGE_ROW:
2805 case CHARTAB_RANGE_CHAR:
2806 ret = get_char_table (range->ch, closure->ct);
2807 if (!UNBOUNDP (ret))
2808 return (closure->fn) (range, ret, closure->arg);
2820 /* Map FN (with client data ARG) over range RANGE in char table CT.
2821 Mapping stops the first time FN returns non-zero, and that value
2822 becomes the return value of map_char_table(). */
2825 map_char_table (Lisp_Char_Table *ct,
2826 struct chartab_range *range,
2827 int (*fn) (struct chartab_range *range,
2828 Lisp_Object val, void *arg),
2831 switch (range->type)
2833 case CHARTAB_RANGE_ALL:
2835 if (!UNBOUNDP (ct->default_value))
2837 struct chartab_range rainj;
2840 rainj.type = CHARTAB_RANGE_DEFAULT;
2841 retval = (fn) (&rainj, ct->default_value, arg);
2845 if (UINT8_BYTE_TABLE_P (ct->table))
2846 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
2848 else if (UINT16_BYTE_TABLE_P (ct->table))
2849 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
2851 else if (BYTE_TABLE_P (ct->table))
2852 return map_over_byte_table (XBYTE_TABLE(ct->table), ct,
2854 else if (EQ (ct->table, Qunloaded))
2857 struct chartab_range rainj;
2860 Emchar c1 = c + unit;
2863 rainj.type = CHARTAB_RANGE_CHAR;
2865 for (retval = 0; c < c1 && retval == 0; c++)
2867 Lisp_Object ret = get_char_id_table (ct, c);
2869 if (!UNBOUNDP (ret))
2872 retval = (fn) (&rainj, ct->table, arg);
2877 ct->table = Qunbound;
2880 else if (!UNBOUNDP (ct->table))
2881 return (fn) (range, ct->table, arg);
2887 retval = map_over_charset_ascii (ct, fn, arg);
2891 retval = map_over_charset_control_1 (ct, fn, arg);
2896 Charset_ID start = MIN_LEADING_BYTE;
2897 Charset_ID stop = start + NUM_LEADING_BYTES;
2899 for (i = start, retval = 0; i < stop && retval == 0; i++)
2901 retval = map_over_other_charset (ct, i, fn, arg);
2910 case CHARTAB_RANGE_DEFAULT:
2911 if (!UNBOUNDP (ct->default_value))
2912 return (fn) (range, ct->default_value, arg);
2917 case CHARTAB_RANGE_CHARSET:
2920 Lisp_Object encoding_table
2921 = XCHARSET_ENCODING_TABLE (range->charset);
2923 if (!NILP (encoding_table))
2925 struct chartab_range rainj;
2926 struct map_char_table_for_charset_arg mcarg;
2929 if (XCHAR_TABLE_UNLOADED(encoding_table))
2930 Fload_char_attribute_table (XCHAR_TABLE_NAME (encoding_table));
2935 rainj.type = CHARTAB_RANGE_ALL;
2936 return map_char_table (XCHAR_TABLE(encoding_table),
2938 &map_char_table_for_charset_fun,
2944 return map_over_other_charset (ct,
2945 XCHARSET_LEADING_BYTE (range->charset),
2949 case CHARTAB_RANGE_ROW:
2952 int cell_min, cell_max, i;
2954 struct chartab_range rainj;
2956 i = XCHARSET_CELL_RANGE (range->charset);
2958 cell_max = i & 0xFF;
2959 rainj.type = CHARTAB_RANGE_CHAR;
2960 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2962 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2964 if ( charset_code_point (range->charset, ch, 0) >= 0 )
2967 = get_byte_table (get_byte_table
2971 (unsigned char)(ch >> 24)),
2972 (unsigned char) (ch >> 16)),
2973 (unsigned char) (ch >> 8)),
2974 (unsigned char) ch);
2977 val = ct->default_value;
2979 retval = (fn) (&rainj, val, arg);
2986 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
2987 - MIN_LEADING_BYTE];
2988 if (!CHAR_TABLE_ENTRYP (val))
2990 struct chartab_range rainj;
2992 rainj.type = CHARTAB_RANGE_ROW;
2993 rainj.charset = range->charset;
2994 rainj.row = range->row;
2995 return (fn) (&rainj, val, arg);
2998 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
2999 range->charset, range->row,
3002 #endif /* not UTF2000 */
3005 case CHARTAB_RANGE_CHAR:
3007 Emchar ch = range->ch;
3008 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
3010 if (!UNBOUNDP (val))
3012 struct chartab_range rainj;
3014 rainj.type = CHARTAB_RANGE_CHAR;
3016 return (fn) (&rainj, val, arg);
3028 struct slow_map_char_table_arg
3030 Lisp_Object function;
3035 slow_map_char_table_fun (struct chartab_range *range,
3036 Lisp_Object val, void *arg)
3038 Lisp_Object ranjarg = Qnil;
3039 struct slow_map_char_table_arg *closure =
3040 (struct slow_map_char_table_arg *) arg;
3042 switch (range->type)
3044 case CHARTAB_RANGE_ALL:
3049 case CHARTAB_RANGE_DEFAULT:
3055 case CHARTAB_RANGE_CHARSET:
3056 ranjarg = XCHARSET_NAME (range->charset);
3059 case CHARTAB_RANGE_ROW:
3060 ranjarg = vector2 (XCHARSET_NAME (range->charset),
3061 make_int (range->row));
3064 case CHARTAB_RANGE_CHAR:
3065 ranjarg = make_char (range->ch);
3071 closure->retval = call2 (closure->function, ranjarg, val);
3072 return !NILP (closure->retval);
3075 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
3076 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
3077 each key and value in the table.
3079 RANGE specifies a subrange to map over and is in the same format as
3080 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3083 (function, char_table, range))
3085 Lisp_Char_Table *ct;
3086 struct slow_map_char_table_arg slarg;
3087 struct gcpro gcpro1, gcpro2;
3088 struct chartab_range rainj;
3090 CHECK_CHAR_TABLE (char_table);
3091 ct = XCHAR_TABLE (char_table);
3094 decode_char_table_range (range, &rainj);
3095 slarg.function = function;
3096 slarg.retval = Qnil;
3097 GCPRO2 (slarg.function, slarg.retval);
3098 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3101 return slarg.retval;
3105 /************************************************************************/
3106 /* Character Attributes */
3107 /************************************************************************/
3111 Lisp_Object Vchar_attribute_hash_table;
3113 /* We store the char-attributes in hash tables with the names as the
3114 key and the actual char-id-table object as the value. Occasionally
3115 we need to use them in a list format. These routines provide us
3117 struct char_attribute_list_closure
3119 Lisp_Object *char_attribute_list;
3123 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
3124 void *char_attribute_list_closure)
3126 /* This function can GC */
3127 struct char_attribute_list_closure *calcl
3128 = (struct char_attribute_list_closure*) char_attribute_list_closure;
3129 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
3131 *char_attribute_list = Fcons (key, *char_attribute_list);
3135 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
3136 Return the list of all existing character attributes except coded-charsets.
3140 Lisp_Object char_attribute_list = Qnil;
3141 struct gcpro gcpro1;
3142 struct char_attribute_list_closure char_attribute_list_closure;
3144 GCPRO1 (char_attribute_list);
3145 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
3146 elisp_maphash (add_char_attribute_to_list_mapper,
3147 Vchar_attribute_hash_table,
3148 &char_attribute_list_closure);
3150 return char_attribute_list;
3153 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
3154 Return char-id-table corresponding to ATTRIBUTE.
3158 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
3162 /* We store the char-id-tables in hash tables with the attributes as
3163 the key and the actual char-id-table object as the value. Each
3164 char-id-table stores values of an attribute corresponding with
3165 characters. Occasionally we need to get attributes of a character
3166 in a association-list format. These routines provide us with
3168 struct char_attribute_alist_closure
3171 Lisp_Object *char_attribute_alist;
3175 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
3176 void *char_attribute_alist_closure)
3178 /* This function can GC */
3179 struct char_attribute_alist_closure *caacl =
3180 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
3182 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
3183 if (!UNBOUNDP (ret))
3185 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
3186 *char_attribute_alist
3187 = Fcons (Fcons (key, ret), *char_attribute_alist);
3192 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
3193 Return the alist of attributes of CHARACTER.
3197 struct gcpro gcpro1;
3198 struct char_attribute_alist_closure char_attribute_alist_closure;
3199 Lisp_Object alist = Qnil;
3201 CHECK_CHAR (character);
3204 char_attribute_alist_closure.char_id = XCHAR (character);
3205 char_attribute_alist_closure.char_attribute_alist = &alist;
3206 elisp_maphash (add_char_attribute_alist_mapper,
3207 Vchar_attribute_hash_table,
3208 &char_attribute_alist_closure);
3214 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
3215 Return the value of CHARACTER's ATTRIBUTE.
3216 Return DEFAULT-VALUE if the value is not exist.
3218 (character, attribute, default_value))
3222 CHECK_CHAR (character);
3224 if (CHARSETP (attribute))
3225 attribute = XCHARSET_NAME (attribute);
3227 table = Fgethash (attribute, Vchar_attribute_hash_table,
3229 if (!UNBOUNDP (table))
3231 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
3233 if (!UNBOUNDP (ret))
3236 return default_value;
3239 void put_char_composition (Lisp_Object character, Lisp_Object value);
3241 put_char_composition (Lisp_Object character, Lisp_Object value)
3244 signal_simple_error ("Invalid value for ->decomposition",
3247 if (CONSP (Fcdr (value)))
3249 if (NILP (Fcdr (Fcdr (value))))
3251 Lisp_Object base = Fcar (value);
3252 Lisp_Object modifier = Fcar (Fcdr (value));
3256 base = make_char (XINT (base));
3257 Fsetcar (value, base);
3259 if (INTP (modifier))
3261 modifier = make_char (XINT (modifier));
3262 Fsetcar (Fcdr (value), modifier);
3267 = Fget_char_attribute (base, Qcomposition, Qnil);
3268 Lisp_Object ret = Fassq (modifier, alist);
3271 Fput_char_attribute (base, Qcomposition,
3272 Fcons (Fcons (modifier, character),
3275 Fsetcdr (ret, character);
3281 Lisp_Object v = Fcar (value);
3285 Emchar c = XINT (v);
3287 = Fget_char_attribute (make_char (c), Q_ucs_unified, Qnil);
3291 Fput_char_attribute (make_char (c), Q_ucs_unified,
3292 Fcons (character, Qnil));
3294 else if (NILP (Fmemq (character, ret)))
3296 Fput_char_attribute (make_char (c), Q_ucs_unified,
3297 Fcons (character, ret));
3303 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
3304 Store CHARACTER's ATTRIBUTE with VALUE.
3306 (character, attribute, value))
3308 Lisp_Object ccs = Ffind_charset (attribute);
3310 CHECK_CHAR (character);
3314 value = put_char_ccs_code_point (character, ccs, value);
3315 attribute = XCHARSET_NAME (ccs);
3317 else if (EQ (attribute, Q_decomposition))
3318 put_char_composition (character, value);
3319 else if (EQ (attribute, Qto_ucs))
3325 signal_simple_error ("Invalid value for =>ucs", value);
3329 ret = Fget_char_attribute (make_char (c), Q_ucs_unified, Qnil);
3332 Fput_char_attribute (make_char (c), Q_ucs_unified,
3333 Fcons (character, Qnil));
3335 else if (NILP (Fmemq (character, ret)))
3337 Fput_char_attribute (make_char (c), Q_ucs_unified,
3338 Fcons (character, ret));
3342 else if (EQ (attribute, Qideographic_structure))
3343 value = Fcopy_sequence (Fchar_refs_simplify_char_specs (value));
3346 Lisp_Object table = Fgethash (attribute,
3347 Vchar_attribute_hash_table,
3352 table = make_char_id_table (Qunbound);
3353 Fputhash (attribute, table, Vchar_attribute_hash_table);
3355 XCHAR_TABLE_NAME (table) = attribute;
3358 put_char_id_table (XCHAR_TABLE(table), character, value);
3363 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3364 Remove CHARACTER's ATTRIBUTE.
3366 (character, attribute))
3370 CHECK_CHAR (character);
3371 ccs = Ffind_charset (attribute);
3374 return remove_char_ccs (character, ccs);
3378 Lisp_Object table = Fgethash (attribute,
3379 Vchar_attribute_hash_table,
3381 if (!UNBOUNDP (table))
3383 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3392 int char_table_open_db_maybe (Lisp_Char_Table* cit);
3393 void char_table_close_db_maybe (Lisp_Char_Table* cit);
3394 Lisp_Object char_table_get_db (Lisp_Char_Table* cit, Emchar ch);
3396 #ifdef HAVE_LIBCHISE
3398 open_chise_data_source_maybe ()
3400 if (default_chise_data_source == NULL)
3402 Lisp_Object db_dir = Vexec_directory;
3403 int modemask = 0755; /* rwxr-xr-x */
3406 db_dir = build_string ("../lib-src");
3407 db_dir = Fexpand_file_name (build_string ("char-db"), db_dir);
3409 default_chise_data_source
3410 = CHISE_DS_open (CHISE_DS_Berkeley_DB, XSTRING_DATA (db_dir),
3412 if (default_chise_data_source == NULL)
3417 #endif /* HAVE_LIBCHISE */
3419 DEFUN ("close-char-data-source", Fclose_char_data_source, 0, 0, 0, /*
3420 Close data-source of CHISE.
3424 #ifdef HAVE_LIBCHISE
3425 int status = CHISE_DS_close (default_chise_data_source);
3427 default_chise_data_source = NULL;
3430 #endif /* HAVE_LIBCHISE */
3435 char_table_open_db_maybe (Lisp_Char_Table* cit)
3437 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3439 if (!NILP (attribute))
3441 #ifdef HAVE_LIBCHISE
3442 if ( open_chise_data_source_maybe () )
3444 #else /* HAVE_LIBCHISE */
3445 if (NILP (Fdatabase_live_p (cit->db)))
3448 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3450 cit->db = Fopen_database (db_file, Qnil, Qnil,
3451 build_string ("r"), Qnil);
3455 #endif /* not HAVE_LIBCHISE */
3463 char_table_close_db_maybe (Lisp_Char_Table* cit)
3465 #ifndef HAVE_LIBCHISE
3466 if (!NILP (cit->db))
3468 if (!NILP (Fdatabase_live_p (cit->db)))
3469 Fclose_database (cit->db);
3472 #endif /* not HAVE_LIBCHISE */
3476 char_table_get_db (Lisp_Char_Table* cit, Emchar ch)
3479 #ifdef HAVE_LIBCHISE
3482 = chise_ds_load_char_feature_value (default_chise_data_source, ch,
3483 XSTRING_DATA(Fsymbol_name
3489 val = Fread (make_string (chise_value_data (&value),
3490 chise_value_size (&value) ));
3494 #else /* HAVE_LIBCHISE */
3495 val = Fget_database (Fprin1_to_string (make_char (ch), Qnil),
3497 if (!UNBOUNDP (val))
3501 #endif /* not HAVE_LIBCHISE */
3505 #ifndef HAVE_LIBCHISE
3507 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
3510 Lisp_Object db_dir = Vexec_directory;
3513 db_dir = build_string ("../lib-src");
3515 db_dir = Fexpand_file_name (build_string ("char-db"), db_dir);
3516 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3517 Fmake_directory_internal (db_dir);
3519 db_dir = Fexpand_file_name (Fsymbol_name (key_type), db_dir);
3520 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3521 Fmake_directory_internal (db_dir);
3524 Lisp_Object attribute_name = Fsymbol_name (attribute);
3525 Lisp_Object dest = Qnil, ret;
3527 struct gcpro gcpro1, gcpro2;
3528 int len = XSTRING_CHAR_LENGTH (attribute_name);
3532 for (i = 0; i < len; i++)
3534 Emchar c = string_char (XSTRING (attribute_name), i);
3536 if ( (c == '/') || (c == '%') )
3540 sprintf (str, "%%%02X", c);
3541 dest = concat3 (dest,
3542 Fsubstring (attribute_name,
3543 make_int (base), make_int (i)),
3544 build_string (str));
3548 ret = Fsubstring (attribute_name, make_int (base), make_int (len));
3549 dest = concat2 (dest, ret);
3551 return Fexpand_file_name (dest, db_dir);
3554 #endif /* not HAVE_LIBCHISE */
3556 DEFUN ("save-char-attribute-table", Fsave_char_attribute_table, 1, 1, 0, /*
3557 Save values of ATTRIBUTE into database file.
3561 Lisp_Object table = Fgethash (attribute,
3562 Vchar_attribute_hash_table, Qunbound);
3563 Lisp_Char_Table *ct;
3564 #ifdef HAVE_LIBCHISE
3565 CHISE_Feature feature;
3566 #else /* HAVE_LIBCHISE */
3567 Lisp_Object db_file;
3569 #endif /* not HAVE_LIBCHISE */
3571 if (CHAR_TABLEP (table))
3572 ct = XCHAR_TABLE (table);
3576 #ifdef HAVE_LIBCHISE
3577 if ( open_chise_data_source_maybe () )
3580 = chise_ds_get_feature (default_chise_data_source,
3581 XSTRING_DATA (Fsymbol_name (attribute)));
3582 #else /* HAVE_LIBCHISE */
3583 db_file = char_attribute_system_db_file (Qsystem_char_id, attribute, 1);
3584 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
3585 #endif /* not HAVE_LIBCHISE */
3587 #ifdef HAVE_LIBCHISE
3589 #else /* HAVE_LIBCHISE */
3591 #endif /* not HAVE_LIBCHISE */
3594 Lisp_Object (*filter)(Lisp_Object value);
3596 if (EQ (attribute, Qideographic_structure))
3597 filter = &Fchar_refs_simplify_char_specs;
3601 if (UINT8_BYTE_TABLE_P (ct->table))
3602 save_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
3603 #ifdef HAVE_LIBCHISE
3605 #else /* HAVE_LIBCHISE */
3607 #endif /* not HAVE_LIBCHISE */
3609 else if (UINT16_BYTE_TABLE_P (ct->table))
3610 save_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
3611 #ifdef HAVE_LIBCHISE
3613 #else /* HAVE_LIBCHISE */
3615 #endif /* not HAVE_LIBCHISE */
3617 else if (BYTE_TABLE_P (ct->table))
3618 save_byte_table (XBYTE_TABLE(ct->table), ct,
3619 #ifdef HAVE_LIBCHISE
3621 #else /* HAVE_LIBCHISE */
3623 #endif /* not HAVE_LIBCHISE */
3625 #ifdef HAVE_LIBCHISE
3626 chise_feature_sync (feature);
3627 #else /* HAVE_LIBCHISE */
3628 Fclose_database (db);
3629 #endif /* not HAVE_LIBCHISE */
3636 DEFUN ("mount-char-attribute-table", Fmount_char_attribute_table, 1, 1, 0, /*
3637 Mount database file on char-attribute-table ATTRIBUTE.
3641 Lisp_Object table = Fgethash (attribute,
3642 Vchar_attribute_hash_table, Qunbound);
3644 if (UNBOUNDP (table))
3646 Lisp_Char_Table *ct;
3648 table = make_char_id_table (Qunbound);
3649 Fputhash (attribute, table, Vchar_attribute_hash_table);
3650 XCHAR_TABLE_NAME(table) = attribute;
3651 ct = XCHAR_TABLE (table);
3652 ct->table = Qunloaded;
3653 XCHAR_TABLE_UNLOADED(table) = 1;
3654 #ifndef HAVE_LIBCHISE
3656 #endif /* not HAVE_LIBCHISE */
3662 DEFUN ("close-char-attribute-table", Fclose_char_attribute_table, 1, 1, 0, /*
3663 Close database of ATTRIBUTE.
3667 Lisp_Object table = Fgethash (attribute,
3668 Vchar_attribute_hash_table, Qunbound);
3669 Lisp_Char_Table *ct;
3671 if (CHAR_TABLEP (table))
3672 ct = XCHAR_TABLE (table);
3675 char_table_close_db_maybe (ct);
3679 DEFUN ("reset-char-attribute-table", Freset_char_attribute_table, 1, 1, 0, /*
3680 Reset values of ATTRIBUTE with database file.
3684 #ifdef HAVE_LIBCHISE
3685 CHISE_Feature feature
3686 = chise_ds_get_feature (default_chise_data_source,
3687 XSTRING_DATA (Fsymbol_name
3690 if (feature == NULL)
3693 if (chise_feature_setup_db (feature, 0) == 0)
3695 Lisp_Object table = Fgethash (attribute,
3696 Vchar_attribute_hash_table, Qunbound);
3697 Lisp_Char_Table *ct;
3699 chise_feature_sync (feature);
3700 if (UNBOUNDP (table))
3702 table = make_char_id_table (Qunbound);
3703 Fputhash (attribute, table, Vchar_attribute_hash_table);
3704 XCHAR_TABLE_NAME(table) = attribute;
3706 ct = XCHAR_TABLE (table);
3707 ct->table = Qunloaded;
3708 char_table_close_db_maybe (ct);
3709 XCHAR_TABLE_UNLOADED(table) = 1;
3713 Lisp_Object table = Fgethash (attribute,
3714 Vchar_attribute_hash_table, Qunbound);
3715 Lisp_Char_Table *ct;
3717 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3719 if (!NILP (Ffile_exists_p (db_file)))
3721 if (UNBOUNDP (table))
3723 table = make_char_id_table (Qunbound);
3724 Fputhash (attribute, table, Vchar_attribute_hash_table);
3725 XCHAR_TABLE_NAME(table) = attribute;
3727 ct = XCHAR_TABLE (table);
3728 ct->table = Qunloaded;
3729 char_table_close_db_maybe (ct);
3730 XCHAR_TABLE_UNLOADED(table) = 1;
3738 load_char_attribute_maybe (Lisp_Char_Table* cit, Emchar ch)
3740 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3742 if (!NILP (attribute))
3746 if (char_table_open_db_maybe (cit))
3749 val = char_table_get_db (cit, ch);
3751 if (!NILP (Vchar_db_stingy_mode))
3752 char_table_close_db_maybe (cit);
3759 Lisp_Char_Table* char_attribute_table_to_load;
3761 #ifdef HAVE_LIBCHISE
3763 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3764 CHISE_Feature feature,
3765 CHISE_Value *value);
3767 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3768 CHISE_Feature feature,
3772 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3774 if (EQ (ret, Qunloaded))
3775 put_char_id_table_0 (char_attribute_table_to_load, code,
3776 Fread (make_string ((Bufbyte *) value->data,
3780 #else /* HAVE_LIBCHISE */
3781 Lisp_Object Qload_char_attribute_table_map_function;
3783 DEFUN ("load-char-attribute-table-map-function",
3784 Fload_char_attribute_table_map_function, 2, 2, 0, /*
3785 For internal use. Don't use it.
3789 Lisp_Object c = Fread (key);
3790 Emchar code = XCHAR (c);
3791 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3793 if (EQ (ret, Qunloaded))
3794 put_char_id_table_0 (char_attribute_table_to_load, code, Fread (value));
3797 #endif /* not HAVE_LIBCHISE */
3799 DEFUN ("load-char-attribute-table", Fload_char_attribute_table, 1, 1, 0, /*
3800 Load values of ATTRIBUTE into database file.
3804 Lisp_Object table = Fgethash (attribute,
3805 Vchar_attribute_hash_table,
3807 if (CHAR_TABLEP (table))
3809 Lisp_Char_Table *cit = XCHAR_TABLE (table);
3811 if (char_table_open_db_maybe (cit))
3814 char_attribute_table_to_load = XCHAR_TABLE (table);
3816 struct gcpro gcpro1;
3819 #ifdef HAVE_LIBCHISE
3820 chise_char_feature_value_iterate
3821 (chise_ds_get_feature (default_chise_data_source,
3822 XSTRING_DATA (Fsymbol_name (cit->name))),
3823 &load_char_attribute_table_map_func);
3824 #else /* HAVE_LIBCHISE */
3825 Fmap_database (Qload_char_attribute_table_map_function, cit->db);
3826 #endif /* not HAVE_LIBCHISE */
3829 char_table_close_db_maybe (cit);
3830 XCHAR_TABLE_UNLOADED(table) = 0;
3835 #endif /* HAVE_CHISE */
3837 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3838 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3839 each key and value in the table.
3841 RANGE specifies a subrange to map over and is in the same format as
3842 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3845 (function, attribute, range))
3848 Lisp_Char_Table *ct;
3849 struct slow_map_char_table_arg slarg;
3850 struct gcpro gcpro1, gcpro2;
3851 struct chartab_range rainj;
3853 if (!NILP (ccs = Ffind_charset (attribute)))
3855 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3857 if (CHAR_TABLEP (encoding_table))
3858 ct = XCHAR_TABLE (encoding_table);
3864 Lisp_Object table = Fgethash (attribute,
3865 Vchar_attribute_hash_table,
3867 if (CHAR_TABLEP (table))
3868 ct = XCHAR_TABLE (table);
3874 decode_char_table_range (range, &rainj);
3876 if (CHAR_TABLE_UNLOADED(ct))
3877 Fload_char_attribute_table (attribute);
3879 slarg.function = function;
3880 slarg.retval = Qnil;
3881 GCPRO2 (slarg.function, slarg.retval);
3882 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3885 return slarg.retval;
3888 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3889 Store character's ATTRIBUTES.
3893 Lisp_Object rest = attributes;
3894 Lisp_Object code = Fcdr (Fassq (Qmap_ucs, attributes));
3895 Lisp_Object character;
3898 code = Fcdr (Fassq (Qucs, attributes));
3901 while (CONSP (rest))
3903 Lisp_Object cell = Fcar (rest);
3907 signal_simple_error ("Invalid argument", attributes);
3908 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3909 && ((XCHARSET_FINAL (ccs) != 0) ||
3910 (XCHARSET_MAX_CODE (ccs) > 0) ||
3911 (EQ (ccs, Vcharset_chinese_big5))) )
3915 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3917 character = Fdecode_char (ccs, cell, Qnil);
3918 if (!NILP (character))
3919 goto setup_attributes;
3923 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
3926 signal_simple_error ("Invalid argument", attributes);
3928 character = make_char (XINT (code) + 0x100000);
3929 goto setup_attributes;
3933 else if (!INTP (code))
3934 signal_simple_error ("Invalid argument", attributes);
3936 character = make_char (XINT (code));
3940 while (CONSP (rest))
3942 Lisp_Object cell = Fcar (rest);
3945 signal_simple_error ("Invalid argument", attributes);
3947 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
3953 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
3954 Retrieve the character of the given ATTRIBUTES.
3958 Lisp_Object rest = attributes;
3961 while (CONSP (rest))
3963 Lisp_Object cell = Fcar (rest);
3967 signal_simple_error ("Invalid argument", attributes);
3968 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
3972 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3974 return Fdecode_char (ccs, cell, Qnil);
3978 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
3981 signal_simple_error ("Invalid argument", attributes);
3983 return make_char (XINT (code) + 0x100000);
3991 /************************************************************************/
3992 /* Char table read syntax */
3993 /************************************************************************/
3996 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
3997 Error_behavior errb)
3999 /* #### should deal with ERRB */
4000 symbol_to_char_table_type (value);
4005 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
4006 Error_behavior errb)
4010 /* #### should deal with ERRB */
4011 EXTERNAL_LIST_LOOP (rest, value)
4013 Lisp_Object range = XCAR (rest);
4014 struct chartab_range dummy;
4018 signal_simple_error ("Invalid list format", value);
4021 if (!CONSP (XCDR (range))
4022 || !NILP (XCDR (XCDR (range))))
4023 signal_simple_error ("Invalid range format", range);
4024 decode_char_table_range (XCAR (range), &dummy);
4025 decode_char_table_range (XCAR (XCDR (range)), &dummy);
4028 decode_char_table_range (range, &dummy);
4035 chartab_instantiate (Lisp_Object data)
4037 Lisp_Object chartab;
4038 Lisp_Object type = Qgeneric;
4039 Lisp_Object dataval = Qnil;
4041 while (!NILP (data))
4043 Lisp_Object keyw = Fcar (data);
4049 if (EQ (keyw, Qtype))
4051 else if (EQ (keyw, Qdata))
4055 chartab = Fmake_char_table (type);
4058 while (!NILP (data))
4060 Lisp_Object range = Fcar (data);
4061 Lisp_Object val = Fcar (Fcdr (data));
4063 data = Fcdr (Fcdr (data));
4066 if (CHAR_OR_CHAR_INTP (XCAR (range)))
4068 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
4069 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
4072 for (i = first; i <= last; i++)
4073 Fput_char_table (make_char (i), val, chartab);
4079 Fput_char_table (range, val, chartab);
4088 /************************************************************************/
4089 /* Category Tables, specifically */
4090 /************************************************************************/
4092 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
4093 Return t if OBJECT is a category table.
4094 A category table is a type of char table used for keeping track of
4095 categories. Categories are used for classifying characters for use
4096 in regexps -- you can refer to a category rather than having to use
4097 a complicated [] expression (and category lookups are significantly
4100 There are 95 different categories available, one for each printable
4101 character (including space) in the ASCII charset. Each category
4102 is designated by one such character, called a "category designator".
4103 They are specified in a regexp using the syntax "\\cX", where X is
4104 a category designator.
4106 A category table specifies, for each character, the categories that
4107 the character is in. Note that a character can be in more than one
4108 category. More specifically, a category table maps from a character
4109 to either the value nil (meaning the character is in no categories)
4110 or a 95-element bit vector, specifying for each of the 95 categories
4111 whether the character is in that category.
4113 Special Lisp functions are provided that abstract this, so you do not
4114 have to directly manipulate bit vectors.
4118 return (CHAR_TABLEP (object) &&
4119 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
4124 check_category_table (Lisp_Object object, Lisp_Object default_)
4128 while (NILP (Fcategory_table_p (object)))
4129 object = wrong_type_argument (Qcategory_table_p, object);
4134 check_category_char (Emchar ch, Lisp_Object table,
4135 unsigned int designator, unsigned int not_p)
4137 REGISTER Lisp_Object temp;
4138 Lisp_Char_Table *ctbl;
4139 #ifdef ERROR_CHECK_TYPECHECK
4140 if (NILP (Fcategory_table_p (table)))
4141 signal_simple_error ("Expected category table", table);
4143 ctbl = XCHAR_TABLE (table);
4144 temp = get_char_table (ch, ctbl);
4149 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
4152 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
4153 Return t if category of the character at POSITION includes DESIGNATOR.
4154 Optional third arg BUFFER specifies which buffer to use, and defaults
4155 to the current buffer.
4156 Optional fourth arg CATEGORY-TABLE specifies the category table to
4157 use, and defaults to BUFFER's category table.
4159 (position, designator, buffer, category_table))
4164 struct buffer *buf = decode_buffer (buffer, 0);
4166 CHECK_INT (position);
4167 CHECK_CATEGORY_DESIGNATOR (designator);
4168 des = XCHAR (designator);
4169 ctbl = check_category_table (category_table, Vstandard_category_table);
4170 ch = BUF_FETCH_CHAR (buf, XINT (position));
4171 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4174 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
4175 Return t if category of CHARACTER includes DESIGNATOR, else nil.
4176 Optional third arg CATEGORY-TABLE specifies the category table to use,
4177 and defaults to the standard category table.
4179 (character, designator, category_table))
4185 CHECK_CATEGORY_DESIGNATOR (designator);
4186 des = XCHAR (designator);
4187 CHECK_CHAR (character);
4188 ch = XCHAR (character);
4189 ctbl = check_category_table (category_table, Vstandard_category_table);
4190 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4193 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
4194 Return BUFFER's current category table.
4195 BUFFER defaults to the current buffer.
4199 return decode_buffer (buffer, 0)->category_table;
4202 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
4203 Return the standard category table.
4204 This is the one used for new buffers.
4208 return Vstandard_category_table;
4211 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
4212 Return a new category table which is a copy of CATEGORY-TABLE.
4213 CATEGORY-TABLE defaults to the standard category table.
4217 if (NILP (Vstandard_category_table))
4218 return Fmake_char_table (Qcategory);
4221 check_category_table (category_table, Vstandard_category_table);
4222 return Fcopy_char_table (category_table);
4225 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
4226 Select CATEGORY-TABLE as the new category table for BUFFER.
4227 BUFFER defaults to the current buffer if omitted.
4229 (category_table, buffer))
4231 struct buffer *buf = decode_buffer (buffer, 0);
4232 category_table = check_category_table (category_table, Qnil);
4233 buf->category_table = category_table;
4234 /* Indicate that this buffer now has a specified category table. */
4235 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
4236 return category_table;
4239 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
4240 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
4244 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
4247 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
4248 Return t if OBJECT is a category table value.
4249 Valid values are nil or a bit vector of size 95.
4253 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
4257 #define CATEGORYP(x) \
4258 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
4260 #define CATEGORY_SET(c) \
4261 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
4263 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
4264 The faster version of `!NILP (Faref (category_set, category))'. */
4265 #define CATEGORY_MEMBER(category, category_set) \
4266 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
4268 /* Return 1 if there is a word boundary between two word-constituent
4269 characters C1 and C2 if they appear in this order, else return 0.
4270 Use the macro WORD_BOUNDARY_P instead of calling this function
4273 int word_boundary_p (Emchar c1, Emchar c2);
4275 word_boundary_p (Emchar c1, Emchar c2)
4277 Lisp_Object category_set1, category_set2;
4282 if (COMPOSITE_CHAR_P (c1))
4283 c1 = cmpchar_component (c1, 0, 1);
4284 if (COMPOSITE_CHAR_P (c2))
4285 c2 = cmpchar_component (c2, 0, 1);
4289 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
4292 tail = Vword_separating_categories;
4298 tail = Vword_combining_categories;
4303 category_set1 = CATEGORY_SET (c1);
4304 if (NILP (category_set1))
4305 return default_result;
4306 category_set2 = CATEGORY_SET (c2);
4307 if (NILP (category_set2))
4308 return default_result;
4310 for (; CONSP (tail); tail = XCONS (tail)->cdr)
4312 Lisp_Object elt = XCONS(tail)->car;
4315 && CATEGORYP (XCONS (elt)->car)
4316 && CATEGORYP (XCONS (elt)->cdr)
4317 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
4318 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
4319 return !default_result;
4321 return default_result;
4327 syms_of_chartab (void)
4330 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
4331 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
4332 INIT_LRECORD_IMPLEMENTATION (byte_table);
4334 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
4335 defsymbol (&Qsystem_char_id, "system-char-id");
4338 defsymbol (&Qto_ucs, "=>ucs");
4339 defsymbol (&Q_ucs_unified, "->ucs-unified");
4340 defsymbol (&Qcomposition, "composition");
4341 defsymbol (&Q_decomposition, "->decomposition");
4342 defsymbol (&Qcompat, "compat");
4343 defsymbol (&Qisolated, "isolated");
4344 defsymbol (&Qinitial, "initial");
4345 defsymbol (&Qmedial, "medial");
4346 defsymbol (&Qfinal, "final");
4347 defsymbol (&Qvertical, "vertical");
4348 defsymbol (&QnoBreak, "noBreak");
4349 defsymbol (&Qfraction, "fraction");
4350 defsymbol (&Qsuper, "super");
4351 defsymbol (&Qsub, "sub");
4352 defsymbol (&Qcircle, "circle");
4353 defsymbol (&Qsquare, "square");
4354 defsymbol (&Qwide, "wide");
4355 defsymbol (&Qnarrow, "narrow");
4356 defsymbol (&Qsmall, "small");
4357 defsymbol (&Qfont, "font");
4359 DEFSUBR (Fchar_attribute_list);
4360 DEFSUBR (Ffind_char_attribute_table);
4361 defsymbol (&Qput_char_table_map_function, "put-char-table-map-function");
4362 DEFSUBR (Fput_char_table_map_function);
4364 DEFSUBR (Fsave_char_attribute_table);
4365 DEFSUBR (Fmount_char_attribute_table);
4366 DEFSUBR (Freset_char_attribute_table);
4367 DEFSUBR (Fclose_char_attribute_table);
4368 DEFSUBR (Fclose_char_data_source);
4369 #ifndef HAVE_LIBCHISE
4370 defsymbol (&Qload_char_attribute_table_map_function,
4371 "load-char-attribute-table-map-function");
4372 DEFSUBR (Fload_char_attribute_table_map_function);
4374 DEFSUBR (Fload_char_attribute_table);
4376 DEFSUBR (Fchar_attribute_alist);
4377 DEFSUBR (Fget_char_attribute);
4378 DEFSUBR (Fput_char_attribute);
4379 DEFSUBR (Fremove_char_attribute);
4380 DEFSUBR (Fmap_char_attribute);
4381 DEFSUBR (Fdefine_char);
4382 DEFSUBR (Ffind_char);
4383 DEFSUBR (Fchar_variants);
4385 DEFSUBR (Fget_composite_char);
4388 INIT_LRECORD_IMPLEMENTATION (char_table);
4392 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
4395 defsymbol (&Qcategory_table_p, "category-table-p");
4396 defsymbol (&Qcategory_designator_p, "category-designator-p");
4397 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
4400 defsymbol (&Qchar_table, "char-table");
4401 defsymbol (&Qchar_tablep, "char-table-p");
4403 DEFSUBR (Fchar_table_p);
4404 DEFSUBR (Fchar_table_type_list);
4405 DEFSUBR (Fvalid_char_table_type_p);
4406 DEFSUBR (Fchar_table_type);
4407 DEFSUBR (Freset_char_table);
4408 DEFSUBR (Fmake_char_table);
4409 DEFSUBR (Fcopy_char_table);
4410 DEFSUBR (Fget_char_table);
4411 DEFSUBR (Fget_range_char_table);
4412 DEFSUBR (Fvalid_char_table_value_p);
4413 DEFSUBR (Fcheck_valid_char_table_value);
4414 DEFSUBR (Fput_char_table);
4415 DEFSUBR (Fmap_char_table);
4418 DEFSUBR (Fcategory_table_p);
4419 DEFSUBR (Fcategory_table);
4420 DEFSUBR (Fstandard_category_table);
4421 DEFSUBR (Fcopy_category_table);
4422 DEFSUBR (Fset_category_table);
4423 DEFSUBR (Fcheck_category_at);
4424 DEFSUBR (Fchar_in_category_p);
4425 DEFSUBR (Fcategory_designator_p);
4426 DEFSUBR (Fcategory_table_value_p);
4432 vars_of_chartab (void)
4435 DEFVAR_LISP ("char-db-stingy-mode", &Vchar_db_stingy_mode /*
4437 Vchar_db_stingy_mode = Qt;
4438 #endif /* HAVE_CHISE */
4439 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
4440 Vall_syntax_tables = Qnil;
4441 dump_add_weak_object_chain (&Vall_syntax_tables);
4445 structure_type_create_chartab (void)
4447 struct structure_type *st;
4449 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
4451 define_structure_type_keyword (st, Qtype, chartab_type_validate);
4452 define_structure_type_keyword (st, Qdata, chartab_data_validate);
4456 complex_vars_of_chartab (void)
4459 staticpro (&Vchar_attribute_hash_table);
4460 Vchar_attribute_hash_table
4461 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
4462 #endif /* UTF2000 */
4464 /* Set this now, so first buffer creation can refer to it. */
4465 /* Make it nil before calling copy-category-table
4466 so that copy-category-table will know not to try to copy from garbage */
4467 Vstandard_category_table = Qnil;
4468 Vstandard_category_table = Fcopy_category_table (Qnil);
4469 staticpro (&Vstandard_category_table);
4471 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
4472 List of pair (cons) of categories to determine word boundary.
4474 Emacs treats a sequence of word constituent characters as a single
4475 word (i.e. finds no word boundary between them) iff they belongs to
4476 the same charset. But, exceptions are allowed in the following cases.
4478 \(1) The case that characters are in different charsets is controlled
4479 by the variable `word-combining-categories'.
4481 Emacs finds no word boundary between characters of different charsets
4482 if they have categories matching some element of this list.
4484 More precisely, if an element of this list is a cons of category CAT1
4485 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4486 C2 which has CAT2, there's no word boundary between C1 and C2.
4488 For instance, to tell that ASCII characters and Latin-1 characters can
4489 form a single word, the element `(?l . ?l)' should be in this list
4490 because both characters have the category `l' (Latin characters).
4492 \(2) The case that character are in the same charset is controlled by
4493 the variable `word-separating-categories'.
4495 Emacs find a word boundary between characters of the same charset
4496 if they have categories matching some element of this list.
4498 More precisely, if an element of this list is a cons of category CAT1
4499 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4500 C2 which has CAT2, there's a word boundary between C1 and C2.
4502 For instance, to tell that there's a word boundary between Japanese
4503 Hiragana and Japanese Kanji (both are in the same charset), the
4504 element `(?H . ?C) should be in this list.
4507 Vword_combining_categories = Qnil;
4509 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
4510 List of pair (cons) of categories to determine word boundary.
4511 See the documentation of the variable `word-combining-categories'.
4514 Vword_separating_categories = Qnil;