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 MORIOKA Tomohiko
9 This file is part of XEmacs.
11 XEmacs is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 XEmacs is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with XEmacs; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */
26 /* Synched up with: Mule 2.3. Not synched with FSF.
28 This file was written independently of the FSF implementation,
29 and is not compatible. */
33 Ben Wing: wrote, for 19.13 (Mule). Some category table stuff
34 loosely based on the original Mule.
35 Jareth Hein: fixed a couple of bugs in the implementation, and
36 added regex support for categories with check_category_at
49 Lisp_Object Vutf_2000_version;
52 Lisp_Object Qchar_tablep, Qchar_table;
54 Lisp_Object Vall_syntax_tables;
57 Lisp_Object Qcategory_table_p;
58 Lisp_Object Qcategory_designator_p;
59 Lisp_Object Qcategory_table_value_p;
61 Lisp_Object Vstandard_category_table;
63 /* Variables to determine word boundary. */
64 Lisp_Object Vword_combining_categories, Vword_separating_categories;
70 #define BT_UINT8_MIN 0
71 #define BT_UINT8_MAX (UCHAR_MAX - 3)
72 #define BT_UINT8_t (UCHAR_MAX - 2)
73 #define BT_UINT8_nil (UCHAR_MAX - 1)
74 #define BT_UINT8_unbound UCHAR_MAX
76 INLINE_HEADER int INT_UINT8_P (Lisp_Object obj);
77 INLINE_HEADER int UINT8_VALUE_P (Lisp_Object obj);
78 INLINE_HEADER unsigned char UINT8_ENCODE (Lisp_Object obj);
79 INLINE_HEADER Lisp_Object UINT8_DECODE (unsigned char n);
80 INLINE_HEADER unsigned short UINT8_TO_UINT16 (unsigned char n);
83 INT_UINT8_P (Lisp_Object obj)
89 return (BT_UINT8_MIN <= num) && (num <= BT_UINT8_MAX);
96 UINT8_VALUE_P (Lisp_Object obj)
98 return EQ (obj, Qunbound)
99 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT8_P (obj);
102 INLINE_HEADER unsigned char
103 UINT8_ENCODE (Lisp_Object obj)
105 if (EQ (obj, Qunbound))
106 return BT_UINT8_unbound;
107 else if (EQ (obj, Qnil))
109 else if (EQ (obj, Qt))
115 INLINE_HEADER Lisp_Object
116 UINT8_DECODE (unsigned char n)
118 if (n == BT_UINT8_unbound)
120 else if (n == BT_UINT8_nil)
122 else if (n == BT_UINT8_t)
129 mark_uint8_byte_table (Lisp_Object obj)
135 print_uint8_byte_table (Lisp_Object obj,
136 Lisp_Object printcharfun, int escapeflag)
138 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
140 struct gcpro gcpro1, gcpro2;
141 GCPRO2 (obj, printcharfun);
143 write_c_string ("\n#<uint8-byte-table", printcharfun);
144 for (i = 0; i < 256; i++)
146 unsigned char n = bte->property[i];
148 write_c_string ("\n ", printcharfun);
149 write_c_string (" ", printcharfun);
150 if (n == BT_UINT8_unbound)
151 write_c_string ("void", printcharfun);
152 else if (n == BT_UINT8_nil)
153 write_c_string ("nil", printcharfun);
154 else if (n == BT_UINT8_t)
155 write_c_string ("t", printcharfun);
160 sprintf (buf, "%hd", n);
161 write_c_string (buf, printcharfun);
165 write_c_string (">", printcharfun);
169 uint8_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
171 Lisp_Uint8_Byte_Table *te1 = XUINT8_BYTE_TABLE (obj1);
172 Lisp_Uint8_Byte_Table *te2 = XUINT8_BYTE_TABLE (obj2);
175 for (i = 0; i < 256; i++)
176 if (te1->property[i] != te2->property[i])
182 uint8_byte_table_hash (Lisp_Object obj, int depth)
184 Lisp_Uint8_Byte_Table *te = XUINT8_BYTE_TABLE (obj);
188 for (i = 0; i < 256; i++)
189 hash = HASH2 (hash, te->property[i]);
193 DEFINE_LRECORD_IMPLEMENTATION ("uint8-byte-table", uint8_byte_table,
194 mark_uint8_byte_table,
195 print_uint8_byte_table,
196 0, uint8_byte_table_equal,
197 uint8_byte_table_hash,
198 0 /* uint8_byte_table_description */,
199 Lisp_Uint8_Byte_Table);
202 make_uint8_byte_table (unsigned char initval)
206 Lisp_Uint8_Byte_Table *cte;
208 cte = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
209 &lrecord_uint8_byte_table);
211 for (i = 0; i < 256; i++)
212 cte->property[i] = initval;
214 XSETUINT8_BYTE_TABLE (obj, cte);
219 copy_uint8_byte_table (Lisp_Object entry)
221 Lisp_Uint8_Byte_Table *cte = XUINT8_BYTE_TABLE (entry);
224 Lisp_Uint8_Byte_Table *ctenew
225 = alloc_lcrecord_type (Lisp_Uint8_Byte_Table,
226 &lrecord_uint8_byte_table);
228 for (i = 0; i < 256; i++)
230 ctenew->property[i] = cte->property[i];
233 XSETUINT8_BYTE_TABLE (obj, ctenew);
238 uint8_byte_table_same_value_p (Lisp_Object obj)
240 Lisp_Uint8_Byte_Table *bte = XUINT8_BYTE_TABLE (obj);
241 unsigned char v0 = bte->property[0];
244 for (i = 1; i < 256; i++)
246 if (bte->property[i] != v0)
253 map_over_uint8_byte_table (Lisp_Uint8_Byte_Table *ct, Emchar ofs, int place,
254 int (*fn) (struct chartab_range *range,
255 Lisp_Object val, void *arg),
258 struct chartab_range rainj;
260 int unit = 1 << (8 * place);
264 rainj.type = CHARTAB_RANGE_CHAR;
266 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
268 if (ct->property[i] != BT_UINT8_unbound)
271 for (; c < c1 && retval == 0; c++)
274 retval = (fn) (&rainj, UINT8_DECODE (ct->property[i]), arg);
283 #define BT_UINT16_MIN 0
284 #define BT_UINT16_MAX (USHRT_MAX - 3)
285 #define BT_UINT16_t (USHRT_MAX - 2)
286 #define BT_UINT16_nil (USHRT_MAX - 1)
287 #define BT_UINT16_unbound USHRT_MAX
289 INLINE_HEADER int INT_UINT16_P (Lisp_Object obj);
290 INLINE_HEADER int UINT16_VALUE_P (Lisp_Object obj);
291 INLINE_HEADER unsigned short UINT16_ENCODE (Lisp_Object obj);
292 INLINE_HEADER Lisp_Object UINT16_DECODE (unsigned short us);
295 INT_UINT16_P (Lisp_Object obj)
299 int num = XINT (obj);
301 return (BT_UINT16_MIN <= num) && (num <= BT_UINT16_MAX);
308 UINT16_VALUE_P (Lisp_Object obj)
310 return EQ (obj, Qunbound)
311 || EQ (obj, Qnil) || EQ (obj, Qt) || INT_UINT16_P (obj);
314 INLINE_HEADER unsigned short
315 UINT16_ENCODE (Lisp_Object obj)
317 if (EQ (obj, Qunbound))
318 return BT_UINT16_unbound;
319 else if (EQ (obj, Qnil))
320 return BT_UINT16_nil;
321 else if (EQ (obj, Qt))
327 INLINE_HEADER Lisp_Object
328 UINT16_DECODE (unsigned short n)
330 if (n == BT_UINT16_unbound)
332 else if (n == BT_UINT16_nil)
334 else if (n == BT_UINT16_t)
340 INLINE_HEADER unsigned short
341 UINT8_TO_UINT16 (unsigned char n)
343 if (n == BT_UINT8_unbound)
344 return BT_UINT16_unbound;
345 else if (n == BT_UINT8_nil)
346 return BT_UINT16_nil;
347 else if (n == BT_UINT8_t)
354 mark_uint16_byte_table (Lisp_Object obj)
360 print_uint16_byte_table (Lisp_Object obj,
361 Lisp_Object printcharfun, int escapeflag)
363 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
365 struct gcpro gcpro1, gcpro2;
366 GCPRO2 (obj, printcharfun);
368 write_c_string ("\n#<uint16-byte-table", printcharfun);
369 for (i = 0; i < 256; i++)
371 unsigned short n = bte->property[i];
373 write_c_string ("\n ", printcharfun);
374 write_c_string (" ", printcharfun);
375 if (n == BT_UINT16_unbound)
376 write_c_string ("void", printcharfun);
377 else if (n == BT_UINT16_nil)
378 write_c_string ("nil", printcharfun);
379 else if (n == BT_UINT16_t)
380 write_c_string ("t", printcharfun);
385 sprintf (buf, "%hd", n);
386 write_c_string (buf, printcharfun);
390 write_c_string (">", printcharfun);
394 uint16_byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
396 Lisp_Uint16_Byte_Table *te1 = XUINT16_BYTE_TABLE (obj1);
397 Lisp_Uint16_Byte_Table *te2 = XUINT16_BYTE_TABLE (obj2);
400 for (i = 0; i < 256; i++)
401 if (te1->property[i] != te2->property[i])
407 uint16_byte_table_hash (Lisp_Object obj, int depth)
409 Lisp_Uint16_Byte_Table *te = XUINT16_BYTE_TABLE (obj);
413 for (i = 0; i < 256; i++)
414 hash = HASH2 (hash, te->property[i]);
418 DEFINE_LRECORD_IMPLEMENTATION ("uint16-byte-table", uint16_byte_table,
419 mark_uint16_byte_table,
420 print_uint16_byte_table,
421 0, uint16_byte_table_equal,
422 uint16_byte_table_hash,
423 0 /* uint16_byte_table_description */,
424 Lisp_Uint16_Byte_Table);
427 make_uint16_byte_table (unsigned short initval)
431 Lisp_Uint16_Byte_Table *cte;
433 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
434 &lrecord_uint16_byte_table);
436 for (i = 0; i < 256; i++)
437 cte->property[i] = initval;
439 XSETUINT16_BYTE_TABLE (obj, cte);
444 copy_uint16_byte_table (Lisp_Object entry)
446 Lisp_Uint16_Byte_Table *cte = XUINT16_BYTE_TABLE (entry);
449 Lisp_Uint16_Byte_Table *ctenew
450 = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
451 &lrecord_uint16_byte_table);
453 for (i = 0; i < 256; i++)
455 ctenew->property[i] = cte->property[i];
458 XSETUINT16_BYTE_TABLE (obj, ctenew);
463 expand_uint8_byte_table_to_uint16 (Lisp_Object table)
467 Lisp_Uint8_Byte_Table* bte = XUINT8_BYTE_TABLE(table);
468 Lisp_Uint16_Byte_Table* cte;
470 cte = alloc_lcrecord_type (Lisp_Uint16_Byte_Table,
471 &lrecord_uint16_byte_table);
472 for (i = 0; i < 256; i++)
474 cte->property[i] = UINT8_TO_UINT16 (bte->property[i]);
476 XSETUINT16_BYTE_TABLE (obj, cte);
481 uint16_byte_table_same_value_p (Lisp_Object obj)
483 Lisp_Uint16_Byte_Table *bte = XUINT16_BYTE_TABLE (obj);
484 unsigned short v0 = bte->property[0];
487 for (i = 1; i < 256; i++)
489 if (bte->property[i] != v0)
496 map_over_uint16_byte_table (Lisp_Uint16_Byte_Table *ct, Emchar ofs, int place,
497 int (*fn) (struct chartab_range *range,
498 Lisp_Object val, void *arg),
501 struct chartab_range rainj;
503 int unit = 1 << (8 * place);
507 rainj.type = CHARTAB_RANGE_CHAR;
509 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
511 if (ct->property[i] != BT_UINT16_unbound)
514 for (; c < c1 && retval == 0; c++)
517 retval = (fn) (&rainj, UINT16_DECODE (ct->property[i]), arg);
528 mark_byte_table (Lisp_Object obj)
530 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
533 for (i = 0; i < 256; i++)
535 mark_object (cte->property[i]);
541 print_byte_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
543 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
545 struct gcpro gcpro1, gcpro2;
546 GCPRO2 (obj, printcharfun);
548 write_c_string ("\n#<byte-table", printcharfun);
549 for (i = 0; i < 256; i++)
551 Lisp_Object elt = bte->property[i];
553 write_c_string ("\n ", printcharfun);
554 write_c_string (" ", printcharfun);
555 if (EQ (elt, Qunbound))
556 write_c_string ("void", printcharfun);
558 print_internal (elt, printcharfun, escapeflag);
561 write_c_string (">", printcharfun);
565 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
567 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
568 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
571 for (i = 0; i < 256; i++)
572 if (BYTE_TABLE_P (cte1->property[i]))
574 if (BYTE_TABLE_P (cte2->property[i]))
576 if (!byte_table_equal (cte1->property[i],
577 cte2->property[i], depth + 1))
584 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
590 byte_table_hash (Lisp_Object obj, int depth)
592 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
594 return internal_array_hash (cte->property, 256, depth);
597 static const struct lrecord_description byte_table_description[] = {
598 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
602 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
607 byte_table_description,
611 make_byte_table (Lisp_Object initval)
615 Lisp_Byte_Table *cte;
617 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
619 for (i = 0; i < 256; i++)
620 cte->property[i] = initval;
622 XSETBYTE_TABLE (obj, cte);
627 copy_byte_table (Lisp_Object entry)
629 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
632 Lisp_Byte_Table *ctnew
633 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
635 for (i = 0; i < 256; i++)
637 if (UINT8_BYTE_TABLE_P (cte->property[i]))
639 ctnew->property[i] = copy_uint8_byte_table (cte->property[i]);
641 else if (UINT16_BYTE_TABLE_P (cte->property[i]))
643 ctnew->property[i] = copy_uint16_byte_table (cte->property[i]);
645 else if (BYTE_TABLE_P (cte->property[i]))
647 ctnew->property[i] = copy_byte_table (cte->property[i]);
650 ctnew->property[i] = cte->property[i];
653 XSETBYTE_TABLE (obj, ctnew);
658 byte_table_same_value_p (Lisp_Object obj)
660 Lisp_Byte_Table *bte = XBYTE_TABLE (obj);
661 Lisp_Object v0 = bte->property[0];
664 for (i = 1; i < 256; i++)
666 if (!internal_equal (bte->property[i], v0, 0))
673 map_over_byte_table (Lisp_Byte_Table *ct, Emchar ofs, int place,
674 int (*fn) (struct chartab_range *range,
675 Lisp_Object val, void *arg),
680 int unit = 1 << (8 * place);
683 for (i = 0, retval = 0; i < 256 && retval == 0; i++)
686 if (UINT8_BYTE_TABLE_P (v))
689 = map_over_uint8_byte_table (XUINT8_BYTE_TABLE(v),
690 c, place - 1, fn, arg);
693 else if (UINT16_BYTE_TABLE_P (v))
696 = map_over_uint16_byte_table (XUINT16_BYTE_TABLE(v),
697 c, place - 1, fn, arg);
700 else if (BYTE_TABLE_P (v))
702 retval = map_over_byte_table (XBYTE_TABLE(v),
703 c, place - 1, fn, arg);
706 else if (!UNBOUNDP (v))
708 struct chartab_range rainj;
709 Emchar c1 = c + unit;
711 rainj.type = CHARTAB_RANGE_CHAR;
713 for (; c < c1 && retval == 0; c++)
716 retval = (fn) (&rainj, v, arg);
727 get_byte_table (Lisp_Object table, unsigned char idx)
729 if (UINT8_BYTE_TABLE_P (table))
730 return UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[idx]);
731 else if (UINT16_BYTE_TABLE_P (table))
732 return UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[idx]);
733 else if (BYTE_TABLE_P (table))
734 return XBYTE_TABLE(table)->property[idx];
740 put_byte_table (Lisp_Object table, unsigned char idx, Lisp_Object value)
742 if (UINT8_BYTE_TABLE_P (table))
744 if (UINT8_VALUE_P (value))
746 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
747 if (!UINT8_BYTE_TABLE_P (value) &&
748 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
749 && uint8_byte_table_same_value_p (table))
754 else if (UINT16_VALUE_P (value))
756 Lisp_Object new = expand_uint8_byte_table_to_uint16 (table);
758 XUINT16_BYTE_TABLE(new)->property[idx] = UINT16_ENCODE (value);
763 Lisp_Object new = make_byte_table (Qnil);
766 for (i = 0; i < 256; i++)
768 XBYTE_TABLE(new)->property[i]
769 = UINT8_DECODE (XUINT8_BYTE_TABLE(table)->property[i]);
771 XBYTE_TABLE(new)->property[idx] = value;
775 else if (UINT16_BYTE_TABLE_P (table))
777 if (UINT16_VALUE_P (value))
779 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
780 if (!UINT8_BYTE_TABLE_P (value) &&
781 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
782 && uint16_byte_table_same_value_p (table))
789 Lisp_Object new = make_byte_table (Qnil);
792 for (i = 0; i < 256; i++)
794 XBYTE_TABLE(new)->property[i]
795 = UINT16_DECODE (XUINT16_BYTE_TABLE(table)->property[i]);
797 XBYTE_TABLE(new)->property[idx] = value;
801 else if (BYTE_TABLE_P (table))
803 XBYTE_TABLE(table)->property[idx] = value;
804 if (!UINT8_BYTE_TABLE_P (value) &&
805 !UINT16_BYTE_TABLE_P (value) && !BYTE_TABLE_P (value)
806 && byte_table_same_value_p (table))
811 else if (!internal_equal (table, value, 0))
813 if (UINT8_VALUE_P (table) && UINT8_VALUE_P (value))
815 table = make_uint8_byte_table (UINT8_ENCODE (table));
816 XUINT8_BYTE_TABLE(table)->property[idx] = UINT8_ENCODE (value);
818 else if (UINT16_VALUE_P (table) && UINT16_VALUE_P (value))
820 table = make_uint16_byte_table (UINT16_ENCODE (table));
821 XUINT16_BYTE_TABLE(table)->property[idx] = UINT16_ENCODE (value);
825 table = make_byte_table (table);
826 XBYTE_TABLE(table)->property[idx] = value;
834 make_char_id_table (Lisp_Object initval)
837 obj = Fmake_char_table (Qgeneric);
838 fill_char_table (XCHAR_TABLE (obj), initval);
843 get_char_id_table (Lisp_Char_Table* cit, Emchar ch)
845 Lisp_Object val = get_byte_table (get_byte_table
849 (unsigned char)(ch >> 24)),
850 (unsigned char) (ch >> 16)),
851 (unsigned char) (ch >> 8)),
854 return cit->default_value;
860 Lisp_Object Vcharacter_composition_table;
861 Lisp_Object Vcharacter_variant_table;
864 Lisp_Object Q_decomposition;
868 Lisp_Object Qisolated;
869 Lisp_Object Qinitial;
872 Lisp_Object Qvertical;
873 Lisp_Object QnoBreak;
874 Lisp_Object Qfraction;
884 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
887 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
893 else if (EQ (v, Qcompat))
895 else if (EQ (v, Qisolated))
897 else if (EQ (v, Qinitial))
899 else if (EQ (v, Qmedial))
901 else if (EQ (v, Qfinal))
903 else if (EQ (v, Qvertical))
905 else if (EQ (v, QnoBreak))
907 else if (EQ (v, Qfraction))
909 else if (EQ (v, Qsuper))
911 else if (EQ (v, Qsub))
913 else if (EQ (v, Qcircle))
915 else if (EQ (v, Qsquare))
917 else if (EQ (v, Qwide))
919 else if (EQ (v, Qnarrow))
921 else if (EQ (v, Qsmall))
923 else if (EQ (v, Qfont))
926 signal_simple_error (err_msg, err_arg);
929 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
930 Return character corresponding with list.
934 Lisp_Object table = Vcharacter_composition_table;
935 Lisp_Object rest = list;
939 Lisp_Object v = Fcar (rest);
941 Emchar c = to_char_id (v, "Invalid value for composition", list);
943 ret = get_char_id_table (XCHAR_TABLE(table), c);
948 if (!CHAR_TABLEP (ret))
953 else if (!CONSP (rest))
955 else if (CHAR_TABLEP (ret))
958 signal_simple_error ("Invalid table is found with", list);
960 signal_simple_error ("Invalid value for composition", list);
963 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
964 Return variants of CHARACTER.
968 CHECK_CHAR (character);
969 return Fcopy_list (get_char_id_table
970 (XCHAR_TABLE(Vcharacter_variant_table),
977 /* A char table maps from ranges of characters to values.
979 Implementing a general data structure that maps from arbitrary
980 ranges of numbers to values is tricky to do efficiently. As it
981 happens, it should suffice (and is usually more convenient, anyway)
982 when dealing with characters to restrict the sorts of ranges that
983 can be assigned values, as follows:
986 2) All characters in a charset.
987 3) All characters in a particular row of a charset, where a "row"
988 means all characters with the same first byte.
989 4) A particular character in a charset.
991 We use char tables to generalize the 256-element vectors now
992 littering the Emacs code.
994 Possible uses (all should be converted at some point):
1000 5) keyboard-translate-table?
1003 abstract type to generalize the Emacs vectors and Mule
1004 vectors-of-vectors goo.
1007 /************************************************************************/
1008 /* Char Table object */
1009 /************************************************************************/
1011 #if defined(MULE)&&!defined(UTF2000)
1014 mark_char_table_entry (Lisp_Object obj)
1016 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1019 for (i = 0; i < 96; i++)
1021 mark_object (cte->level2[i]);
1027 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1029 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
1030 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
1033 for (i = 0; i < 96; i++)
1034 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
1040 static unsigned long
1041 char_table_entry_hash (Lisp_Object obj, int depth)
1043 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
1045 return internal_array_hash (cte->level2, 96, depth);
1048 static const struct lrecord_description char_table_entry_description[] = {
1049 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
1053 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
1054 mark_char_table_entry, internal_object_printer,
1055 0, char_table_entry_equal,
1056 char_table_entry_hash,
1057 char_table_entry_description,
1058 Lisp_Char_Table_Entry);
1062 mark_char_table (Lisp_Object obj)
1064 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1067 mark_object (ct->table);
1071 for (i = 0; i < NUM_ASCII_CHARS; i++)
1072 mark_object (ct->ascii[i]);
1074 for (i = 0; i < NUM_LEADING_BYTES; i++)
1075 mark_object (ct->level1[i]);
1079 return ct->default_value;
1081 return ct->mirror_table;
1085 /* WARNING: All functions of this nature need to be written extremely
1086 carefully to avoid crashes during GC. Cf. prune_specifiers()
1087 and prune_weak_hash_tables(). */
1090 prune_syntax_tables (void)
1092 Lisp_Object rest, prev = Qnil;
1094 for (rest = Vall_syntax_tables;
1096 rest = XCHAR_TABLE (rest)->next_table)
1098 if (! marked_p (rest))
1100 /* This table is garbage. Remove it from the list. */
1102 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
1104 XCHAR_TABLE (prev)->next_table =
1105 XCHAR_TABLE (rest)->next_table;
1111 char_table_type_to_symbol (enum char_table_type type)
1116 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
1117 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
1118 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
1119 case CHAR_TABLE_TYPE_CHAR: return Qchar;
1121 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
1126 static enum char_table_type
1127 symbol_to_char_table_type (Lisp_Object symbol)
1129 CHECK_SYMBOL (symbol);
1131 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
1132 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
1133 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
1134 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
1136 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
1139 signal_simple_error ("Unrecognized char table type", symbol);
1140 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
1144 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
1145 Lisp_Object printcharfun)
1149 write_c_string (" (", printcharfun);
1150 print_internal (make_char (first), printcharfun, 0);
1151 write_c_string (" ", printcharfun);
1152 print_internal (make_char (last), printcharfun, 0);
1153 write_c_string (") ", printcharfun);
1157 write_c_string (" ", printcharfun);
1158 print_internal (make_char (first), printcharfun, 0);
1159 write_c_string (" ", printcharfun);
1161 print_internal (val, printcharfun, 1);
1164 #if defined(MULE)&&!defined(UTF2000)
1167 print_chartab_charset_row (Lisp_Object charset,
1169 Lisp_Char_Table_Entry *cte,
1170 Lisp_Object printcharfun)
1173 Lisp_Object cat = Qunbound;
1176 for (i = 32; i < 128; i++)
1178 Lisp_Object pam = cte->level2[i - 32];
1190 print_chartab_range (MAKE_CHAR (charset, first, 0),
1191 MAKE_CHAR (charset, i - 1, 0),
1194 print_chartab_range (MAKE_CHAR (charset, row, first),
1195 MAKE_CHAR (charset, row, i - 1),
1205 print_chartab_range (MAKE_CHAR (charset, first, 0),
1206 MAKE_CHAR (charset, i - 1, 0),
1209 print_chartab_range (MAKE_CHAR (charset, row, first),
1210 MAKE_CHAR (charset, row, i - 1),
1216 print_chartab_two_byte_charset (Lisp_Object charset,
1217 Lisp_Char_Table_Entry *cte,
1218 Lisp_Object printcharfun)
1222 for (i = 32; i < 128; i++)
1224 Lisp_Object jen = cte->level2[i - 32];
1226 if (!CHAR_TABLE_ENTRYP (jen))
1230 write_c_string (" [", printcharfun);
1231 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
1232 sprintf (buf, " %d] ", i);
1233 write_c_string (buf, printcharfun);
1234 print_internal (jen, printcharfun, 0);
1237 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
1245 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1247 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1250 struct gcpro gcpro1, gcpro2;
1251 GCPRO2 (obj, printcharfun);
1253 write_c_string ("#s(char-table ", printcharfun);
1254 write_c_string (" ", printcharfun);
1255 write_c_string (string_data
1257 (XSYMBOL (char_table_type_to_symbol (ct->type)))),
1259 write_c_string ("\n ", printcharfun);
1260 print_internal (ct->default_value, printcharfun, escapeflag);
1261 for (i = 0; i < 256; i++)
1263 Lisp_Object elt = get_byte_table (ct->table, i);
1264 if (i != 0) write_c_string ("\n ", printcharfun);
1265 if (EQ (elt, Qunbound))
1266 write_c_string ("void", printcharfun);
1268 print_internal (elt, printcharfun, escapeflag);
1271 #else /* non UTF2000 */
1274 sprintf (buf, "#s(char-table type %s data (",
1275 string_data (symbol_name (XSYMBOL
1276 (char_table_type_to_symbol (ct->type)))));
1277 write_c_string (buf, printcharfun);
1279 /* Now write out the ASCII/Control-1 stuff. */
1283 Lisp_Object val = Qunbound;
1285 for (i = 0; i < NUM_ASCII_CHARS; i++)
1294 if (!EQ (ct->ascii[i], val))
1296 print_chartab_range (first, i - 1, val, printcharfun);
1303 print_chartab_range (first, i - 1, val, printcharfun);
1310 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1313 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
1314 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
1316 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
1317 || i == LEADING_BYTE_CONTROL_1)
1319 if (!CHAR_TABLE_ENTRYP (ann))
1321 write_c_string (" ", printcharfun);
1322 print_internal (XCHARSET_NAME (charset),
1324 write_c_string (" ", printcharfun);
1325 print_internal (ann, printcharfun, 0);
1329 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
1330 if (XCHARSET_DIMENSION (charset) == 1)
1331 print_chartab_charset_row (charset, -1, cte, printcharfun);
1333 print_chartab_two_byte_charset (charset, cte, printcharfun);
1338 #endif /* non UTF2000 */
1340 write_c_string ("))", printcharfun);
1344 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1346 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
1347 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
1350 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
1354 for (i = 0; i < 256; i++)
1356 if (!internal_equal (get_byte_table (ct1->table, i),
1357 get_byte_table (ct2->table, i), 0))
1361 for (i = 0; i < NUM_ASCII_CHARS; i++)
1362 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
1366 for (i = 0; i < NUM_LEADING_BYTES; i++)
1367 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
1370 #endif /* non UTF2000 */
1375 static unsigned long
1376 char_table_hash (Lisp_Object obj, int depth)
1378 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
1380 return byte_table_hash (ct->table, depth + 1);
1382 unsigned long hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
1385 hashval = HASH2 (hashval,
1386 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
1392 static const struct lrecord_description char_table_description[] = {
1394 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, table) },
1395 { XD_LISP_OBJECT, offsetof(Lisp_Char_Table, default_value) },
1397 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
1399 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
1403 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
1405 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
1409 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
1410 mark_char_table, print_char_table, 0,
1411 char_table_equal, char_table_hash,
1412 char_table_description,
1415 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
1416 Return non-nil if OBJECT is a char table.
1418 A char table is a table that maps characters (or ranges of characters)
1419 to values. Char tables are specialized for characters, only allowing
1420 particular sorts of ranges to be assigned values. Although this
1421 loses in generality, it makes for extremely fast (constant-time)
1422 lookups, and thus is feasible for applications that do an extremely
1423 large number of lookups (e.g. scanning a buffer for a character in
1424 a particular syntax, where a lookup in the syntax table must occur
1425 once per character).
1427 When Mule support exists, the types of ranges that can be assigned
1431 -- an entire charset
1432 -- a single row in a two-octet charset
1433 -- a single character
1435 When Mule support is not present, the types of ranges that can be
1439 -- a single character
1441 To create a char table, use `make-char-table'.
1442 To modify a char table, use `put-char-table' or `remove-char-table'.
1443 To retrieve the value for a particular character, use `get-char-table'.
1444 See also `map-char-table', `clear-char-table', `copy-char-table',
1445 `valid-char-table-type-p', `char-table-type-list',
1446 `valid-char-table-value-p', and `check-char-table-value'.
1450 return CHAR_TABLEP (object) ? Qt : Qnil;
1453 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
1454 Return a list of the recognized char table types.
1455 See `valid-char-table-type-p'.
1460 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
1462 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
1466 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
1467 Return t if TYPE if a recognized char table type.
1469 Each char table type is used for a different purpose and allows different
1470 sorts of values. The different char table types are
1473 Used for category tables, which specify the regexp categories
1474 that a character is in. The valid values are nil or a
1475 bit vector of 95 elements. Higher-level Lisp functions are
1476 provided for working with category tables. Currently categories
1477 and category tables only exist when Mule support is present.
1479 A generalized char table, for mapping from one character to
1480 another. Used for case tables, syntax matching tables,
1481 `keyboard-translate-table', etc. The valid values are characters.
1483 An even more generalized char table, for mapping from a
1484 character to anything.
1486 Used for display tables, which specify how a particular character
1487 is to appear when displayed. #### Not yet implemented.
1489 Used for syntax tables, which specify the syntax of a particular
1490 character. Higher-level Lisp functions are provided for
1491 working with syntax tables. The valid values are integers.
1496 return (EQ (type, Qchar) ||
1498 EQ (type, Qcategory) ||
1500 EQ (type, Qdisplay) ||
1501 EQ (type, Qgeneric) ||
1502 EQ (type, Qsyntax)) ? Qt : Qnil;
1505 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
1506 Return the type of CHAR-TABLE.
1507 See `valid-char-table-type-p'.
1511 CHECK_CHAR_TABLE (char_table);
1512 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
1516 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
1519 ct->table = Qunbound;
1520 ct->default_value = value;
1524 for (i = 0; i < NUM_ASCII_CHARS; i++)
1525 ct->ascii[i] = value;
1527 for (i = 0; i < NUM_LEADING_BYTES; i++)
1528 ct->level1[i] = value;
1533 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
1534 update_syntax_table (ct);
1538 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
1539 Reset CHAR-TABLE to its default state.
1543 Lisp_Char_Table *ct;
1545 CHECK_CHAR_TABLE (char_table);
1546 ct = XCHAR_TABLE (char_table);
1550 case CHAR_TABLE_TYPE_CHAR:
1551 fill_char_table (ct, make_char (0));
1553 case CHAR_TABLE_TYPE_DISPLAY:
1554 case CHAR_TABLE_TYPE_GENERIC:
1556 case CHAR_TABLE_TYPE_CATEGORY:
1558 fill_char_table (ct, Qnil);
1561 case CHAR_TABLE_TYPE_SYNTAX:
1562 fill_char_table (ct, make_int (Sinherit));
1572 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
1573 Return a new, empty char table of type TYPE.
1574 Currently recognized types are 'char, 'category, 'display, 'generic,
1575 and 'syntax. See `valid-char-table-type-p'.
1579 Lisp_Char_Table *ct;
1581 enum char_table_type ty = symbol_to_char_table_type (type);
1583 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1586 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1588 ct->mirror_table = Fmake_char_table (Qgeneric);
1589 fill_char_table (XCHAR_TABLE (ct->mirror_table),
1593 ct->mirror_table = Qnil;
1595 ct->next_table = Qnil;
1596 XSETCHAR_TABLE (obj, ct);
1597 if (ty == CHAR_TABLE_TYPE_SYNTAX)
1599 ct->next_table = Vall_syntax_tables;
1600 Vall_syntax_tables = obj;
1602 Freset_char_table (obj);
1606 #if defined(MULE)&&!defined(UTF2000)
1609 make_char_table_entry (Lisp_Object initval)
1613 Lisp_Char_Table_Entry *cte =
1614 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1616 for (i = 0; i < 96; i++)
1617 cte->level2[i] = initval;
1619 XSETCHAR_TABLE_ENTRY (obj, cte);
1624 copy_char_table_entry (Lisp_Object entry)
1626 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
1629 Lisp_Char_Table_Entry *ctenew =
1630 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
1632 for (i = 0; i < 96; i++)
1634 Lisp_Object new = cte->level2[i];
1635 if (CHAR_TABLE_ENTRYP (new))
1636 ctenew->level2[i] = copy_char_table_entry (new);
1638 ctenew->level2[i] = new;
1641 XSETCHAR_TABLE_ENTRY (obj, ctenew);
1647 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
1648 Return a new char table which is a copy of CHAR-TABLE.
1649 It will contain the same values for the same characters and ranges
1650 as CHAR-TABLE. The values will not themselves be copied.
1654 Lisp_Char_Table *ct, *ctnew;
1660 CHECK_CHAR_TABLE (char_table);
1661 ct = XCHAR_TABLE (char_table);
1662 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
1663 ctnew->type = ct->type;
1665 ctnew->default_value = ct->default_value;
1667 if (UINT8_BYTE_TABLE_P (ct->table))
1669 ctnew->table = copy_uint8_byte_table (ct->table);
1671 else if (UINT16_BYTE_TABLE_P (ct->table))
1673 ctnew->table = copy_uint16_byte_table (ct->table);
1675 else if (BYTE_TABLE_P (ct->table))
1677 ctnew->table = copy_byte_table (ct->table);
1679 else if (!UNBOUNDP (ct->table))
1680 ctnew->table = ct->table;
1681 #else /* non UTF2000 */
1683 for (i = 0; i < NUM_ASCII_CHARS; i++)
1685 Lisp_Object new = ct->ascii[i];
1687 assert (! (CHAR_TABLE_ENTRYP (new)));
1689 ctnew->ascii[i] = new;
1694 for (i = 0; i < NUM_LEADING_BYTES; i++)
1696 Lisp_Object new = ct->level1[i];
1697 if (CHAR_TABLE_ENTRYP (new))
1698 ctnew->level1[i] = copy_char_table_entry (new);
1700 ctnew->level1[i] = new;
1704 #endif /* non UTF2000 */
1707 if (CHAR_TABLEP (ct->mirror_table))
1708 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
1710 ctnew->mirror_table = ct->mirror_table;
1712 ctnew->next_table = Qnil;
1713 XSETCHAR_TABLE (obj, ctnew);
1714 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
1716 ctnew->next_table = Vall_syntax_tables;
1717 Vall_syntax_tables = obj;
1726 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
1729 outrange->type = CHARTAB_RANGE_ALL;
1730 else if (EQ (range, Qnil))
1731 outrange->type = CHARTAB_RANGE_DEFAULT;
1732 else if (CHAR_OR_CHAR_INTP (range))
1734 outrange->type = CHARTAB_RANGE_CHAR;
1735 outrange->ch = XCHAR_OR_CHAR_INT (range);
1739 signal_simple_error ("Range must be t or a character", range);
1741 else if (VECTORP (range))
1743 Lisp_Vector *vec = XVECTOR (range);
1744 Lisp_Object *elts = vector_data (vec);
1745 if (vector_length (vec) != 2)
1746 signal_simple_error ("Length of charset row vector must be 2",
1748 outrange->type = CHARTAB_RANGE_ROW;
1749 outrange->charset = Fget_charset (elts[0]);
1750 CHECK_INT (elts[1]);
1751 outrange->row = XINT (elts[1]);
1752 if (XCHARSET_DIMENSION (outrange->charset) >= 2)
1754 switch (XCHARSET_CHARS (outrange->charset))
1757 check_int_range (outrange->row, 33, 126);
1760 check_int_range (outrange->row, 32, 127);
1767 signal_simple_error ("Charset in row vector must be multi-byte",
1772 if (!CHARSETP (range) && !SYMBOLP (range))
1774 ("Char table range must be t, charset, char, or vector", range);
1775 outrange->type = CHARTAB_RANGE_CHARSET;
1776 outrange->charset = Fget_charset (range);
1781 #if defined(MULE)&&!defined(UTF2000)
1783 /* called from CHAR_TABLE_VALUE(). */
1785 get_non_ascii_char_table_value (Lisp_Char_Table *ct, Charset_ID leading_byte,
1790 Lisp_Object charset;
1792 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
1797 BREAKUP_CHAR (c, charset, byte1, byte2);
1799 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
1801 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
1802 if (CHAR_TABLE_ENTRYP (val))
1804 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
1805 val = cte->level2[byte1 - 32];
1806 if (CHAR_TABLE_ENTRYP (val))
1808 cte = XCHAR_TABLE_ENTRY (val);
1809 assert (byte2 >= 32);
1810 val = cte->level2[byte2 - 32];
1811 assert (!CHAR_TABLE_ENTRYP (val));
1821 get_char_table (Emchar ch, Lisp_Char_Table *ct)
1824 Lisp_Object val = get_byte_table (get_byte_table
1828 (unsigned char)(ch >> 24)),
1829 (unsigned char) (ch >> 16)),
1830 (unsigned char) (ch >> 8)),
1831 (unsigned char) ch);
1833 return ct->default_value;
1838 Lisp_Object charset;
1842 BREAKUP_CHAR (ch, charset, byte1, byte2);
1844 if (EQ (charset, Vcharset_ascii))
1845 val = ct->ascii[byte1];
1846 else if (EQ (charset, Vcharset_control_1))
1847 val = ct->ascii[byte1 + 128];
1850 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
1851 val = ct->level1[lb];
1852 if (CHAR_TABLE_ENTRYP (val))
1854 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
1855 val = cte->level2[byte1 - 32];
1856 if (CHAR_TABLE_ENTRYP (val))
1858 cte = XCHAR_TABLE_ENTRY (val);
1859 assert (byte2 >= 32);
1860 val = cte->level2[byte2 - 32];
1861 assert (!CHAR_TABLE_ENTRYP (val));
1868 #else /* not MULE */
1869 return ct->ascii[(unsigned char)ch];
1870 #endif /* not MULE */
1874 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
1875 Find value for CHARACTER in CHAR-TABLE.
1877 (character, char_table))
1879 CHECK_CHAR_TABLE (char_table);
1880 CHECK_CHAR_COERCE_INT (character);
1882 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
1885 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
1886 Find value for a range in CHAR-TABLE.
1887 If there is more than one value, return MULTI (defaults to nil).
1889 (range, char_table, multi))
1891 Lisp_Char_Table *ct;
1892 struct chartab_range rainj;
1894 if (CHAR_OR_CHAR_INTP (range))
1895 return Fget_char_table (range, char_table);
1896 CHECK_CHAR_TABLE (char_table);
1897 ct = XCHAR_TABLE (char_table);
1899 decode_char_table_range (range, &rainj);
1902 case CHARTAB_RANGE_ALL:
1905 if (UINT8_BYTE_TABLE_P (ct->table))
1907 else if (UINT16_BYTE_TABLE_P (ct->table))
1909 else if (BYTE_TABLE_P (ct->table))
1913 #else /* non UTF2000 */
1915 Lisp_Object first = ct->ascii[0];
1917 for (i = 1; i < NUM_ASCII_CHARS; i++)
1918 if (!EQ (first, ct->ascii[i]))
1922 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
1925 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
1926 || i == LEADING_BYTE_ASCII
1927 || i == LEADING_BYTE_CONTROL_1)
1929 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
1935 #endif /* non UTF2000 */
1939 case CHARTAB_RANGE_CHARSET:
1943 if (EQ (rainj.charset, Vcharset_ascii))
1946 Lisp_Object first = ct->ascii[0];
1948 for (i = 1; i < 128; i++)
1949 if (!EQ (first, ct->ascii[i]))
1954 if (EQ (rainj.charset, Vcharset_control_1))
1957 Lisp_Object first = ct->ascii[128];
1959 for (i = 129; i < 160; i++)
1960 if (!EQ (first, ct->ascii[i]))
1966 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
1968 if (CHAR_TABLE_ENTRYP (val))
1974 case CHARTAB_RANGE_ROW:
1979 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
1981 if (!CHAR_TABLE_ENTRYP (val))
1983 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
1984 if (CHAR_TABLE_ENTRYP (val))
1988 #endif /* not UTF2000 */
1989 #endif /* not MULE */
1995 return Qnil; /* not reached */
1999 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
2000 Error_behavior errb)
2004 case CHAR_TABLE_TYPE_SYNTAX:
2005 if (!ERRB_EQ (errb, ERROR_ME))
2006 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
2007 && CHAR_OR_CHAR_INTP (XCDR (value)));
2010 Lisp_Object cdr = XCDR (value);
2011 CHECK_INT (XCAR (value));
2012 CHECK_CHAR_COERCE_INT (cdr);
2019 case CHAR_TABLE_TYPE_CATEGORY:
2020 if (!ERRB_EQ (errb, ERROR_ME))
2021 return CATEGORY_TABLE_VALUEP (value);
2022 CHECK_CATEGORY_TABLE_VALUE (value);
2026 case CHAR_TABLE_TYPE_GENERIC:
2029 case CHAR_TABLE_TYPE_DISPLAY:
2031 maybe_signal_simple_error ("Display char tables not yet implemented",
2032 value, Qchar_table, errb);
2035 case CHAR_TABLE_TYPE_CHAR:
2036 if (!ERRB_EQ (errb, ERROR_ME))
2037 return CHAR_OR_CHAR_INTP (value);
2038 CHECK_CHAR_COERCE_INT (value);
2045 return 0; /* not reached */
2049 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
2053 case CHAR_TABLE_TYPE_SYNTAX:
2056 Lisp_Object car = XCAR (value);
2057 Lisp_Object cdr = XCDR (value);
2058 CHECK_CHAR_COERCE_INT (cdr);
2059 return Fcons (car, cdr);
2062 case CHAR_TABLE_TYPE_CHAR:
2063 CHECK_CHAR_COERCE_INT (value);
2071 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
2072 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
2074 (value, char_table_type))
2076 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2078 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
2081 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
2082 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
2084 (value, char_table_type))
2086 enum char_table_type type = symbol_to_char_table_type (char_table_type);
2088 check_valid_char_table_value (value, type, ERROR_ME);
2092 /* Assign VAL to all characters in RANGE in char table CT. */
2095 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
2098 switch (range->type)
2100 case CHARTAB_RANGE_ALL:
2101 /* printf ("put-char-table: range = all\n"); */
2102 fill_char_table (ct, val);
2103 return; /* avoid the duplicate call to update_syntax_table() below,
2104 since fill_char_table() also did that. */
2107 case CHARTAB_RANGE_DEFAULT:
2108 ct->default_value = val;
2113 case CHARTAB_RANGE_CHARSET:
2117 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (range->charset);
2119 /* printf ("put-char-table: range = charset: %d\n",
2120 XCHARSET_LEADING_BYTE (range->charset));
2122 if ( CHAR_TABLEP (encoding_table) )
2124 for (c = 0; c < 1 << 24; c++)
2126 if ( INTP (get_char_id_table (XCHAR_TABLE(encoding_table),
2128 put_char_id_table_0 (ct, c, val);
2133 for (c = 0; c < 1 << 24; c++)
2135 if ( charset_code_point (range->charset, c) >= 0 )
2136 put_char_id_table_0 (ct, c, val);
2141 if (EQ (range->charset, Vcharset_ascii))
2144 for (i = 0; i < 128; i++)
2147 else if (EQ (range->charset, Vcharset_control_1))
2150 for (i = 128; i < 160; i++)
2155 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2156 ct->level1[lb] = val;
2161 case CHARTAB_RANGE_ROW:
2164 int cell_min, cell_max, i;
2166 /* printf ("put-char-table: range = charset-row: %d, 0x%x\n",
2167 XCHARSET_LEADING_BYTE (range->charset), range->row); */
2168 if (XCHARSET_DIMENSION (range->charset) < 2)
2169 signal_simple_error ("Charset in row vector must be multi-byte",
2173 switch (XCHARSET_CHARS (range->charset))
2176 cell_min = 33; cell_max = 126;
2179 cell_min = 32; cell_max = 127;
2182 cell_min = 0; cell_max = 127;
2185 cell_min = 0; cell_max = 255;
2191 if (XCHARSET_DIMENSION (range->charset) == 2)
2192 check_int_range (range->row, cell_min, cell_max);
2193 else if (XCHARSET_DIMENSION (range->charset) == 3)
2195 check_int_range (range->row >> 8 , cell_min, cell_max);
2196 check_int_range (range->row & 0xFF, cell_min, cell_max);
2198 else if (XCHARSET_DIMENSION (range->charset) == 4)
2200 check_int_range ( range->row >> 16 , cell_min, cell_max);
2201 check_int_range ((range->row >> 8) & 0xFF, cell_min, cell_max);
2202 check_int_range ( range->row & 0xFF, cell_min, cell_max);
2207 for (i = cell_min; i <= cell_max; i++)
2209 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2210 if ( charset_code_point (range->charset, ch) >= 0 )
2211 put_char_id_table_0 (ct, ch, val);
2216 Lisp_Char_Table_Entry *cte;
2217 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
2218 /* make sure that there is a separate entry for the row. */
2219 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2220 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2221 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2222 cte->level2[range->row - 32] = val;
2224 #endif /* not UTF2000 */
2228 case CHARTAB_RANGE_CHAR:
2230 /* printf ("put-char-table: range = char: 0x%x\n", range->ch); */
2231 put_char_id_table_0 (ct, range->ch, val);
2235 Lisp_Object charset;
2238 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
2239 if (EQ (charset, Vcharset_ascii))
2240 ct->ascii[byte1] = val;
2241 else if (EQ (charset, Vcharset_control_1))
2242 ct->ascii[byte1 + 128] = val;
2245 Lisp_Char_Table_Entry *cte;
2246 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
2247 /* make sure that there is a separate entry for the row. */
2248 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
2249 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
2250 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
2251 /* now CTE is a char table entry for the charset;
2252 each entry is for a single row (or character of
2253 a one-octet charset). */
2254 if (XCHARSET_DIMENSION (charset) == 1)
2255 cte->level2[byte1 - 32] = val;
2258 /* assigning to one character in a two-octet charset. */
2259 /* make sure that the charset row contains a separate
2260 entry for each character. */
2261 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
2262 cte->level2[byte1 - 32] =
2263 make_char_table_entry (cte->level2[byte1 - 32]);
2264 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
2265 cte->level2[byte2 - 32] = val;
2269 #else /* not MULE */
2270 ct->ascii[(unsigned char) (range->ch)] = val;
2272 #endif /* not MULE */
2276 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
2277 update_syntax_table (ct);
2281 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
2282 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
2284 RANGE specifies one or more characters to be affected and should be
2285 one of the following:
2287 -- t (all characters are affected)
2288 -- A charset (only allowed when Mule support is present)
2289 -- A vector of two elements: a two-octet charset and a row number
2290 (only allowed when Mule support is present)
2291 -- A single character
2293 VALUE must be a value appropriate for the type of CHAR-TABLE.
2294 See `valid-char-table-type-p'.
2296 (range, value, char_table))
2298 Lisp_Char_Table *ct;
2299 struct chartab_range rainj;
2301 CHECK_CHAR_TABLE (char_table);
2302 ct = XCHAR_TABLE (char_table);
2303 check_valid_char_table_value (value, ct->type, ERROR_ME);
2304 decode_char_table_range (range, &rainj);
2305 value = canonicalize_char_table_value (value, ct->type);
2306 put_char_table (ct, &rainj, value);
2311 /* Map FN over the ASCII chars in CT. */
2314 map_over_charset_ascii (Lisp_Char_Table *ct,
2315 int (*fn) (struct chartab_range *range,
2316 Lisp_Object val, void *arg),
2319 struct chartab_range rainj;
2328 rainj.type = CHARTAB_RANGE_CHAR;
2330 for (i = start, retval = 0; i < stop && retval == 0; i++)
2332 rainj.ch = (Emchar) i;
2333 retval = (fn) (&rainj, ct->ascii[i], arg);
2341 /* Map FN over the Control-1 chars in CT. */
2344 map_over_charset_control_1 (Lisp_Char_Table *ct,
2345 int (*fn) (struct chartab_range *range,
2346 Lisp_Object val, void *arg),
2349 struct chartab_range rainj;
2352 int stop = start + 32;
2354 rainj.type = CHARTAB_RANGE_CHAR;
2356 for (i = start, retval = 0; i < stop && retval == 0; i++)
2358 rainj.ch = (Emchar) (i);
2359 retval = (fn) (&rainj, ct->ascii[i], arg);
2365 /* Map FN over the row ROW of two-byte charset CHARSET.
2366 There must be a separate value for that row in the char table.
2367 CTE specifies the char table entry for CHARSET. */
2370 map_over_charset_row (Lisp_Char_Table_Entry *cte,
2371 Lisp_Object charset, int row,
2372 int (*fn) (struct chartab_range *range,
2373 Lisp_Object val, void *arg),
2376 Lisp_Object val = cte->level2[row - 32];
2378 if (!CHAR_TABLE_ENTRYP (val))
2380 struct chartab_range rainj;
2382 rainj.type = CHARTAB_RANGE_ROW;
2383 rainj.charset = charset;
2385 return (fn) (&rainj, val, arg);
2389 struct chartab_range rainj;
2391 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2392 int start = charset94_p ? 33 : 32;
2393 int stop = charset94_p ? 127 : 128;
2395 cte = XCHAR_TABLE_ENTRY (val);
2397 rainj.type = CHARTAB_RANGE_CHAR;
2399 for (i = start, retval = 0; i < stop && retval == 0; i++)
2401 rainj.ch = MAKE_CHAR (charset, row, i);
2402 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2410 map_over_other_charset (Lisp_Char_Table *ct, Charset_ID lb,
2411 int (*fn) (struct chartab_range *range,
2412 Lisp_Object val, void *arg),
2415 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
2416 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
2418 if (!CHARSETP (charset)
2419 || lb == LEADING_BYTE_ASCII
2420 || lb == LEADING_BYTE_CONTROL_1)
2423 if (!CHAR_TABLE_ENTRYP (val))
2425 struct chartab_range rainj;
2427 rainj.type = CHARTAB_RANGE_CHARSET;
2428 rainj.charset = charset;
2429 return (fn) (&rainj, val, arg);
2433 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
2434 int charset94_p = (XCHARSET_CHARS (charset) == 94);
2435 int start = charset94_p ? 33 : 32;
2436 int stop = charset94_p ? 127 : 128;
2439 if (XCHARSET_DIMENSION (charset) == 1)
2441 struct chartab_range rainj;
2442 rainj.type = CHARTAB_RANGE_CHAR;
2444 for (i = start, retval = 0; i < stop && retval == 0; i++)
2446 rainj.ch = MAKE_CHAR (charset, i, 0);
2447 retval = (fn) (&rainj, cte->level2[i - 32], arg);
2452 for (i = start, retval = 0; i < stop && retval == 0; i++)
2453 retval = map_over_charset_row (cte, charset, i, fn, arg);
2461 #endif /* not UTF2000 */
2464 struct map_char_table_for_charset_arg
2466 int (*fn) (struct chartab_range *range, Lisp_Object val, void *arg);
2467 Lisp_Char_Table *ct;
2472 map_char_table_for_charset_fun (struct chartab_range *range,
2473 Lisp_Object val, void *arg)
2475 struct map_char_table_for_charset_arg *closure =
2476 (struct map_char_table_for_charset_arg *) arg;
2479 switch (range->type)
2481 case CHARTAB_RANGE_ALL:
2484 case CHARTAB_RANGE_DEFAULT:
2487 case CHARTAB_RANGE_CHARSET:
2490 case CHARTAB_RANGE_ROW:
2493 case CHARTAB_RANGE_CHAR:
2494 ret = get_char_table (range->ch, closure->ct);
2495 if (!UNBOUNDP (ret))
2496 return (closure->fn) (range, ret, closure->arg);
2507 /* Map FN (with client data ARG) over range RANGE in char table CT.
2508 Mapping stops the first time FN returns non-zero, and that value
2509 becomes the return value of map_char_table(). */
2512 map_char_table (Lisp_Char_Table *ct,
2513 struct chartab_range *range,
2514 int (*fn) (struct chartab_range *range,
2515 Lisp_Object val, void *arg),
2518 switch (range->type)
2520 case CHARTAB_RANGE_ALL:
2522 if (!UNBOUNDP (ct->default_value))
2524 struct chartab_range rainj;
2527 rainj.type = CHARTAB_RANGE_DEFAULT;
2528 retval = (fn) (&rainj, ct->default_value, arg);
2532 if (UINT8_BYTE_TABLE_P (ct->table))
2533 return map_over_uint8_byte_table (XUINT8_BYTE_TABLE(ct->table),
2535 else if (UINT16_BYTE_TABLE_P (ct->table))
2536 return map_over_uint16_byte_table (XUINT16_BYTE_TABLE(ct->table),
2538 else if (BYTE_TABLE_P (ct->table))
2539 return map_over_byte_table (XBYTE_TABLE(ct->table),
2541 else if (!UNBOUNDP (ct->table))
2544 struct chartab_range rainj;
2547 Emchar c1 = c + unit;
2550 rainj.type = CHARTAB_RANGE_CHAR;
2552 for (retval = 0; c < c1 && retval == 0; c++)
2555 retval = (fn) (&rainj, ct->table, arg);
2560 return (fn) (range, ct->table, arg);
2567 retval = map_over_charset_ascii (ct, fn, arg);
2571 retval = map_over_charset_control_1 (ct, fn, arg);
2576 Charset_ID start = MIN_LEADING_BYTE;
2577 Charset_ID stop = start + NUM_LEADING_BYTES;
2579 for (i = start, retval = 0; i < stop && retval == 0; i++)
2581 retval = map_over_other_charset (ct, i, fn, arg);
2590 case CHARTAB_RANGE_DEFAULT:
2591 if (!UNBOUNDP (ct->default_value))
2592 return (fn) (range, ct->default_value, arg);
2597 case CHARTAB_RANGE_CHARSET:
2600 Lisp_Object encoding_table
2601 = XCHARSET_ENCODING_TABLE (range->charset);
2603 if (!NILP (encoding_table))
2605 struct chartab_range rainj;
2606 struct map_char_table_for_charset_arg mcarg;
2611 rainj.type = CHARTAB_RANGE_ALL;
2612 return map_char_table (XCHAR_TABLE(encoding_table),
2614 &map_char_table_for_charset_fun,
2620 return map_over_other_charset (ct,
2621 XCHARSET_LEADING_BYTE (range->charset),
2625 case CHARTAB_RANGE_ROW:
2628 int cell_min, cell_max, i;
2630 struct chartab_range rainj;
2632 if (XCHARSET_DIMENSION (range->charset) < 2)
2633 signal_simple_error ("Charset in row vector must be multi-byte",
2637 switch (XCHARSET_CHARS (range->charset))
2640 cell_min = 33; cell_max = 126;
2643 cell_min = 32; cell_max = 127;
2646 cell_min = 0; cell_max = 127;
2649 cell_min = 0; cell_max = 255;
2655 if (XCHARSET_DIMENSION (range->charset) == 2)
2656 check_int_range (range->row, cell_min, cell_max);
2657 else if (XCHARSET_DIMENSION (range->charset) == 3)
2659 check_int_range (range->row >> 8 , cell_min, cell_max);
2660 check_int_range (range->row & 0xFF, cell_min, cell_max);
2662 else if (XCHARSET_DIMENSION (range->charset) == 4)
2664 check_int_range ( range->row >> 16 , cell_min, cell_max);
2665 check_int_range ((range->row >> 8) & 0xFF, cell_min, cell_max);
2666 check_int_range ( range->row & 0xFF, cell_min, cell_max);
2671 rainj.type = CHARTAB_RANGE_CHAR;
2672 for (retval =0, i = cell_min; i <= cell_max && retval == 0; i++)
2674 Emchar ch = DECODE_CHAR (range->charset, (range->row << 8) | i);
2676 if ( charset_code_point (range->charset, ch) >= 0 )
2679 = get_byte_table (get_byte_table
2683 (unsigned char)(ch >> 24)),
2684 (unsigned char) (ch >> 16)),
2685 (unsigned char) (ch >> 8)),
2686 (unsigned char) ch);
2689 val = ct->default_value;
2691 retval = (fn) (&rainj, val, arg);
2698 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset)
2699 - MIN_LEADING_BYTE];
2700 if (!CHAR_TABLE_ENTRYP (val))
2702 struct chartab_range rainj;
2704 rainj.type = CHARTAB_RANGE_ROW;
2705 rainj.charset = range->charset;
2706 rainj.row = range->row;
2707 return (fn) (&rainj, val, arg);
2710 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
2711 range->charset, range->row,
2714 #endif /* not UTF2000 */
2717 case CHARTAB_RANGE_CHAR:
2719 Emchar ch = range->ch;
2720 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
2722 if (!UNBOUNDP (val))
2724 struct chartab_range rainj;
2726 rainj.type = CHARTAB_RANGE_CHAR;
2728 return (fn) (&rainj, val, arg);
2740 struct slow_map_char_table_arg
2742 Lisp_Object function;
2747 slow_map_char_table_fun (struct chartab_range *range,
2748 Lisp_Object val, void *arg)
2750 Lisp_Object ranjarg = Qnil;
2751 struct slow_map_char_table_arg *closure =
2752 (struct slow_map_char_table_arg *) arg;
2754 switch (range->type)
2756 case CHARTAB_RANGE_ALL:
2761 case CHARTAB_RANGE_DEFAULT:
2767 case CHARTAB_RANGE_CHARSET:
2768 ranjarg = XCHARSET_NAME (range->charset);
2771 case CHARTAB_RANGE_ROW:
2772 ranjarg = vector2 (XCHARSET_NAME (range->charset),
2773 make_int (range->row));
2776 case CHARTAB_RANGE_CHAR:
2777 ranjarg = make_char (range->ch);
2783 closure->retval = call2 (closure->function, ranjarg, val);
2784 return !NILP (closure->retval);
2787 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
2788 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
2789 each key and value in the table.
2791 RANGE specifies a subrange to map over and is in the same format as
2792 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
2795 (function, char_table, range))
2797 Lisp_Char_Table *ct;
2798 struct slow_map_char_table_arg slarg;
2799 struct gcpro gcpro1, gcpro2;
2800 struct chartab_range rainj;
2802 CHECK_CHAR_TABLE (char_table);
2803 ct = XCHAR_TABLE (char_table);
2806 decode_char_table_range (range, &rainj);
2807 slarg.function = function;
2808 slarg.retval = Qnil;
2809 GCPRO2 (slarg.function, slarg.retval);
2810 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
2813 return slarg.retval;
2817 /************************************************************************/
2818 /* Character Attributes */
2819 /************************************************************************/
2823 Lisp_Object Vchar_attribute_hash_table;
2825 /* We store the char-attributes in hash tables with the names as the
2826 key and the actual char-id-table object as the value. Occasionally
2827 we need to use them in a list format. These routines provide us
2829 struct char_attribute_list_closure
2831 Lisp_Object *char_attribute_list;
2835 add_char_attribute_to_list_mapper (Lisp_Object key, Lisp_Object value,
2836 void *char_attribute_list_closure)
2838 /* This function can GC */
2839 struct char_attribute_list_closure *calcl
2840 = (struct char_attribute_list_closure*) char_attribute_list_closure;
2841 Lisp_Object *char_attribute_list = calcl->char_attribute_list;
2843 *char_attribute_list = Fcons (key, *char_attribute_list);
2847 DEFUN ("char-attribute-list", Fchar_attribute_list, 0, 0, 0, /*
2848 Return the list of all existing character attributes except coded-charsets.
2852 Lisp_Object char_attribute_list = Qnil;
2853 struct gcpro gcpro1;
2854 struct char_attribute_list_closure char_attribute_list_closure;
2856 GCPRO1 (char_attribute_list);
2857 char_attribute_list_closure.char_attribute_list = &char_attribute_list;
2858 elisp_maphash (add_char_attribute_to_list_mapper,
2859 Vchar_attribute_hash_table,
2860 &char_attribute_list_closure);
2862 return char_attribute_list;
2865 DEFUN ("find-char-attribute-table", Ffind_char_attribute_table, 1, 1, 0, /*
2866 Return char-id-table corresponding to ATTRIBUTE.
2870 return Fgethash (attribute, Vchar_attribute_hash_table, Qnil);
2874 /* We store the char-id-tables in hash tables with the attributes as
2875 the key and the actual char-id-table object as the value. Each
2876 char-id-table stores values of an attribute corresponding with
2877 characters. Occasionally we need to get attributes of a character
2878 in a association-list format. These routines provide us with
2880 struct char_attribute_alist_closure
2883 Lisp_Object *char_attribute_alist;
2887 add_char_attribute_alist_mapper (Lisp_Object key, Lisp_Object value,
2888 void *char_attribute_alist_closure)
2890 /* This function can GC */
2891 struct char_attribute_alist_closure *caacl =
2892 (struct char_attribute_alist_closure*) char_attribute_alist_closure;
2894 = get_char_id_table (XCHAR_TABLE(value), caacl->char_id);
2895 if (!UNBOUNDP (ret))
2897 Lisp_Object *char_attribute_alist = caacl->char_attribute_alist;
2898 *char_attribute_alist
2899 = Fcons (Fcons (key, ret), *char_attribute_alist);
2904 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
2905 Return the alist of attributes of CHARACTER.
2909 Lisp_Object alist = Qnil;
2912 CHECK_CHAR (character);
2914 struct gcpro gcpro1;
2915 struct char_attribute_alist_closure char_attribute_alist_closure;
2918 char_attribute_alist_closure.char_id = XCHAR (character);
2919 char_attribute_alist_closure.char_attribute_alist = &alist;
2920 elisp_maphash (add_char_attribute_alist_mapper,
2921 Vchar_attribute_hash_table,
2922 &char_attribute_alist_closure);
2926 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
2928 Lisp_Object ccs = chlook->charset_by_leading_byte[i];
2932 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
2935 if ( CHAR_TABLEP (encoding_table)
2937 = get_char_id_table (XCHAR_TABLE(encoding_table),
2938 XCHAR (character))) )
2940 alist = Fcons (Fcons (ccs, cpos), alist);
2947 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 3, 0, /*
2948 Return the value of CHARACTER's ATTRIBUTE.
2949 Return DEFAULT-VALUE if the value is not exist.
2951 (character, attribute, default_value))
2955 CHECK_CHAR (character);
2956 if (!NILP (ccs = Ffind_charset (attribute)))
2958 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
2960 if (CHAR_TABLEP (encoding_table))
2961 return get_char_id_table (XCHAR_TABLE(encoding_table),
2966 Lisp_Object table = Fgethash (attribute,
2967 Vchar_attribute_hash_table,
2969 if (!UNBOUNDP (table))
2971 Lisp_Object ret = get_char_id_table (XCHAR_TABLE(table),
2973 if (!UNBOUNDP (ret))
2977 return default_value;
2980 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
2981 Store CHARACTER's ATTRIBUTE with VALUE.
2983 (character, attribute, value))
2987 ccs = Ffind_charset (attribute);
2990 CHECK_CHAR (character);
2991 return put_char_ccs_code_point (character, ccs, value);
2993 else if (EQ (attribute, Q_decomposition))
2997 CHECK_CHAR (character);
2999 signal_simple_error ("Invalid value for ->decomposition",
3002 if (CONSP (Fcdr (value)))
3004 Lisp_Object rest = value;
3005 Lisp_Object table = Vcharacter_composition_table;
3009 GET_EXTERNAL_LIST_LENGTH (rest, len);
3010 seq = make_vector (len, Qnil);
3012 while (CONSP (rest))
3014 Lisp_Object v = Fcar (rest);
3017 = to_char_id (v, "Invalid value for ->decomposition", value);
3020 XVECTOR_DATA(seq)[i++] = v;
3022 XVECTOR_DATA(seq)[i++] = make_char (c);
3026 put_char_id_table (XCHAR_TABLE(table),
3027 make_char (c), character);
3032 ntable = get_char_id_table (XCHAR_TABLE(table), c);
3033 if (!CHAR_TABLEP (ntable))
3035 ntable = make_char_id_table (Qnil);
3036 put_char_id_table (XCHAR_TABLE(table),
3037 make_char (c), ntable);
3045 Lisp_Object v = Fcar (value);
3049 Emchar c = XINT (v);
3051 = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3054 if (NILP (Fmemq (v, ret)))
3056 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3057 make_char (c), Fcons (character, ret));
3060 seq = make_vector (1, v);
3064 else if (EQ (attribute, Qto_ucs) || EQ (attribute, Q_ucs))
3069 CHECK_CHAR (character);
3071 signal_simple_error ("Invalid value for ->ucs", value);
3075 ret = get_char_id_table (XCHAR_TABLE(Vcharacter_variant_table), c);
3076 if (NILP (Fmemq (character, ret)))
3078 put_char_id_table (XCHAR_TABLE(Vcharacter_variant_table),
3079 make_char (c), Fcons (character, ret));
3082 if (EQ (attribute, Q_ucs))
3083 attribute = Qto_ucs;
3087 Lisp_Object table = Fgethash (attribute,
3088 Vchar_attribute_hash_table,
3093 table = make_char_id_table (Qunbound);
3094 Fputhash (attribute, table, Vchar_attribute_hash_table);
3096 put_char_id_table (XCHAR_TABLE(table), character, value);
3101 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
3102 Remove CHARACTER's ATTRIBUTE.
3104 (character, attribute))
3108 CHECK_CHAR (character);
3109 ccs = Ffind_charset (attribute);
3112 return remove_char_ccs (character, ccs);
3116 Lisp_Object table = Fgethash (attribute,
3117 Vchar_attribute_hash_table,
3119 if (!UNBOUNDP (table))
3121 put_char_id_table (XCHAR_TABLE(table), character, Qunbound);
3128 DEFUN ("map-char-attribute", Fmap_char_attribute, 2, 3, 0, /*
3129 Map FUNCTION over entries in ATTRIBUTE, calling it with two args,
3130 each key and value in the table.
3132 RANGE specifies a subrange to map over and is in the same format as
3133 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
3136 (function, attribute, range))
3139 Lisp_Char_Table *ct;
3140 struct slow_map_char_table_arg slarg;
3141 struct gcpro gcpro1, gcpro2;
3142 struct chartab_range rainj;
3144 if (!NILP (ccs = Ffind_charset (attribute)))
3146 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
3148 if (CHAR_TABLEP (encoding_table))
3149 ct = XCHAR_TABLE (encoding_table);
3155 Lisp_Object table = Fgethash (attribute,
3156 Vchar_attribute_hash_table,
3158 if (CHAR_TABLEP (table))
3159 ct = XCHAR_TABLE (table);
3165 decode_char_table_range (range, &rainj);
3166 slarg.function = function;
3167 slarg.retval = Qnil;
3168 GCPRO2 (slarg.function, slarg.retval);
3169 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
3172 return slarg.retval;
3175 EXFUN (Fmake_char, 3);
3176 EXFUN (Fdecode_char, 2);
3178 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
3179 Store character's ATTRIBUTES.
3183 Lisp_Object rest = attributes;
3184 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
3185 Lisp_Object character;
3189 while (CONSP (rest))
3191 Lisp_Object cell = Fcar (rest);
3195 signal_simple_error ("Invalid argument", attributes);
3196 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
3197 && ((XCHARSET_FINAL (ccs) != 0) ||
3198 (XCHARSET_UCS_MAX (ccs) > 0)) )
3202 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3204 character = Fdecode_char (ccs, cell);
3205 if (!NILP (character))
3206 goto setup_attributes;
3210 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3211 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3215 signal_simple_error ("Invalid argument", attributes);
3217 character = make_char (XINT (code) + 0x100000);
3218 goto setup_attributes;
3222 else if (!INTP (code))
3223 signal_simple_error ("Invalid argument", attributes);
3225 character = make_char (XINT (code));
3229 while (CONSP (rest))
3231 Lisp_Object cell = Fcar (rest);
3234 signal_simple_error ("Invalid argument", attributes);
3236 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
3242 DEFUN ("find-char", Ffind_char, 1, 1, 0, /*
3243 Retrieve the character of the given ATTRIBUTES.
3247 Lisp_Object rest = attributes;
3250 while (CONSP (rest))
3252 Lisp_Object cell = Fcar (rest);
3256 signal_simple_error ("Invalid argument", attributes);
3257 if (!NILP (ccs = Ffind_charset (Fcar (cell))))
3261 return Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
3263 return Fdecode_char (ccs, cell);
3267 if ( (!NILP (code = Fcdr (Fassq (Qto_ucs, attributes)))) ||
3268 (!NILP (code = Fcdr (Fassq (Q_ucs, attributes)))) )
3271 signal_simple_error ("Invalid argument", attributes);
3273 return make_char (XINT (code) + 0x100000);
3281 /************************************************************************/
3282 /* Char table read syntax */
3283 /************************************************************************/
3286 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
3287 Error_behavior errb)
3289 /* #### should deal with ERRB */
3290 symbol_to_char_table_type (value);
3295 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
3296 Error_behavior errb)
3300 /* #### should deal with ERRB */
3301 EXTERNAL_LIST_LOOP (rest, value)
3303 Lisp_Object range = XCAR (rest);
3304 struct chartab_range dummy;
3308 signal_simple_error ("Invalid list format", value);
3311 if (!CONSP (XCDR (range))
3312 || !NILP (XCDR (XCDR (range))))
3313 signal_simple_error ("Invalid range format", range);
3314 decode_char_table_range (XCAR (range), &dummy);
3315 decode_char_table_range (XCAR (XCDR (range)), &dummy);
3318 decode_char_table_range (range, &dummy);
3325 chartab_instantiate (Lisp_Object data)
3327 Lisp_Object chartab;
3328 Lisp_Object type = Qgeneric;
3329 Lisp_Object dataval = Qnil;
3331 while (!NILP (data))
3333 Lisp_Object keyw = Fcar (data);
3339 if (EQ (keyw, Qtype))
3341 else if (EQ (keyw, Qdata))
3345 chartab = Fmake_char_table (type);
3348 while (!NILP (data))
3350 Lisp_Object range = Fcar (data);
3351 Lisp_Object val = Fcar (Fcdr (data));
3353 data = Fcdr (Fcdr (data));
3356 if (CHAR_OR_CHAR_INTP (XCAR (range)))
3358 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
3359 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
3362 for (i = first; i <= last; i++)
3363 Fput_char_table (make_char (i), val, chartab);
3369 Fput_char_table (range, val, chartab);
3378 /************************************************************************/
3379 /* Category Tables, specifically */
3380 /************************************************************************/
3382 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
3383 Return t if OBJECT is a category table.
3384 A category table is a type of char table used for keeping track of
3385 categories. Categories are used for classifying characters for use
3386 in regexps -- you can refer to a category rather than having to use
3387 a complicated [] expression (and category lookups are significantly
3390 There are 95 different categories available, one for each printable
3391 character (including space) in the ASCII charset. Each category
3392 is designated by one such character, called a "category designator".
3393 They are specified in a regexp using the syntax "\\cX", where X is
3394 a category designator.
3396 A category table specifies, for each character, the categories that
3397 the character is in. Note that a character can be in more than one
3398 category. More specifically, a category table maps from a character
3399 to either the value nil (meaning the character is in no categories)
3400 or a 95-element bit vector, specifying for each of the 95 categories
3401 whether the character is in that category.
3403 Special Lisp functions are provided that abstract this, so you do not
3404 have to directly manipulate bit vectors.
3408 return (CHAR_TABLEP (object) &&
3409 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
3414 check_category_table (Lisp_Object object, Lisp_Object default_)
3418 while (NILP (Fcategory_table_p (object)))
3419 object = wrong_type_argument (Qcategory_table_p, object);
3424 check_category_char (Emchar ch, Lisp_Object table,
3425 unsigned int designator, unsigned int not)
3427 REGISTER Lisp_Object temp;
3428 Lisp_Char_Table *ctbl;
3429 #ifdef ERROR_CHECK_TYPECHECK
3430 if (NILP (Fcategory_table_p (table)))
3431 signal_simple_error ("Expected category table", table);
3433 ctbl = XCHAR_TABLE (table);
3434 temp = get_char_table (ch, ctbl);
3439 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not : not;
3442 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
3443 Return t if category of the character at POSITION includes DESIGNATOR.
3444 Optional third arg BUFFER specifies which buffer to use, and defaults
3445 to the current buffer.
3446 Optional fourth arg CATEGORY-TABLE specifies the category table to
3447 use, and defaults to BUFFER's category table.
3449 (position, designator, buffer, category_table))
3454 struct buffer *buf = decode_buffer (buffer, 0);
3456 CHECK_INT (position);
3457 CHECK_CATEGORY_DESIGNATOR (designator);
3458 des = XCHAR (designator);
3459 ctbl = check_category_table (category_table, Vstandard_category_table);
3460 ch = BUF_FETCH_CHAR (buf, XINT (position));
3461 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3464 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
3465 Return t if category of CHARACTER includes DESIGNATOR, else nil.
3466 Optional third arg CATEGORY-TABLE specifies the category table to use,
3467 and defaults to the standard category table.
3469 (character, designator, category_table))
3475 CHECK_CATEGORY_DESIGNATOR (designator);
3476 des = XCHAR (designator);
3477 CHECK_CHAR (character);
3478 ch = XCHAR (character);
3479 ctbl = check_category_table (category_table, Vstandard_category_table);
3480 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
3483 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
3484 Return BUFFER's current category table.
3485 BUFFER defaults to the current buffer.
3489 return decode_buffer (buffer, 0)->category_table;
3492 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
3493 Return the standard category table.
3494 This is the one used for new buffers.
3498 return Vstandard_category_table;
3501 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
3502 Return a new category table which is a copy of CATEGORY-TABLE.
3503 CATEGORY-TABLE defaults to the standard category table.
3507 if (NILP (Vstandard_category_table))
3508 return Fmake_char_table (Qcategory);
3511 check_category_table (category_table, Vstandard_category_table);
3512 return Fcopy_char_table (category_table);
3515 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
3516 Select CATEGORY-TABLE as the new category table for BUFFER.
3517 BUFFER defaults to the current buffer if omitted.
3519 (category_table, buffer))
3521 struct buffer *buf = decode_buffer (buffer, 0);
3522 category_table = check_category_table (category_table, Qnil);
3523 buf->category_table = category_table;
3524 /* Indicate that this buffer now has a specified category table. */
3525 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
3526 return category_table;
3529 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
3530 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
3534 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
3537 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
3538 Return t if OBJECT is a category table value.
3539 Valid values are nil or a bit vector of size 95.
3543 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
3547 #define CATEGORYP(x) \
3548 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
3550 #define CATEGORY_SET(c) \
3551 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
3553 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
3554 The faster version of `!NILP (Faref (category_set, category))'. */
3555 #define CATEGORY_MEMBER(category, category_set) \
3556 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
3558 /* Return 1 if there is a word boundary between two word-constituent
3559 characters C1 and C2 if they appear in this order, else return 0.
3560 Use the macro WORD_BOUNDARY_P instead of calling this function
3563 int word_boundary_p (Emchar c1, Emchar c2);
3565 word_boundary_p (Emchar c1, Emchar c2)
3567 Lisp_Object category_set1, category_set2;
3572 if (COMPOSITE_CHAR_P (c1))
3573 c1 = cmpchar_component (c1, 0, 1);
3574 if (COMPOSITE_CHAR_P (c2))
3575 c2 = cmpchar_component (c2, 0, 1);
3578 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
3580 tail = Vword_separating_categories;
3585 tail = Vword_combining_categories;
3589 category_set1 = CATEGORY_SET (c1);
3590 if (NILP (category_set1))
3591 return default_result;
3592 category_set2 = CATEGORY_SET (c2);
3593 if (NILP (category_set2))
3594 return default_result;
3596 for (; CONSP (tail); tail = XCONS (tail)->cdr)
3598 Lisp_Object elt = XCONS(tail)->car;
3601 && CATEGORYP (XCONS (elt)->car)
3602 && CATEGORYP (XCONS (elt)->cdr)
3603 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
3604 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
3605 return !default_result;
3607 return default_result;
3613 syms_of_chartab (void)
3616 INIT_LRECORD_IMPLEMENTATION (uint8_byte_table);
3617 INIT_LRECORD_IMPLEMENTATION (uint16_byte_table);
3618 INIT_LRECORD_IMPLEMENTATION (byte_table);
3620 defsymbol (&Qto_ucs, "=>ucs");
3621 defsymbol (&Q_ucs, "->ucs");
3622 defsymbol (&Q_decomposition, "->decomposition");
3623 defsymbol (&Qcompat, "compat");
3624 defsymbol (&Qisolated, "isolated");
3625 defsymbol (&Qinitial, "initial");
3626 defsymbol (&Qmedial, "medial");
3627 defsymbol (&Qfinal, "final");
3628 defsymbol (&Qvertical, "vertical");
3629 defsymbol (&QnoBreak, "noBreak");
3630 defsymbol (&Qfraction, "fraction");
3631 defsymbol (&Qsuper, "super");
3632 defsymbol (&Qsub, "sub");
3633 defsymbol (&Qcircle, "circle");
3634 defsymbol (&Qsquare, "square");
3635 defsymbol (&Qwide, "wide");
3636 defsymbol (&Qnarrow, "narrow");
3637 defsymbol (&Qsmall, "small");
3638 defsymbol (&Qfont, "font");
3640 DEFSUBR (Fchar_attribute_list);
3641 DEFSUBR (Ffind_char_attribute_table);
3642 DEFSUBR (Fchar_attribute_alist);
3643 DEFSUBR (Fget_char_attribute);
3644 DEFSUBR (Fput_char_attribute);
3645 DEFSUBR (Fremove_char_attribute);
3646 DEFSUBR (Fmap_char_attribute);
3647 DEFSUBR (Fdefine_char);
3648 DEFSUBR (Ffind_char);
3649 DEFSUBR (Fchar_variants);
3651 DEFSUBR (Fget_composite_char);
3654 INIT_LRECORD_IMPLEMENTATION (char_table);
3658 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
3661 defsymbol (&Qcategory_table_p, "category-table-p");
3662 defsymbol (&Qcategory_designator_p, "category-designator-p");
3663 defsymbol (&Qcategory_table_value_p, "category-table-value-p");
3666 defsymbol (&Qchar_table, "char-table");
3667 defsymbol (&Qchar_tablep, "char-table-p");
3669 DEFSUBR (Fchar_table_p);
3670 DEFSUBR (Fchar_table_type_list);
3671 DEFSUBR (Fvalid_char_table_type_p);
3672 DEFSUBR (Fchar_table_type);
3673 DEFSUBR (Freset_char_table);
3674 DEFSUBR (Fmake_char_table);
3675 DEFSUBR (Fcopy_char_table);
3676 DEFSUBR (Fget_char_table);
3677 DEFSUBR (Fget_range_char_table);
3678 DEFSUBR (Fvalid_char_table_value_p);
3679 DEFSUBR (Fcheck_valid_char_table_value);
3680 DEFSUBR (Fput_char_table);
3681 DEFSUBR (Fmap_char_table);
3684 DEFSUBR (Fcategory_table_p);
3685 DEFSUBR (Fcategory_table);
3686 DEFSUBR (Fstandard_category_table);
3687 DEFSUBR (Fcopy_category_table);
3688 DEFSUBR (Fset_category_table);
3689 DEFSUBR (Fcheck_category_at);
3690 DEFSUBR (Fchar_in_category_p);
3691 DEFSUBR (Fcategory_designator_p);
3692 DEFSUBR (Fcategory_table_value_p);
3698 vars_of_chartab (void)
3701 Vutf_2000_version = build_string("0.18 (Yamato-Koizumi)");
3702 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
3703 Version number of XEmacs UTF-2000.
3706 staticpro (&Vcharacter_composition_table);
3707 Vcharacter_composition_table = make_char_id_table (Qnil);
3709 staticpro (&Vcharacter_variant_table);
3710 Vcharacter_variant_table = make_char_id_table (Qnil);
3712 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
3713 Vall_syntax_tables = Qnil;
3714 dump_add_weak_object_chain (&Vall_syntax_tables);
3718 structure_type_create_chartab (void)
3720 struct structure_type *st;
3722 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
3724 define_structure_type_keyword (st, Qtype, chartab_type_validate);
3725 define_structure_type_keyword (st, Qdata, chartab_data_validate);
3729 complex_vars_of_chartab (void)
3732 staticpro (&Vchar_attribute_hash_table);
3733 Vchar_attribute_hash_table
3734 = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3735 #endif /* UTF2000 */
3737 /* Set this now, so first buffer creation can refer to it. */
3738 /* Make it nil before calling copy-category-table
3739 so that copy-category-table will know not to try to copy from garbage */
3740 Vstandard_category_table = Qnil;
3741 Vstandard_category_table = Fcopy_category_table (Qnil);
3742 staticpro (&Vstandard_category_table);
3744 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
3745 List of pair (cons) of categories to determine word boundary.
3747 Emacs treats a sequence of word constituent characters as a single
3748 word (i.e. finds no word boundary between them) iff they belongs to
3749 the same charset. But, exceptions are allowed in the following cases.
3751 \(1) The case that characters are in different charsets is controlled
3752 by the variable `word-combining-categories'.
3754 Emacs finds no word boundary between characters of different charsets
3755 if they have categories matching some element of this list.
3757 More precisely, if an element of this list is a cons of category CAT1
3758 and CAT2, and a multibyte character C1 which has CAT1 is followed by
3759 C2 which has CAT2, there's no word boundary between C1 and C2.
3761 For instance, to tell that ASCII characters and Latin-1 characters can
3762 form a single word, the element `(?l . ?l)' should be in this list
3763 because both characters have the category `l' (Latin characters).
3765 \(2) The case that character are in the same charset is controlled by
3766 the variable `word-separating-categories'.
3768 Emacs find a word boundary between characters of the same charset
3769 if they have categories matching some element of this list.
3771 More precisely, if an element of this list is a cons of category CAT1
3772 and CAT2, and a multibyte character C1 which has CAT1 is followed by
3773 C2 which has CAT2, there's a word boundary between C1 and C2.
3775 For instance, to tell that there's a word boundary between Japanese
3776 Hiragana and Japanese Kanji (both are in the same charset), the
3777 element `(?H . ?C) should be in this list.
3780 Vword_combining_categories = Qnil;
3782 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
3783 List of pair (cons) of categories to determine word boundary.
3784 See the documentation of the variable `word-combining-categories'.
3787 Vword_separating_categories = Qnil;