aboutsummaryrefslogtreecommitdiffstats
path: root/src/chartab.c
diff options
context:
space:
mode:
authorKenichi Handa2007-06-25 10:25:21 +0000
committerKenichi Handa2007-06-25 10:25:21 +0000
commit57d53d1bdd44cac6c330736fe7c48e8ccaeee3a3 (patch)
tree2966e6ce10d34b8a0d4cdcb079336b59e5f8e72b /src/chartab.c
parentee82fbcd45722d310f1ed08a767cb33fd9efb48c (diff)
downloademacs-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/chartab.c')
-rw-r--r--src/chartab.c145
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
708static Lisp_Object 722static Lisp_Object
709map_sub_char_table (c_function, function, table, arg, val, range, 723map_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