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 Lisp_Object Vnext_defined_char_id;
79 EXFUN (Fdefine_char, 1);
81 EXFUN (Fmap_char_attribute, 3);
84 EXFUN (Fmount_char_attribute_table, 1);
88 EXFUN (Fload_char_attribute_table, 1);
90 Lisp_Object Vchar_db_stingy_mode;
93 #define BT_UINT8_MIN 0
94 #define BT_UINT8_MAX (UCHAR_MAX - 4)
95 #define BT_UINT8_t (UCHAR_MAX - 3)
96 #define BT_UINT8_nil (UCHAR_MAX - 2)
97 #define BT_UINT8_unbound (UCHAR_MAX - 1)
98 #define BT_UINT8_unloaded UCHAR_MAX
100 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
101 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
102 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
103 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
104 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
107 INT_UINT8_P (Lisp_Object obj)
111 int num = XINT (obj);
113 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
120 UINT8_VALUE_P (Lisp_Object obj)
122 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
123 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
126 INLINE_HEADER unsigned char
127 UINT8_ENCODE (Lisp_Object obj)
129 if (EQ (obj, Qunloaded))
130 return BT_UINT8_unloaded;
131 else if (EQ (obj, Qunbound))
132 return BT_UINT8_unbound;
133 else if (EQ (obj, Qnil))
135 else if (EQ (obj, Qt))
141 INLINE_HEADER Lisp_Object
142 UINT8_DECODE (unsigned char n)
144 if (n == BT_UINT8_unloaded)
146 else if (n == BT_UINT8_unbound)
148 else if (n == BT_UINT8_nil)
150 else if (n == BT_UINT8_t)
157 mark_uint8_byte_table (Lisp_Object obj)
163 print_uint8_byte_table (Lisp_Object obj,
164 Lisp_Object printcharfun, int escapeflag)
166 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
168 struct gcpro gcpro1, gcpro2;
169 GCPRO2 (obj, printcharfun);
171 write_c_string ("\n#<uint8-byte-table", printcharfun);
172 for (i = 0; i < 256; i++)
174 unsigned char n = bte->property[i];
176 write_c_string ("\n ", printcharfun);
177 write_c_string (" ", printcharfun);
178 if (n == BT_UINT8_unbound)
179 write_c_string ("void", printcharfun);
180 else if (n == BT_UINT8_nil)
181 write_c_string ("nil", printcharfun);
182 else if (n == BT_UINT8_t)
183 write_c_string ("t", printcharfun);
188 sprintf (buf, "%hd", n);
189 write_c_string (buf, printcharfun);
193 write_c_string (">", printcharfun);
197 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
199 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
200 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
203 for (i = 0; i < 256; i++)
204 if (te1->property[i] != te2->property[i])
210 uint8_byte_table_hash (Lisp_Object obj, int depth)
212 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
216 for (i = 0; i < 256; i++)
217 hash = HASH2 (hash, te->property[i]);
221 static const struct lrecord_description uint8_byte_table_description[] = {
225 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
226 mark_uint8_byte_table,
227 print_uint8_byte_table,
228 0, uint8_byte_table_equal,
229 uint8_byte_table_hash,
230 uint8_byte_table_description,
231 Lisp_Uint8_Byte_Table);
234 make_uint8_byte_table (unsigned char initval)
238 Lisp_Uint8_Byte_Table *cte;
240 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
241 &lrecord_uint8_byte_table);
243 for (i = 0; i < 256; i++)
244 cte->property[i] = initval;
246 XSETUINT8_BYTE_TABLE (obj, cte);
251 copy_uint8_byte_table (Lisp_Object entry)
253 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
256 Lisp_Uint8_Byte_Table *ctenew
257 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
258 &lrecord_uint8_byte_table);
260 for (i = 0; i < 256; i++)
262 ctenew->property[i] = cte->property[i];
265 XSETUINT8_BYTE_TABLE (obj, ctenew);
270 uint8_byte_table_same_value_p (Lisp_Object obj)
272 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
273 unsigned char v0 = bte->property[0];
276 for (i = 1; i < 256; i++)
278 if (bte->property[i] != v0)
285 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
286 Emchar ofs, int place,
287 int (*fn) (struct chartab_range *range,
288 Lisp_Object val, void *arg),
291 struct chartab_range rainj;
293 int unit = 1 << (8 * place);
297 rainj.type = CHARTAB_RANGE_CHAR;
299 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
301 if (ct->property[i] == BT_UINT8_unloaded)
305 for (; c < c1 && retval == 0; c++)
307 Lisp_Object ret = get_char_id_table (root, c);
312 retval = (fn) (&rainj, ret, arg);
316 ct->property[i] = BT_UINT8_unbound;
320 else if (ct->property[i] != BT_UINT8_unbound)
323 for (; c < c1 && retval == 0; c++)
326 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
337 save_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Lisp_Char_Table* root,
339 CHISE_Feature feature,
343 Emchar ofs, int place,
344 Lisp_Object (*filter)(Lisp_Object value))
346 struct chartab_range rainj;
348 int unit = 1 << (8 * place);
352 rainj.type = CHARTAB_RANGE_CHAR;
354 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
356 if (ct->property[i] == BT_UINT8_unloaded)
360 else if (ct->property[i] != BT_UINT8_unbound)
363 for (; c < c1 && retval == 0; c++)
366 chise_char_set_feature_value
369 (Fprin1_to_string (UINT8_DECODE (ct->property[i]),
372 Fput_database (Fprin1_to_string (make_char (c), Qnil),
373 Fprin1_to_string (UINT8_DECODE (ct->property[i]),
385 #define BT_UINT16_MIN 0
386 #define BT_UINT16_MAX (USHRT_MAX - 4)
387 #define BT_UINT16_t (USHRT_MAX - 3)
388 #define BT_UINT16_nil (USHRT_MAX - 2)
389 #define BT_UINT16_unbound (USHRT_MAX - 1)
390 #define BT_UINT16_unloaded USHRT_MAX
392 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
393 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
394 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
395 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
398 INT_UINT16_P (Lisp_Object obj)
402 int num = XINT (obj);
404 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
411 UINT16_VALUE_P (Lisp_Object obj)
413 return EQ (obj, Qunloaded) || EQ (obj, Qunbound)
414 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
417 INLINE_HEADER unsigned short
418 UINT16_ENCODE (Lisp_Object obj)
420 if (EQ (obj, Qunloaded))
421 return BT_UINT16_unloaded;
422 else if (EQ (obj, Qunbound))
423 return BT_UINT16_unbound;
424 else if (EQ (obj, Qnil))
425 return BT_UINT16_nil;
426 else if (EQ (obj, Qt))
432 INLINE_HEADER Lisp_Object
433 UINT16_DECODE (unsigned short n)
435 if (n == BT_UINT16_unloaded)
437 else if (n == BT_UINT16_unbound)
439 else if (n == BT_UINT16_nil)
441 else if (n == BT_UINT16_t)
447 INLINE_HEADER unsigned short
448 UINT8_TO_UINT16 (unsigned char n)
450 if (n == BT_UINT8_unloaded)
451 return BT_UINT16_unloaded;
452 else if (n == BT_UINT8_unbound)
453 return BT_UINT16_unbound;
454 else if (n == BT_UINT8_nil)
455 return BT_UINT16_nil;
456 else if (n == BT_UINT8_t)
463 mark_uint16_byte_table (Lisp_Object obj)
469 print_uint16_byte_table (Lisp_Object obj,
470 Lisp_Object printcharfun, int escapeflag)
472 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
474 struct gcpro gcpro1, gcpro2;
475 GCPRO2 (obj, printcharfun);
477 write_c_string ("\n#<uint16-byte-table", printcharfun);
478 for (i = 0; i < 256; i++)
480 unsigned short n = bte->property[i];
482 write_c_string ("\n ", printcharfun);
483 write_c_string (" ", printcharfun);
484 if (n == BT_UINT16_unbound)
485 write_c_string ("void", printcharfun);
486 else if (n == BT_UINT16_nil)
487 write_c_string ("nil", printcharfun);
488 else if (n == BT_UINT16_t)
489 write_c_string ("t", printcharfun);
494 sprintf (buf, "%hd", n);
495 write_c_string (buf, printcharfun);
499 write_c_string (">", printcharfun);
503 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
505 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
506 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
509 for (i = 0; i < 256; i++)
510 if (te1->property[i] != te2->property[i])
516 uint16_byte_table_hash (Lisp_Object obj, int depth)
518 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
522 for (i = 0; i < 256; i++)
523 hash = HASH2 (hash, te->property[i]);
527 static const struct lrecord_description uint16_byte_table_description[] = {
531 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
532 mark_uint16_byte_table,
533 print_uint16_byte_table,
534 0, uint16_byte_table_equal,
535 uint16_byte_table_hash,
536 uint16_byte_table_description,
537 Lisp_Uint16_Byte_Table);
540 make_uint16_byte_table (unsigned short initval)
544 Lisp_Uint16_Byte_Table *cte;
546 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
547 &lrecord_uint16_byte_table);
549 for (i = 0; i < 256; i++)
550 cte->property[i] = initval;
552 XSETUINT16_BYTE_TABLE (obj, cte);
557 copy_uint16_byte_table (Lisp_Object entry)
559 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
562 Lisp_Uint16_Byte_Table *ctenew
563 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
564 &lrecord_uint16_byte_table);
566 for (i = 0; i < 256; i++)
568 ctenew->property[i] = cte->property[i];
571 XSETUINT16_BYTE_TABLE (obj, ctenew);
576 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
580 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
581 Lisp_Uint16_Byte_Table* cte;
583 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
584 &lrecord_uint16_byte_table);
585 for (i = 0; i < 256; i++)
587 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
589 XSETUINT16_BYTE_TABLE (obj, cte);
594 uint16_byte_table_same_value_p (Lisp_Object obj)
596 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
597 unsigned short v0 = bte->property[0];
600 for (i = 1; i < 256; i++)
602 if (bte->property[i] != v0)
609 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
610 Emchar ofs, int place,
611 int (*fn) (struct chartab_range *range,
612 Lisp_Object val, void *arg),
615 struct chartab_range rainj;
617 int unit = 1 << (8 * place);
621 rainj.type = CHARTAB_RANGE_CHAR;
623 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
625 if (ct->property[i] == BT_UINT16_unloaded)
629 for (; c < c1 && retval == 0; c++)
631 Lisp_Object ret = get_char_id_table (root, c);
636 retval = (fn) (&rainj, ret, arg);
640 ct->property[i] = BT_UINT16_unbound;
644 else if (ct->property[i] != BT_UINT16_unbound)
647 for (; c < c1 && retval == 0; c++)
650 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
661 save_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Lisp_Char_Table* root,
663 CHISE_Feature feature,
667 Emchar ofs, int place,
668 Lisp_Object (*filter)(Lisp_Object value))
670 struct chartab_range rainj;
672 int unit = 1 << (8 * place);
676 rainj.type = CHARTAB_RANGE_CHAR;
678 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
680 if (ct->property[i] == BT_UINT16_unloaded)
684 else if (ct->property[i] != BT_UINT16_unbound)
687 for (; c < c1 && retval == 0; c++)
690 chise_char_set_feature_value
693 (Fprin1_to_string (UINT16_DECODE (ct->property[i]),
696 Fput_database (Fprin1_to_string (make_char (c), Qnil),
697 Fprin1_to_string (UINT16_DECODE (ct->property[i]),
711 mark_byte_table (Lisp_Object obj)
713 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
716 for (i = 0; i < 256; i++)
718 mark_object (cte->property[i]);
724 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
726 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
728 struct gcpro gcpro1, gcpro2;
729 GCPRO2 (obj, printcharfun);
731 write_c_string ("\n#<byte-table", printcharfun);
732 for (i = 0; i < 256; i++)
734 Lisp_Object elt = bte->property[i];
736 write_c_string ("\n ", printcharfun);
737 write_c_string (" ", printcharfun);
738 if (EQ (elt, Qunbound))
739 write_c_string ("void", printcharfun);
741 print_internal (elt, printcharfun, escapeflag);
744 write_c_string (">", printcharfun);
748 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
750 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
751 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
754 for (i = 0; i < 256; i++)
755 if (BYTE_TABLE_P (cte1->property[i]))
757 if (BYTE_TABLE_P (cte2->property[i]))
759 if (!byte_table_equal (cte1->property[i],
760 cte2->property[i], depth + 1))
767 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
773 byte_table_hash (Lisp_Object obj, int depth)
775 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
777 return internal_array_hash (cte->property, 256, depth);
780 static const struct lrecord_description byte_table_description[] = {
781 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
785 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
790 byte_table_description,
794 make_byte_table (Lisp_Object initval)
798 Lisp_Byte_Table *cte;
800 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
802 for (i = 0; i < 256; i++)
803 cte->property[i] = initval;
805 XSETBYTE_TABLE (obj, cte);
810 copy_byte_table (Lisp_Object entry)
812 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
815 Lisp_Byte_Table *ctnew
816 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
818 for (i = 0; i < 256; i++)
820 if (UINT8_BYTE_TABLE_P (cte->property[i]))
822 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
824 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
826 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
828 else if (BYTE_TABLE_P (cte->property[i]))
830 ctnew->property[i] = copy_byte_table (cte->property[i]);
833 ctnew->property[i] = cte->property[i];
836 XSETBYTE_TABLE (obj, ctnew);
841 byte_table_same_value_p (Lisp_Object obj)
843 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
844 Lisp_Object v0 = bte->property[0];
847 for (i = 1; i < 256; i++)
849 if (!internal_equal (bte->property[i], v0, 0))
856 map_over_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
857 Emchar ofs, int place,
858 int (*fn) (struct chartab_range *range,
859 Lisp_Object val, void *arg),
864 int unit = 1 << (8 * place);
867 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
870 if (UINT8_BYTE_TABLE_P (v))
873 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
874 c, place - 1, fn, arg);
877 else if (UINT16_BYTE_TABLE_P (v))
880 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
881 c, place - 1, fn, arg);
884 else if (BYTE_TABLE_P (v))
886 retval = map_over_byte_table (XBYTE_TABLE(v), root,
887 c, place - 1, fn, arg);
890 else if (EQ (v, Qunloaded))
893 struct chartab_range rainj;
894 Emchar c1 = c + unit;
896 rainj.type = CHARTAB_RANGE_CHAR;
898 for (; c < c1 && retval == 0; c++)
900 Lisp_Object ret = get_char_id_table (root, c);
905 retval = (fn) (&rainj, ret, arg);
909 ct->property[i] = Qunbound;
913 else if (!UNBOUNDP (v))
915 struct chartab_range rainj;
916 Emchar c1 = c + unit;
918 rainj.type = CHARTAB_RANGE_CHAR;
920 for (; c < c1 && retval == 0; c++)
923 retval = (fn) (&rainj, v, arg);
934 save_byte_table (Lisp_Byte_Table *ct, Lisp_Char_Table* root,
936 CHISE_Feature feature,
940 Emchar ofs, int place,
941 Lisp_Object (*filter)(Lisp_Object value))
945 int unit = 1 << (8 * place);
948 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
951 if (UINT8_BYTE_TABLE_P (v))
953 save_uint8_byte_table (XUINT8_BYTE_TABLE(v), root,
959 c, place - 1, filter);
962 else if (UINT16_BYTE_TABLE_P (v))
964 save_uint16_byte_table (XUINT16_BYTE_TABLE(v), root,
970 c, place - 1, filter);
973 else if (BYTE_TABLE_P (v))
975 save_byte_table (XBYTE_TABLE(v), root,
981 c, place - 1, filter);
984 else if (EQ (v, Qunloaded))
988 else if (!UNBOUNDP (v))
990 struct chartab_range rainj;
991 Emchar c1 = c + unit;
996 rainj.type = CHARTAB_RANGE_CHAR;
998 for (; c < c1 && retval == 0; c++)
1000 #ifdef HAVE_LIBCHISE
1001 chise_char_set_feature_value
1002 (c, feature, XSTRING_DATA (Fprin1_to_string (v, Qnil)));
1004 Fput_database (Fprin1_to_string (make_char (c), Qnil),
1005 Fprin1_to_string (v, Qnil),
1017 get_byte_table (Lisp_Object table, unsigned char idx)
1019 if (UINT8_BYTE_TABLE_P (table))
1020 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
1021 else if (UINT16_BYTE_TABLE_P (table))
1022 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
1023 else if (BYTE_TABLE_P (table))
1024 return XBYTE_TABLE(table)->property[idx];
1030 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
1032 if (UINT8_BYTE_TABLE_P (table))
1034 if (UINT8_VALUE_P (value))
1036 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1037 if (!UINT8_BYTE_TABLE_P (value) &&
1038 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1039 && uint8_byte_table_same_value_p (table))
1044 else if (UINT16_VALUE_P (value))
1046 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
1048 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
1053 Lisp_Object new = make_byte_table (Qnil);
1056 for (i = 0; i < 256; i++)
1058 XBYTE_TABLE(new)->property[i]
1059 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
1061 XBYTE_TABLE(new)->property[idx] = value;
1065 else if (UINT16_BYTE_TABLE_P (table))
1067 if (UINT16_VALUE_P (value))
1069 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1070 if (!UINT8_BYTE_TABLE_P (value) &&
1071 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1072 && uint16_byte_table_same_value_p (table))
1079 Lisp_Object new = make_byte_table (Qnil);
1082 for (i = 0; i < 256; i++)
1084 XBYTE_TABLE(new)->property[i]
1085 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
1087 XBYTE_TABLE(new)->property[idx] = value;
1091 else if (BYTE_TABLE_P (table))
1093 XBYTE_TABLE(table)->property[idx] = value;
1094 if (!UINT8_BYTE_TABLE_P (value) &&
1095 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
1096 && byte_table_same_value_p (table))
1101 else if (!internal_equal (table, value, 0))
1103 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
1105 table = make_uint8_byte_table (UINT8_ENCODE (table));
1106 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
1108 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
1110 table = make_uint16_byte_table (UINT16_ENCODE (table));
1111 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
1115 table = make_byte_table (table);
1116 XBYTE_TABLE(table)->property[idx] = value;
1124 make_char_id_table (Lisp_Object initval)
1127 obj = Fmake_char_table (Qgeneric);
1128 fill_char_table (XCHAR_TABLE (obj), initval);
1133 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
1134 Lisp_Object Qsystem_char_id;
1137 Lisp_Object Qcomposition;
1138 Lisp_Object Q_decomposition;
1139 Lisp_Object Q_unified;
1140 Lisp_Object Q_unified_from;
1141 Lisp_Object Qto_ucs;
1142 Lisp_Object Q_ucs_unified;
1143 Lisp_Object Qcompat;
1144 Lisp_Object Qisolated;
1145 Lisp_Object Qinitial;
1146 Lisp_Object Qmedial;
1148 Lisp_Object Qvertical;
1149 Lisp_Object QnoBreak;
1150 Lisp_Object Qfraction;
1153 Lisp_Object Qcircle;
1154 Lisp_Object Qsquare;
1156 Lisp_Object Qnarrow;
1160 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
1163 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
1169 else if (EQ (v, Qcompat))
1171 else if (EQ (v, Qisolated))
1173 else if (EQ (v, Qinitial))
1175 else if (EQ (v, Qmedial))
1177 else if (EQ (v, Qfinal))
1179 else if (EQ (v, Qvertical))
1181 else if (EQ (v, QnoBreak))
1183 else if (EQ (v, Qfraction))
1185 else if (EQ (v, Qsuper))
1187 else if (EQ (v, Qsub))
1189 else if (EQ (v, Qcircle))
1191 else if (EQ (v, Qsquare))
1193 else if (EQ (v, Qwide))
1195 else if (EQ (v, Qnarrow))
1197 else if (EQ (v, Qsmall))
1199 else if (EQ (v, Qfont))
1202 signal_simple_error (err_msg, err_arg);
1205 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
1206 Return character corresponding with list.
1210 Lisp_Object base, modifier;
1214 signal_simple_error ("Invalid value for composition", list);
1217 while (!NILP (rest))
1222 signal_simple_error ("Invalid value for composition", list);
1223 modifier = Fcar (rest);
1225 base = Fcdr (Fassq (modifier,
1226 Fchar_feature (base, Qcomposition, Qnil,
1232 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
1233 Return variants of CHARACTER.
1239 CHECK_CHAR (character);
1240 ret = Fchar_feature (character, Q_ucs_unified, Qnil,
1243 return Fcopy_list (ret);
1251 /* A char table maps from ranges of characters to values.
1253 Implementing a general data structure that maps from arbitrary
1254 ranges of numbers to values is tricky to do efficiently. As it
1255 happens, it should suffice (and is usually more convenient, anyway)
1256 when dealing with characters to restrict the sorts of ranges that
1257 can be assigned values, as follows:
1260 2) All characters in a charset.
1261 3) All characters in a particular row of a charset, where a "row"
1262 means all characters with the same first byte.
1263 4) A particular character in a charset.
1265 We use char tables to generalize the 256-element vectors now
1266 littering the Emacs code.
1268 Possible uses (all should be converted at some point):
1274 5) keyboard-translate-table?
1277 abstract type to generalize the Emacs vectors and Mule
1278 vectors-of-vectors goo.
1281 /************************************************************************/
1282 /* Char Table object */
1283 /************************************************************************/
1285 #if defined(MULE)&&!defined(UTF2000)
1288 mark_char_table_entry (Lisp_Object obj)
1290 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1293 for (i = 0; i < 96; i++)
1295 mark_object (cte->level2[i]);
1301 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1303 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1304 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1307 for (i = 0; i < 96; i++)
1308 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1314 static unsigned long
1315 char_table_entry_hash (Lisp_Object obj, int depth)
1317 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1319 return internal_array_hash (cte->level2, 96, depth);
1322 static const struct lrecord_description char_table_entry_description[] = {
1323 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1327 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1328 mark_char_table_entry, internal_object_printer,
1329 0, char_table_entry_equal,
1330 char_table_entry_hash,
1331 char_table_entry_description,
1332 Lisp_Char_Table_Entry);
1336 mark_char_table (Lisp_Object obj)
1338 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1341 mark_object (ct->table);
1342 mark_object (ct->name);
1343 #ifndef HAVE_LIBCHISE
1344 mark_object (ct->db);
1349 for (i = 0; i < NUM_ASCII_CHARS; i++)
1350 mark_object (ct->ascii[i]);
1352 for (i = 0; i < NUM_LEADING_BYTES; i++)
1353 mark_object (ct->level1[i]);
1357 return ct->default_value;
1359 return ct->mirror_table;
1363 /* WARNING: All functions of this nature need to be written extremely
1364 carefully to avoid crashes during GC. Cf. prune_specifiers()
1365 and prune_weak_hash_tables(). */
1368 prune_syntax_tables (void)
1370 Lisp_Object rest, prev = Qnil;
1372 for (rest = Vall_syntax_tables;
1374 rest = XCHAR_TABLE (rest)->next_table)
1376 if (! marked_p (rest))
1378 /* This table is garbage. Remove it from the list. */
1380 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1382 XCHAR_TABLE (prev)->next_table =
1383 XCHAR_TABLE (rest)->next_table;
1389 char_table_type_to_symbol (enum char_table_type type)
1394 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1395 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1396 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1397 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1399 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1404 static enum char_table_type
1405 symbol_to_char_table_type (Lisp_Object symbol)
1407 CHECK_SYMBOL (symbol);
1409 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1410 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1411 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1412 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1414 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1417 signal_simple_error ("Unrecognized char table type", symbol);
1418 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1423 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1424 Lisp_Object printcharfun)
1428 write_c_string (" (", printcharfun);
1429 print_internal (make_char (first), printcharfun, 0);
1430 write_c_string (" ", printcharfun);
1431 print_internal (make_char (last), printcharfun, 0);
1432 write_c_string (") ", printcharfun);
1436 write_c_string (" ", printcharfun);
1437 print_internal (make_char (first), printcharfun, 0);
1438 write_c_string (" ", printcharfun);
1440 print_internal (val, printcharfun, 1);
1444 #if defined(MULE)&&!defined(UTF2000)
1447 print_chartab_charset_row (Lisp_Object charset,
1449 Lisp_Char_Table_Entry *cte,
1450 Lisp_Object printcharfun)
1453 Lisp_Object cat = Qunbound;
1456 for (i = 32; i < 128; i++)
1458 Lisp_Object pam = cte->level2[i - 32];
1470 print_chartab_range (MAKE_CHAR (charset, first, 0),
1471 MAKE_CHAR (charset, i - 1, 0),
1474 print_chartab_range (MAKE_CHAR (charset, row, first),
1475 MAKE_CHAR (charset, row, i - 1),
1485 print_chartab_range (MAKE_CHAR (charset, first, 0),
1486 MAKE_CHAR (charset, i - 1, 0),
1489 print_chartab_range (MAKE_CHAR (charset, row, first),
1490 MAKE_CHAR (charset, row, i - 1),
1496 print_chartab_two_byte_charset (Lisp_Object charset,
1497 Lisp_Char_Table_Entry *cte,
1498 Lisp_Object printcharfun)
1502 for (i = 32; i < 128; i++)
1504 Lisp_Object jen = cte->level2[i - 32];
1506 if (!CHAR_TABLE_ENTRYP (jen))
1510 write_c_string (" [", printcharfun);
1511 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1512 sprintf (buf, " %d] ", i);
1513 write_c_string (buf, printcharfun);
1514 print_internal (jen, printcharfun, 0);
1517 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1525 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1527 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1530 struct gcpro gcpro1, gcpro2;
1531 GCPRO2 (obj, printcharfun);
1533 write_c_string ("#s(char-table ", printcharfun);
1534 write_c_string (" ", printcharfun);
1535 write_c_string (string_data
1537 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1539 write_c_string ("\n ", printcharfun);
1540 print_internal (ct->default_value, printcharfun, escapeflag);
1541 for (i = 0; i < 256; i++)
1543 Lisp_Object elt = get_byte_table (ct->table, i);
1544 if (i != 0) write_c_string ("\n ", printcharfun);
1545 if (EQ (elt, Qunbound))
1546 write_c_string ("void", printcharfun);
1548 print_internal (elt, printcharfun, escapeflag);
1551 #else /* non UTF2000 */
1554 sprintf (buf, "#s(char-table type %s data (",
1555 string_data (symbol_name (XSYMBOL
1556 (char_table_type_to_symbol (ct->type)))));
1557 write_c_string (buf, printcharfun);
1559 /* Now write out the ASCII/Control-1 stuff. */
1563 Lisp_Object val = Qunbound;
1565 for (i = 0; i < NUM_ASCII_CHARS; i++)
1574 if (!EQ (ct->ascii[i], val))
1576 print_chartab_range (first, i - 1, val, printcharfun);
1583 print_chartab_range (first, i - 1, val, printcharfun);
1590 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1593 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1594 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1596 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1597 || i == LEADING_BYTE_CONTROL_1)
1599 if (!CHAR_TABLE_ENTRYP (ann))
1601 write_c_string (" ", printcharfun);
1602 print_internal (XCHARSET_NAME (charset),
1604 write_c_string (" ", printcharfun);
1605 print_internal (ann, printcharfun, 0);
1609 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1610 if (XCHARSET_DIMENSION (charset) == 1)
1611 print_chartab_charset_row (charset, -1, cte, printcharfun);
1613 print_chartab_two_byte_charset (charset, cte, printcharfun);
1618 #endif /* non UTF2000 */
1620 write_c_string ("))", printcharfun);
1624 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1626 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1627 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1630 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1634 for (i = 0; i < 256; i++)
1636 if (!internal_equal (get_byte_table (ct1->table, i),
1637 get_byte_table (ct2->table, i), 0))
1641 for (i = 0; i < NUM_ASCII_CHARS; i++)
1642 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1646 for (i = 0; i < NUM_LEADING_BYTES; i++)
1647 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1650 #endif /* non UTF2000 */
1655 static unsigned long
1656 char_table_hash (Lisp_Object obj, int depth)
1658 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1660 return byte_table_hash (ct->table, depth + 1);
1662 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1665 hashval = HASH2 (hashval,
1666 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1672 static const struct lrecord_description char_table_description[] = {
1674 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1675 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1676 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, name) },
1677 #ifndef HAVE_LIBCHISE
1678 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, db) },
1681 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1683 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1687 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1689 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1693 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1694 mark_char_table, print_char_table, 0,
1695 char_table_equal, char_table_hash,
1696 char_table_description,
1699 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1700 Return non-nil if OBJECT is a char table.
1702 A char table is a table that maps characters (or ranges of characters)
1703 to values. Char tables are specialized for characters, only allowing
1704 particular sorts of ranges to be assigned values. Although this
1705 loses in generality, it makes for extremely fast (constant-time)
1706 lookups, and thus is feasible for applications that do an extremely
1707 large number of lookups (e.g. scanning a buffer for a character in
1708 a particular syntax, where a lookup in the syntax table must occur
1709 once per character).
1711 When Mule support exists, the types of ranges that can be assigned
1715 -- an entire charset
1716 -- a single row in a two-octet charset
1717 -- a single character
1719 When Mule support is not present, the types of ranges that can be
1723 -- a single character
1725 To create a char table, use `make-char-table'.
1726 To modify a char table, use `put-char-table' or `remove-char-table'.
1727 To retrieve the value for a particular character, use `get-char-table'.
1728 See also `map-char-table', `clear-char-table', `copy-char-table',
1729 `valid-char-table-type-p', `char-table-type-list',
1730 `valid-char-table-value-p', and `check-char-table-value'.
1734 return CHAR_TABLEP (object) ? Qt : Qnil;
1737 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1738 Return a list of the recognized char table types.
1739 See `valid-char-table-type-p'.
1744 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1746 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1750 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1751 Return t if TYPE if a recognized char table type.
1753 Each char table type is used for a different purpose and allows different
1754 sorts of values. The different char table types are
1757 Used for category tables, which specify the regexp categories
1758 that a character is in. The valid values are nil or a
1759 bit vector of 95 elements. Higher-level Lisp functions are
1760 provided for working with category tables. Currently categories
1761 and category tables only exist when Mule support is present.
1763 A generalized char table, for mapping from one character to
1764 another. Used for case tables, syntax matching tables,
1765 `keyboard-translate-table', etc. The valid values are characters.
1767 An even more generalized char table, for mapping from a
1768 character to anything.
1770 Used for display tables, which specify how a particular character
1771 is to appear when displayed. #### Not yet implemented.
1773 Used for syntax tables, which specify the syntax of a particular
1774 character. Higher-level Lisp functions are provided for
1775 working with syntax tables. The valid values are integers.
1780 return (EQ (type, Qchar) ||
1782 EQ (type, Qcategory) ||
1784 EQ (type, Qdisplay) ||
1785 EQ (type, Qgeneric) ||
1786 EQ (type, Qsyntax)) ? Qt : Qnil;
1789 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1790 Return the type of CHAR-TABLE.
1791 See `valid-char-table-type-p'.
1795 CHECK_CHAR_TABLE (char_table);
1796 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1800 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1803 ct->table = Qunbound;
1804 ct->default_value = value;
1809 for (i = 0; i < NUM_ASCII_CHARS; i++)
1810 ct->ascii[i] = value;
1812 for (i = 0; i < NUM_LEADING_BYTES; i++)
1813 ct->level1[i] = value;
1818 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1819 update_syntax_table (ct);
1823 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1824 Reset CHAR-TABLE to its default state.
1828 Lisp_Char_Table *ct;
1830 CHECK_CHAR_TABLE (char_table);
1831 ct = XCHAR_TABLE (char_table);
1835 case CHAR_TABLE_TYPE_CHAR:
1836 fill_char_table (ct, make_char (0));
1838 case CHAR_TABLE_TYPE_DISPLAY:
1839 case CHAR_TABLE_TYPE_GENERIC:
1841 case CHAR_TABLE_TYPE_CATEGORY:
1843 fill_char_table (ct, Qnil);
1846 case CHAR_TABLE_TYPE_SYNTAX:
1847 fill_char_table (ct, make_int (Sinherit));
1857 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1858 Return a new, empty char table of type TYPE.
1859 Currently recognized types are 'char, 'category, 'display, 'generic,
1860 and 'syntax. See `valid-char-table-type-p'.
1864 Lisp_Char_Table *ct;
1866 enum char_table_type ty = symbol_to_char_table_type (type);
1868 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1871 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1873 ct->mirror_table = Fmake_char_table (Qgeneric);
1874 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1878 ct->mirror_table = Qnil;
1881 #ifndef HAVE_LIBCHISE
1885 ct->next_table = Qnil;
1886 XSETCHAR_TABLE (obj, ct);
1887 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1889 ct->next_table = Vall_syntax_tables;
1890 Vall_syntax_tables = obj;
1892 Freset_char_table (obj);
1896 #if defined(MULE)&&!defined(UTF2000)
1899 make_char_table_entry (Lisp_Object initval)
1903 Lisp_Char_Table_Entry *cte =
1904 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1906 for (i = 0; i < 96; i++)
1907 cte->level2[i] = initval;
1909 XSETCHAR_TABLE_ENTRY (obj, cte);
1914 copy_char_table_entry (Lisp_Object entry)
1916 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1919 Lisp_Char_Table_Entry *ctenew =
1920 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1922 for (i = 0; i < 96; i++)
1924 Lisp_Object new = cte->level2[i];
1925 if (CHAR_TABLE_ENTRYP (new))
1926 ctenew->level2[i] = copy_char_table_entry (new);
1928 ctenew->level2[i] = new;
1931 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1937 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1938 Return a new char table which is a copy of CHAR-TABLE.
1939 It will contain the same values for the same characters and ranges
1940 as CHAR-TABLE. The values will not themselves be copied.
1944 Lisp_Char_Table *ct, *ctnew;
1950 CHECK_CHAR_TABLE (char_table);
1951 ct = XCHAR_TABLE (char_table);
1952 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1953 ctnew->type = ct->type;
1955 ctnew->default_value = ct->default_value;
1956 /* [tomo:2002-01-21] Perhaps this code seems wrong */
1957 ctnew->name = ct->name;
1958 #ifndef HAVE_LIBCHISE
1962 if (UINT8_BYTE_TABLE_P (ct->table))
1964 ctnew->table = copy_uint8_byte_table (ct->table);
1966 else if (UINT16_BYTE_TABLE_P (ct->table))
1968 ctnew->table = copy_uint16_byte_table (ct->table);
1970 else if (BYTE_TABLE_P (ct->table))
1972 ctnew->table = copy_byte_table (ct->table);
1974 else if (!UNBOUNDP (ct->table))
1975 ctnew->table = ct->table;
1976 #else /* non UTF2000 */
1978 for (i = 0; i < NUM_ASCII_CHARS; i++)
1980 Lisp_Object new = ct->ascii[i];
1982 assert (! (CHAR_TABLE_ENTRYP (new)));
1984 ctnew->ascii[i] = new;
1989 for (i = 0; i < NUM_LEADING_BYTES; i++)
1991 Lisp_Object new = ct->level1[i];
1992 if (CHAR_TABLE_ENTRYP (new))
1993 ctnew->level1[i] = copy_char_table_entry (new);
1995 ctnew->level1[i] = new;
1999 #endif /* non UTF2000 */
2002 if (CHAR_TABLEP (ct->mirror_table))
2003 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
2005 ctnew->mirror_table = ct->mirror_table;
2007 ctnew->next_table = Qnil;
2008 XSETCHAR_TABLE (obj, ctnew);
2009 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
2011 ctnew->next_table = Vall_syntax_tables;
2012 Vall_syntax_tables = obj;
2017 INLINE_HEADER int XCHARSET_CELL_RANGE (Lisp_Object ccs);
2019 XCHARSET_CELL_RANGE (Lisp_Object ccs)
2021 switch (XCHARSET_CHARS (ccs))
2024 return (33 << 8) | 126;
2026 return (32 << 8) | 127;
2029 return (0 << 8) | 127;
2031 return (0 << 8) | 255;
2043 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
2046 outrange->type = CHARTAB_RANGE_ALL;
2048 else if (EQ (range, Qnil))
2049 outrange->type = CHARTAB_RANGE_DEFAULT;
2051 else if (CHAR_OR_CHAR_INTP (range))
2053 outrange->type = CHARTAB_RANGE_CHAR;
2054 outrange->ch = XCHAR_OR_CHAR_INT (range);
2058 signal_simple_error ("Range must be t or a character", range);
2060 else if (VECTORP (range))
2062 Lisp_Vector *vec = XVECTOR (range);
2063 Lisp_Object *elts = vector_data (vec);
2064 int cell_min, cell_max;
2066 outrange->type = CHARTAB_RANGE_ROW;
2067 outrange->charset = Fget_charset (elts[0]);
2068 CHECK_INT (elts[1]);
2069 outrange->row = XINT (elts[1]);
2070 if (XCHARSET_DIMENSION (outrange->charset) < 2)
2071 signal_simple_error ("Charset in row vector must be multi-byte",
2075 int ret = XCHARSET_CELL_RANGE (outrange->charset);
2077 cell_min = ret >> 8;
2078 cell_max = ret & 0xFF;
2080 if (XCHARSET_DIMENSION (outrange->charset) == 2)
2081 check_int_range (outrange->row, cell_min, cell_max);
2083 else if (XCHARSET_DIMENSION (outrange->charset) == 3)
2085 check_int_range (outrange->row >> 8 , cell_min, cell_max);
2086 check_int_range (outrange->row & 0xFF, cell_min, cell_max);
2088 else if (XCHARSET_DIMENSION (outrange->charset) == 4)
2090 check_int_range ( outrange->row >> 16 , cell_min, cell_max);
2091 check_int_range ((outrange->row >> 8) & 0xFF, cell_min, cell_max);
2092 check_int_range ( outrange->row & 0xFF, cell_min, cell_max);
2100 if (!CHARSETP (range) && !SYMBOLP (range))
2102 ("Char table range must be t, charset, char, or vector", range);
2103 outrange->type = CHARTAB_RANGE_CHARSET;
2104 outrange->charset = Fget_charset (range);
2109 #if defined(MULE)&&!defined(UTF2000)
2111 /* called from CHAR_TABLE_VALUE(). */
2113 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
2118 Lisp_Object charset;
2120 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
2125 BREAKUP_CHAR (c, charset, byte1, byte2);
2127 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
2129 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
2130 if (CHAR_TABLE_ENTRYP (val))
2132 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2133 val = cte->level2[byte1 - 32];
2134 if (CHAR_TABLE_ENTRYP (val))
2136 cte = XCHAR_TABLE_ENTRY (val);
2137 assert (byte2 >= 32);
2138 val = cte->level2[byte2 - 32];
2139 assert (!CHAR_TABLE_ENTRYP (val));
2149 get_char_table (Emchar ch, Lisp_Char_Table *ct)
2153 Lisp_Object ret = get_char_id_table (ct, ch);
2158 if (EQ (CHAR_TABLE_NAME (ct), Qdowncase))
2159 ret = Fchar_feature (make_char (ch), Q_lowercase, Qnil,
2161 else if (EQ (CHAR_TABLE_NAME (ct), Qflippedcase))
2162 ret = Fchar_feature (make_char (ch), Q_uppercase, Qnil,
2168 ret = Ffind_char (ret);
2176 Lisp_Object charset;
2180 BREAKUP_CHAR (ch, charset, byte1, byte2);
2182 if (EQ (charset, Vcharset_ascii))
2183 val = ct->ascii[byte1];
2184 else if (EQ (charset, Vcharset_control_1))
2185 val = ct->ascii[byte1 + 128];
2188 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2189 val = ct->level1[lb];
2190 if (CHAR_TABLE_ENTRYP (val))
2192 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2193 val = cte->level2[byte1 - 32];
2194 if (CHAR_TABLE_ENTRYP (val))
2196 cte = XCHAR_TABLE_ENTRY (val);
2197 assert (byte2 >= 32);
2198 val = cte->level2[byte2 - 32];
2199 assert (!CHAR_TABLE_ENTRYP (val));
2206 #else /* not MULE */
2207 return ct->ascii[(unsigned char)ch];
2208 #endif /* not MULE */
2212 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
2213 Find value for CHARACTER in CHAR-TABLE.
2215 (character, char_table))
2217 CHECK_CHAR_TABLE (char_table);
2218 CHECK_CHAR_COERCE_INT (character);
2220 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
2223 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
2224 Find value for a range in CHAR-TABLE.
2225 If there is more than one value, return MULTI (defaults to nil).
2227 (range, char_table, multi))
2229 Lisp_Char_Table *ct;
2230 struct chartab_range rainj;
2232 if (CHAR_OR_CHAR_INTP (range))
2233 return Fget_char_table (range, char_table);
2234 CHECK_CHAR_TABLE (char_table);
2235 ct = XCHAR_TABLE (char_table);
2237 decode_char_table_range (range, &rainj);
2240 case CHARTAB_RANGE_ALL:
2243 if (UINT8_BYTE_TABLE_P (ct->table))
2245 else if (UINT16_BYTE_TABLE_P (ct->table))
2247 else if (BYTE_TABLE_P (ct->table))
2251 #else /* non UTF2000 */
2253 Lisp_Object first = ct->ascii[0];
2255 for (i = 1; i < NUM_ASCII_CHARS; i++)
2256 if (!EQ (first, ct->ascii[i]))
2260 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
2263 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
2264 || i == LEADING_BYTE_ASCII
2265 || i == LEADING_BYTE_CONTROL_1)
2267 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
2273 #endif /* non UTF2000 */
2277 case CHARTAB_RANGE_CHARSET:
2281 if (EQ (rainj.charset, Vcharset_ascii))
2284 Lisp_Object first = ct->ascii[0];
2286 for (i = 1; i < 128; i++)
2287 if (!EQ (first, ct->ascii[i]))
2292 if (EQ (rainj.charset, Vcharset_control_1))
2295 Lisp_Object first = ct->ascii[128];
2297 for (i = 129; i < 160; i++)
2298 if (!EQ (first, ct->ascii[i]))
2304 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2306 if (CHAR_TABLE_ENTRYP (val))
2312 case CHARTAB_RANGE_ROW:
2317 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
2319 if (!CHAR_TABLE_ENTRYP (val))
2321 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
2322 if (CHAR_TABLE_ENTRYP (val))
2326 #endif /* not UTF2000 */
2327 #endif /* not MULE */
2333 return Qnil; /* not reached */
2337 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2338 Error_behavior errb)
2342 case CHAR_TABLE_TYPE_SYNTAX:
2343 if (!ERRB_EQ (errb, ERROR_ME))
2344 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2345 && CHAR_OR_CHAR_INTP (XCDR (value)));
2348 Lisp_Object cdr = XCDR (value);
2349 CHECK_INT (XCAR (value));
2350 CHECK_CHAR_COERCE_INT (cdr);
2357 case CHAR_TABLE_TYPE_CATEGORY:
2358 if (!ERRB_EQ (errb, ERROR_ME))
2359 return CATEGORY_TABLE_VALUEP (value);
2360 CHECK_CATEGORY_TABLE_VALUE (value);
2364 case CHAR_TABLE_TYPE_GENERIC:
2367 case CHAR_TABLE_TYPE_DISPLAY:
2369 maybe_signal_simple_error ("Display char tables not yet implemented",
2370 value, Qchar_table, errb);
2373 case CHAR_TABLE_TYPE_CHAR:
2374 if (!ERRB_EQ (errb, ERROR_ME))
2375 return CHAR_OR_CHAR_INTP (value);
2376 CHECK_CHAR_COERCE_INT (value);
2383 return 0; /* not reached */
2387 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2391 case CHAR_TABLE_TYPE_SYNTAX:
2394 Lisp_Object car = XCAR (value);
2395 Lisp_Object cdr = XCDR (value);
2396 CHECK_CHAR_COERCE_INT (cdr);
2397 return Fcons (car, cdr);
2400 case CHAR_TABLE_TYPE_CHAR:
2401 CHECK_CHAR_COERCE_INT (value);
2409 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2410 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2412 (value, char_table_type))
2414 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2416 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2419 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2420 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2422 (value, char_table_type))
2424 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2426 check_valid_char_table_value (value, type, ERROR_ME);
2431 Lisp_Char_Table* char_attribute_table_to_put;
2432 Lisp_Object Qput_char_table_map_function;
2433 Lisp_Object value_to_put;
2435 DEFUN ("put-char-table-map-function",
2436 Fput_char_table_map_function, 2, 2, 0, /*
2437 For internal use. Don't use it.
2441 put_char_id_table_0 (char_attribute_table_to_put,
2442 XCHAR (c), value_to_put);
2447 /* Assign VAL to all characters in RANGE in char table CT. */
2450 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2453 switch (range->type)
2455 case CHARTAB_RANGE_ALL:
2456 fill_char_table (ct, val);
2457 return; /* avoid the duplicate call to update_syntax_table() below,
2458 since fill_char_table() also did that. */
2461 case CHARTAB_RANGE_DEFAULT:
2462 ct->default_value = val;
2467 case CHARTAB_RANGE_CHARSET:
2470 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2472 if ( CHAR_TABLEP (encoding_table) )
2474 Lisp_Object mother = XCHARSET_MOTHER (range->charset);
2476 char_attribute_table_to_put = ct;
2478 Fmap_char_attribute (Qput_char_table_map_function,
2479 XCHAR_TABLE_NAME (encoding_table),
2481 if ( CHARSETP (mother) )
2483 struct chartab_range r;
2485 r.type = CHARTAB_RANGE_CHARSET;
2487 put_char_table (ct, &r, val);
2495 for (c = 0; c < 1 << 24; c++)
2497 if ( charset_code_point (range->charset, c) >= 0 )
2498 put_char_id_table_0 (ct, c, val);
2504 if (EQ (range->charset, Vcharset_ascii))
2507 for (i = 0; i < 128; i++)
2510 else if (EQ (range->charset, Vcharset_control_1))
2513 for (i = 128; i < 160; i++)
2518 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2519 ct->level1[lb] = val;
2524 case CHARTAB_RANGE_ROW:
2527 int cell_min, cell_max, i;
2529 i = XCHARSET_CELL_RANGE (range->charset);
2531 cell_max = i & 0xFF;
2532 for (i = cell_min; i <= cell_max; i++)
2535 = DECODE_CHAR (range->charset, (range->row << 8) | i, 0);
2537 if ( charset_code_point (range->charset, ch, 0) >= 0 )
2538 put_char_id_table_0 (ct, ch, val);
2543 Lisp_Char_Table_Entry *cte;
2544 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2545 /* make sure that there is a separate entry for the row. */
2546 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2547 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2548 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2549 cte->level2[range->row - 32] = val;
2551 #endif /* not UTF2000 */
2555 case CHARTAB_RANGE_CHAR:
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 DEFUN ("char-feature", Fchar_feature, 2, 5, 0, /*
3277 Return the value of CHARACTER's FEATURE.
3278 Return DEFAULT-VALUE if the value is not exist.
3280 (character, attribute, default_value,
3281 feature_rel_max, char_rel_max))
3284 = Fget_char_attribute (character, attribute, Qunbound);
3286 if (!UNBOUNDP (ret))
3289 if (NILP (feature_rel_max)
3290 || (INTP (feature_rel_max) &&
3291 XINT (feature_rel_max) > 0))
3293 Lisp_String* name = symbol_name (XSYMBOL (attribute));
3294 Bufbyte *name_str = string_data (name);
3296 if (name_str[0] == '=' && name_str[1] == '>')
3298 Bytecount length = string_length (name) - 1;
3299 Lisp_Object map_to = make_uninit_string (length);
3301 memcpy (XSTRING_DATA (map_to) + 1, name_str + 2, length - 1);
3302 XSTRING_DATA(map_to)[0] = '=';
3303 ret = Fchar_feature (character, Fintern (map_to, Qnil),
3305 NILP (feature_rel_max)
3307 : make_int (XINT (feature_rel_max) - 1),
3309 if (!UNBOUNDP (ret))
3314 if ( !(EQ (attribute, Q_unified_from))
3315 && ( (NILP (char_rel_max)
3316 || (INTP (char_rel_max) &&
3317 XINT (char_rel_max) > 0)) ) )
3319 Lisp_String* name = symbol_name (XSYMBOL (attribute));
3320 Bufbyte *name_str = string_data (name);
3322 if ( (name_str[0] != '=') || (name_str[1] == '>') )
3324 Lisp_Object ancestors
3325 = Fget_char_attribute (character, Q_unified_from, Qnil);
3327 while (!NILP (ancestors))
3329 Lisp_Object ancestor = XCAR (ancestors);
3331 if (!EQ (ancestors, character))
3333 ret = Fchar_feature (ancestor, attribute, Qunbound,
3334 Qnil, make_int (0));
3335 if (!UNBOUNDP (ret))
3338 ancestors = XCDR (ancestors);
3339 ret = Fget_char_attribute (ancestor, Q_unified_from, Qnil);
3341 ancestors = nconc2 (Fcopy_sequence (ancestors), ret);
3344 ancestors = XCDR (ancestors);
3348 return default_value;
3351 void put_char_composition (Lisp_Object character, Lisp_Object value);
3353 put_char_composition (Lisp_Object character, Lisp_Object value)
3356 signal_simple_error ("Invalid value for ->decomposition",
3359 if (CONSP (Fcdr (value)))
3361 if (NILP (Fcdr (Fcdr (value))))
3363 Lisp_Object base = Fcar (value);
3364 Lisp_Object modifier = Fcar (Fcdr (value));
3368 base = make_char (XINT (base));
3369 Fsetcar (value, base);
3371 if (INTP (modifier))
3373 modifier = make_char (XINT (modifier));
3374 Fsetcar (Fcdr (value), modifier);
3379 = Fchar_feature (base, Qcomposition, Qnil,
3381 Lisp_Object ret = Fassq (modifier, alist);
3384 Fput_char_attribute (base, Qcomposition,
3385 Fcons (Fcons (modifier, character),
3388 Fsetcdr (ret, character);
3394 Lisp_Object v = Fcar (value);
3398 Emchar c = XINT (v);
3400 = Fchar_feature (make_char (c), Q_ucs_unified, Qnil,
3405 Fput_char_attribute (make_char (c), Q_ucs_unified,
3406 Fcons (character, Qnil));
3408 else if (NILP (Fmemq (character, ret)))
3410 Fput_char_attribute (make_char (c), Q_ucs_unified,
3411 Fcons (character, ret));
3417 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
3418 Store CHARACTER's ATTRIBUTE with VALUE.
3420 (character, attribute, value))
3422 Lisp_Object ccs = Ffind_charset (attribute);
3424 CHECK_CHAR (character);
3429 Lisp_String* name = symbol_name (XSYMBOL (attribute));
3430 Bufbyte *name_str = string_data (name);
3432 value = put_char_ccs_code_point (character, ccs, value);
3433 attribute = XCHARSET_NAME (ccs);
3435 if (name_str[0] == '=')
3437 Bytecount length = string_length (name) + 1;
3438 Lisp_Object map_to = make_uninit_string (length);
3440 memcpy (XSTRING_DATA (map_to) + 2, name_str + 1, length - 2);
3441 XSTRING_DATA(map_to)[0] = '=';
3442 XSTRING_DATA(map_to)[1] = '>';
3443 Fput_char_attribute (character,
3444 Fintern (map_to, Qnil), value);
3448 else if (EQ (attribute, Q_decomposition))
3449 put_char_composition (character, value);
3450 else if (EQ (attribute, Qto_ucs))
3456 signal_simple_error ("Invalid value for =>ucs", value);
3460 ret = Fchar_feature (make_char (c), Q_ucs_unified, Qnil,
3464 Fput_char_attribute (make_char (c), Q_ucs_unified,
3465 Fcons (character, Qnil));
3467 else if (NILP (Fmemq (character, ret)))
3469 Fput_char_attribute (make_char (c), Q_ucs_unified,
3470 Fcons (character, ret));
3473 else if (EQ (attribute, Q_unified))
3475 Lisp_Object rest = value;
3478 while (CONSP (rest))
3483 ret = Fdefine_char (ret);
3485 if ( !NILP (ret) && !EQ (ret, character) )
3487 Fput_char_attribute (ret, Q_unified_from, list1 (character));
3488 Fsetcar (rest, ret);
3494 else if (EQ (attribute, Qideographic_structure))
3495 value = Fcopy_sequence (Fchar_refs_simplify_char_specs (value));
3498 Lisp_Object table = Fgethash (attribute,
3499 Vchar_attribute_hash_table,
3504 table = make_char_id_table (Qunbound);
3505 Fputhash (attribute, table, Vchar_attribute_hash_table);
3507 XCHAR_TABLE_NAME (table) = attribute;
3510 put_char_id_table (XCHAR_TABLE(table), character, value);
3515 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3516 Remove CHARACTER's ATTRIBUTE.
3518 (character, attribute))
3522 CHECK_CHAR (character);
3523 ccs = Ffind_charset (attribute);
3526 return remove_char_ccs (character, ccs);
3530 Lisp_Object table = Fgethash (attribute,
3531 Vchar_attribute_hash_table,
3533 if (!UNBOUNDP (table))
3535 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3544 int char_table_open_db_maybe (Lisp_Char_Table* cit);
3545 void char_table_close_db_maybe (Lisp_Char_Table* cit);
3546 Lisp_Object char_table_get_db (Lisp_Char_Table* cit, Emchar ch);
3548 #ifdef HAVE_LIBCHISE
3550 open_chise_data_source_maybe ()
3552 if (default_chise_data_source == NULL)
3554 Lisp_Object db_dir = Vexec_directory;
3555 int modemask = 0755; /* rwxr-xr-x */
3558 db_dir = build_string ("../lib-src");
3559 db_dir = Fexpand_file_name (build_string ("chise-db"), db_dir);
3561 default_chise_data_source
3562 = CHISE_DS_open (CHISE_DS_Berkeley_DB, XSTRING_DATA (db_dir),
3563 0 /* DB_HASH */, modemask);
3564 if (default_chise_data_source == NULL)
3569 #endif /* HAVE_LIBCHISE */
3571 DEFUN ("close-char-data-source", Fclose_char_data_source, 0, 0, 0, /*
3572 Close data-source of CHISE.
3576 #ifdef HAVE_LIBCHISE
3577 int status = CHISE_DS_close (default_chise_data_source);
3579 default_chise_data_source = NULL;
3582 #endif /* HAVE_LIBCHISE */
3587 char_table_open_db_maybe (Lisp_Char_Table* cit)
3589 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3591 if (!NILP (attribute))
3593 #ifdef HAVE_LIBCHISE
3594 if ( open_chise_data_source_maybe () )
3596 #else /* HAVE_LIBCHISE */
3597 if (NILP (Fdatabase_live_p (cit->db)))
3600 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3602 cit->db = Fopen_database (db_file, Qnil, Qnil,
3603 build_string ("r"), Qnil);
3607 #endif /* not HAVE_LIBCHISE */
3615 char_table_close_db_maybe (Lisp_Char_Table* cit)
3617 #ifndef HAVE_LIBCHISE
3618 if (!NILP (cit->db))
3620 if (!NILP (Fdatabase_live_p (cit->db)))
3621 Fclose_database (cit->db);
3624 #endif /* not HAVE_LIBCHISE */
3628 char_table_get_db (Lisp_Char_Table* cit, Emchar ch)
3631 #ifdef HAVE_LIBCHISE
3634 = chise_ds_load_char_feature_value (default_chise_data_source, ch,
3635 XSTRING_DATA(Fsymbol_name
3641 val = Fread (make_string (chise_value_data (&value),
3642 chise_value_size (&value) ));
3646 #else /* HAVE_LIBCHISE */
3647 val = Fget_database (Fprin1_to_string (make_char (ch), Qnil),
3649 if (!UNBOUNDP (val))
3653 #endif /* not HAVE_LIBCHISE */
3657 #ifndef HAVE_LIBCHISE
3659 char_attribute_system_db_file (Lisp_Object key_type, Lisp_Object attribute,
3662 Lisp_Object db_dir = Vexec_directory;
3665 db_dir = build_string ("../lib-src");
3667 db_dir = Fexpand_file_name (build_string ("chise-db"), db_dir);
3668 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3669 Fmake_directory_internal (db_dir);
3671 db_dir = Fexpand_file_name (Fsymbol_name (key_type), db_dir);
3672 if (writing_mode && NILP (Ffile_exists_p (db_dir)))
3673 Fmake_directory_internal (db_dir);
3676 Lisp_Object attribute_name = Fsymbol_name (attribute);
3677 Lisp_Object dest = Qnil, ret;
3679 struct gcpro gcpro1, gcpro2;
3680 int len = XSTRING_CHAR_LENGTH (attribute_name);
3684 for (i = 0; i < len; i++)
3686 Emchar c = string_char (XSTRING (attribute_name), i);
3688 if ( (c == '/') || (c == '%') )
3692 sprintf (str, "%%%02X", c);
3693 dest = concat3 (dest,
3694 Fsubstring (attribute_name,
3695 make_int (base), make_int (i)),
3696 build_string (str));
3700 ret = Fsubstring (attribute_name, make_int (base), make_int (len));
3701 dest = concat2 (dest, ret);
3703 return Fexpand_file_name (dest, db_dir);
3706 #endif /* not HAVE_LIBCHISE */
3708 DEFUN ("save-char-attribute-table", Fsave_char_attribute_table, 1, 1, 0, /*
3709 Save values of ATTRIBUTE into database file.
3713 Lisp_Object table = Fgethash (attribute,
3714 Vchar_attribute_hash_table, Qunbound);
3715 Lisp_Char_Table *ct;
3716 #ifdef HAVE_LIBCHISE
3717 CHISE_Feature feature;
3718 #else /* HAVE_LIBCHISE */
3719 Lisp_Object db_file;
3721 #endif /* not HAVE_LIBCHISE */
3723 if (CHAR_TABLEP (table))
3724 ct = XCHAR_TABLE (table);
3728 #ifdef HAVE_LIBCHISE
3729 if ( open_chise_data_source_maybe () )
3732 = chise_ds_get_feature (default_chise_data_source,
3733 XSTRING_DATA (Fsymbol_name (attribute)));
3734 #else /* HAVE_LIBCHISE */
3735 db_file = char_attribute_system_db_file (Qsystem_char_id, attribute, 1);
3736 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
3737 #endif /* not HAVE_LIBCHISE */
3739 #ifdef HAVE_LIBCHISE
3741 #else /* HAVE_LIBCHISE */
3743 #endif /* not HAVE_LIBCHISE */
3746 Lisp_Object (*filter)(Lisp_Object value);
3748 if (EQ (attribute, Qideographic_structure))
3749 filter = &Fchar_refs_simplify_char_specs;
3753 if (UINT8_BYTE_TABLE_P (ct->table))
3754 save_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table), ct,
3755 #ifdef HAVE_LIBCHISE
3757 #else /* HAVE_LIBCHISE */
3759 #endif /* not HAVE_LIBCHISE */
3761 else if (UINT16_BYTE_TABLE_P (ct->table))
3762 save_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table), ct,
3763 #ifdef HAVE_LIBCHISE
3765 #else /* HAVE_LIBCHISE */
3767 #endif /* not HAVE_LIBCHISE */
3769 else if (BYTE_TABLE_P (ct->table))
3770 save_byte_table (XBYTE_TABLE(ct->table), ct,
3771 #ifdef HAVE_LIBCHISE
3773 #else /* HAVE_LIBCHISE */
3775 #endif /* not HAVE_LIBCHISE */
3777 #ifdef HAVE_LIBCHISE
3778 chise_feature_sync (feature);
3779 #else /* HAVE_LIBCHISE */
3780 Fclose_database (db);
3781 #endif /* not HAVE_LIBCHISE */
3788 DEFUN ("mount-char-attribute-table", Fmount_char_attribute_table, 1, 1, 0, /*
3789 Mount database file on char-attribute-table ATTRIBUTE.
3793 Lisp_Object table = Fgethash (attribute,
3794 Vchar_attribute_hash_table, Qunbound);
3796 if (UNBOUNDP (table))
3798 Lisp_Char_Table *ct;
3800 table = make_char_id_table (Qunbound);
3801 Fputhash (attribute, table, Vchar_attribute_hash_table);
3802 XCHAR_TABLE_NAME(table) = attribute;
3803 ct = XCHAR_TABLE (table);
3804 ct->table = Qunloaded;
3805 XCHAR_TABLE_UNLOADED(table) = 1;
3806 #ifndef HAVE_LIBCHISE
3808 #endif /* not HAVE_LIBCHISE */
3814 DEFUN ("close-char-attribute-table", Fclose_char_attribute_table, 1, 1, 0, /*
3815 Close database of ATTRIBUTE.
3819 Lisp_Object table = Fgethash (attribute,
3820 Vchar_attribute_hash_table, Qunbound);
3821 Lisp_Char_Table *ct;
3823 if (CHAR_TABLEP (table))
3824 ct = XCHAR_TABLE (table);
3827 char_table_close_db_maybe (ct);
3831 DEFUN ("reset-char-attribute-table", Freset_char_attribute_table, 1, 1, 0, /*
3832 Reset values of ATTRIBUTE with database file.
3836 #ifdef HAVE_LIBCHISE
3837 CHISE_Feature feature
3838 = chise_ds_get_feature (default_chise_data_source,
3839 XSTRING_DATA (Fsymbol_name
3842 if (feature == NULL)
3845 if (chise_feature_setup_db (feature, 0) == 0)
3847 Lisp_Object table = Fgethash (attribute,
3848 Vchar_attribute_hash_table, Qunbound);
3849 Lisp_Char_Table *ct;
3851 chise_feature_sync (feature);
3852 if (UNBOUNDP (table))
3854 table = make_char_id_table (Qunbound);
3855 Fputhash (attribute, table, Vchar_attribute_hash_table);
3856 XCHAR_TABLE_NAME(table) = attribute;
3858 ct = XCHAR_TABLE (table);
3859 ct->table = Qunloaded;
3860 char_table_close_db_maybe (ct);
3861 XCHAR_TABLE_UNLOADED(table) = 1;
3865 Lisp_Object table = Fgethash (attribute,
3866 Vchar_attribute_hash_table, Qunbound);
3867 Lisp_Char_Table *ct;
3869 = char_attribute_system_db_file (Qsystem_char_id, attribute, 0);
3871 if (!NILP (Ffile_exists_p (db_file)))
3873 if (UNBOUNDP (table))
3875 table = make_char_id_table (Qunbound);
3876 Fputhash (attribute, table, Vchar_attribute_hash_table);
3877 XCHAR_TABLE_NAME(table) = attribute;
3879 ct = XCHAR_TABLE (table);
3880 ct->table = Qunloaded;
3881 char_table_close_db_maybe (ct);
3882 XCHAR_TABLE_UNLOADED(table) = 1;
3890 load_char_attribute_maybe (Lisp_Char_Table* cit, Emchar ch)
3892 Lisp_Object attribute = CHAR_TABLE_NAME (cit);
3894 if (!NILP (attribute))
3898 if (char_table_open_db_maybe (cit))
3901 val = char_table_get_db (cit, ch);
3903 if (!NILP (Vchar_db_stingy_mode))
3904 char_table_close_db_maybe (cit);
3911 Lisp_Char_Table* char_attribute_table_to_load;
3913 #ifdef HAVE_LIBCHISE
3915 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3916 CHISE_Feature feature,
3917 CHISE_Value *value);
3919 load_char_attribute_table_map_func (CHISE_Char_ID cid,
3920 CHISE_Feature feature,
3924 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3926 if (EQ (ret, Qunloaded))
3927 put_char_id_table_0 (char_attribute_table_to_load, code,
3928 Fread (make_string ((Bufbyte *) value->data,
3932 #else /* HAVE_LIBCHISE */
3933 Lisp_Object Qload_char_attribute_table_map_function;
3935 DEFUN ("load-char-attribute-table-map-function",
3936 Fload_char_attribute_table_map_function, 2, 2, 0, /*
3937 For internal use. Don't use it.
3941 Lisp_Object c = Fread (key);
3942 Emchar code = XCHAR (c);
3943 Lisp_Object ret = get_char_id_table_0 (char_attribute_table_to_load, code);
3945 if (EQ (ret, Qunloaded))
3946 put_char_id_table_0 (char_attribute_table_to_load, code, Fread (value));
3949 #endif /* not HAVE_LIBCHISE */
3951 DEFUN ("load-char-attribute-table", Fload_char_attribute_table, 1, 1, 0, /*
3952 Load values of ATTRIBUTE into database file.
3956 Lisp_Object table = Fgethash (attribute,
3957 Vchar_attribute_hash_table,
3959 if (CHAR_TABLEP (table))
3961 Lisp_Char_Table *cit = XCHAR_TABLE (table);
3963 if (char_table_open_db_maybe (cit))
3966 char_attribute_table_to_load = XCHAR_TABLE (table);
3968 struct gcpro gcpro1;
3971 #ifdef HAVE_LIBCHISE
3972 chise_feature_foreach_char_with_value
3973 (chise_ds_get_feature (default_chise_data_source,
3974 XSTRING_DATA (Fsymbol_name (cit->name))),
3975 &load_char_attribute_table_map_func);
3976 #else /* HAVE_LIBCHISE */
3977 Fmap_database (Qload_char_attribute_table_map_function, cit->db);
3978 #endif /* not HAVE_LIBCHISE */
3981 char_table_close_db_maybe (cit);
3982 XCHAR_TABLE_UNLOADED(table) = 0;
3987 #endif /* HAVE_CHISE */
3989 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3990 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3991 each key and value in the table.
3993 RANGE specifies a subrange to map over and is in the same format as
3994 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3997 (function, attribute, range))
4000 Lisp_Char_Table *ct;
4001 struct slow_map_char_table_arg slarg;
4002 struct gcpro gcpro1, gcpro2;
4003 struct chartab_range rainj;
4005 if (!NILP (ccs = Ffind_charset (attribute)))
4007 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
4009 if (CHAR_TABLEP (encoding_table))
4010 ct = XCHAR_TABLE (encoding_table);
4016 Lisp_Object table = Fgethash (attribute,
4017 Vchar_attribute_hash_table,
4019 if (CHAR_TABLEP (table))
4020 ct = XCHAR_TABLE (table);
4026 decode_char_table_range (range, &rainj);
4028 if (CHAR_TABLE_UNLOADED(ct))
4029 Fload_char_attribute_table (attribute);
4031 slarg.function = function;
4032 slarg.retval = Qnil;
4033 GCPRO2 (slarg.function, slarg.retval);
4034 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
4037 return slarg.retval;
4040 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
4041 Store character's ATTRIBUTES.
4045 Lisp_Object rest = attributes;
4046 Lisp_Object code = Fcdr (Fassq (Qmap_ucs, attributes));
4047 Lisp_Object character;
4050 code = Fcdr (Fassq (Qucs, attributes));
4053 while (CONSP (rest))
4055 Lisp_Object cell = Fcar (rest);
4059 signal_simple_error ("Invalid argument", attributes);
4060 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
4061 && ((XCHARSET_FINAL (ccs) != 0) ||
4062 (XCHARSET_MAX_CODE (ccs) > 0) ||
4063 (EQ (ccs, Vcharset_chinese_big5))) )
4067 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
4069 character = Fdecode_char (ccs, cell, Qnil, Qt);
4070 if (!NILP (character))
4071 goto setup_attributes;
4077 int cid = XINT (Vnext_defined_char_id);
4079 if (cid <= 0xE00000)
4081 character = make_char (cid);
4082 Vnext_defined_char_id = make_int (cid + 1);
4083 goto setup_attributes;
4087 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
4090 signal_simple_error ("Invalid argument", attributes);
4092 character = make_char (XINT (code) + 0x100000);
4093 goto setup_attributes;
4098 else if (!INTP (code))
4099 signal_simple_error ("Invalid argument", attributes);
4101 character = make_char (XINT (code));
4105 while (CONSP (rest))
4107 Lisp_Object cell = Fcar (rest);
4110 signal_simple_error ("Invalid argument", attributes);
4112 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
4118 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
4119 Retrieve the character of the given ATTRIBUTES.
4123 Lisp_Object rest = attributes;
4126 while (CONSP (rest))
4128 Lisp_Object cell = Fcar (rest);
4132 signal_simple_error ("Invalid argument", attributes);
4133 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
4137 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
4139 return Fdecode_char (ccs, cell, Qnil, Qnil);
4143 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) )
4146 signal_simple_error ("Invalid argument", attributes);
4148 return make_char (XINT (code) + 0x100000);
4156 /************************************************************************/
4157 /* Char table read syntax */
4158 /************************************************************************/
4161 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
4162 Error_behavior errb)
4164 /* #### should deal with ERRB */
4165 symbol_to_char_table_type (value);
4170 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
4171 Error_behavior errb)
4175 /* #### should deal with ERRB */
4176 EXTERNAL_LIST_LOOP (rest, value)
4178 Lisp_Object range = XCAR (rest);
4179 struct chartab_range dummy;
4183 signal_simple_error ("Invalid list format", value);
4186 if (!CONSP (XCDR (range))
4187 || !NILP (XCDR (XCDR (range))))
4188 signal_simple_error ("Invalid range format", range);
4189 decode_char_table_range (XCAR (range), &dummy);
4190 decode_char_table_range (XCAR (XCDR (range)), &dummy);
4193 decode_char_table_range (range, &dummy);
4200 chartab_instantiate (Lisp_Object data)
4202 Lisp_Object chartab;
4203 Lisp_Object type = Qgeneric;
4204 Lisp_Object dataval = Qnil;
4206 while (!NILP (data))
4208 Lisp_Object keyw = Fcar (data);
4214 if (EQ (keyw, Qtype))
4216 else if (EQ (keyw, Qdata))
4220 chartab = Fmake_char_table (type);
4223 while (!NILP (data))
4225 Lisp_Object range = Fcar (data);
4226 Lisp_Object val = Fcar (Fcdr (data));
4228 data = Fcdr (Fcdr (data));
4231 if (CHAR_OR_CHAR_INTP (XCAR (range)))
4233 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
4234 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
4237 for (i = first; i <= last; i++)
4238 Fput_char_table (make_char (i), val, chartab);
4244 Fput_char_table (range, val, chartab);
4253 /************************************************************************/
4254 /* Category Tables, specifically */
4255 /************************************************************************/
4257 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
4258 Return t if OBJECT is a category table.
4259 A category table is a type of char table used for keeping track of
4260 categories. Categories are used for classifying characters for use
4261 in regexps -- you can refer to a category rather than having to use
4262 a complicated [] expression (and category lookups are significantly
4265 There are 95 different categories available, one for each printable
4266 character (including space) in the ASCII charset. Each category
4267 is designated by one such character, called a "category designator".
4268 They are specified in a regexp using the syntax "\\cX", where X is
4269 a category designator.
4271 A category table specifies, for each character, the categories that
4272 the character is in. Note that a character can be in more than one
4273 category. More specifically, a category table maps from a character
4274 to either the value nil (meaning the character is in no categories)
4275 or a 95-element bit vector, specifying for each of the 95 categories
4276 whether the character is in that category.
4278 Special Lisp functions are provided that abstract this, so you do not
4279 have to directly manipulate bit vectors.
4283 return (CHAR_TABLEP (object) &&
4284 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
4289 check_category_table (Lisp_Object object, Lisp_Object default_)
4293 while (NILP (Fcategory_table_p (object)))
4294 object = wrong_type_argument (Qcategory_table_p, object);
4299 check_category_char (Emchar ch, Lisp_Object table,
4300 unsigned int designator, unsigned int not_p)
4302 REGISTER Lisp_Object temp;
4303 Lisp_Char_Table *ctbl;
4304 #ifdef ERROR_CHECK_TYPECHECK
4305 if (NILP (Fcategory_table_p (table)))
4306 signal_simple_error ("Expected category table", table);
4308 ctbl = XCHAR_TABLE (table);
4309 temp = get_char_table (ch, ctbl);
4314 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
4317 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
4318 Return t if category of the character at POSITION includes DESIGNATOR.
4319 Optional third arg BUFFER specifies which buffer to use, and defaults
4320 to the current buffer.
4321 Optional fourth arg CATEGORY-TABLE specifies the category table to
4322 use, and defaults to BUFFER's category table.
4324 (position, designator, buffer, category_table))
4329 struct buffer *buf = decode_buffer (buffer, 0);
4331 CHECK_INT (position);
4332 CHECK_CATEGORY_DESIGNATOR (designator);
4333 des = XCHAR (designator);
4334 ctbl = check_category_table (category_table, Vstandard_category_table);
4335 ch = BUF_FETCH_CHAR (buf, XINT (position));
4336 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4339 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
4340 Return t if category of CHARACTER includes DESIGNATOR, else nil.
4341 Optional third arg CATEGORY-TABLE specifies the category table to use,
4342 and defaults to the standard category table.
4344 (character, designator, category_table))
4350 CHECK_CATEGORY_DESIGNATOR (designator);
4351 des = XCHAR (designator);
4352 CHECK_CHAR (character);
4353 ch = XCHAR (character);
4354 ctbl = check_category_table (category_table, Vstandard_category_table);
4355 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
4358 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
4359 Return BUFFER's current category table.
4360 BUFFER defaults to the current buffer.
4364 return decode_buffer (buffer, 0)->category_table;
4367 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
4368 Return the standard category table.
4369 This is the one used for new buffers.
4373 return Vstandard_category_table;
4376 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
4377 Return a new category table which is a copy of CATEGORY-TABLE.
4378 CATEGORY-TABLE defaults to the standard category table.
4382 if (NILP (Vstandard_category_table))
4383 return Fmake_char_table (Qcategory);
4386 check_category_table (category_table, Vstandard_category_table);
4387 return Fcopy_char_table (category_table);
4390 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
4391 Select CATEGORY-TABLE as the new category table for BUFFER.
4392 BUFFER defaults to the current buffer if omitted.
4394 (category_table, buffer))
4396 struct buffer *buf = decode_buffer (buffer, 0);
4397 category_table = check_category_table (category_table, Qnil);
4398 buf->category_table = category_table;
4399 /* Indicate that this buffer now has a specified category table. */
4400 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
4401 return category_table;
4404 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
4405 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
4409 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
4412 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
4413 Return t if OBJECT is a category table value.
4414 Valid values are nil or a bit vector of size 95.
4418 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
4422 #define CATEGORYP(x) \
4423 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
4425 #define CATEGORY_SET(c) \
4426 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
4428 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
4429 The faster version of `!NILP (Faref (category_set, category))'. */
4430 #define CATEGORY_MEMBER(category, category_set) \
4431 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
4433 /* Return 1 if there is a word boundary between two word-constituent
4434 characters C1 and C2 if they appear in this order, else return 0.
4435 Use the macro WORD_BOUNDARY_P instead of calling this function
4438 int word_boundary_p (Emchar c1, Emchar c2);
4440 word_boundary_p (Emchar c1, Emchar c2)
4442 Lisp_Object category_set1, category_set2;
4447 if (COMPOSITE_CHAR_P (c1))
4448 c1 = cmpchar_component (c1, 0, 1);
4449 if (COMPOSITE_CHAR_P (c2))
4450 c2 = cmpchar_component (c2, 0, 1);
4454 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
4457 tail = Vword_separating_categories;
4463 tail = Vword_combining_categories;
4468 category_set1 = CATEGORY_SET (c1);
4469 if (NILP (category_set1))
4470 return default_result;
4471 category_set2 = CATEGORY_SET (c2);
4472 if (NILP (category_set2))
4473 return default_result;
4475 for (; CONSP (tail); tail = XCONS (tail)->cdr)
4477 Lisp_Object elt = XCONS(tail)->car;
4480 && CATEGORYP (XCONS (elt)->car)
4481 && CATEGORYP (XCONS (elt)->cdr)
4482 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
4483 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
4484 return !default_result;
4486 return default_result;
4492 syms_of_chartab (void)
4495 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
4496 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
4497 INIT_LRECORD_IMPLEMENTATION (byte_table);
4499 #if defined(HAVE_CHISE) && !defined(HAVE_LIBCHISE_LIBCHISE)
4500 defsymbol (&Qsystem_char_id, "system-char-id");
4503 defsymbol (&Qto_ucs, "=>ucs");
4504 defsymbol (&Q_ucs_unified, "->ucs-unified");
4505 defsymbol (&Q_unified, "->unified");
4506 defsymbol (&Q_unified_from, "<-unified");
4507 defsymbol (&Qcomposition, "composition");
4508 defsymbol (&Q_decomposition, "->decomposition");
4509 defsymbol (&Qcompat, "compat");
4510 defsymbol (&Qisolated, "isolated");
4511 defsymbol (&Qinitial, "initial");
4512 defsymbol (&Qmedial, "medial");
4513 defsymbol (&Qfinal, "final");
4514 defsymbol (&Qvertical, "vertical");
4515 defsymbol (&QnoBreak, "noBreak");
4516 defsymbol (&Qfraction, "fraction");
4517 defsymbol (&Qsuper, "super");
4518 defsymbol (&Qsub, "sub");
4519 defsymbol (&Qcircle, "circle");
4520 defsymbol (&Qsquare, "square");
4521 defsymbol (&Qwide, "wide");
4522 defsymbol (&Qnarrow, "narrow");
4523 defsymbol (&Qsmall, "small");
4524 defsymbol (&Qfont, "font");
4526 DEFSUBR (Fchar_attribute_list);
4527 DEFSUBR (Ffind_char_attribute_table);
4528 defsymbol (&Qput_char_table_map_function, "put-char-table-map-function");
4529 DEFSUBR (Fput_char_table_map_function);
4531 DEFSUBR (Fsave_char_attribute_table);
4532 DEFSUBR (Fmount_char_attribute_table);
4533 DEFSUBR (Freset_char_attribute_table);
4534 DEFSUBR (Fclose_char_attribute_table);
4535 DEFSUBR (Fclose_char_data_source);
4536 #ifndef HAVE_LIBCHISE
4537 defsymbol (&Qload_char_attribute_table_map_function,
4538 "load-char-attribute-table-map-function");
4539 DEFSUBR (Fload_char_attribute_table_map_function);
4541 DEFSUBR (Fload_char_attribute_table);
4543 DEFSUBR (Fchar_feature);
4544 DEFSUBR (Fchar_attribute_alist);
4545 DEFSUBR (Fget_char_attribute);
4546 DEFSUBR (Fput_char_attribute);
4547 DEFSUBR (Fremove_char_attribute);
4548 DEFSUBR (Fmap_char_attribute);
4549 DEFSUBR (Fdefine_char);
4550 DEFSUBR (Ffind_char);
4551 DEFSUBR (Fchar_variants);
4553 DEFSUBR (Fget_composite_char);
4556 INIT_LRECORD_IMPLEMENTATION (char_table);
4560 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
4563 defsymbol (&Qcategory_table_p, "category-table-p");
4564 defsymbol (&Qcategory_designator_p, "category-designator-p");
4565 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
4568 defsymbol (&Qchar_table, "char-table");
4569 defsymbol (&Qchar_tablep, "char-table-p");
4571 DEFSUBR (Fchar_table_p);
4572 DEFSUBR (Fchar_table_type_list);
4573 DEFSUBR (Fvalid_char_table_type_p);
4574 DEFSUBR (Fchar_table_type);
4575 DEFSUBR (Freset_char_table);
4576 DEFSUBR (Fmake_char_table);
4577 DEFSUBR (Fcopy_char_table);
4578 DEFSUBR (Fget_char_table);
4579 DEFSUBR (Fget_range_char_table);
4580 DEFSUBR (Fvalid_char_table_value_p);
4581 DEFSUBR (Fcheck_valid_char_table_value);
4582 DEFSUBR (Fput_char_table);
4583 DEFSUBR (Fmap_char_table);
4586 DEFSUBR (Fcategory_table_p);
4587 DEFSUBR (Fcategory_table);
4588 DEFSUBR (Fstandard_category_table);
4589 DEFSUBR (Fcopy_category_table);
4590 DEFSUBR (Fset_category_table);
4591 DEFSUBR (Fcheck_category_at);
4592 DEFSUBR (Fchar_in_category_p);
4593 DEFSUBR (Fcategory_designator_p);
4594 DEFSUBR (Fcategory_table_value_p);
4600 vars_of_chartab (void)
4603 DEFVAR_LISP ("next-defined-char-id", &Vnext_defined_char_id /*
4605 Vnext_defined_char_id = make_int (0x0F0000);
4609 DEFVAR_LISP ("char-db-stingy-mode", &Vchar_db_stingy_mode /*
4611 Vchar_db_stingy_mode = Qt;
4613 #ifdef HAVE_LIBCHISE
4614 Vchise_db_directory = build_string(chise_db_dir);
4615 DEFVAR_LISP ("chise-db-directory", &Vchise_db_directory /*
4616 Directory of CHISE character databases.
4619 Vchise_system_db_directory = build_string(chise_system_db_dir);
4620 DEFVAR_LISP ("chise-system-db-directory", &Vchise_system_db_directory /*
4621 Directory of system character database of CHISE.
4625 #endif /* HAVE_CHISE */
4626 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
4627 Vall_syntax_tables = Qnil;
4628 dump_add_weak_object_chain (&Vall_syntax_tables);
4632 structure_type_create_chartab (void)
4634 struct structure_type *st;
4636 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
4638 define_structure_type_keyword (st, Qtype, chartab_type_validate);
4639 define_structure_type_keyword (st, Qdata, chartab_data_validate);
4643 complex_vars_of_chartab (void)
4646 staticpro (&Vchar_attribute_hash_table);
4647 Vchar_attribute_hash_table
4648 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
4649 #endif /* UTF2000 */
4651 /* Set this now, so first buffer creation can refer to it. */
4652 /* Make it nil before calling copy-category-table
4653 so that copy-category-table will know not to try to copy from garbage */
4654 Vstandard_category_table = Qnil;
4655 Vstandard_category_table = Fcopy_category_table (Qnil);
4656 staticpro (&Vstandard_category_table);
4658 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
4659 List of pair (cons) of categories to determine word boundary.
4661 Emacs treats a sequence of word constituent characters as a single
4662 word (i.e. finds no word boundary between them) iff they belongs to
4663 the same charset. But, exceptions are allowed in the following cases.
4665 \(1) The case that characters are in different charsets is controlled
4666 by the variable `word-combining-categories'.
4668 Emacs finds no word boundary between characters of different charsets
4669 if they have categories matching some element of this list.
4671 More precisely, if an element of this list is a cons of category CAT1
4672 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4673 C2 which has CAT2, there's no word boundary between C1 and C2.
4675 For instance, to tell that ASCII characters and Latin-1 characters can
4676 form a single word, the element `(?l . ?l)' should be in this list
4677 because both characters have the category `l' (Latin characters).
4679 \(2) The case that character are in the same charset is controlled by
4680 the variable `word-separating-categories'.
4682 Emacs find a word boundary between characters of the same charset
4683 if they have categories matching some element of this list.
4685 More precisely, if an element of this list is a cons of category CAT1
4686 and CAT2, and a multibyte character C1 which has CAT1 is followed by
4687 C2 which has CAT2, there's a word boundary between C1 and C2.
4689 For instance, to tell that there's a word boundary between Japanese
4690 Hiragana and Japanese Kanji (both are in the same charset), the
4691 element `(?H . ?C) should be in this list.
4694 Vword_combining_categories = Qnil;
4696 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
4697 List of pair (cons) of categories to determine word boundary.
4698 See the documentation of the variable `word-combining-categories'.
4701 Vword_separating_categories = Qnil;