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,2004 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 CHISE
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 Lisp_Object Vchise_db_directory;
68 Lisp_Object Vchise_system_db_directory;
70 CHISE_DS *default_chise_data_source = NULL;
75 EXFUN (Fchar_refs_simplify_char_specs, 1);
76 extern Lisp_Object Qideographic_structure;
78 EXFUN (Fdefine_char, 1);
80 EXFUN (Fmap_char_attribute, 3);
83 EXFUN (Fmount_char_attribute_table, 1);
87 EXFUN (Fload_char_attribute_table, 1);
89 Lisp_Object Vchar_db_stingy_mode;
92 #define BT_UINT8_MIN 0
93 #define BT_UINT8_MAX (UCHAR_MAX - 4)
94 #define BT_UINT8_t (UCHAR_MAX - 3)
95 #define BT_UINT8_nil (UCHAR_MAX - 2)
96 #define BT_UINT8_unbound (UCHAR_MAX - 1)
97 #define BT_UINT8_unloaded UCHAR_MAX
99 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
100 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
101 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
102 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
103 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
106 INT_UINT8_P (Lisp_Object obj)
110 int num = XINT (obj);
112 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
119 UINT8_VALUE_P (Lisp_Object obj)
121 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
122 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
125 INLINE_HEADER unsigned char
126 UINT8_ENCODE (Lisp_Object obj)
128 if (EQ (obj, Qunloaded))
129 return BT_UINT8_unloaded;
130 else if (EQ (obj, Qunbound))
131 return BT_UINT8_unbound;
132 else if (EQ (obj, Qnil))
134 else if (EQ (obj, Qt))
140 INLINE_HEADER Lisp_Object
141 UINT8_DECODE (unsigned char n)
143 if (n == BT_UINT8_unloaded)
145 else if (n == BT_UINT8_unbound)
147 else if (n == BT_UINT8_nil)
149 else if (n == BT_UINT8_t)
156 mark_uint8_byte_table (Lisp_Object obj)
162 print_uint8_byte_table (Lisp_Object obj,
163 Lisp_Object printcharfun, int escapeflag)
165 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
167 struct gcpro gcpro1, gcpro2;
168 GCPRO2 (obj, printcharfun);
170 write_c_string ("\n#<uint8-byte-table", printcharfun);
171 for (i = 0; i < 256; i++)
173 unsigned char n = bte->property[i];
175 write_c_string ("\n ", printcharfun);
176 write_c_string (" ", printcharfun);
177 if (n == BT_UINT8_unbound)
178 write_c_string ("void", printcharfun);
179 else if (n == BT_UINT8_nil)
180 write_c_string ("nil", printcharfun);
181 else if (n == BT_UINT8_t)
182 write_c_string ("t", printcharfun);
187 sprintf (buf, "%hd", n);
188 write_c_string (buf, printcharfun);
192 write_c_string (">", printcharfun);
196 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
198 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
199 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
202 for (i = 0; i < 256; i++)
203 if (te1->property[i] != te2->property[i])
209 uint8_byte_table_hash (Lisp_Object obj, int depth)
211 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
215 for (i = 0; i < 256; i++)
216 hash = HASH2 (hash, te->property[i]);
220 static const struct lrecord_description uint8_byte_table_description[] = {
224 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
225 mark_uint8_byte_table,
226 print_uint8_byte_table,
227 0, uint8_byte_table_equal,
228 uint8_byte_table_hash,
229 uint8_byte_table_description,
230 Lisp_Uint8_Byte_Table);
233 make_uint8_byte_table (unsigned char initval)
237 Lisp_Uint8_Byte_Table *cte;
239 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
240 &lrecord_uint8_byte_table);
242 for (i = 0; i < 256; i++)
243 cte->property[i] = initval;
245 XSETUINT8_BYTE_TABLE (obj, cte);
250 copy_uint8_byte_table (Lisp_Object entry)
252 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
255 Lisp_Uint8_Byte_Table *ctenew
256 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
257 &lrecord_uint8_byte_table);
259 for (i = 0; i < 256; i++)
261 ctenew->property[i] = cte->property[i];
264 XSETUINT8_BYTE_TABLE (obj, ctenew);
269 uint8_byte_table_same_value_p (Lisp_Object obj)
271 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
272 unsigned char v0 = bte->property[0];
275 for (i = 1; i < 256; i++)
277 if (bte->property[i] != v0)
284 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
285 Emchar ofs, int place,
286 int (*fn) (struct chartab_range *range,
287 Lisp_Object val, void *arg),
290 struct chartab_range rainj;
292 int unit = 1 << (8 * place);
296 rainj.type = CHARTAB_RANGE_CHAR;
298 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
300 if (ct->property[i] == BT_UINT8_unloaded)
304 for (; c < c1 && retval == 0; c++)
306 Lisp_Object ret = get_char_id_table (root, c);
311 retval = (fn) (&rainj, ret, arg);
315 ct->property[i] = BT_UINT8_unbound;
319 else if (ct->property[i] != BT_UINT8_unbound)
322 for (; c < c1 && retval == 0; c++)
325 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
336 save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
338 CHISE_Feature feature,
342 Emchar ofs, int place,
343 Lisp_Object (*filter)(Lisp_Object value))
345 struct chartab_range rainj;
347 int unit = 1 << (8 * place);
351 rainj.type = CHARTAB_RANGE_CHAR;
353 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
355 if (ct->property[i] == BT_UINT8_unloaded)
359 else if (ct->property[i] != BT_UINT8_unbound)
362 for (; c < c1 && retval == 0; c++)
365 chise_char_set_feature_value
368 (Fprin1_to_string (UINT8_DECODE (ct->property[i]),
371 Fput_database (Fprin1_to_string (make_char (c), Qnil),
372 Fprin1_to_string (UINT8_DECODE (ct->property[i]),
384 #define BT_UINT16_MIN 0
385 #define BT_UINT16_MAX (USHRT_MAX - 4)
386 #define BT_UINT16_t (USHRT_MAX - 3)
387 #define BT_UINT16_nil (USHRT_MAX - 2)
388 #define BT_UINT16_unbound (USHRT_MAX - 1)
389 #define BT_UINT16_unloaded USHRT_MAX
391 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
392 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
393 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
394 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
397 INT_UINT16_P (Lisp_Object obj)
401 int num = XINT (obj);
403 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
410 UINT16_VALUE_P (Lisp_Object obj)
412 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
413 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
416 INLINE_HEADER unsigned short
417 UINT16_ENCODE (Lisp_Object obj)
419 if (EQ (obj, Qunloaded))
420 return BT_UINT16_unloaded;
421 else if (EQ (obj, Qunbound))
422 return BT_UINT16_unbound;
423 else if (EQ (obj, Qnil))
424 return BT_UINT16_nil;
425 else if (EQ (obj, Qt))
431 INLINE_HEADER Lisp_Object
432 UINT16_DECODE (unsigned short n)
434 if (n == BT_UINT16_unloaded)
436 else if (n == BT_UINT16_unbound)
438 else if (n == BT_UINT16_nil)
440 else if (n == BT_UINT16_t)
446 INLINE_HEADER unsigned short
447 UINT8_TO_UINT16 (unsigned char n)
449 if (n == BT_UINT8_unloaded)
450 return BT_UINT16_unloaded;
451 else if (n == BT_UINT8_unbound)
452 return BT_UINT16_unbound;
453 else if (n == BT_UINT8_nil)
454 return BT_UINT16_nil;
455 else if (n == BT_UINT8_t)
462 mark_uint16_byte_table (Lisp_Object obj)
468 print_uint16_byte_table (Lisp_Object obj,
469 Lisp_Object printcharfun, int escapeflag)
471 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
473 struct gcpro gcpro1, gcpro2;
474 GCPRO2 (obj, printcharfun);
476 write_c_string ("\n#<uint16-byte-table", printcharfun);
477 for (i = 0; i < 256; i++)
479 unsigned short n = bte->property[i];
481 write_c_string ("\n ", printcharfun);
482 write_c_string (" ", printcharfun);
483 if (n == BT_UINT16_unbound)
484 write_c_string ("void", printcharfun);
485 else if (n == BT_UINT16_nil)
486 write_c_string ("nil", printcharfun);
487 else if (n == BT_UINT16_t)
488 write_c_string ("t", printcharfun);
493 sprintf (buf, "%hd", n);
494 write_c_string (buf, printcharfun);
498 write_c_string (">", printcharfun);
502 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
504 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
505 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
508 for (i = 0; i < 256; i++)
509 if (te1->property[i] != te2->property[i])
515 uint16_byte_table_hash (Lisp_Object obj, int depth)
517 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
521 for (i = 0; i < 256; i++)
522 hash = HASH2 (hash, te->property[i]);
526 static const struct lrecord_description uint16_byte_table_description[] = {
530 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
531 mark_uint16_byte_table,
532 print_uint16_byte_table,
533 0, uint16_byte_table_equal,
534 uint16_byte_table_hash,
535 uint16_byte_table_description,
536 Lisp_Uint16_Byte_Table);
539 make_uint16_byte_table (unsigned short initval)
543 Lisp_Uint16_Byte_Table *cte;
545 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
546 &lrecord_uint16_byte_table);
548 for (i = 0; i < 256; i++)
549 cte->property[i] = initval;
551 XSETUINT16_BYTE_TABLE (obj, cte);
556 copy_uint16_byte_table (Lisp_Object entry)
558 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
561 Lisp_Uint16_Byte_Table *ctenew
562 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
563 &lrecord_uint16_byte_table);
565 for (i = 0; i < 256; i++)
567 ctenew->property[i] = cte->property[i];
570 XSETUINT16_BYTE_TABLE (obj, ctenew);
575 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
579 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
580 Lisp_Uint16_Byte_Table* cte;
582 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
583 &lrecord_uint16_byte_table);
584 for (i = 0; i < 256; i++)
586 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
588 XSETUINT16_BYTE_TABLE (obj, cte);
593 uint16_byte_table_same_value_p (Lisp_Object obj)
595 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
596 unsigned short v0 = bte->property[0];
599 for (i = 1; i < 256; i++)
601 if (bte->property[i] != v0)
608 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
609 Emchar ofs, int place,
610 int (*fn) (struct chartab_range *range,
611 Lisp_Object val, void *arg),
614 struct chartab_range rainj;
616 int unit = 1 << (8 * place);
620 rainj.type = CHARTAB_RANGE_CHAR;
622 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
624 if (ct->property[i] == BT_UINT16_unloaded)
628 for (; c < c1 && retval == 0; c++)
630 Lisp_Object ret = get_char_id_table (root, c);
635 retval = (fn) (&rainj, ret, arg);
639 ct->property[i] = BT_UINT16_unbound;
643 else if (ct->property[i] != BT_UINT16_unbound)
646 for (; c < c1 && retval == 0; c++)
649 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
660 save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
662 CHISE_Feature feature,
666 Emchar ofs, int place,
667 Lisp_Object (*filter)(Lisp_Object value))
669 struct chartab_range rainj;
671 int unit = 1 << (8 * place);
675 rainj.type = CHARTAB_RANGE_CHAR;
677 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
679 if (ct->property[i] == BT_UINT16_unloaded)
683 else if (ct->property[i] != BT_UINT16_unbound)
686 for (; c < c1 && retval == 0; c++)
689 chise_char_set_feature_value
692 (Fprin1_to_string (UINT16_DECODE (ct->property[i]),
695 Fput_database (Fprin1_to_string (make_char (c), Qnil),
696 Fprin1_to_string (UINT16_DECODE (ct->property[i]),
710 mark_byte_table (Lisp_Object obj)
712 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
715 for (i = 0; i < 256; i++)
717 mark_object (cte->property[i]);
723 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
725 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
727 struct gcpro gcpro1, gcpro2;
728 GCPRO2 (obj, printcharfun);
730 write_c_string ("\n#<byte-table", printcharfun);
731 for (i = 0; i < 256; i++)
733 Lisp_Object elt = bte->property[i];
735 write_c_string ("\n ", printcharfun);
736 write_c_string (" ", printcharfun);
737 if (EQ (elt, Qunbound))
738 write_c_string ("void", printcharfun);
740 print_internal (elt, printcharfun, escapeflag);
743 write_c_string (">", printcharfun);
747 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
749 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
750 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
753 for (i = 0; i < 256; i++)
754 if (BYTE_TABLE_P (cte1->property[i]))
756 if (BYTE_TABLE_P (cte2->property[i]))
758 if (!byte_table_equal (cte1->property[i],
759 cte2->property[i], depth + 1))
766 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
772 byte_table_hash (Lisp_Object obj, int depth)
774 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
776 return internal_array_hash (cte->property, 256, depth);
779 static const struct lrecord_description byte_table_description[] = {
780 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
784 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
789 byte_table_description,
793 make_byte_table (Lisp_Object initval)
797 Lisp_Byte_Table *cte;
799 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
801 for (i = 0; i < 256; i++)
802 cte->property[i] = initval;
804 XSETBYTE_TABLE (obj, cte);
809 copy_byte_table (Lisp_Object entry)
811 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
814 Lisp_Byte_Table *ctnew
815 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
817 for (i = 0; i < 256; i++)
819 if (UINT8_BYTE_TABLE_P (cte->property[i]))
821 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
823 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
825 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
827 else if (BYTE_TABLE_P (cte->property[i]))
829 ctnew->property[i] = copy_byte_table (cte->property[i]);
832 ctnew->property[i] = cte->property[i];
835 XSETBYTE_TABLE (obj, ctnew);
840 byte_table_same_value_p (Lisp_Object obj)
842 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
843 Lisp_Object v0 = bte->property[0];
846 for (i = 1; i < 256; i++)
848 if (!internal_equal (bte->property[i], v0, 0))
855 map_over_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
856 Emchar ofs, int place,
857 int (*fn) (struct chartab_range *range,
858 Lisp_Object val, void *arg),
863 int unit = 1 << (8 * place);
866 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
869 if (UINT8_BYTE_TABLE_P (v))
872 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
873 c, place - 1, fn, arg);
876 else if (UINT16_BYTE_TABLE_P (v))
879 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
880 c, place - 1, fn, arg);
883 else if (BYTE_TABLE_P (v))
885 retval = map_over_byte_table (XBYTE_TABLE(v), root,
886 c, place - 1, fn, arg);
889 else if (EQ (v, Qunloaded))
892 struct chartab_range rainj;
893 Emchar c1 = c + unit;
895 rainj.type = CHARTAB_RANGE_CHAR;
897 for (; c < c1 && retval == 0; c++)
899 Lisp_Object ret = get_char_id_table (root, c);
904 retval = (fn) (&rainj, ret, arg);
908 ct->property[i] = Qunbound;
912 else if (!UNBOUNDP (v))
914 struct chartab_range rainj;
915 Emchar c1 = c + unit;
917 rainj.type = CHARTAB_RANGE_CHAR;
919 for (; c < c1 && retval == 0; c++)
922 retval = (fn) (&rainj, v, arg);
933 save_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
935 CHISE_Feature feature,
939 Emchar ofs, int place,
940 Lisp_Object (*filter)(Lisp_Object value))
944 int unit = 1 << (8 * place);
947 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
950 if (UINT8_BYTE_TABLE_P (v))
952 save_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
958 c, place - 1, filter);
961 else if (UINT16_BYTE_TABLE_P (v))
963 save_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
969 c, place - 1, filter);
972 else if (BYTE_TABLE_P (v))
974 save_byte_table (XBYTE_TABLE(v), root,
980 c, place - 1, filter);
983 else if (EQ (v, Qunloaded))
987 else if (!UNBOUNDP (v))
989 struct chartab_range rainj;
990 Emchar c1 = c + unit;
995 rainj.type = CHARTAB_RANGE_CHAR;
997 for (; c < c1 && retval == 0; c++)
1000 chise_char_set_feature_value
1001 (c, feature, XSTRING_DATA (Fprin1_to_string (v, Qnil)));
1003 Fput_database (Fprin1_to_string (make_char (c), Qnil),
1004 Fprin1_to_string (v, Qnil),
1016 get_byte_table (Lisp_Object table, unsigned char idx)
1018 if (UINT8_BYTE_TABLE_P (table))
1019 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
1020 else if (UINT16_BYTE_TABLE_P (table))
1021 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
1022 else if (BYTE_TABLE_P (table))
1023 return XBYTE_TABLE(table)->property[idx];
1029 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
1031 if (UINT8_BYTE_TABLE_P (table))
1033 if (UINT8_VALUE_P (value))
1035 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1036 if (!UINT8_BYTE_TABLE_P (value) &&
1037 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1038 && uint8_byte_table_same_value_p (table))
1043 else if (UINT16_VALUE_P (value))
1045 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
1047 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
1052 Lisp_Object new = make_byte_table (Qnil);
1055 for (i = 0; i < 256; i++)
1057 XBYTE_TABLE(new)->property[i]
1058 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
1060 XBYTE_TABLE(new)->property[idx] = value;
1064 else if (UINT16_BYTE_TABLE_P (table))
1066 if (UINT16_VALUE_P (value))
1068 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1069 if (!UINT8_BYTE_TABLE_P (value) &&
1070 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1071 && uint16_byte_table_same_value_p (table))
1078 Lisp_Object new = make_byte_table (Qnil);
1081 for (i = 0; i < 256; i++)
1083 XBYTE_TABLE(new)->property[i]
1084 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
1086 XBYTE_TABLE(new)->property[idx] = value;
1090 else if (BYTE_TABLE_P (table))
1092 XBYTE_TABLE(table)->property[idx] = value;
1093 if (!UINT8_BYTE_TABLE_P (value) &&
1094 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1095 && byte_table_same_value_p (table))
1100 else if (!internal_equal (table, value, 0))
1102 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
1104 table = make_uint8_byte_table (UINT8_ENCODE (table));
1105 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1107 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
1109 table = make_uint16_byte_table (UINT16_ENCODE (table));
1110 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1114 table = make_byte_table (table);
1115 XBYTE_TABLE(table)->property[idx] = value;
1123 make_char_id_table (Lisp_Object initval)
1126 obj = Fmake_char_table (Qgeneric);
1127 fill_char_table (XCHAR_TABLE (obj), initval);
1132 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
1133 Lisp_Object Qsystem_char_id;
1136 Lisp_Object Qcomposition;
1137 Lisp_Object Q_decomposition;
1138 Lisp_Object Q_unified;
1139 Lisp_Object Q_unified_from;
1140 Lisp_Object Qto_ucs;
1141 Lisp_Object Q_ucs_unified;
1142 Lisp_Object Qcompat;
1143 Lisp_Object Qisolated;
1144 Lisp_Object Qinitial;
1145 Lisp_Object Qmedial;
1147 Lisp_Object Qvertical;
1148 Lisp_Object QnoBreak;
1149 Lisp_Object Qfraction;
1152 Lisp_Object Qcircle;
1153 Lisp_Object Qsquare;
1155 Lisp_Object Qnarrow;
1159 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
1162 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
1168 else if (EQ (v, Qcompat))
1170 else if (EQ (v, Qisolated))
1172 else if (EQ (v, Qinitial))
1174 else if (EQ (v, Qmedial))
1176 else if (EQ (v, Qfinal))
1178 else if (EQ (v, Qvertical))
1180 else if (EQ (v, QnoBreak))
1182 else if (EQ (v, Qfraction))
1184 else if (EQ (v, Qsuper))
1186 else if (EQ (v, Qsub))
1188 else if (EQ (v, Qcircle))
1190 else if (EQ (v, Qsquare))
1192 else if (EQ (v, Qwide))
1194 else if (EQ (v, Qnarrow))
1196 else if (EQ (v, Qsmall))
1198 else if (EQ (v, Qfont))
1201 signal_simple_error (err_msg, err_arg);
1204 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
1205 Return character corresponding with list.
1209 Lisp_Object base, modifier;
1213 signal_simple_error ("Invalid value for composition", list);
1216 while (!NILP (rest))
1221 signal_simple_error ("Invalid value for composition", list);
1222 modifier = Fcar (rest);
1224 base = Fcdr (Fassq (modifier,
1225 Fget_char_attribute (base, Qcomposition, Qnil)));
1230 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
1231 Return variants of CHARACTER.
1237 CHECK_CHAR (character);
1238 ret = Fget_char_attribute (character, Q_ucs_unified, Qnil);
1240 return Fcopy_list (ret);
1248 /* A char table maps from ranges of characters to values.
1250 Implementing a general data structure that maps from arbitrary
1251 ranges of numbers to values is tricky to do efficiently. As it
1252 happens, it should suffice (and is usually more convenient, anyway)
1253 when dealing with characters to restrict the sorts of ranges that
1254 can be assigned values, as follows:
1257 2) All characters in a charset.
1258 3) All characters in a particular row of a charset, where a "row"
1259 means all characters with the same first byte.
1260 4) A particular character in a charset.
1262 We use char tables to generalize the 256-element vectors now
1263 littering the Emacs code.
1265 Possible uses (all should be converted at some point):
1271 5) keyboard-translate-table?
1274 abstract type to generalize the Emacs vectors and Mule
1275 vectors-of-vectors goo.
1278 /************************************************************************/
1279 /* Char Table object */
1280 /************************************************************************/
1282 #if defined(MULE)&&!defined(UTF2000)
1285 mark_char_table_entry (Lisp_Object obj)
1287 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1290 for (i = 0; i < 96; i++)
1292 mark_object (cte->level2[i]);
1298 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1300 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1301 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1304 for (i = 0; i < 96; i++)
1305 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1311 static unsigned long
1312 char_table_entry_hash (Lisp_Object obj, int depth)
1314 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1316 return internal_array_hash (cte->level2, 96, depth);
1319 static const struct lrecord_description char_table_entry_description[] = {
1320 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1324 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1325 mark_char_table_entry, internal_object_printer,
1326 0, char_table_entry_equal,
1327 char_table_entry_hash,
1328 char_table_entry_description,
1329 Lisp_Char_Table_Entry);
1333 mark_char_table (Lisp_Object obj)
1335 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1338 mark_object (ct->table);
1339 mark_object (ct->name);
1340 #ifndef HAVE_LIBCHISE
1341 mark_object (ct->db);
1346 for (i = 0; i < NUM_ASCII_CHARS; i++)
1347 mark_object (ct->ascii[i]);
1349 for (i = 0; i < NUM_LEADING_BYTES; i++)
1350 mark_object (ct->level1[i]);
1354 return ct->default_value;
1356 return ct->mirror_table;
1360 /* WARNING: All functions of this nature need to be written extremely
1361 carefully to avoid crashes during GC. Cf. prune_specifiers()
1362 and prune_weak_hash_tables(). */
1365 prune_syntax_tables (void)
1367 Lisp_Object rest, prev = Qnil;
1369 for (rest = Vall_syntax_tables;
1371 rest = XCHAR_TABLE (rest)->next_table)
1373 if (! marked_p (rest))
1375 /* This table is garbage. Remove it from the list. */
1377 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1379 XCHAR_TABLE (prev)->next_table =
1380 XCHAR_TABLE (rest)->next_table;
1386 char_table_type_to_symbol (enum char_table_type type)
1391 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1392 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1393 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1394 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1396 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1401 static enum char_table_type
1402 symbol_to_char_table_type (Lisp_Object symbol)
1404 CHECK_SYMBOL (symbol);
1406 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1407 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1408 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1409 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1411 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1414 signal_simple_error ("Unrecognized char table type", symbol);
1415 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1420 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1421 Lisp_Object printcharfun)
1425 write_c_string (" (", printcharfun);
1426 print_internal (make_char (first), printcharfun, 0);
1427 write_c_string (" ", printcharfun);
1428 print_internal (make_char (last), printcharfun, 0);
1429 write_c_string (") ", printcharfun);
1433 write_c_string (" ", printcharfun);
1434 print_internal (make_char (first), printcharfun, 0);
1435 write_c_string (" ", printcharfun);
1437 print_internal (val, printcharfun, 1);
1441 #if defined(MULE)&&!defined(UTF2000)
1444 print_chartab_charset_row (Lisp_Object charset,
1446 Lisp_Char_Table_Entry *cte,
1447 Lisp_Object printcharfun)
1450 Lisp_Object cat = Qunbound;
1453 for (i = 32; i < 128; i++)
1455 Lisp_Object pam = cte->level2[i - 32];
1467 print_chartab_range (MAKE_CHAR (charset, first, 0),
1468 MAKE_CHAR (charset, i - 1, 0),
1471 print_chartab_range (MAKE_CHAR (charset, row, first),
1472 MAKE_CHAR (charset, row, i - 1),
1482 print_chartab_range (MAKE_CHAR (charset, first, 0),
1483 MAKE_CHAR (charset, i - 1, 0),
1486 print_chartab_range (MAKE_CHAR (charset, row, first),
1487 MAKE_CHAR (charset, row, i - 1),
1493 print_chartab_two_byte_charset (Lisp_Object charset,
1494 Lisp_Char_Table_Entry *cte,
1495 Lisp_Object printcharfun)
1499 for (i = 32; i < 128; i++)
1501 Lisp_Object jen = cte->level2[i - 32];
1503 if (!CHAR_TABLE_ENTRYP (jen))
1507 write_c_string (" [", printcharfun);
1508 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1509 sprintf (buf, " %d] ", i);
1510 write_c_string (buf, printcharfun);
1511 print_internal (jen, printcharfun, 0);
1514 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1522 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1524 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1527 struct gcpro gcpro1, gcpro2;
1528 GCPRO2 (obj, printcharfun);
1530 write_c_string ("#s(char-table ", printcharfun);
1531 write_c_string (" ", printcharfun);
1532 write_c_string (string_data
1534 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1536 write_c_string ("\n ", printcharfun);
1537 print_internal (ct->default_value, printcharfun, escapeflag);
1538 for (i = 0; i < 256; i++)
1540 Lisp_Object elt = get_byte_table (ct->table, i);
1541 if (i != 0) write_c_string ("\n ", printcharfun);
1542 if (EQ (elt, Qunbound))
1543 write_c_string ("void", printcharfun);
1545 print_internal (elt, printcharfun, escapeflag);
1548 #else /* non UTF2000 */
1551 sprintf (buf, "#s(char-table type %s data (",
1552 string_data (symbol_name (XSYMBOL
1553 (char_table_type_to_symbol (ct->type)))));
1554 write_c_string (buf, printcharfun);
1556 /* Now write out the ASCII/Control-1 stuff. */
1560 Lisp_Object val = Qunbound;
1562 for (i = 0; i < NUM_ASCII_CHARS; i++)
1571 if (!EQ (ct->ascii[i], val))
1573 print_chartab_range (first, i - 1, val, printcharfun);
1580 print_chartab_range (first, i - 1, val, printcharfun);
1587 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1590 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1591 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1593 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1594 || i == LEADING_BYTE_CONTROL_1)
1596 if (!CHAR_TABLE_ENTRYP (ann))
1598 write_c_string (" ", printcharfun);
1599 print_internal (XCHARSET_NAME (charset),
1601 write_c_string (" ", printcharfun);
1602 print_internal (ann, printcharfun, 0);
1606 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1607 if (XCHARSET_DIMENSION (charset) == 1)
1608 print_chartab_charset_row (charset, -1, cte, printcharfun);
1610 print_chartab_two_byte_charset (charset, cte, printcharfun);
1615 #endif /* non UTF2000 */
1617 write_c_string ("))", printcharfun);
1621 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1623 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1624 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1627 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1631 for (i = 0; i < 256; i++)
1633 if (!internal_equal (get_byte_table (ct1->table, i),
1634 get_byte_table (ct2->table, i), 0))
1638 for (i = 0; i < NUM_ASCII_CHARS; i++)
1639 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1643 for (i = 0; i < NUM_LEADING_BYTES; i++)
1644 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1647 #endif /* non UTF2000 */
1652 static unsigned long
1653 char_table_hash (Lisp_Object obj, int depth)
1655 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1657 return byte_table_hash (ct->table, depth + 1);
1659 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1662 hashval = HASH2 (hashval,
1663 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1669 static const struct lrecord_description char_table_description[] = {
1671 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1672 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1673 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, name) },
1674 #ifndef HAVE_LIBCHISE
1675 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, db) },
1678 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1680 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1684 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1686 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1690 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1691 mark_char_table, print_char_table, 0,
1692 char_table_equal, char_table_hash,
1693 char_table_description,
1696 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1697 Return non-nil if OBJECT is a char table.
1699 A char table is a table that maps characters (or ranges of characters)
1700 to values. Char tables are specialized for characters, only allowing
1701 particular sorts of ranges to be assigned values. Although this
1702 loses in generality, it makes for extremely fast (constant-time)
1703 lookups, and thus is feasible for applications that do an extremely
1704 large number of lookups (e.g. scanning a buffer for a character in
1705 a particular syntax, where a lookup in the syntax table must occur
1706 once per character).
1708 When Mule support exists, the types of ranges that can be assigned
1712 -- an entire charset
1713 -- a single row in a two-octet charset
1714 -- a single character
1716 When Mule support is not present, the types of ranges that can be
1720 -- a single character
1722 To create a char table, use `make-char-table'.
1723 To modify a char table, use `put-char-table' or `remove-char-table'.
1724 To retrieve the value for a particular character, use `get-char-table'.
1725 See also `map-char-table', `clear-char-table', `copy-char-table',
1726 `valid-char-table-type-p', `char-table-type-list',
1727 `valid-char-table-value-p', and `check-char-table-value'.
1731 return CHAR_TABLEP (object) ? Qt : Qnil;
1734 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1735 Return a list of the recognized char table types.
1736 See `valid-char-table-type-p'.
1741 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1743 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1747 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1748 Return t if TYPE if a recognized char table type.
1750 Each char table type is used for a different purpose and allows different
1751 sorts of values. The different char table types are
1754 Used for category tables, which specify the regexp categories
1755 that a character is in. The valid values are nil or a
1756 bit vector of 95 elements. Higher-level Lisp functions are
1757 provided for working with category tables. Currently categories
1758 and category tables only exist when Mule support is present.
1760 A generalized char table, for mapping from one character to
1761 another. Used for case tables, syntax matching tables,
1762 `keyboard-translate-table', etc. The valid values are characters.
1764 An even more generalized char table, for mapping from a
1765 character to anything.
1767 Used for display tables, which specify how a particular character
1768 is to appear when displayed. #### Not yet implemented.
1770 Used for syntax tables, which specify the syntax of a particular
1771 character. Higher-level Lisp functions are provided for
1772 working with syntax tables. The valid values are integers.
1777 return (EQ (type, Qchar) ||
1779 EQ (type, Qcategory) ||
1781 EQ (type, Qdisplay) ||
1782 EQ (type, Qgeneric) ||
1783 EQ (type, Qsyntax)) ? Qt : Qnil;
1786 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1787 Return the type of CHAR-TABLE.
1788 See `valid-char-table-type-p'.
1792 CHECK_CHAR_TABLE (char_table);
1793 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1797 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1800 ct->table = Qunbound;
1801 ct->default_value = value;
1806 for (i = 0; i < NUM_ASCII_CHARS; i++)
1807 ct->ascii[i] = value;
1809 for (i = 0; i < NUM_LEADING_BYTES; i++)
1810 ct->level1[i] = value;
1815 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1816 update_syntax_table (ct);
1820 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1821 Reset CHAR-TABLE to its default state.
1825 Lisp_Char_Table *ct;
1827 CHECK_CHAR_TABLE (char_table);
1828 ct = XCHAR_TABLE (char_table);
1832 case CHAR_TABLE_TYPE_CHAR:
1833 fill_char_table (ct, make_char (0));
1835 case CHAR_TABLE_TYPE_DISPLAY:
1836 case CHAR_TABLE_TYPE_GENERIC:
1838 case CHAR_TABLE_TYPE_CATEGORY:
1840 fill_char_table (ct, Qnil);
1843 case CHAR_TABLE_TYPE_SYNTAX:
1844 fill_char_table (ct, make_int (Sinherit));
1854 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1855 Return a new, empty char table of type TYPE.
1856 Currently recognized types are 'char, 'category, 'display, 'generic,
1857 and 'syntax. See `valid-char-table-type-p'.
1861 Lisp_Char_Table *ct;
1863 enum char_table_type ty = symbol_to_char_table_type (type);
1865 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1868 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1870 ct->mirror_table = Fmake_char_table (Qgeneric);
1871 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1875 ct->mirror_table = Qnil;
1878 #ifndef HAVE_LIBCHISE
1882 ct->next_table = Qnil;
1883 XSETCHAR_TABLE (obj, ct);
1884 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1886 ct->next_table = Vall_syntax_tables;
1887 Vall_syntax_tables = obj;
1889 Freset_char_table (obj);
1893 #if defined(MULE)&&!defined(UTF2000)
1896 make_char_table_entry (Lisp_Object initval)
1900 Lisp_Char_Table_Entry *cte =
1901 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1903 for (i = 0; i < 96; i++)
1904 cte->level2[i] = initval;
1906 XSETCHAR_TABLE_ENTRY (obj, cte);
1911 copy_char_table_entry (Lisp_Object entry)
1913 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1916 Lisp_Char_Table_Entry *ctenew =
1917 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1919 for (i = 0; i < 96; i++)
1921 Lisp_Object new = cte->level2[i];
1922 if (CHAR_TABLE_ENTRYP (new))
1923 ctenew->level2[i] = copy_char_table_entry (new);
1925 ctenew->level2[i] = new;
1928 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1934 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1935 Return a new char table which is a copy of CHAR-TABLE.
1936 It will contain the same values for the same characters and ranges
1937 as CHAR-TABLE. The values will not themselves be copied.
1941 Lisp_Char_Table *ct, *ctnew;
1947 CHECK_CHAR_TABLE (char_table);
1948 ct = XCHAR_TABLE (char_table);
1949 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1950 ctnew->type = ct->type;
1952 ctnew->default_value = ct->default_value;
1953 /* [tomo:2002-01-21] Perhaps this code seems wrong */
1954 ctnew->name = ct->name;
1955 #ifndef HAVE_LIBCHISE
1959 if (UINT8_BYTE_TABLE_P (ct->table))
1961 ctnew->table = copy_uint8_byte_table (ct->table);
1963 else if (UINT16_BYTE_TABLE_P (ct->table))
1965 ctnew->table = copy_uint16_byte_table (ct->table);
1967 else if (BYTE_TABLE_P (ct->table))
1969 ctnew->table = copy_byte_table (ct->table);
1971 else if (!UNBOUNDP (ct->table))
1972 ctnew->table = ct->table;
1973 #else /* non UTF2000 */
1975 for (i = 0; i < NUM_ASCII_CHARS; i++)
1977 Lisp_Object new = ct->ascii[i];
1979 assert (! (CHAR_TABLE_ENTRYP (new)));
1981 ctnew->ascii[i] = new;
1986 for (i = 0; i < NUM_LEADING_BYTES; i++)
1988 Lisp_Object new = ct->level1[i];
1989 if (CHAR_TABLE_ENTRYP (new))
1990 ctnew->level1[i] = copy_char_table_entry (new);
1992 ctnew->level1[i] = new;
1996 #endif /* non UTF2000 */
1999 if (CHAR_TABLEP (ct->mirror_table))
2000 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
2002 ctnew->mirror_table = ct->mirror_table;
2004 ctnew->next_table = Qnil;
2005 XSETCHAR_TABLE (obj, ctnew);
2006 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
2008 ctnew->next_table = Vall_syntax_tables;
2009 Vall_syntax_tables = obj;
2014 INLINE_HEADER int XCHARSET_CELL_RANGE (Lisp_Object ccs);
2016 XCHARSET_CELL_RANGE (Lisp_Object ccs)
2018 switch (XCHARSET_CHARS (ccs))
2021 return (33 << 8) | 126;
2023 return (32 << 8) | 127;
2026 return (0 << 8) | 127;
2028 return (0 << 8) | 255;
2040 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
2043 outrange->type = CHARTAB_RANGE_ALL;
2045 else if (EQ (range, Qnil))
2046 outrange->type = CHARTAB_RANGE_DEFAULT;
2048 else if (CHAR_OR_CHAR_INTP (range))
2050 outrange->type = CHARTAB_RANGE_CHAR;
2051 outrange->ch = XCHAR_OR_CHAR_INT (range);
2055 signal_simple_error ("Range must be t or a character", range);
2057 else if (VECTORP (range))
2059 Lisp_Vector *vec = XVECTOR (range);
2060 Lisp_Object *elts = vector_data (vec);
2061 int cell_min, cell_max;
2063 outrange->type = CHARTAB_RANGE_ROW;
2064 outrange->charset = Fget_charset (elts[0]);
2065 CHECK_INT (elts[1]);
2066 outrange->row = XINT (elts[1]);
2067 if (XCHARSET_DIMENSION (outrange->charset) < 2)
2068 signal_simple_error ("Charset in row vector must be multi-byte",
2072 int ret = XCHARSET_CELL_RANGE (outrange->charset);
2074 cell_min = ret >> 8;
2075 cell_max = ret & 0xFF;
2077 if (XCHARSET_DIMENSION (outrange->charset) == 2)
2078 check_int_range (outrange->row, cell_min, cell_max);
2080 else if (XCHARSET_DIMENSION (outrange->charset) == 3)
2082 check_int_range (outrange->row >> 8 , cell_min, cell_max);
2083 check_int_range (outrange->row & 0xFF, cell_min, cell_max);
2085 else if (XCHARSET_DIMENSION (outrange->charset) == 4)
2087 check_int_range ( outrange->row >> 16 , cell_min, cell_max);
2088 check_int_range ((outrange->row >> 8) & 0xFF, cell_min, cell_max);
2089 check_int_range ( outrange->row & 0xFF, cell_min, cell_max);
2097 if (!CHARSETP (range) && !SYMBOLP (range))
2099 ("Char table range must be t, charset, char, or vector", range);
2100 outrange->type = CHARTAB_RANGE_CHARSET;
2101 outrange->charset = Fget_charset (range);
2106 #if defined(MULE)&&!defined(UTF2000)
2108 /* called from CHAR_TABLE_VALUE(). */
2110 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
2115 Lisp_Object charset;
2117 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
2122 BREAKUP_CHAR (c, charset, byte1, byte2);
2124 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
2126 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
2127 if (CHAR_TABLE_ENTRYP (val))
2129 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2130 val = cte->level2[byte1 - 32];
2131 if (CHAR_TABLE_ENTRYP (val))
2133 cte = XCHAR_TABLE_ENTRY (val);
2134 assert (byte2 >= 32);
2135 val = cte->level2[byte2 - 32];
2136 assert (!CHAR_TABLE_ENTRYP (val));
2146 get_char_table (Emchar ch, Lisp_Char_Table *ct)
2150 Lisp_Object ret = get_char_id_table (ct, ch);
2155 if (EQ (CHAR_TABLE_NAME (ct), Qdowncase))
2156 ret = Fget_char_attribute (make_char (ch), Q_lowercase, Qnil);
2157 else if (EQ (CHAR_TABLE_NAME (ct), Qflippedcase))
2158 ret = Fget_char_attribute (make_char (ch), Q_uppercase, Qnil);
2163 ret = Ffind_char (ret);
2171 Lisp_Object charset;
2175 BREAKUP_CHAR (ch, charset, byte1, byte2);
2177 if (EQ (charset, Vcharset_ascii))
2178 val = ct->ascii[byte1];
2179 else if (EQ (charset, Vcharset_control_1))
2180 val = ct->ascii[byte1 + 128];
2183 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2184 val = ct->level1[lb];
2185 if (CHAR_TABLE_ENTRYP (val))
2187 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2188 val = cte->level2[byte1 - 32];
2189 if (CHAR_TABLE_ENTRYP (val))
2191 cte = XCHAR_TABLE_ENTRY (val);
2192 assert (byte2 >= 32);
2193 val = cte->level2[byte2 - 32];
2194 assert (!CHAR_TABLE_ENTRYP (val));
2201 #else /* not MULE */
2202 return ct->ascii[(unsigned char)ch];
2203 #endif /* not MULE */
2207 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
2208 Find value for CHARACTER in CHAR-TABLE.
2210 (character, char_table))
2212 CHECK_CHAR_TABLE (char_table);
2213 CHECK_CHAR_COERCE_INT (character);
2215 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
2218 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
2219 Find value for a range in CHAR-TABLE.
2220 If there is more than one value, return MULTI (defaults to nil).
2222 (range, char_table, multi))
2224 Lisp_Char_Table *ct;
2225 struct chartab_range rainj;
2227 if (CHAR_OR_CHAR_INTP (range))
2228 return Fget_char_table (range, char_table);
2229 CHECK_CHAR_TABLE (char_table);
2230 ct = XCHAR_TABLE (char_table);
2232 decode_char_table_range (range, &rainj);
2235 case CHARTAB_RANGE_ALL:
2238 if (UINT8_BYTE_TABLE_P (ct->table))
2240 else if (UINT16_BYTE_TABLE_P (ct->table))
2242 else if (BYTE_TABLE_P (ct->table))
2246 #else /* non UTF2000 */
2248 Lisp_Object first = ct->ascii[0];
2250 for (i = 1; i < NUM_ASCII_CHARS; i++)
2251 if (!EQ (first, ct->ascii[i]))
2255 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
2258 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
2259 || i == LEADING_BYTE_ASCII
2260 || i == LEADING_BYTE_CONTROL_1)
2262 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
2268 #endif /* non UTF2000 */
2272 case CHARTAB_RANGE_CHARSET:
2276 if (EQ (rainj.charset, Vcharset_ascii))
2279 Lisp_Object first = ct->ascii[0];
2281 for (i = 1; i < 128; i++)
2282 if (!EQ (first, ct->ascii[i]))
2287 if (EQ (rainj.charset, Vcharset_control_1))
2290 Lisp_Object first = ct->ascii[128];
2292 for (i = 129; i < 160; i++)
2293 if (!EQ (first, ct->ascii[i]))
2299 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2301 if (CHAR_TABLE_ENTRYP (val))
2307 case CHARTAB_RANGE_ROW:
2312 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2314 if (!CHAR_TABLE_ENTRYP (val))
2316 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
2317 if (CHAR_TABLE_ENTRYP (val))
2321 #endif /* not UTF2000 */
2322 #endif /* not MULE */
2328 return Qnil; /* not reached */
2332 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2333 Error_behavior errb)
2337 case CHAR_TABLE_TYPE_SYNTAX:
2338 if (!ERRB_EQ (errb, ERROR_ME))
2339 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2340 && CHAR_OR_CHAR_INTP (XCDR (value)));
2343 Lisp_Object cdr = XCDR (value);
2344 CHECK_INT (XCAR (value));
2345 CHECK_CHAR_COERCE_INT (cdr);
2352 case CHAR_TABLE_TYPE_CATEGORY:
2353 if (!ERRB_EQ (errb, ERROR_ME))
2354 return CATEGORY_TABLE_VALUEP (value);
2355 CHECK_CATEGORY_TABLE_VALUE (value);
2359 case CHAR_TABLE_TYPE_GENERIC:
2362 case CHAR_TABLE_TYPE_DISPLAY:
2364 maybe_signal_simple_error ("Display char tables not yet implemented",
2365 value, Qchar_table, errb);
2368 case CHAR_TABLE_TYPE_CHAR:
2369 if (!ERRB_EQ (errb, ERROR_ME))
2370 return CHAR_OR_CHAR_INTP (value);
2371 CHECK_CHAR_COERCE_INT (value);
2378 return 0; /* not reached */
2382 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2386 case CHAR_TABLE_TYPE_SYNTAX:
2389 Lisp_Object car = XCAR (value);
2390 Lisp_Object cdr = XCDR (value);
2391 CHECK_CHAR_COERCE_INT (cdr);
2392 return Fcons (car, cdr);
2395 case CHAR_TABLE_TYPE_CHAR:
2396 CHECK_CHAR_COERCE_INT (value);
2404 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2405 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2407 (value, char_table_type))
2409 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2411 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2414 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2415 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2417 (value, char_table_type))
2419 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2421 check_valid_char_table_value (value, type, ERROR_ME);
2426 Lisp_Char_Table* char_attribute_table_to_put;
2427 Lisp_Object Qput_char_table_map_function;
2428 Lisp_Object value_to_put;
2430 DEFUN ("put-char-table-map-function",
2431 Fput_char_table_map_function, 2, 2, 0, /*
2432 For internal use. Don't use it.
2436 put_char_id_table_0 (char_attribute_table_to_put,
2437 XCHAR (c), value_to_put);
2442 /* Assign VAL to all characters in RANGE in char table CT. */
2445 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2448 switch (range->type)
2450 case CHARTAB_RANGE_ALL:
2451 /* printf ("put-char-table: range = all\n"); */
2452 fill_char_table (ct, val);
2453 return; /* avoid the duplicate call to update_syntax_table() below,
2454 since fill_char_table() also did that. */
2457 case CHARTAB_RANGE_DEFAULT:
2458 ct->default_value = val;
2463 case CHARTAB_RANGE_CHARSET:
2466 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2468 /* printf ("put-char-table: range = charset: %d\n",
2469 XCHARSET_LEADING_BYTE (range->charset));
2471 if ( CHAR_TABLEP (encoding_table) )
2473 Lisp_Object mother = XCHARSET_MOTHER (range->charset);
2475 char_attribute_table_to_put = ct;
2477 Fmap_char_attribute (Qput_char_table_map_function,
2478 XCHAR_TABLE_NAME (encoding_table),
2480 if ( CHARSETP (mother) )
2482 struct chartab_range r;
2484 r.type = CHARTAB_RANGE_CHARSET;
2486 put_char_table (ct, &r, val);
2494 for (c = 0; c < 1 << 24; c++)
2496 if ( charset_code_point (range->charset, c) >= 0 )
2497 put_char_id_table_0 (ct, c, val);
2503 if (EQ (range->charset, Vcharset_ascii))
2506 for (i = 0; i < 128; i++)
2509 else if (EQ (range->charset, Vcharset_control_1))
2512 for (i = 128; i < 160; i++)
2517 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2518 ct->level1[lb] = val;
2523 case CHARTAB_RANGE_ROW:
2526 int cell_min, cell_max, i;
2528 i = XCHARSET_CELL_RANGE (range->charset);
2530 cell_max = i & 0xFF;
2531 for (i = cell_min; i <= cell_max; i++)
2534 = DECODE_CHAR (range->charset, (range->row << 8) | i, 0);
2536 if ( charset_code_point (range->charset, ch, 0) >= 0 )
2537 put_char_id_table_0 (ct, ch, val);
2542 Lisp_Char_Table_Entry *cte;
2543 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2544 /* make sure that there is a separate entry for the row. */
2545 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2546 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2547 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2548 cte->level2[range->row - 32] = val;
2550 #endif /* not UTF2000 */
2554 case CHARTAB_RANGE_CHAR:
2556 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2557 put_char_id_table_0 (ct, range->ch, val);
2561 Lisp_Object charset;
2564 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2565 if (EQ (charset, Vcharset_ascii))
2566 ct->ascii[byte1] = val;
2567 else if (EQ (charset, Vcharset_control_1))
2568 ct->ascii[byte1 + 128] = val;
2571 Lisp_Char_Table_Entry *cte;
2572 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2573 /* make sure that there is a separate entry for the row. */
2574 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2575 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2576 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2577 /* now CTE is a char table entry for the charset;
2578 each entry is for a single row (or character of
2579 a one-octet charset). */
2580 if (XCHARSET_DIMENSION (charset) == 1)
2581 cte->level2[byte1 - 32] = val;
2584 /* assigning to one character in a two-octet charset. */
2585 /* make sure that the charset row contains a separate
2586 entry for each character. */
2587 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2588 cte->level2[byte1 - 32] =
2589 make_char_table_entry (cte->level2[byte1 - 32]);
2590 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2591 cte->level2[byte2 - 32] = val;
2595 #else /* not MULE */
2596 ct->ascii[(unsigned char) (range->ch)] = val;
2598 #endif /* not MULE */
2602 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2603 update_syntax_table (ct);
2607 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2608 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2610 RANGE specifies one or more characters to be affected and should be
2611 one of the following:
2613 -- t (all characters are affected)
2614 -- A charset (only allowed when Mule support is present)
2615 -- A vector of two elements: a two-octet charset and a row number
2616 (only allowed when Mule support is present)
2617 -- A single character
2619 VALUE must be a value appropriate for the type of CHAR-TABLE.
2620 See `valid-char-table-type-p'.
2622 (range, value, char_table))
2624 Lisp_Char_Table *ct;
2625 struct chartab_range rainj;
2627 CHECK_CHAR_TABLE (char_table);
2628 ct = XCHAR_TABLE (char_table);
2629 check_valid_char_table_value (value, ct->type, ERROR_ME);
2630 decode_char_table_range (range, &rainj);
2631 value = canonicalize_char_table_value (value, ct->type);
2632 put_char_table (ct, &rainj, value);
2637 /* Map FN over the ASCII chars in CT. */
2640 map_over_charset_ascii (Lisp_Char_Table *ct,
2641 int (*fn) (struct chartab_range *range,
2642 Lisp_Object val, void *arg),
2645 struct chartab_range rainj;
2654 rainj.type = CHARTAB_RANGE_CHAR;
2656 for (i = start, retval = 0; i < stop && retval == 0; i++)
2658 rainj.ch = (Emchar) i;
2659 retval = (fn) (&rainj, ct->ascii[i], arg);
2667 /* Map FN over the Control-1 chars in CT. */
2670 map_over_charset_control_1 (Lisp_Char_Table *ct,
2671 int (*fn) (struct chartab_range *range,
2672 Lisp_Object val, void *arg),
2675 struct chartab_range rainj;
2678 int stop = start + 32;
2680 rainj.type = CHARTAB_RANGE_CHAR;
2682 for (i = start, retval = 0; i < stop && retval == 0; i++)
2684 rainj.ch = (Emchar) (i);
2685 retval = (fn) (&rainj, ct->ascii[i], arg);
2691 /* Map FN over the row ROW of two-byte charset CHARSET.
2692 There must be a separate value for that row in the char table.
2693 CTE specifies the char table entry for CHARSET. */
2696 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2697 Lisp_Object charset, int row,
2698 int (*fn) (struct chartab_range *range,
2699 Lisp_Object val, void *arg),
2702 Lisp_Object val = cte->level2[row - 32];
2704 if (!CHAR_TABLE_ENTRYP (val))
2706 struct chartab_range rainj;
2708 rainj.type = CHARTAB_RANGE_ROW;
2709 rainj.charset = charset;
2711 return (fn) (&rainj, val, arg);
2715 struct chartab_range rainj;
2717 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2718 int start = charset94_p ? 33 : 32;
2719 int stop = charset94_p ? 127 : 128;
2721 cte = XCHAR_TABLE_ENTRY (val);
2723 rainj.type = CHARTAB_RANGE_CHAR;
2725 for (i = start, retval = 0; i < stop && retval == 0; i++)
2727 rainj.ch = MAKE_CHAR (charset, row, i);
2728 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2736 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2737 int (*fn) (struct chartab_range *range,
2738 Lisp_Object val, void *arg),
2741 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2742 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2744 if (!CHARSETP (charset)
2745 || lb == LEADING_BYTE_ASCII
2746 || lb == LEADING_BYTE_CONTROL_1)
2749 if (!CHAR_TABLE_ENTRYP (val))
2751 struct chartab_range rainj;
2753 rainj.type = CHARTAB_RANGE_CHARSET;
2754 rainj.charset = charset;
2755 return (fn) (&rainj, val, arg);
2759 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2760 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2761 int start = charset94_p ? 33 : 32;
2762 int stop = charset94_p ? 127 : 128;
2765 if (XCHARSET_DIMENSION (charset) == 1)
2767 struct chartab_range rainj;
2768 rainj.type = CHARTAB_RANGE_CHAR;
2770 for (i = start, retval = 0; i < stop && retval == 0; i++)
2772 rainj.ch = MAKE_CHAR (charset, i, 0);
2773 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2778 for (i = start, retval = 0; i < stop && retval == 0; i++)
2779 retval = map_over_charset_row (cte, charset, i, fn, arg);
2787 #endif /* not UTF2000 */
2790 struct map_char_table_for_charset_arg
2792 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2793 Lisp_Char_Table *ct;
2798 map_char_table_for_charset_fun (struct chartab_range *range,
2799 Lisp_Object val, void *arg)
2801 struct map_char_table_for_charset_arg *closure =
2802 (struct map_char_table_for_charset_arg *) arg;
2805 switch (range->type)
2807 case CHARTAB_RANGE_ALL:
2810 case CHARTAB_RANGE_DEFAULT:
2813 case CHARTAB_RANGE_CHARSET:
2816 case CHARTAB_RANGE_ROW:
2819 case CHARTAB_RANGE_CHAR:
2820 ret = get_char_table (range->ch, closure->ct);
2821 if (!UNBOUNDP (ret))
2822 return (closure->fn) (range, ret, closure->arg);
2834 /* Map FN (with client data ARG) over range RANGE in char table CT.
2835 Mapping stops the first time FN returns non-zero, and that value
2836 becomes the return value of map_char_table(). */
2839 map_char_table (Lisp_Char_Table *ct,
2840 struct chartab_range *range,
2841 int (*fn) (struct chartab_range *range,
2842 Lisp_Object val, void *arg),
2845 switch (range->type)
2847 case CHARTAB_RANGE_ALL:
2849 if (!UNBOUNDP (ct->default_value))
2851 struct chartab_range rainj;
2854 rainj.type = CHARTAB_RANGE_DEFAULT;
2855 retval = (fn) (&rainj, ct->default_value, arg);
2859 if (UINT8_BYTE_TABLE_P (ct->table))
2860 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
2862 else if (UINT16_BYTE_TABLE_P (ct->table))
2863 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
2865 else if (BYTE_TABLE_P (ct->table))
2866 return map_over_byte_table (XBYTE_TABLE(ct->table), ct,
2868 else if (EQ (ct->table, Qunloaded))
2871 struct chartab_range rainj;
2874 Emchar c1 = c + unit;
2877 rainj.type = CHARTAB_RANGE_CHAR;
2879 for (retval = 0; c < c1 && retval == 0; c++)
2881 Lisp_Object ret = get_char_id_table (ct, c);
2883 if (!UNBOUNDP (ret))
2886 retval = (fn) (&rainj, ct->table, arg);
2891 ct->table = Qunbound;
2894 else if (!UNBOUNDP (ct->table))
2895 return (fn) (range, ct->table, arg);
2901 retval = map_over_charset_ascii (ct, fn, arg);
2905 retval = map_over_charset_control_1 (ct, fn, arg);
2910 Charset_ID start = MIN_LEADING_BYTE;
2911 Charset_ID stop = start + NUM_LEADING_BYTES;
2913 for (i = start, retval = 0; i < stop && retval == 0; i++)
2915 retval = map_over_other_charset (ct, i, fn, arg);
2924 case CHARTAB_RANGE_DEFAULT:
2925 if (!UNBOUNDP (ct->default_value))
2926 return (fn) (range, ct->default_value, arg);
2931 case CHARTAB_RANGE_CHARSET:
2934 Lisp_Object encoding_table
2935 = XCHARSET_ENCODING_TABLE (range->charset);
2937 if (!NILP (encoding_table))
2939 struct chartab_range rainj;
2940 struct map_char_table_for_charset_arg mcarg;
2943 if (XCHAR_TABLE_UNLOADED(encoding_table))
2944 Fload_char_attribute_table (XCHAR_TABLE_NAME (encoding_table));
2949 rainj.type = CHARTAB_RANGE_ALL;
2950 return map_char_table (XCHAR_TABLE(encoding_table),
2952 &map_char_table_for_charset_fun,
2958 return map_over_other_charset (ct,
2959 XCHARSET_LEADING_BYTE (range->charset),
2963 case CHARTAB_RANGE_ROW:
2966 int cell_min, cell_max, i;
2968 struct chartab_range rainj;
2970 i = XCHARSET_CELL_RANGE (range->charset);
2972 cell_max = i & 0xFF;
2973 rainj.type = CHARTAB_RANGE_CHAR;
2974 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2977 = DECODE_CHAR (range->charset, (range->row << 8) | i, 0);
2979 if ( charset_code_point (range->charset, ch, 0) >= 0 )
2982 = get_byte_table (get_byte_table
2986 (unsigned char)(ch >> 24)),
2987 (unsigned char) (ch >> 16)),
2988 (unsigned char) (ch >> 8)),
2989 (unsigned char) ch);
2992 val = ct->default_value;
2994 retval = (fn) (&rainj, val, arg);
3001 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
3002 - MIN_LEADING_BYTE];
3003 if (!CHAR_TABLE_ENTRYP (val))
3005 struct chartab_range rainj;
3007 rainj.type = CHARTAB_RANGE_ROW;
3008 rainj.charset = range->charset;
3009 rainj.row = range->row;
3010 return (fn) (&rainj, val, arg);
3013 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
3014 range->charset, range->row,
3017 #endif /* not UTF2000 */
3020 case CHARTAB_RANGE_CHAR:
3022 Emchar ch = range->ch;
3023 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
3025 if (!UNBOUNDP (val))
3027 struct chartab_range rainj;
3029 rainj.type = CHARTAB_RANGE_CHAR;
3031 return (fn) (&rainj, val, arg);
3043 struct slow_map_char_table_arg
3045 Lisp_Object function;
3050 slow_map_char_table_fun (struct chartab_range *range,
3051 Lisp_Object val, void *arg)
3053 Lisp_Object ranjarg = Qnil;
3054 struct slow_map_char_table_arg *closure =
3055 (struct slow_map_char_table_arg *) arg;
3057 switch (range->type)
3059 case CHARTAB_RANGE_ALL:
3064 case CHARTAB_RANGE_DEFAULT:
3070 case CHARTAB_RANGE_CHARSET:
3071 ranjarg = XCHARSET_NAME (range->charset);
3074 case CHARTAB_RANGE_ROW:
3075 ranjarg = vector2 (XCHARSET_NAME (range->charset),
3076 make_int (range->row));
3079 case CHARTAB_RANGE_CHAR:
3080 ranjarg = make_char (range->ch);
3086 closure->retval = call2 (closure->function, ranjarg, val);
3087 return !NILP (closure->retval);
3090 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
3091 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
3092 each key and value in the table.
3094 RANGE specifies a subrange to map over and is in the same format as
3095 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3098 (function, char_table, range))
3100 Lisp_Char_Table *ct;
3101 struct slow_map_char_table_arg slarg;
3102 struct gcpro gcpro1, gcpro2;
3103 struct chartab_range rainj;
3105 CHECK_CHAR_TABLE (char_table);
3106 ct = XCHAR_TABLE (char_table);
3109 decode_char_table_range (range, &rainj);
3110 slarg.function = function;
3111 slarg.retval = Qnil;
3112 GCPRO2 (slarg.function, slarg.retval);
3113 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3116 return slarg.retval;
3120 /************************************************************************/
3121 /* Character Attributes */
3122 /************************************************************************/
3126 Lisp_Object Vchar_attribute_hash_table;
3128 /* We store the char-attributes in hash tables with the names as the
3129 key and the actual char-id-table object as the value. Occasionally
3130 we need to use them in a list format. These routines provide us
3132 struct char_attribute_list_closure
3134 Lisp_Object *char_attribute_list;
3138 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
3139 void *char_attribute_list_closure)
3141 /* This function can GC */
3142 struct char_attribute_list_closure *calcl
3143 = (struct char_attribute_list_closure*) char_attribute_list_closure;
3144 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
3146 *char_attribute_list = Fcons (key, *char_attribute_list);
3150 #ifdef HAVE_LIBCHISE
3152 char_attribute_list_reset_map_func (CHISE_DS *ds, unsigned char *name)
3154 Fmount_char_attribute_table (intern (name));
3158 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 1, 0, /*
3159 Return the list of all existing character attributes except coded-charsets.
3163 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
3164 Return the list of all existing character attributes except coded-charsets.
3169 Lisp_Object char_attribute_list = Qnil;
3170 struct gcpro gcpro1;
3171 struct char_attribute_list_closure char_attribute_list_closure;
3173 #ifdef HAVE_LIBCHISE
3176 open_chise_data_source_maybe ();
3177 chise_ds_foreach_char_feature_name
3178 (default_chise_data_source, &char_attribute_list_reset_map_func);
3181 GCPRO1 (char_attribute_list);
3182 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
3183 elisp_maphash (add_char_attribute_to_list_mapper,
3184 Vchar_attribute_hash_table,
3185 &char_attribute_list_closure);
3187 return char_attribute_list;
3190 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
3191 Return char-id-table corresponding to ATTRIBUTE.
3195 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
3199 /* We store the char-id-tables in hash tables with the attributes as
3200 the key and the actual char-id-table object as the value. Each
3201 char-id-table stores values of an attribute corresponding with
3202 characters. Occasionally we need to get attributes of a character
3203 in a association-list format. These routines provide us with
3205 struct char_attribute_alist_closure
3208 Lisp_Object *char_attribute_alist;
3212 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
3213 void *char_attribute_alist_closure)
3215 /* This function can GC */
3216 struct char_attribute_alist_closure *caacl =
3217 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
3219 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
3220 if (!UNBOUNDP (ret))
3222 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
3223 *char_attribute_alist
3224 = Fcons (Fcons (key, ret), *char_attribute_alist);
3229 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
3230 Return the alist of attributes of CHARACTER.
3234 struct gcpro gcpro1;
3235 struct char_attribute_alist_closure char_attribute_alist_closure;
3236 Lisp_Object alist = Qnil;
3238 CHECK_CHAR (character);
3241 char_attribute_alist_closure.char_id = XCHAR (character);
3242 char_attribute_alist_closure.char_attribute_alist = &alist;
3243 elisp_maphash (add_char_attribute_alist_mapper,
3244 Vchar_attribute_hash_table,
3245 &char_attribute_alist_closure);
3251 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
3252 Return the value of CHARACTER's ATTRIBUTE.
3253 Return DEFAULT-VALUE if the value is not exist.
3255 (character, attribute, default_value))
3259 CHECK_CHAR (character);
3261 if (CHARSETP (attribute))
3262 attribute = XCHARSET_NAME (attribute);
3264 table = Fgethash (attribute, Vchar_attribute_hash_table,
3266 if (!UNBOUNDP (table))
3268 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
3270 if (!UNBOUNDP (ret))
3273 return default_value;
3276 void put_char_composition (Lisp_Object character, Lisp_Object value);
3278 put_char_composition (Lisp_Object character, Lisp_Object value)
3281 signal_simple_error ("Invalid value for ->decomposition",
3284 if (CONSP (Fcdr (value)))
3286 if (NILP (Fcdr (Fcdr (value))))
3288 Lisp_Object base = Fcar (value);
3289 Lisp_Object modifier = Fcar (Fcdr (value));
3293 base = make_char (XINT (base));
3294 Fsetcar (value, base);
3296 if (INTP (modifier))
3298 modifier = make_char (XINT (modifier));
3299 Fsetcar (Fcdr (value), modifier);
3304 = Fget_char_attribute (base, Qcomposition, Qnil);
3305 Lisp_Object ret = Fassq (modifier, alist);
3308 Fput_char_attribute (base, Qcomposition,
3309 Fcons (Fcons (modifier, character),
3312 Fsetcdr (ret, character);
3318 Lisp_Object v = Fcar (value);
3322 Emchar c = XINT (v);
3324 = Fget_char_attribute (make_char (c), Q_ucs_unified, Qnil);
3328 Fput_char_attribute (make_char (c), Q_ucs_unified,
3329 Fcons (character, Qnil));
3331 else if (NILP (Fmemq (character, ret)))
3333 Fput_char_attribute (make_char (c), Q_ucs_unified,
3334 Fcons (character, ret));
3340 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
3341 Store CHARACTER's ATTRIBUTE with VALUE.
3343 (character, attribute, value))
3345 Lisp_Object ccs = Ffind_charset (attribute);
3347 CHECK_CHAR (character);
3351 value = put_char_ccs_code_point (character, ccs, value);
3352 attribute = XCHARSET_NAME (ccs);
3354 else if (EQ (attribute, Q_decomposition))
3355 put_char_composition (character, value);
3356 else if (EQ (attribute, Qto_ucs))
3362 signal_simple_error ("Invalid value for =>ucs", value);
3366 ret = Fget_char_attribute (make_char (c), Q_ucs_unified, Qnil);
3369 Fput_char_attribute (make_char (c), Q_ucs_unified,
3370 Fcons (character, Qnil));
3372 else if (NILP (Fmemq (character, ret)))
3374 Fput_char_attribute (make_char (c), Q_ucs_unified,
3375 Fcons (character, ret));
3378 else if (EQ (attribute, Q_unified))
3380 Lisp_Object rest = value;
3383 while (CONSP (rest))
3385 ret = Fdefine_char (XCAR (rest));
3388 Fput_char_attribute (ret, Q_unified_from, list1 (character));
3389 Fsetcar (rest, ret);
3395 else if (EQ (attribute, Qideographic_structure))
3396 value = Fcopy_sequence (Fchar_refs_simplify_char_specs (value));
3399 Lisp_Object table = Fgethash (attribute,
3400 Vchar_attribute_hash_table,
3405 table = make_char_id_table (Qunbound);
3406 Fputhash (attribute, table, Vchar_attribute_hash_table);
3408 XCHAR_TABLE_NAME (table) = attribute;
3411 put_char_id_table (XCHAR_TABLE(table), character, value);
3416 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3417 Remove CHARACTER's ATTRIBUTE.
3419 (character, attribute))
3423 CHECK_CHAR (character);
3424 ccs = Ffind_charset (attribute);
3427 return remove_char_ccs (character, ccs);
3431 Lisp_Object table = Fgethash (attribute,
3432 Vchar_attribute_hash_table,
3434 if (!UNBOUNDP (table))
3436 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3445 int char_table_open_db_maybe (Lisp_Char_Table* cit);
3446 void char_table_close_db_maybe (Lisp_Char_Table* cit);
3447 Lisp_Object char_table_get_db (Lisp_Char_Table* cit, Emchar ch);
3449 #ifdef HAVE_LIBCHISE
3451 open_chise_data_source_maybe ()
3453 if (default_chise_data_source == NULL)
3455 Lisp_Object db_dir = Vexec_directory;
3456 int modemask = 0755; /* rwxr-xr-x */
3459 db_dir = build_string ("../lib-src");
3460 db_dir = Fexpand_file_name (build_string ("chise-db"), db_dir);
3462 default_chise_data_source
3463 = CHISE_DS_open (CHISE_DS_Berkeley_DB, XSTRING_DATA (db_dir),
3464 0 /* DB_HASH */, modemask);
3465 if (default_chise_data_source == NULL)
3470 #endif /* HAVE_LIBCHISE */
3472 DEFUN ("close-char-data-source", Fclose_char_data_source, 0, 0, 0, /*
3473 Close data-source of CHISE.
3477 #ifdef HAVE_LIBCHISE
3478 int status = CHISE_DS_close (default_chise_data_source);
3480 default_chise_data_source = NULL;
3483 #endif /* HAVE_LIBCHISE */
3488 char_table_open_db_maybe (Lisp_Char_Table* cit)
3490 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3492 if (!NILP (attribute))
3494 #ifdef HAVE_LIBCHISE
3495 if ( open_chise_data_source_maybe () )
3497 #else /* HAVE_LIBCHISE */
3498 if (NILP (Fdatabase_live_p (cit->db)))
3501 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3503 cit->db = Fopen_database (db_file, Qnil, Qnil,
3504 build_string ("r"), Qnil);
3508 #endif /* not HAVE_LIBCHISE */
3516 char_table_close_db_maybe (Lisp_Char_Table* cit)
3518 #ifndef HAVE_LIBCHISE
3519 if (!NILP (cit->db))
3521 if (!NILP (Fdatabase_live_p (cit->db)))
3522 Fclose_database (cit->db);
3525 #endif /* not HAVE_LIBCHISE */
3529 char_table_get_db (Lisp_Char_Table* cit, Emchar ch)
3532 #ifdef HAVE_LIBCHISE
3535 = chise_ds_load_char_feature_value (default_chise_data_source, ch,
3536 XSTRING_DATA(Fsymbol_name
3542 val = Fread (make_string (chise_value_data (&value),
3543 chise_value_size (&value) ));
3547 #else /* HAVE_LIBCHISE */
3548 val = Fget_database (Fprin1_to_string (make_char (ch), Qnil),
3550 if (!UNBOUNDP (val))
3554 #endif /* not HAVE_LIBCHISE */
3558 #ifndef HAVE_LIBCHISE
3560 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
3563 Lisp_Object db_dir = Vexec_directory;
3566 db_dir = build_string ("../lib-src");
3568 db_dir = Fexpand_file_name (build_string ("chise-db"), db_dir);
3569 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3570 Fmake_directory_internal (db_dir);
3572 db_dir = Fexpand_file_name (Fsymbol_name (key_type), db_dir);
3573 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3574 Fmake_directory_internal (db_dir);
3577 Lisp_Object attribute_name = Fsymbol_name (attribute);
3578 Lisp_Object dest = Qnil, ret;
3580 struct gcpro gcpro1, gcpro2;
3581 int len = XSTRING_CHAR_LENGTH (attribute_name);
3585 for (i = 0; i < len; i++)
3587 Emchar c = string_char (XSTRING (attribute_name), i);
3589 if ( (c == '/') || (c == '%') )
3593 sprintf (str, "%%%02X", c);
3594 dest = concat3 (dest,
3595 Fsubstring (attribute_name,
3596 make_int (base), make_int (i)),
3597 build_string (str));
3601 ret = Fsubstring (attribute_name, make_int (base), make_int (len));
3602 dest = concat2 (dest, ret);
3604 return Fexpand_file_name (dest, db_dir);
3607 #endif /* not HAVE_LIBCHISE */
3609 DEFUN ("save-char-attribute-table", Fsave_char_attribute_table, 1, 1, 0, /*
3610 Save values of ATTRIBUTE into database file.
3614 Lisp_Object table = Fgethash (attribute,
3615 Vchar_attribute_hash_table, Qunbound);
3616 Lisp_Char_Table *ct;
3617 #ifdef HAVE_LIBCHISE
3618 CHISE_Feature feature;
3619 #else /* HAVE_LIBCHISE */
3620 Lisp_Object db_file;
3622 #endif /* not HAVE_LIBCHISE */
3624 if (CHAR_TABLEP (table))
3625 ct = XCHAR_TABLE (table);
3629 #ifdef HAVE_LIBCHISE
3630 if ( open_chise_data_source_maybe () )
3633 = chise_ds_get_feature (default_chise_data_source,
3634 XSTRING_DATA (Fsymbol_name (attribute)));
3635 #else /* HAVE_LIBCHISE */
3636 db_file = char_attribute_system_db_file (Qsystem_char_id, attribute, 1);
3637 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
3638 #endif /* not HAVE_LIBCHISE */
3640 #ifdef HAVE_LIBCHISE
3642 #else /* HAVE_LIBCHISE */
3644 #endif /* not HAVE_LIBCHISE */
3647 Lisp_Object (*filter)(Lisp_Object value);
3649 if (EQ (attribute, Qideographic_structure))
3650 filter = &Fchar_refs_simplify_char_specs;
3654 if (UINT8_BYTE_TABLE_P (ct->table))
3655 save_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
3656 #ifdef HAVE_LIBCHISE
3658 #else /* HAVE_LIBCHISE */
3660 #endif /* not HAVE_LIBCHISE */
3662 else if (UINT16_BYTE_TABLE_P (ct->table))
3663 save_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
3664 #ifdef HAVE_LIBCHISE
3666 #else /* HAVE_LIBCHISE */
3668 #endif /* not HAVE_LIBCHISE */
3670 else if (BYTE_TABLE_P (ct->table))
3671 save_byte_table (XBYTE_TABLE(ct->table), ct,
3672 #ifdef HAVE_LIBCHISE
3674 #else /* HAVE_LIBCHISE */
3676 #endif /* not HAVE_LIBCHISE */
3678 #ifdef HAVE_LIBCHISE
3679 chise_feature_sync (feature);
3680 #else /* HAVE_LIBCHISE */
3681 Fclose_database (db);
3682 #endif /* not HAVE_LIBCHISE */
3689 DEFUN ("mount-char-attribute-table", Fmount_char_attribute_table, 1, 1, 0, /*
3690 Mount database file on char-attribute-table ATTRIBUTE.
3694 Lisp_Object table = Fgethash (attribute,
3695 Vchar_attribute_hash_table, Qunbound);
3697 if (UNBOUNDP (table))
3699 Lisp_Char_Table *ct;
3701 table = make_char_id_table (Qunbound);
3702 Fputhash (attribute, table, Vchar_attribute_hash_table);
3703 XCHAR_TABLE_NAME(table) = attribute;
3704 ct = XCHAR_TABLE (table);
3705 ct->table = Qunloaded;
3706 XCHAR_TABLE_UNLOADED(table) = 1;
3707 #ifndef HAVE_LIBCHISE
3709 #endif /* not HAVE_LIBCHISE */
3715 DEFUN ("close-char-attribute-table", Fclose_char_attribute_table, 1, 1, 0, /*
3716 Close database of ATTRIBUTE.
3720 Lisp_Object table = Fgethash (attribute,
3721 Vchar_attribute_hash_table, Qunbound);
3722 Lisp_Char_Table *ct;
3724 if (CHAR_TABLEP (table))
3725 ct = XCHAR_TABLE (table);
3728 char_table_close_db_maybe (ct);
3732 DEFUN ("reset-char-attribute-table", Freset_char_attribute_table, 1, 1, 0, /*
3733 Reset values of ATTRIBUTE with database file.
3737 #ifdef HAVE_LIBCHISE
3738 CHISE_Feature feature
3739 = chise_ds_get_feature (default_chise_data_source,
3740 XSTRING_DATA (Fsymbol_name
3743 if (feature == NULL)
3746 if (chise_feature_setup_db (feature, 0) == 0)
3748 Lisp_Object table = Fgethash (attribute,
3749 Vchar_attribute_hash_table, Qunbound);
3750 Lisp_Char_Table *ct;
3752 chise_feature_sync (feature);
3753 if (UNBOUNDP (table))
3755 table = make_char_id_table (Qunbound);
3756 Fputhash (attribute, table, Vchar_attribute_hash_table);
3757 XCHAR_TABLE_NAME(table) = attribute;
3759 ct = XCHAR_TABLE (table);
3760 ct->table = Qunloaded;
3761 char_table_close_db_maybe (ct);
3762 XCHAR_TABLE_UNLOADED(table) = 1;
3766 Lisp_Object table = Fgethash (attribute,
3767 Vchar_attribute_hash_table, Qunbound);
3768 Lisp_Char_Table *ct;
3770 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3772 if (!NILP (Ffile_exists_p (db_file)))
3774 if (UNBOUNDP (table))
3776 table = make_char_id_table (Qunbound);
3777 Fputhash (attribute, table, Vchar_attribute_hash_table);
3778 XCHAR_TABLE_NAME(table) = attribute;
3780 ct = XCHAR_TABLE (table);
3781 ct->table = Qunloaded;
3782 char_table_close_db_maybe (ct);
3783 XCHAR_TABLE_UNLOADED(table) = 1;
3791 load_char_attribute_maybe (Lisp_Char_Table* cit, Emchar ch)
3793 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3795 if (!NILP (attribute))
3799 if (char_table_open_db_maybe (cit))
3802 val = char_table_get_db (cit, ch);
3804 if (!NILP (Vchar_db_stingy_mode))
3805 char_table_close_db_maybe (cit);
3812 Lisp_Char_Table* char_attribute_table_to_load;
3814 #ifdef HAVE_LIBCHISE
3816 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3817 CHISE_Feature feature,
3818 CHISE_Value *value);
3820 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3821 CHISE_Feature feature,
3825 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3827 if (EQ (ret, Qunloaded))
3828 put_char_id_table_0 (char_attribute_table_to_load, code,
3829 Fread (make_string ((Bufbyte *) value->data,
3833 #else /* HAVE_LIBCHISE */
3834 Lisp_Object Qload_char_attribute_table_map_function;
3836 DEFUN ("load-char-attribute-table-map-function",
3837 Fload_char_attribute_table_map_function, 2, 2, 0, /*
3838 For internal use. Don't use it.
3842 Lisp_Object c = Fread (key);
3843 Emchar code = XCHAR (c);
3844 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3846 if (EQ (ret, Qunloaded))
3847 put_char_id_table_0 (char_attribute_table_to_load, code, Fread (value));
3850 #endif /* not HAVE_LIBCHISE */
3852 DEFUN ("load-char-attribute-table", Fload_char_attribute_table, 1, 1, 0, /*
3853 Load values of ATTRIBUTE into database file.
3857 Lisp_Object table = Fgethash (attribute,
3858 Vchar_attribute_hash_table,
3860 if (CHAR_TABLEP (table))
3862 Lisp_Char_Table *cit = XCHAR_TABLE (table);
3864 if (char_table_open_db_maybe (cit))
3867 char_attribute_table_to_load = XCHAR_TABLE (table);
3869 struct gcpro gcpro1;
3872 #ifdef HAVE_LIBCHISE
3873 chise_feature_foreach_char_with_value
3874 (chise_ds_get_feature (default_chise_data_source,
3875 XSTRING_DATA (Fsymbol_name (cit->name))),
3876 &load_char_attribute_table_map_func);
3877 #else /* HAVE_LIBCHISE */
3878 Fmap_database (Qload_char_attribute_table_map_function, cit->db);
3879 #endif /* not HAVE_LIBCHISE */
3882 char_table_close_db_maybe (cit);
3883 XCHAR_TABLE_UNLOADED(table) = 0;
3888 #endif /* HAVE_CHISE */
3890 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3891 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3892 each key and value in the table.
3894 RANGE specifies a subrange to map over and is in the same format as
3895 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3898 (function, attribute, range))
3901 Lisp_Char_Table *ct;
3902 struct slow_map_char_table_arg slarg;
3903 struct gcpro gcpro1, gcpro2;
3904 struct chartab_range rainj;
3906 if (!NILP (ccs = Ffind_charset (attribute)))
3908 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3910 if (CHAR_TABLEP (encoding_table))
3911 ct = XCHAR_TABLE (encoding_table);
3917 Lisp_Object table = Fgethash (attribute,
3918 Vchar_attribute_hash_table,
3920 if (CHAR_TABLEP (table))
3921 ct = XCHAR_TABLE (table);
3927 decode_char_table_range (range, &rainj);
3929 if (CHAR_TABLE_UNLOADED(ct))
3930 Fload_char_attribute_table (attribute);
3932 slarg.function = function;
3933 slarg.retval = Qnil;
3934 GCPRO2 (slarg.function, slarg.retval);
3935 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3938 return slarg.retval;
3941 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3942 Store character's ATTRIBUTES.
3946 Lisp_Object rest = attributes;
3947 Lisp_Object code = Fcdr (Fassq (Qmap_ucs, attributes));
3948 Lisp_Object character;
3951 code = Fcdr (Fassq (Qucs, attributes));
3954 while (CONSP (rest))
3956 Lisp_Object cell = Fcar (rest);
3960 signal_simple_error ("Invalid argument", attributes);
3961 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3962 && ((XCHARSET_FINAL (ccs) != 0) ||
3963 (XCHARSET_MAX_CODE (ccs) > 0) ||
3964 (EQ (ccs, Vcharset_chinese_big5))) )
3968 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3970 character = Fdecode_char (ccs, cell, Qnil, Qt);
3971 if (!NILP (character))
3972 goto setup_attributes;
3976 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
3979 signal_simple_error ("Invalid argument", attributes);
3981 character = make_char (XINT (code) + 0x100000);
3982 goto setup_attributes;
3986 else if (!INTP (code))
3987 signal_simple_error ("Invalid argument", attributes);
3989 character = make_char (XINT (code));
3993 while (CONSP (rest))
3995 Lisp_Object cell = Fcar (rest);
3998 signal_simple_error ("Invalid argument", attributes);
4000 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
4006 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
4007 Retrieve the character of the given ATTRIBUTES.
4011 Lisp_Object rest = attributes;
4014 while (CONSP (rest))
4016 Lisp_Object cell = Fcar (rest);
4020 signal_simple_error ("Invalid argument", attributes);
4021 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
4025 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
4027 return Fdecode_char (ccs, cell, Qnil, Qnil);
4031 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
4034 signal_simple_error ("Invalid argument", attributes);
4036 return make_char (XINT (code) + 0x100000);
4044 /************************************************************************/
4045 /* Char table read syntax */
4046 /************************************************************************/
4049 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
4050 Error_behavior errb)
4052 /* #### should deal with ERRB */
4053 symbol_to_char_table_type (value);
4058 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
4059 Error_behavior errb)
4063 /* #### should deal with ERRB */
4064 EXTERNAL_LIST_LOOP (rest, value)
4066 Lisp_Object range = XCAR (rest);
4067 struct chartab_range dummy;
4071 signal_simple_error ("Invalid list format", value);
4074 if (!CONSP (XCDR (range))
4075 || !NILP (XCDR (XCDR (range))))
4076 signal_simple_error ("Invalid range format", range);
4077 decode_char_table_range (XCAR (range), &dummy);
4078 decode_char_table_range (XCAR (XCDR (range)), &dummy);
4081 decode_char_table_range (range, &dummy);
4088 chartab_instantiate (Lisp_Object data)
4090 Lisp_Object chartab;
4091 Lisp_Object type = Qgeneric;
4092 Lisp_Object dataval = Qnil;
4094 while (!NILP (data))
4096 Lisp_Object keyw = Fcar (data);
4102 if (EQ (keyw, Qtype))
4104 else if (EQ (keyw, Qdata))
4108 chartab = Fmake_char_table (type);
4111 while (!NILP (data))
4113 Lisp_Object range = Fcar (data);
4114 Lisp_Object val = Fcar (Fcdr (data));
4116 data = Fcdr (Fcdr (data));
4119 if (CHAR_OR_CHAR_INTP (XCAR (range)))
4121 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
4122 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
4125 for (i = first; i <= last; i++)
4126 Fput_char_table (make_char (i), val, chartab);
4132 Fput_char_table (range, val, chartab);
4141 /************************************************************************/
4142 /* Category Tables, specifically */
4143 /************************************************************************/
4145 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
4146 Return t if OBJECT is a category table.
4147 A category table is a type of char table used for keeping track of
4148 categories. Categories are used for classifying characters for use
4149 in regexps -- you can refer to a category rather than having to use
4150 a complicated [] expression (and category lookups are significantly
4153 There are 95 different categories available, one for each printable
4154 character (including space) in the ASCII charset. Each category
4155 is designated by one such character, called a "category designator".
4156 They are specified in a regexp using the syntax "\\cX", where X is
4157 a category designator.
4159 A category table specifies, for each character, the categories that
4160 the character is in. Note that a character can be in more than one
4161 category. More specifically, a category table maps from a character
4162 to either the value nil (meaning the character is in no categories)
4163 or a 95-element bit vector, specifying for each of the 95 categories
4164 whether the character is in that category.
4166 Special Lisp functions are provided that abstract this, so you do not
4167 have to directly manipulate bit vectors.
4171 return (CHAR_TABLEP (object) &&
4172 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
4177 check_category_table (Lisp_Object object, Lisp_Object default_)
4181 while (NILP (Fcategory_table_p (object)))
4182 object = wrong_type_argument (Qcategory_table_p, object);
4187 check_category_char (Emchar ch, Lisp_Object table,
4188 unsigned int designator, unsigned int not_p)
4190 REGISTER Lisp_Object temp;
4191 Lisp_Char_Table *ctbl;
4192 #ifdef ERROR_CHECK_TYPECHECK
4193 if (NILP (Fcategory_table_p (table)))
4194 signal_simple_error ("Expected category table", table);
4196 ctbl = XCHAR_TABLE (table);
4197 temp = get_char_table (ch, ctbl);
4202 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
4205 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
4206 Return t if category of the character at POSITION includes DESIGNATOR.
4207 Optional third arg BUFFER specifies which buffer to use, and defaults
4208 to the current buffer.
4209 Optional fourth arg CATEGORY-TABLE specifies the category table to
4210 use, and defaults to BUFFER's category table.
4212 (position, designator, buffer, category_table))
4217 struct buffer *buf = decode_buffer (buffer, 0);
4219 CHECK_INT (position);
4220 CHECK_CATEGORY_DESIGNATOR (designator);
4221 des = XCHAR (designator);
4222 ctbl = check_category_table (category_table, Vstandard_category_table);
4223 ch = BUF_FETCH_CHAR (buf, XINT (position));
4224 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4227 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
4228 Return t if category of CHARACTER includes DESIGNATOR, else nil.
4229 Optional third arg CATEGORY-TABLE specifies the category table to use,
4230 and defaults to the standard category table.
4232 (character, designator, category_table))
4238 CHECK_CATEGORY_DESIGNATOR (designator);
4239 des = XCHAR (designator);
4240 CHECK_CHAR (character);
4241 ch = XCHAR (character);
4242 ctbl = check_category_table (category_table, Vstandard_category_table);
4243 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4246 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
4247 Return BUFFER's current category table.
4248 BUFFER defaults to the current buffer.
4252 return decode_buffer (buffer, 0)->category_table;
4255 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
4256 Return the standard category table.
4257 This is the one used for new buffers.
4261 return Vstandard_category_table;
4264 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
4265 Return a new category table which is a copy of CATEGORY-TABLE.
4266 CATEGORY-TABLE defaults to the standard category table.
4270 if (NILP (Vstandard_category_table))
4271 return Fmake_char_table (Qcategory);
4274 check_category_table (category_table, Vstandard_category_table);
4275 return Fcopy_char_table (category_table);
4278 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
4279 Select CATEGORY-TABLE as the new category table for BUFFER.
4280 BUFFER defaults to the current buffer if omitted.
4282 (category_table, buffer))
4284 struct buffer *buf = decode_buffer (buffer, 0);
4285 category_table = check_category_table (category_table, Qnil);
4286 buf->category_table = category_table;
4287 /* Indicate that this buffer now has a specified category table. */
4288 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
4289 return category_table;
4292 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
4293 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
4297 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
4300 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
4301 Return t if OBJECT is a category table value.
4302 Valid values are nil or a bit vector of size 95.
4306 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
4310 #define CATEGORYP(x) \
4311 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
4313 #define CATEGORY_SET(c) \
4314 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
4316 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
4317 The faster version of `!NILP (Faref (category_set, category))'. */
4318 #define CATEGORY_MEMBER(category, category_set) \
4319 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
4321 /* Return 1 if there is a word boundary between two word-constituent
4322 characters C1 and C2 if they appear in this order, else return 0.
4323 Use the macro WORD_BOUNDARY_P instead of calling this function
4326 int word_boundary_p (Emchar c1, Emchar c2);
4328 word_boundary_p (Emchar c1, Emchar c2)
4330 Lisp_Object category_set1, category_set2;
4335 if (COMPOSITE_CHAR_P (c1))
4336 c1 = cmpchar_component (c1, 0, 1);
4337 if (COMPOSITE_CHAR_P (c2))
4338 c2 = cmpchar_component (c2, 0, 1);
4342 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
4345 tail = Vword_separating_categories;
4351 tail = Vword_combining_categories;
4356 category_set1 = CATEGORY_SET (c1);
4357 if (NILP (category_set1))
4358 return default_result;
4359 category_set2 = CATEGORY_SET (c2);
4360 if (NILP (category_set2))
4361 return default_result;
4363 for (; CONSP (tail); tail = XCONS (tail)->cdr)
4365 Lisp_Object elt = XCONS(tail)->car;
4368 && CATEGORYP (XCONS (elt)->car)
4369 && CATEGORYP (XCONS (elt)->cdr)
4370 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
4371 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
4372 return !default_result;
4374 return default_result;
4380 syms_of_chartab (void)
4383 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
4384 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
4385 INIT_LRECORD_IMPLEMENTATION (byte_table);
4387 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
4388 defsymbol (&Qsystem_char_id, "system-char-id");
4391 defsymbol (&Qto_ucs, "=>ucs");
4392 defsymbol (&Q_ucs_unified, "->ucs-unified");
4393 defsymbol (&Q_unified, "->unified");
4394 defsymbol (&Q_unified_from, "<-unified");
4395 defsymbol (&Qcomposition, "composition");
4396 defsymbol (&Q_decomposition, "->decomposition");
4397 defsymbol (&Qcompat, "compat");
4398 defsymbol (&Qisolated, "isolated");
4399 defsymbol (&Qinitial, "initial");
4400 defsymbol (&Qmedial, "medial");
4401 defsymbol (&Qfinal, "final");
4402 defsymbol (&Qvertical, "vertical");
4403 defsymbol (&QnoBreak, "noBreak");
4404 defsymbol (&Qfraction, "fraction");
4405 defsymbol (&Qsuper, "super");
4406 defsymbol (&Qsub, "sub");
4407 defsymbol (&Qcircle, "circle");
4408 defsymbol (&Qsquare, "square");
4409 defsymbol (&Qwide, "wide");
4410 defsymbol (&Qnarrow, "narrow");
4411 defsymbol (&Qsmall, "small");
4412 defsymbol (&Qfont, "font");
4414 DEFSUBR (Fchar_attribute_list);
4415 DEFSUBR (Ffind_char_attribute_table);
4416 defsymbol (&Qput_char_table_map_function, "put-char-table-map-function");
4417 DEFSUBR (Fput_char_table_map_function);
4419 DEFSUBR (Fsave_char_attribute_table);
4420 DEFSUBR (Fmount_char_attribute_table);
4421 DEFSUBR (Freset_char_attribute_table);
4422 DEFSUBR (Fclose_char_attribute_table);
4423 DEFSUBR (Fclose_char_data_source);
4424 #ifndef HAVE_LIBCHISE
4425 defsymbol (&Qload_char_attribute_table_map_function,
4426 "load-char-attribute-table-map-function");
4427 DEFSUBR (Fload_char_attribute_table_map_function);
4429 DEFSUBR (Fload_char_attribute_table);
4431 DEFSUBR (Fchar_attribute_alist);
4432 DEFSUBR (Fget_char_attribute);
4433 DEFSUBR (Fput_char_attribute);
4434 DEFSUBR (Fremove_char_attribute);
4435 DEFSUBR (Fmap_char_attribute);
4436 DEFSUBR (Fdefine_char);
4437 DEFSUBR (Ffind_char);
4438 DEFSUBR (Fchar_variants);
4440 DEFSUBR (Fget_composite_char);
4443 INIT_LRECORD_IMPLEMENTATION (char_table);
4447 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
4450 defsymbol (&Qcategory_table_p, "category-table-p");
4451 defsymbol (&Qcategory_designator_p, "category-designator-p");
4452 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
4455 defsymbol (&Qchar_table, "char-table");
4456 defsymbol (&Qchar_tablep, "char-table-p");
4458 DEFSUBR (Fchar_table_p);
4459 DEFSUBR (Fchar_table_type_list);
4460 DEFSUBR (Fvalid_char_table_type_p);
4461 DEFSUBR (Fchar_table_type);
4462 DEFSUBR (Freset_char_table);
4463 DEFSUBR (Fmake_char_table);
4464 DEFSUBR (Fcopy_char_table);
4465 DEFSUBR (Fget_char_table);
4466 DEFSUBR (Fget_range_char_table);
4467 DEFSUBR (Fvalid_char_table_value_p);
4468 DEFSUBR (Fcheck_valid_char_table_value);
4469 DEFSUBR (Fput_char_table);
4470 DEFSUBR (Fmap_char_table);
4473 DEFSUBR (Fcategory_table_p);
4474 DEFSUBR (Fcategory_table);
4475 DEFSUBR (Fstandard_category_table);
4476 DEFSUBR (Fcopy_category_table);
4477 DEFSUBR (Fset_category_table);
4478 DEFSUBR (Fcheck_category_at);
4479 DEFSUBR (Fchar_in_category_p);
4480 DEFSUBR (Fcategory_designator_p);
4481 DEFSUBR (Fcategory_table_value_p);
4487 vars_of_chartab (void)
4490 DEFVAR_LISP ("char-db-stingy-mode", &Vchar_db_stingy_mode /*
4492 Vchar_db_stingy_mode = Qt;
4494 #ifdef HAVE_LIBCHISE
4495 Vchise_db_directory = build_string(chise_db_dir);
4496 DEFVAR_LISP ("chise-db-directory", &Vchise_db_directory /*
4497 Directory of CHISE character databases.
4500 Vchise_system_db_directory = build_string(chise_system_db_dir);
4501 DEFVAR_LISP ("chise-system-db-directory", &Vchise_system_db_directory /*
4502 Directory of system character database of CHISE.
4506 #endif /* HAVE_CHISE */
4507 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
4508 Vall_syntax_tables = Qnil;
4509 dump_add_weak_object_chain (&Vall_syntax_tables);
4513 structure_type_create_chartab (void)
4515 struct structure_type *st;
4517 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
4519 define_structure_type_keyword (st, Qtype, chartab_type_validate);
4520 define_structure_type_keyword (st, Qdata, chartab_data_validate);
4524 complex_vars_of_chartab (void)
4527 staticpro (&Vchar_attribute_hash_table);
4528 Vchar_attribute_hash_table
4529 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
4530 #endif /* UTF2000 */
4532 /* Set this now, so first buffer creation can refer to it. */
4533 /* Make it nil before calling copy-category-table
4534 so that copy-category-table will know not to try to copy from garbage */
4535 Vstandard_category_table = Qnil;
4536 Vstandard_category_table = Fcopy_category_table (Qnil);
4537 staticpro (&Vstandard_category_table);
4539 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
4540 List of pair (cons) of categories to determine word boundary.
4542 Emacs treats a sequence of word constituent characters as a single
4543 word (i.e. finds no word boundary between them) iff they belongs to
4544 the same charset. But, exceptions are allowed in the following cases.
4546 \(1) The case that characters are in different charsets is controlled
4547 by the variable `word-combining-categories'.
4549 Emacs finds no word boundary between characters of different charsets
4550 if they have categories matching some element of this list.
4552 More precisely, if an element of this list is a cons of category CAT1
4553 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4554 C2 which has CAT2, there's no word boundary between C1 and C2.
4556 For instance, to tell that ASCII characters and Latin-1 characters can
4557 form a single word, the element `(?l . ?l)' should be in this list
4558 because both characters have the category `l' (Latin characters).
4560 \(2) The case that character are in the same charset is controlled by
4561 the variable `word-separating-categories'.
4563 Emacs find a word boundary between characters of the same charset
4564 if they have categories matching some element of this list.
4566 More precisely, if an element of this list is a cons of category CAT1
4567 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4568 C2 which has CAT2, there's a word boundary between C1 and C2.
4570 For instance, to tell that there's a word boundary between Japanese
4571 Hiragana and Japanese Kanji (both are in the same charset), the
4572 element `(?H . ?C) should be in this list.
4575 Vword_combining_categories = Qnil;
4577 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
4578 List of pair (cons) of categories to determine word boundary.
4579 See the documentation of the variable `word-combining-categories'.
4582 Vword_separating_categories = Qnil;