Mercurial > hg > xemacs-beta
comparison src/chartab.c @ 1296:87084e8445a7
[xemacs-hg @ 2003-02-14 09:50:15 by ben]
syntax-table fixes
1. the updating of mirror tables every time a syntax table was modified
was taking up huge amounts of time so i added a dirty flag and made the
updating "just-in-time".
2. no-longer-used char-table-entries were not getting "freed", generating
tons of garbage.
3. syntax_match() was being incorrectly called on mirror tables in the
cache, not the original syntax table.
buffer.c, syntax.c: Move syntax table description from buffer.c to syntax.c.
chartab.c, chartab.h: Free extra char table entries to avoid excessive garbage.
Add flags for dirty and mirror_table_p to char tables.
Add a back pointer from mirror tables to the original syntax table.
When modifying a syntax table, don't update the mirror table right
away, just mark as dirty.
Add various asserts to make sure we are dealing with the right type
of table (mirror or non-mirror).
font-lock.c, syntax.c, syntax.h: Add entry to syntax caches for the non-mirror table. Set it
appropriately when initializing the syntax table. Use it, not
the mirror table, for calls to syntax_match().
Don't create a bogus float each time, just once at startup.
Add some asserts, as in chartab.c.
syntax.h: When retrieving the syntax code, check the dirty flag and update
the mirror tables as appropriate.
Add some asserts, as above.
author | ben |
---|---|
date | Fri, 14 Feb 2003 09:50:17 +0000 |
parents | e22b0213b713 |
children | 4542b72c005e |
comparison
equal
deleted
inserted
replaced
1295:064ef1d07d63 | 1296:87084e8445a7 |
---|---|
1 /* XEmacs routines to deal with char tables. | 1 /* XEmacs routines to deal with char tables. |
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1992, 1995 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 1995, 1996, 2002 Ben Wing. | 4 Copyright (C) 1995, 1996, 2002, 2003 Ben Wing. |
5 Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN. | 5 Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN. |
6 Licensed to the Free Software Foundation. | 6 Licensed to the Free Software Foundation. |
7 | 7 |
8 This file is part of XEmacs. | 8 This file is part of XEmacs. |
9 | 9 |
442 { | 442 { |
443 CHECK_CHAR_TABLE (char_table); | 443 CHECK_CHAR_TABLE (char_table); |
444 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type); | 444 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type); |
445 } | 445 } |
446 | 446 |
447 static void | |
448 set_char_table_dirty (Lisp_Object table) | |
449 { | |
450 assert (!XCHAR_TABLE (table)->mirror_table_p); | |
451 XCHAR_TABLE (XCHAR_TABLE (table)->mirror_table)->dirty = 1; | |
452 } | |
453 | |
447 void | 454 void |
448 set_char_table_default (Lisp_Object table, Lisp_Object value) | 455 set_char_table_default (Lisp_Object table, Lisp_Object value) |
449 { | 456 { |
450 Lisp_Char_Table *ct = XCHAR_TABLE (table); | 457 Lisp_Char_Table *ct = XCHAR_TABLE (table); |
451 ct->default_ = value; | 458 ct->default_ = value; |
452 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) | 459 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) |
453 update_syntax_table (table); | 460 set_char_table_dirty (table); |
454 } | 461 } |
455 | 462 |
456 static void | 463 static void |
457 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value) | 464 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value) |
458 { | 465 { |
460 | 467 |
461 for (i = 0; i < NUM_ASCII_CHARS; i++) | 468 for (i = 0; i < NUM_ASCII_CHARS; i++) |
462 ct->ascii[i] = value; | 469 ct->ascii[i] = value; |
463 #ifdef MULE | 470 #ifdef MULE |
464 for (i = 0; i < NUM_LEADING_BYTES; i++) | 471 for (i = 0; i < NUM_LEADING_BYTES; i++) |
465 ct->level1[i] = value; | 472 { |
473 /* Don't get stymied when initting the table */ | |
474 if (!EQ (ct->level1[i], Qnull_pointer) && | |
475 CHAR_TABLE_ENTRYP (ct->level1[i])) | |
476 free_lcrecord (ct->level1[i]); | |
477 ct->level1[i] = value; | |
478 } | |
466 #endif /* MULE */ | 479 #endif /* MULE */ |
467 | 480 |
468 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) | 481 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) |
469 update_syntax_table (wrap_char_table (ct)); | 482 set_char_table_dirty (wrap_char_table (ct)); |
470 } | 483 } |
471 | 484 |
472 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /* | 485 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /* |
473 Reset CHAR-TABLE to its default state. | 486 Reset CHAR-TABLE to its default state. |
474 */ | 487 */ |
574 Lisp_Object obj; | 587 Lisp_Object obj; |
575 enum char_table_type ty = symbol_to_char_table_type (type); | 588 enum char_table_type ty = symbol_to_char_table_type (type); |
576 | 589 |
577 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table); | 590 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table); |
578 ct->type = ty; | 591 ct->type = ty; |
592 obj = wrap_char_table (ct); | |
579 if (ty == CHAR_TABLE_TYPE_SYNTAX) | 593 if (ty == CHAR_TABLE_TYPE_SYNTAX) |
580 { | 594 { |
581 /* Qgeneric not Qsyntax because a syntax table has a mirror table | 595 /* Qgeneric not Qsyntax because a syntax table has a mirror table |
582 and we don't want infinite recursion */ | 596 and we don't want infinite recursion */ |
583 ct->mirror_table = Fmake_char_table (Qgeneric); | 597 ct->mirror_table = Fmake_char_table (Qgeneric); |
584 set_char_table_default (ct->mirror_table, make_int (Spunct)); | 598 set_char_table_default (ct->mirror_table, make_int (Spunct)); |
599 XCHAR_TABLE (ct->mirror_table)->mirror_table_p = 1; | |
600 XCHAR_TABLE (ct->mirror_table)->mirror_table = obj; | |
585 } | 601 } |
586 else | 602 else |
587 ct->mirror_table = Qnil; | 603 ct->mirror_table = Qnil; |
588 ct->next_table = Qnil; | 604 ct->next_table = Qnil; |
589 ct->parent = Qnil; | 605 ct->parent = Qnil; |
590 ct->default_ = Qnil; | 606 ct->default_ = Qnil; |
591 obj = wrap_char_table (ct); | |
592 if (ty == CHAR_TABLE_TYPE_SYNTAX) | 607 if (ty == CHAR_TABLE_TYPE_SYNTAX) |
593 { | 608 { |
594 ct->next_table = Vall_syntax_tables; | 609 ct->next_table = Vall_syntax_tables; |
595 Vall_syntax_tables = obj; | 610 Vall_syntax_tables = obj; |
596 } | 611 } |
650 ct = XCHAR_TABLE (char_table); | 665 ct = XCHAR_TABLE (char_table); |
651 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table); | 666 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table); |
652 ctnew->type = ct->type; | 667 ctnew->type = ct->type; |
653 ctnew->parent = ct->parent; | 668 ctnew->parent = ct->parent; |
654 ctnew->default_ = ct->default_; | 669 ctnew->default_ = ct->default_; |
670 ctnew->mirror_table_p = ct->mirror_table_p; | |
671 obj = wrap_char_table (ctnew); | |
655 | 672 |
656 for (i = 0; i < NUM_ASCII_CHARS; i++) | 673 for (i = 0; i < NUM_ASCII_CHARS; i++) |
657 { | 674 { |
658 Lisp_Object new = ct->ascii[i]; | 675 Lisp_Object new = ct->ascii[i]; |
659 #ifdef MULE | 676 #ifdef MULE |
673 ctnew->level1[i] = new; | 690 ctnew->level1[i] = new; |
674 } | 691 } |
675 | 692 |
676 #endif /* MULE */ | 693 #endif /* MULE */ |
677 | 694 |
678 if (CHAR_TABLEP (ct->mirror_table)) | 695 if (!ct->mirror_table_p && CHAR_TABLEP (ct->mirror_table)) |
679 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table); | 696 { |
697 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table); | |
698 XCHAR_TABLE (ctnew->mirror_table)->mirror_table = obj; | |
699 } | |
680 else | 700 else |
681 ctnew->mirror_table = ct->mirror_table; | 701 ctnew->mirror_table = ct->mirror_table; |
682 ctnew->next_table = Qnil; | 702 ctnew->next_table = Qnil; |
683 obj = wrap_char_table (ctnew); | |
684 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX) | 703 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX) |
685 { | 704 { |
686 ctnew->next_table = Vall_syntax_tables; | 705 ctnew->next_table = Vall_syntax_tables; |
687 Vall_syntax_tables = obj; | 706 Vall_syntax_tables = obj; |
688 } | 707 } |
770 struct chartab_range *range) | 789 struct chartab_range *range) |
771 { | 790 { |
772 map_char_table (from, range, copy_mapper, LISP_TO_VOID (to)); | 791 map_char_table (from, range, copy_mapper, LISP_TO_VOID (to)); |
773 } | 792 } |
774 | 793 |
775 Lisp_Object | 794 static Lisp_Object |
776 get_range_char_table (struct chartab_range *range, Lisp_Object table, | 795 get_range_char_table_1 (struct chartab_range *range, Lisp_Object table, |
777 Lisp_Object multi) | 796 Lisp_Object multi) |
778 { | 797 { |
779 Lisp_Char_Table *ct = XCHAR_TABLE (table); | 798 Lisp_Char_Table *ct = XCHAR_TABLE (table); |
780 Lisp_Object retval = Qnil; | 799 Lisp_Object retval = Qnil; |
781 | 800 |
782 switch (range->type) | 801 switch (range->type) |
860 | 879 |
861 if (UNBOUNDP (retval)) | 880 if (UNBOUNDP (retval)) |
862 return ct->default_; | 881 return ct->default_; |
863 return retval; | 882 return retval; |
864 } | 883 } |
884 | |
885 Lisp_Object | |
886 get_range_char_table (struct chartab_range *range, Lisp_Object table, | |
887 Lisp_Object multi) | |
888 { | |
889 if (range->type == CHARTAB_RANGE_CHAR) | |
890 return get_char_table (range->ch, table); | |
891 else | |
892 return get_range_char_table_1 (range, table, multi); | |
893 } | |
894 | |
895 #ifdef ERROR_CHECK_TYPES | |
896 | |
897 /* Only exists so as not to trip an assert in get_char_table(). */ | |
898 Lisp_Object | |
899 updating_mirror_get_range_char_table (struct chartab_range *range, | |
900 Lisp_Object table, | |
901 Lisp_Object multi) | |
902 { | |
903 if (range->type == CHARTAB_RANGE_CHAR) | |
904 return get_char_table_1 (range->ch, table); | |
905 else | |
906 return get_range_char_table_1 (range, table, multi); | |
907 } | |
908 | |
909 #endif /* ERROR_CHECK_TYPES */ | |
865 | 910 |
866 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /* | 911 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /* |
867 Find value for a range in CHAR-TABLE. | 912 Find value for a range in CHAR-TABLE. |
868 If there is more than one value, return MULTI (defaults to nil). | 913 If there is more than one value, return MULTI (defaults to nil). |
869 */ | 914 */ |
984 | 1029 |
985 switch (range->type) | 1030 switch (range->type) |
986 { | 1031 { |
987 case CHARTAB_RANGE_ALL: | 1032 case CHARTAB_RANGE_ALL: |
988 fill_char_table (ct, val); | 1033 fill_char_table (ct, val); |
989 return; /* avoid the duplicate call to update_syntax_table() below, | 1034 return; /* fill_char_table() recorded the table as dirty. */ |
990 since fill_char_table() also did that. */ | |
991 | 1035 |
992 #ifdef MULE | 1036 #ifdef MULE |
993 case CHARTAB_RANGE_CHARSET: | 1037 case CHARTAB_RANGE_CHARSET: |
994 if (EQ (range->charset, Vcharset_ascii)) | 1038 if (EQ (range->charset, Vcharset_ascii)) |
995 { | 1039 { |
1004 ct->ascii[i] = val; | 1048 ct->ascii[i] = val; |
1005 } | 1049 } |
1006 else | 1050 else |
1007 { | 1051 { |
1008 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE; | 1052 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE; |
1053 if (CHAR_TABLE_ENTRYP (ct->level1[lb])) | |
1054 free_lcrecord (ct->level1[lb]); | |
1009 ct->level1[lb] = val; | 1055 ct->level1[lb] = val; |
1010 } | 1056 } |
1011 break; | 1057 break; |
1012 | 1058 |
1013 case CHARTAB_RANGE_ROW: | 1059 case CHARTAB_RANGE_ROW: |
1065 break; | 1111 break; |
1066 #endif /* not MULE */ | 1112 #endif /* not MULE */ |
1067 } | 1113 } |
1068 | 1114 |
1069 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) | 1115 if (ct->type == CHAR_TABLE_TYPE_SYNTAX) |
1070 update_syntax_table (wrap_char_table (ct)); | 1116 set_char_table_dirty (wrap_char_table (ct)); |
1071 } | 1117 } |
1072 | 1118 |
1073 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /* | 1119 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /* |
1074 Set the value for chars in RANGE to be VALUE in CHAR-TABLE. | 1120 Set the value for chars in RANGE to be VALUE in CHAR-TABLE. |
1075 | 1121 |