aboutsummaryrefslogtreecommitdiffstats
path: root/src/intervals.c
diff options
context:
space:
mode:
authorKarl Heuer1998-06-03 14:44:21 +0000
committerKarl Heuer1998-06-03 14:44:21 +0000
commit944d4e4b401fa1dc1d04f74856406bf5a4a813bf (patch)
treec5ef12302569c160a3e4ceaee6e5c933404cec96 /src/intervals.c
parentafee9150208892aada7bb3c60cc6b2357e620c72 (diff)
downloademacs-944d4e4b401fa1dc1d04f74856406bf5a4a813bf.tar.gz
emacs-944d4e4b401fa1dc1d04f74856406bf5a4a813bf.zip
(create_root_interval): Initialize position to 0
for a string. (interval_start_pos): New function. (find_interval): Handle string positions starting at 0. (adjust_intervals_for_insertion): Likewise. (adjust_intervals_for_deletion): Likewise. (compare_string_intervals): Likewise. (graft_intervals_into_buffer): Set `position' in reproduce_tree value. (copy_intervals): Init `position' to 0.
Diffstat (limited to 'src/intervals.c')
-rw-r--r--src/intervals.c103
1 files changed, 76 insertions, 27 deletions
diff --git a/src/intervals.c b/src/intervals.c
index b6a6caaa738..28fa540a383 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -78,15 +78,16 @@ create_root_interval (parent)
78 new->total_length = (BUF_Z (XBUFFER (parent)) 78 new->total_length = (BUF_Z (XBUFFER (parent))
79 - BUF_BEG (XBUFFER (parent))); 79 - BUF_BEG (XBUFFER (parent)));
80 BUF_INTERVALS (XBUFFER (parent)) = new; 80 BUF_INTERVALS (XBUFFER (parent)) = new;
81 new->position = 1;
81 } 82 }
82 else if (STRINGP (parent)) 83 else if (STRINGP (parent))
83 { 84 {
84 new->total_length = XSTRING (parent)->size; 85 new->total_length = XSTRING (parent)->size;
85 XSTRING (parent)->intervals = new; 86 XSTRING (parent)->intervals = new;
87 new->position = 0;
86 } 88 }
87 89
88 new->parent = (INTERVAL) XFASTINT (parent); 90 new->parent = (INTERVAL) XFASTINT (parent);
89 new->position = 1;
90 91
91 return new; 92 return new;
92} 93}
@@ -540,10 +541,34 @@ split_interval_left (interval, offset)
540 return new; 541 return new;
541} 542}
542 543
544/* Return the proper position for the first character
545 described by the interval tree SOURCE.
546 This is 1 if the parent is a buffer,
547 0 if the parent is a string or if there is no parent.
548
549 Don't use this function on an interval which is the child
550 of another interval! */
551
552int
553interval_start_pos (source)
554 INTERVAL source;
555{
556 Lisp_Object parent;
557
558 if (NULL_INTERVAL_P (source))
559 return 0;
560
561 XSETFASTINT (parent, (EMACS_INT) source->parent);
562 if (BUFFERP (parent))
563 return BUF_BEG (XBUFFER (parent));
564 return 0;
565}
566
543/* Find the interval containing text position POSITION in the text 567/* Find the interval containing text position POSITION in the text
544 represented by the interval tree TREE. POSITION is a buffer 568 represented by the interval tree TREE. POSITION is a buffer
545 position; the earliest position is 1. If POSITION is at the end of 569 position (starting from 1) or a string index (starting from 0).
546 the buffer, return the interval containing the last character. 570 If POSITION is at the end of the buffer or string,
571 return the interval containing the last character.
547 572
548 The `position' field, which is a cache of an interval's position, 573 The `position' field, which is a cache of an interval's position,
549 is updated in the interval found. Other functions (e.g., next_interval) 574 is updated in the interval found. Other functions (e.g., next_interval)
@@ -556,11 +581,17 @@ find_interval (tree, position)
556{ 581{
557 /* The distance from the left edge of the subtree at TREE 582 /* The distance from the left edge of the subtree at TREE
558 to POSITION. */ 583 to POSITION. */
559 register int relative_position = position - BEG; 584 register int relative_position;
585 Lisp_Object parent;
560 586
561 if (NULL_INTERVAL_P (tree)) 587 if (NULL_INTERVAL_P (tree))
562 return NULL_INTERVAL; 588 return NULL_INTERVAL;
563 589
590 XSETFASTINT (parent, (EMACS_INT) tree->parent);
591 relative_position = position;
592 if (BUFFERP (parent))
593 relative_position -= BUF_BEG (XBUFFER (parent));
594
564 if (relative_position > TOTAL_LENGTH (tree)) 595 if (relative_position > TOTAL_LENGTH (tree))
565 abort (); /* Paranoia */ 596 abort (); /* Paranoia */
566 597
@@ -582,9 +613,9 @@ find_interval (tree, position)
582 } 613 }
583 else 614 else
584 { 615 {
585 tree->position = 616 tree->position
586 (position - relative_position /* the left edge of *tree */ 617 = (position - relative_position /* the left edge of *tree */
587 + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */ 618 + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */
588 619
589 return tree; 620 return tree;
590 } 621 }
@@ -800,16 +831,22 @@ adjust_intervals_for_insertion (tree, position, length)
800 register INTERVAL i; 831 register INTERVAL i;
801 register INTERVAL temp; 832 register INTERVAL temp;
802 int eobp = 0; 833 int eobp = 0;
834 Lisp_Object parent;
835 int offset;
803 836
804 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ 837 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
805 abort (); 838 abort ();
806 839
840 XSETFASTINT (parent, (EMACS_INT) tree->parent);
841 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
842
807 /* If inserting at point-max of a buffer, that position will be out 843 /* If inserting at point-max of a buffer, that position will be out
808 of range. Remember that buffer positions are 1-based. */ 844 of range. Remember that buffer positions are 1-based. */
809 if (position >= BEG + TOTAL_LENGTH (tree)){ 845 if (position >= TOTAL_LENGTH (tree) + offset)
810 position = BEG + TOTAL_LENGTH (tree); 846 {
811 eobp = 1; 847 position = TOTAL_LENGTH (tree) + offset;
812 } 848 eobp = 1;
849 }
813 850
814 i = find_interval (tree, position); 851 i = find_interval (tree, position);
815 852
@@ -1249,12 +1286,17 @@ adjust_intervals_for_deletion (buffer, start, length)
1249 register int left_to_delete = length; 1286 register int left_to_delete = length;
1250 register INTERVAL tree = BUF_INTERVALS (buffer); 1287 register INTERVAL tree = BUF_INTERVALS (buffer);
1251 register int deleted; 1288 register int deleted;
1289 Lisp_Object parent;
1290 int offset;
1291
1292 XSETFASTINT (parent, (EMACS_INT) tree->parent);
1293 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
1252 1294
1253 if (NULL_INTERVAL_P (tree)) 1295 if (NULL_INTERVAL_P (tree))
1254 return; 1296 return;
1255 1297
1256 if (start > BEG + TOTAL_LENGTH (tree) 1298 if (start > offset + TOTAL_LENGTH (tree)
1257 || start + length > BEG + TOTAL_LENGTH (tree)) 1299 || start + length > offset + TOTAL_LENGTH (tree))
1258 abort (); 1300 abort ();
1259 1301
1260 if (length == TOTAL_LENGTH (tree)) 1302 if (length == TOTAL_LENGTH (tree))
@@ -1269,11 +1311,11 @@ adjust_intervals_for_deletion (buffer, start, length)
1269 return; 1311 return;
1270 } 1312 }
1271 1313
1272 if (start > BEG + TOTAL_LENGTH (tree)) 1314 if (start > offset + TOTAL_LENGTH (tree))
1273 start = BEG + TOTAL_LENGTH (tree); 1315 start = offset + TOTAL_LENGTH (tree);
1274 while (left_to_delete > 0) 1316 while (left_to_delete > 0)
1275 { 1317 {
1276 left_to_delete -= interval_deletion_adjustment (tree, start - 1, 1318 left_to_delete -= interval_deletion_adjustment (tree, start - offset,
1277 left_to_delete); 1319 left_to_delete);
1278 tree = BUF_INTERVALS (buffer); 1320 tree = BUF_INTERVALS (buffer);
1279 if (left_to_delete == tree->total_length) 1321 if (left_to_delete == tree->total_length)
@@ -1481,6 +1523,11 @@ make_new_interval (intervals, start, length)
1481/* Insert the intervals of SOURCE into BUFFER at POSITION. 1523/* Insert the intervals of SOURCE into BUFFER at POSITION.
1482 LENGTH is the length of the text in SOURCE. 1524 LENGTH is the length of the text in SOURCE.
1483 1525
1526 The `position' field of the SOURCE intervals is assumed to be
1527 consistent with its parent; therefore, SOURCE must be an
1528 interval tree made with copy_interval or must be the whole
1529 tree of a buffer or a string.
1530
1484 This is used in insdel.c when inserting Lisp_Strings into the 1531 This is used in insdel.c when inserting Lisp_Strings into the
1485 buffer. The text corresponding to SOURCE is already in the buffer 1532 buffer. The text corresponding to SOURCE is already in the buffer
1486 when this is called. The intervals of new tree are a copy of those 1533 when this is called. The intervals of new tree are a copy of those
@@ -1551,7 +1598,9 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1551 Lisp_Object buf; 1598 Lisp_Object buf;
1552 XSETBUFFER (buf, buffer); 1599 XSETBUFFER (buf, buffer);
1553 BUF_INTERVALS (buffer) = reproduce_tree (source, buf); 1600 BUF_INTERVALS (buffer) = reproduce_tree (source, buf);
1554 /* Explicitly free the old tree here. */ 1601 BUF_INTERVALS (buffer)->position = 1;
1602
1603 /* Explicitly free the old tree here? */
1555 1604
1556 return; 1605 return;
1557 } 1606 }
@@ -1571,6 +1620,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1571 about inserting properly. For now, just waste the old intervals. */ 1620 about inserting properly. For now, just waste the old intervals. */
1572 { 1621 {
1573 BUF_INTERVALS (buffer) = reproduce_tree (source, tree->parent); 1622 BUF_INTERVALS (buffer) = reproduce_tree (source, tree->parent);
1623 BUF_INTERVALS (buffer)->position = 1;
1574 /* Explicitly free the old tree here. */ 1624 /* Explicitly free the old tree here. */
1575 1625
1576 return; 1626 return;
@@ -1583,7 +1633,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1583 this = under = find_interval (tree, position); 1633 this = under = find_interval (tree, position);
1584 if (NULL_INTERVAL_P (under)) /* Paranoia */ 1634 if (NULL_INTERVAL_P (under)) /* Paranoia */
1585 abort (); 1635 abort ();
1586 over = find_interval (source, 1); 1636 over = find_interval (source, interval_start_pos (source));
1587 1637
1588 /* Here for insertion in the middle of an interval. 1638 /* Here for insertion in the middle of an interval.
1589 Split off an equivalent interval to the right, 1639 Split off an equivalent interval to the right,
@@ -2017,7 +2067,8 @@ get_local_map (position, buffer)
2017} 2067}
2018 2068
2019/* Produce an interval tree reflecting the intervals in 2069/* Produce an interval tree reflecting the intervals in
2020 TREE from START to START + LENGTH. */ 2070 TREE from START to START + LENGTH.
2071 The new interval tree has no parent and has a starting-position of 0. */
2021 2072
2022INTERVAL 2073INTERVAL
2023copy_intervals (tree, start, length) 2074copy_intervals (tree, start, length)
@@ -2040,7 +2091,7 @@ copy_intervals (tree, start, length)
2040 return NULL_INTERVAL; 2091 return NULL_INTERVAL;
2041 2092
2042 new = make_interval (); 2093 new = make_interval ();
2043 new->position = 1; 2094 new->position = 0;
2044 got = (LENGTH (i) - (start - i->position)); 2095 got = (LENGTH (i) - (start - i->position));
2045 new->total_length = length; 2096 new->total_length = length;
2046 copy_properties (i, new); 2097 copy_properties (i, new);
@@ -2076,7 +2127,7 @@ copy_intervals_to_string (string, buffer, position, length)
2076 XSTRING (string)->intervals = interval_copy; 2127 XSTRING (string)->intervals = interval_copy;
2077} 2128}
2078 2129
2079/* Return 1 if string S1 and S2 have identical properties; 0 otherwise. 2130/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
2080 Assume they have identical characters. */ 2131 Assume they have identical characters. */
2081 2132
2082int 2133int
@@ -2084,13 +2135,11 @@ compare_string_intervals (s1, s2)
2084 Lisp_Object s1, s2; 2135 Lisp_Object s1, s2;
2085{ 2136{
2086 INTERVAL i1, i2; 2137 INTERVAL i1, i2;
2087 int pos = 1; 2138 int pos = 0;
2088 int end = XSTRING (s1)->size + 1; 2139 int end = XSTRING (s1)->size;
2089 2140
2090 /* We specify 1 as position because the interval functions 2141 i1 = find_interval (XSTRING (s1)->intervals, 0);
2091 always use positions starting at 1. */ 2142 i2 = find_interval (XSTRING (s2)->intervals, 0);
2092 i1 = find_interval (XSTRING (s1)->intervals, 1);
2093 i2 = find_interval (XSTRING (s2)->intervals, 1);
2094 2143
2095 while (pos < end) 2144 while (pos < end)
2096 { 2145 {