diff options
| author | Jim Blandy | 1993-07-06 14:53:54 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-07-06 14:53:54 +0000 |
| commit | 24e3d3bf9eba91c26528d7507b1bb614ff3bb7c7 (patch) | |
| tree | 76528c28a005cc7cdd12da6c8b38796d60786b2c /src | |
| parent | ac811a55ab2bd8c228ea0153141c2bb89eac5acf (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/intervals.c | 147 |
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 | ||
| 845 | static void | 824 | static void |
| 846 | adjust_intervals_for_deletion (buffer, start, length) | 825 | adjust_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; |