aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Blandy1993-07-06 14:53:54 +0000
committerJim Blandy1993-07-06 14:53:54 +0000
commit24e3d3bf9eba91c26528d7507b1bb614ff3bb7c7 (patch)
tree76528c28a005cc7cdd12da6c8b38796d60786b2c
parentac811a55ab2bd8c228ea0153141c2bb89eac5acf (diff)
downloademacs-24e3d3bf9eba91c26528d7507b1bb614ff3bb7c7.tar.gz
emacs-24e3d3bf9eba91c26528d7507b1bb614ff3bb7c7.zip
* intervals.c (find_interval): Doc fixes, computation of
tree->position rearranged for clarity. * intervals.c (find_interval): Consistently treat POSITION as an actual buffer position, i.e. origin 1. The old code seemed undecided on this point. Treat the end of the buffer as being part of the rightmost interval. (adjust_intervals_for_insertion): Consistently treat POSITION as origin 1. (interval_deletion_adjustment): The exception: FROM should be origin zero here. Consistently treat it as such. Simplify code which shrinks and possibly deletes intervals. (adjust_intervals_for_deletion): Treat start as origin 1; our caller does. (set_point): Use buffer positions throughout, not a mix of buffer posns and origin zero posns. (get_local_map): Remove special case for POSITION at end of buffer; find_interval handles that case correctly. (verify_interval_modification): Remove special case for START at end of buffer. * textprop.c (validate_interval_range): End-of-buffer/string positions no longer need special handling. * intervals.c (make_new_interval): #if 0 this out. Nobody calls it.
-rw-r--r--src/intervals.c147
1 files changed, 61 insertions, 86 deletions
diff --git a/src/intervals.c b/src/intervals.c
index 81bf0b123ad..da391d559cb 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -432,8 +432,9 @@ split_interval_left (interval, offset)
432} 432}
433 433
434/* Find the interval containing text position POSITION in the text 434/* Find the interval containing text position POSITION in the text
435 represented by the interval tree TREE. POSITION is relative to 435 represented by the interval tree TREE. POSITION is a buffer
436 the beginning of that text. 436 position; the earliest position is 1. If POSITION is at the end of
437 the buffer, return the interval containing the last character.
437 438
438 The `position' field, which is a cache of an interval's position, 439 The `position' field, which is a cache of an interval's position,
439 is updated in the interval found. Other functions (e.g., next_interval) 440 is updated in the interval found. Other functions (e.g., next_interval)
@@ -444,25 +445,25 @@ find_interval (tree, position)
444 register INTERVAL tree; 445 register INTERVAL tree;
445 register int position; 446 register int position;
446{ 447{
447 register int relative_position = position; 448 /* The distance from the left edge of the subtree at TREE
449 to POSITION. */
450 register int relative_position = position - BEG;
448 451
449 if (NULL_INTERVAL_P (tree)) 452 if (NULL_INTERVAL_P (tree))
450 return NULL_INTERVAL; 453 return NULL_INTERVAL;
451 454
452 if (position > TOTAL_LENGTH (tree)) 455 if (relative_position > TOTAL_LENGTH (tree))
453 abort (); /* Paranoia */ 456 abort (); /* Paranoia */
454#if 0
455 position = TOTAL_LENGTH (tree);
456#endif
457 457
458 while (1) 458 while (1)
459 { 459 {
460 if (relative_position <= LEFT_TOTAL_LENGTH (tree)) 460 if (relative_position < LEFT_TOTAL_LENGTH (tree))
461 { 461 {
462 tree = tree->left; 462 tree = tree->left;
463 } 463 }
464 else if (relative_position > (TOTAL_LENGTH (tree) 464 else if (! NULL_RIGHT_CHILD (tree)
465 - RIGHT_TOTAL_LENGTH (tree))) 465 && relative_position >= (TOTAL_LENGTH (tree)
466 - RIGHT_TOTAL_LENGTH (tree)))
466 { 467 {
467 relative_position -= (TOTAL_LENGTH (tree) 468 relative_position -= (TOTAL_LENGTH (tree)
468 - RIGHT_TOTAL_LENGTH (tree)); 469 - RIGHT_TOTAL_LENGTH (tree));
@@ -470,8 +471,10 @@ find_interval (tree, position)
470 } 471 }
471 else 472 else
472 { 473 {
473 tree->position = LEFT_TOTAL_LENGTH (tree) 474 tree->position =
474 + position - relative_position + 1; 475 (position - relative_position /* the left edge of *tree */
476 + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */
477
475 return tree; 478 return tree;
476 } 479 }
477 } 480 }
@@ -639,16 +642,16 @@ adjust_intervals_for_insertion (tree, position, length)
639 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ 642 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
640 abort (); 643 abort ();
641 644
642 /* If inserting at point-max of a buffer, that position 645 /* If inserting at point-max of a buffer, that position will be out
643 will be out of range. */ 646 of range. Remember that buffer positions are 1-based. */
644 if (position > TOTAL_LENGTH (tree)) 647 if (position > BEG + TOTAL_LENGTH (tree))
645 position = TOTAL_LENGTH (tree); 648 position = BEG + TOTAL_LENGTH (tree);
646 649
647 i = find_interval (tree, position); 650 i = find_interval (tree, position);
648 /* If we are positioned between intervals, check the stickiness of 651 /* If we are positioned between intervals, check the stickiness of
649 both of them. */ 652 both of them. */
650 if (position == i->position 653 if (position == i->position
651 && position != 1) 654 && position != BEG)
652 { 655 {
653 register INTERVAL prev = previous_interval (i); 656 register INTERVAL prev = previous_interval (i);
654 657
@@ -747,11 +750,14 @@ delete_interval (i)
747 } 750 }
748} 751}
749 752
750/* Find the interval in TREE corresponding to the character position FROM 753/* Find the interval in TREE corresponding to the relative position
751 and delete as much as possible of AMOUNT from that interval, starting 754 FROM and delete as much as possible of AMOUNT from that interval.
752 after the relative position of FROM within it. Return the amount 755 Return the amount actually deleted, and if the interval was
753 actually deleted, and if the interval was zeroed-out, delete that 756 zeroed-out, delete that interval node from the tree.
754 interval node from the tree. 757
758 Note that FROM is actually origin zero, aka relative to the
759 leftmost edge of tree. This is appropriate since we call ourselves
760 recursively on subtrees.
755 761
756 Do this by recursing down TREE to the interval in question, and 762 Do this by recursing down TREE to the interval in question, and
757 deleting the appropriate amount of text. */ 763 deleting the appropriate amount of text. */
@@ -767,7 +773,7 @@ interval_deletion_adjustment (tree, from, amount)
767 return 0; 773 return 0;
768 774
769 /* Left branch */ 775 /* Left branch */
770 if (relative_position <= LEFT_TOTAL_LENGTH (tree)) 776 if (relative_position < LEFT_TOTAL_LENGTH (tree))
771 { 777 {
772 int subtract = interval_deletion_adjustment (tree->left, 778 int subtract = interval_deletion_adjustment (tree->left,
773 relative_position, 779 relative_position,
@@ -776,8 +782,8 @@ interval_deletion_adjustment (tree, from, amount)
776 return subtract; 782 return subtract;
777 } 783 }
778 /* Right branch */ 784 /* Right branch */
779 else if (relative_position > (TOTAL_LENGTH (tree) 785 else if (relative_position >= (TOTAL_LENGTH (tree)
780 - RIGHT_TOTAL_LENGTH (tree))) 786 - RIGHT_TOTAL_LENGTH (tree)))
781 { 787 {
782 int subtract; 788 int subtract;
783 789
@@ -792,55 +798,28 @@ interval_deletion_adjustment (tree, from, amount)
792 /* Here -- this node */ 798 /* Here -- this node */
793 else 799 else
794 { 800 {
795 /* If this is a zero-length, marker interval, then 801 /* How much can we delete from this interval? */
796 we must skip it. */ 802 int my_amount = ((tree->total_length
797 803 - RIGHT_TOTAL_LENGTH (tree))
798 if (relative_position == LEFT_TOTAL_LENGTH (tree) + 1) 804 - relative_position);
799 { 805
800 /* This means we're deleting from the beginning of this interval. */ 806 if (amount > my_amount)
801 register int my_amount = LENGTH (tree); 807 amount = my_amount;
802 808
803 if (amount < my_amount) 809 tree->total_length -= amount;
804 { 810 if (LENGTH (tree) == 0)
805 tree->total_length -= amount; 811 delete_interval (tree);
806 return amount; 812
807 } 813 return amount;
808 else
809 {
810 tree->total_length -= my_amount;
811 if (LENGTH (tree) != 0)
812 abort (); /* Paranoia */
813
814 delete_interval (tree);
815 return my_amount;
816 }
817 }
818 else /* Deleting starting in the middle. */
819 {
820 register int my_amount = ((tree->total_length
821 - RIGHT_TOTAL_LENGTH (tree))
822 - relative_position + 1);
823
824 if (amount <= my_amount)
825 {
826 tree->total_length -= amount;
827 return amount;
828 }
829 else
830 {
831 tree->total_length -= my_amount;
832 return my_amount;
833 }
834 }
835 } 814 }
836 815
837 /* Never reach here */ 816 /* Never reach here */
838} 817}
839 818
840/* Effect the adjustments necessary to the interval tree of BUFFER 819/* Effect the adjustments necessary to the interval tree of BUFFER to
841 to correspond to the deletion of LENGTH characters from that buffer 820 correspond to the deletion of LENGTH characters from that buffer
842 text. The deletion is effected at position START (relative to the 821 text. The deletion is effected at position START (which is a
843 buffer). */ 822 buffer position, i.e. origin 1). */
844 823
845static void 824static void
846adjust_intervals_for_deletion (buffer, start, length) 825adjust_intervals_for_deletion (buffer, start, length)
@@ -854,6 +833,10 @@ adjust_intervals_for_deletion (buffer, start, length)
854 if (NULL_INTERVAL_P (tree)) 833 if (NULL_INTERVAL_P (tree))
855 return; 834 return;
856 835
836 if (start > BEG + TOTAL_LENGTH (tree)
837 || start + length > BEG + TOTAL_LENGTH (tree))
838 abort ();
839
857 if (length == TOTAL_LENGTH (tree)) 840 if (length == TOTAL_LENGTH (tree))
858 { 841 {
859 buffer->intervals = NULL_INTERVAL; 842 buffer->intervals = NULL_INTERVAL;
@@ -866,11 +849,11 @@ adjust_intervals_for_deletion (buffer, start, length)
866 return; 849 return;
867 } 850 }
868 851
869 if (start > TOTAL_LENGTH (tree)) 852 if (start > BEG + TOTAL_LENGTH (tree))
870 start = TOTAL_LENGTH (tree); 853 start = BEG + TOTAL_LENGTH (tree);
871 while (left_to_delete > 0) 854 while (left_to_delete > 0)
872 { 855 {
873 left_to_delete -= interval_deletion_adjustment (tree, start, 856 left_to_delete -= interval_deletion_adjustment (tree, start - 1,
874 left_to_delete); 857 left_to_delete);
875 tree = buffer->intervals; 858 tree = buffer->intervals;
876 if (left_to_delete == tree->total_length) 859 if (left_to_delete == tree->total_length)
@@ -1030,6 +1013,9 @@ reproduce_tree (source, parent)
1030 return t; 1013 return t;
1031} 1014}
1032 1015
1016#if 0
1017/* Nobody calls this. Perhaps it's a vestige of an earlier design. */
1018
1033/* Make a new interval of length LENGTH starting at START in the 1019/* Make a new interval of length LENGTH starting at START in the
1034 group of intervals INTERVALS, which is actually an interval tree. 1020 group of intervals INTERVALS, which is actually an interval tree.
1035 Returns the new interval. 1021 Returns the new interval.
@@ -1070,6 +1056,7 @@ make_new_interval (intervals, start, length)
1070 split_interval_right (slot, length + 1); 1056 split_interval_right (slot, length + 1);
1071 return slot; 1057 return slot;
1072} 1058}
1059#endif
1073 1060
1074/* Insert the intervals of SOURCE into BUFFER at POSITION. 1061/* Insert the intervals of SOURCE into BUFFER at POSITION.
1075 1062
@@ -1244,7 +1231,6 @@ set_point (position, buffer)
1244 register struct buffer *buffer; 1231 register struct buffer *buffer;
1245{ 1232{
1246 register INTERVAL to, from, toprev, fromprev, target; 1233 register INTERVAL to, from, toprev, fromprev, target;
1247 register int iposition = position;
1248 int buffer_point; 1234 int buffer_point;
1249 register Lisp_Object obj; 1235 register Lisp_Object obj;
1250 int backwards = (position < BUF_PT (buffer)) ? 1 : 0; 1236 int backwards = (position < BUF_PT (buffer)) ? 1 : 0;
@@ -1265,20 +1251,14 @@ set_point (position, buffer)
1265 return; 1251 return;
1266 } 1252 }
1267 1253
1268 /* Position Z is really one past the last char in the buffer. */
1269 if (position == BUF_ZV (buffer))
1270 iposition = position - 1;
1271
1272 /* Set TO to the interval containing the char after POSITION, 1254 /* Set TO to the interval containing the char after POSITION,
1273 and TOPREV to the interval containing the char before POSITION. 1255 and TOPREV to the interval containing the char before POSITION.
1274 Either one may be null. They may be equal. */ 1256 Either one may be null. They may be equal. */
1275 to = find_interval (buffer->intervals, iposition); 1257 to = find_interval (buffer->intervals, position);
1276 if (position == BUF_BEGV (buffer)) 1258 if (position == BUF_BEGV (buffer))
1277 toprev = 0; 1259 toprev = 0;
1278 else if (to->position == position) 1260 else if (to->position == position)
1279 toprev = previous_interval (to); 1261 toprev = previous_interval (to);
1280 else if (iposition != position)
1281 toprev = to, to = 0;
1282 else 1262 else
1283 toprev = to; 1263 toprev = to;
1284 1264
@@ -1390,10 +1370,6 @@ get_local_map (position, buffer)
1390 if (position > BUF_Z (buffer) || position < BUF_BEG (buffer)) 1370 if (position > BUF_Z (buffer) || position < BUF_BEG (buffer))
1391 abort (); 1371 abort ();
1392 1372
1393 /* Position Z is really one past the last char in the buffer. */
1394 if (position == BUF_ZV (buffer))
1395 return current_buffer->keymap;
1396
1397 interval = find_interval (buffer->intervals, position); 1373 interval = find_interval (buffer->intervals, position);
1398 prop = textget (interval->plist, Qlocal_map); 1374 prop = textget (interval->plist, Qlocal_map);
1399 if (NILP (prop)) 1375 if (NILP (prop))
@@ -1465,8 +1441,7 @@ verify_interval_modification (buf, start, end)
1465 /* Set I to the interval containing the char after START, 1441 /* Set I to the interval containing the char after START,
1466 and PREV to the interval containing the char before START. 1442 and PREV to the interval containing the char before START.
1467 Either one may be null. They may be equal. */ 1443 Either one may be null. They may be equal. */
1468 i = find_interval (intervals, 1444 i = find_interval (intervals, start);
1469 (start == BUF_ZV (buf) ? start - 1 : start));
1470 1445
1471 if (start == BUF_BEGV (buf)) 1446 if (start == BUF_BEGV (buf))
1472 prev = 0; 1447 prev = 0;