diff options
| author | Kenichi Handa | 2007-06-25 10:25:21 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2007-06-25 10:25:21 +0000 |
| commit | 57d53d1bdd44cac6c330736fe7c48e8ccaeee3a3 (patch) | |
| tree | 2966e6ce10d34b8a0d4cdcb079336b59e5f8e72b /src | |
| parent | ee82fbcd45722d310f1ed08a767cb33fd9efb48c (diff) | |
| download | emacs-57d53d1bdd44cac6c330736fe7c48e8ccaeee3a3.tar.gz emacs-57d53d1bdd44cac6c330736fe7c48e8ccaeee3a3.zip | |
(map_sub_char_table): Make it work for the top-level
char-table. Fix handling of parent char-table.
(map_char_table): Adjusted for the above change.
Diffstat (limited to 'src')
| -rw-r--r-- | src/chartab.c | 145 |
1 files changed, 103 insertions, 42 deletions
diff --git a/src/chartab.c b/src/chartab.c index a75ed1e7cda..bc97103c1e3 100644 --- a/src/chartab.c +++ b/src/chartab.c | |||
| @@ -705,34 +705,104 @@ DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table, | |||
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | 707 | ||
| 708 | /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table), | ||
| 709 | calling it for each character or group of characters that share a | ||
| 710 | value. RANGE is a cons (FROM . TO) specifying the range of target | ||
| 711 | characters, VAL is a value of FROM in TABLE, DEFAULT_VAL is the | ||
| 712 | default value of the char-table, PARENT is the parent of the | ||
| 713 | char-table. | ||
| 714 | |||
| 715 | ARG is passed to C_FUNCTION when that is called. | ||
| 716 | |||
| 717 | It returns the value of last character covered by TABLE (not the | ||
| 718 | value inheritted from the parent), and by side-effect, the car part | ||
| 719 | of RANGE is updated to the minimum character C where C and all the | ||
| 720 | following characters in TABLE have the same value. */ | ||
| 721 | |||
| 708 | static Lisp_Object | 722 | static Lisp_Object |
| 709 | map_sub_char_table (c_function, function, table, arg, val, range, | 723 | map_sub_char_table (c_function, function, table, arg, val, range, |
| 710 | default_val, parent) | 724 | default_val, parent) |
| 711 | void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); | 725 | void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); |
| 712 | Lisp_Object function, table, arg, val, range, default_val, parent; | 726 | Lisp_Object function, table, arg, val, range, default_val, parent; |
| 713 | { | 727 | { |
| 714 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 728 | /* Pointer to the elements of TABLE. */ |
| 715 | int depth = XINT (tbl->depth); | 729 | Lisp_Object *contents; |
| 730 | /* Depth of TABLE. */ | ||
| 731 | int depth; | ||
| 732 | /* Minimum and maxinum characters covered by TABLE. */ | ||
| 733 | int min_char, max_char; | ||
| 734 | /* Number of characters covered by one element of TABLE. */ | ||
| 735 | int chars_in_block; | ||
| 736 | int from = XINT (XCAR (range)), to = XINT (XCDR (range)); | ||
| 716 | int i, c; | 737 | int i, c; |
| 717 | 738 | ||
| 718 | for (i = 0, c = XINT (tbl->min_char); i < chartab_size[depth]; | 739 | if (SUB_CHAR_TABLE_P (table)) |
| 719 | i++, c += chartab_chars[depth]) | ||
| 720 | { | 740 | { |
| 721 | Lisp_Object this; | 741 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 742 | |||
| 743 | depth = XINT (tbl->depth); | ||
| 744 | contents = tbl->contents; | ||
| 745 | min_char = XINT (tbl->min_char); | ||
| 746 | max_char = min_char + chartab_chars[depth - 1] - 1; | ||
| 747 | } | ||
| 748 | else | ||
| 749 | { | ||
| 750 | depth = 0; | ||
| 751 | contents = XCHAR_TABLE (table)->contents; | ||
| 752 | min_char = 0; | ||
| 753 | max_char = MAX_CHAR; | ||
| 754 | } | ||
| 755 | chars_in_block = chartab_chars[depth]; | ||
| 756 | |||
| 757 | if (to < max_char) | ||
| 758 | max_char = to; | ||
| 759 | /* Set I to the index of the first element to check. */ | ||
| 760 | if (from <= min_char) | ||
| 761 | i = 0; | ||
| 762 | else | ||
| 763 | i = (from - min_char) / chars_in_block; | ||
| 764 | for (c = min_char + chars_in_block * i; c <= max_char; | ||
| 765 | i++, c += chars_in_block) | ||
| 766 | { | ||
| 767 | Lisp_Object this = contents[i]; | ||
| 768 | int nextc = c + chars_in_block; | ||
| 722 | 769 | ||
| 723 | this = tbl->contents[i]; | ||
| 724 | if (SUB_CHAR_TABLE_P (this)) | 770 | if (SUB_CHAR_TABLE_P (this)) |
| 725 | val = map_sub_char_table (c_function, function, this, arg, val, range, | 771 | { |
| 726 | default_val, parent); | 772 | if (to >= nextc) |
| 773 | XSETCDR (range, make_number (nextc - 1)); | ||
| 774 | val = map_sub_char_table (c_function, function, this, arg, | ||
| 775 | val, range, default_val, parent); | ||
| 776 | } | ||
| 727 | else | 777 | else |
| 728 | { | 778 | { |
| 729 | if (NILP (this)) | 779 | if (NILP (this)) |
| 730 | this = default_val; | 780 | this = default_val; |
| 731 | if (NILP (this) && ! NILP (parent)) | ||
| 732 | this = CHAR_TABLE_REF (parent, c); | ||
| 733 | if (NILP (Fequal (val, this))) | 781 | if (NILP (Fequal (val, this))) |
| 734 | { | 782 | { |
| 735 | if (! NILP (val)) | 783 | int different_value = 1; |
| 784 | |||
| 785 | if (NILP (val)) | ||
| 786 | { | ||
| 787 | if (! NILP (parent)) | ||
| 788 | { | ||
| 789 | Lisp_Object temp = XCHAR_TABLE (parent)->parent; | ||
| 790 | |||
| 791 | /* This is to get a value of FROM in PARENT | ||
| 792 | without checking the parent of PARENT. */ | ||
| 793 | XCHAR_TABLE (parent)->parent = Qnil; | ||
| 794 | val = CHAR_TABLE_REF (parent, from); | ||
| 795 | XCHAR_TABLE (parent)->parent = temp; | ||
| 796 | XSETCDR (range, make_number (c - 1)); | ||
| 797 | val = map_sub_char_table (c_function, function, | ||
| 798 | parent, arg, val, range, | ||
| 799 | XCHAR_TABLE (parent)->defalt, | ||
| 800 | XCHAR_TABLE (parent)->parent); | ||
| 801 | if (! NILP (Fequal (val, this))) | ||
| 802 | different_value = 0; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | if (! NILP (val) && different_value) | ||
| 736 | { | 806 | { |
| 737 | XSETCDR (range, make_number (c - 1)); | 807 | XSETCDR (range, make_number (c - 1)); |
| 738 | if (depth == 3 | 808 | if (depth == 3 |
| @@ -752,9 +822,11 @@ map_sub_char_table (c_function, function, table, arg, val, range, | |||
| 752 | } | 822 | } |
| 753 | } | 823 | } |
| 754 | val = this; | 824 | val = this; |
| 825 | from = c; | ||
| 755 | XSETCAR (range, make_number (c)); | 826 | XSETCAR (range, make_number (c)); |
| 756 | } | 827 | } |
| 757 | } | 828 | } |
| 829 | XSETCDR (range, make_number (to)); | ||
| 758 | } | 830 | } |
| 759 | return val; | 831 | return val; |
| 760 | } | 832 | } |
| @@ -774,46 +846,35 @@ map_char_table (c_function, function, table, arg) | |||
| 774 | int c, i; | 846 | int c, i; |
| 775 | struct gcpro gcpro1, gcpro2, gcpro3; | 847 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 776 | 848 | ||
| 777 | range = Fcons (make_number (0), Qnil); | 849 | range = Fcons (make_number (0), make_number (MAX_CHAR)); |
| 778 | GCPRO3 (table, arg, range); | 850 | GCPRO3 (table, arg, range); |
| 779 | val = XCHAR_TABLE (table)->ascii; | 851 | val = XCHAR_TABLE (table)->ascii; |
| 780 | if (SUB_CHAR_TABLE_P (val)) | 852 | if (SUB_CHAR_TABLE_P (val)) |
| 781 | val = XSUB_CHAR_TABLE (val)->contents[0]; | 853 | val = XSUB_CHAR_TABLE (val)->contents[0]; |
| 782 | 854 | val = map_sub_char_table (c_function, function, table, arg, val, range, | |
| 783 | for (i = 0, c = 0; i < chartab_size[0]; i++, c += chartab_chars[0]) | 855 | XCHAR_TABLE (table)->defalt, |
| 856 | XCHAR_TABLE (table)->parent); | ||
| 857 | /* If VAL is nil and TABLE has a parent, we must consult the parent | ||
| 858 | recursively. */ | ||
| 859 | while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent)) | ||
| 784 | { | 860 | { |
| 785 | Lisp_Object this; | 861 | Lisp_Object parent = XCHAR_TABLE (table)->parent; |
| 786 | 862 | Lisp_Object temp = XCHAR_TABLE (parent)->parent; | |
| 787 | this = XCHAR_TABLE (table)->contents[i]; | 863 | int from = XINT (XCAR (range)); |
| 788 | if (SUB_CHAR_TABLE_P (this)) | 864 | |
| 789 | val = map_sub_char_table (c_function, function, this, arg, val, range, | 865 | /* This is to get a value of FROM in PARENT without checking the |
| 790 | XCHAR_TABLE (table)->defalt, | 866 | parent of PARENT. */ |
| 791 | XCHAR_TABLE (table)->parent); | 867 | XCHAR_TABLE (parent)->parent = Qnil; |
| 792 | else | 868 | val = CHAR_TABLE_REF (parent, from); |
| 793 | { | 869 | XCHAR_TABLE (parent)->parent = temp; |
| 794 | if (NILP (this)) | 870 | val = map_sub_char_table (c_function, function, parent, arg, val, range, |
| 795 | this = XCHAR_TABLE (table)->defalt; | 871 | XCHAR_TABLE (parent)->defalt, |
| 796 | if (NILP (this) && ! NILP (XCHAR_TABLE (table)->parent)) | 872 | XCHAR_TABLE (parent)->parent); |
| 797 | this = CHAR_TABLE_REF (XCHAR_TABLE (table)->parent, c); | 873 | table = parent; |
| 798 | if (NILP (Fequal (val, this))) | ||
| 799 | { | ||
| 800 | if (! NILP (val)) | ||
| 801 | { | ||
| 802 | XSETCDR (range, make_number (c - 1)); | ||
| 803 | if (c_function) | ||
| 804 | (*c_function) (arg, range, val); | ||
| 805 | else | ||
| 806 | call2 (function, range, val); | ||
| 807 | } | ||
| 808 | val = this; | ||
| 809 | XSETCAR (range, make_number (c)); | ||
| 810 | } | ||
| 811 | } | ||
| 812 | } | 874 | } |
| 813 | 875 | ||
| 814 | if (! NILP (val)) | 876 | if (! NILP (val)) |
| 815 | { | 877 | { |
| 816 | XSETCDR (range, make_number (c - 1)); | ||
| 817 | if (c_function) | 878 | if (c_function) |
| 818 | (*c_function) (arg, range, val); | 879 | (*c_function) (arg, range, val); |
| 819 | else | 880 | else |