Commit 944d4e4b authored by Karl Heuer's avatar Karl Heuer

(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.
parent afee9150
...@@ -78,15 +78,16 @@ create_root_interval (parent) ...@@ -78,15 +78,16 @@ create_root_interval (parent)
new->total_length = (BUF_Z (XBUFFER (parent)) new->total_length = (BUF_Z (XBUFFER (parent))
- BUF_BEG (XBUFFER (parent))); - BUF_BEG (XBUFFER (parent)));
BUF_INTERVALS (XBUFFER (parent)) = new; BUF_INTERVALS (XBUFFER (parent)) = new;
new->position = 1;
} }
else if (STRINGP (parent)) else if (STRINGP (parent))
{ {
new->total_length = XSTRING (parent)->size; new->total_length = XSTRING (parent)->size;
XSTRING (parent)->intervals = new; XSTRING (parent)->intervals = new;
new->position = 0;
} }
new->parent = (INTERVAL) XFASTINT (parent); new->parent = (INTERVAL) XFASTINT (parent);
new->position = 1;
return new; return new;
} }
...@@ -540,10 +541,34 @@ split_interval_left (interval, offset) ...@@ -540,10 +541,34 @@ split_interval_left (interval, offset)
return new; return new;
} }
/* Return the proper position for the first character
described by the interval tree SOURCE.
This is 1 if the parent is a buffer,
0 if the parent is a string or if there is no parent.
Don't use this function on an interval which is the child
of another interval! */
int
interval_start_pos (source)
INTERVAL source;
{
Lisp_Object parent;
if (NULL_INTERVAL_P (source))
return 0;
XSETFASTINT (parent, (EMACS_INT) source->parent);
if (BUFFERP (parent))
return BUF_BEG (XBUFFER (parent));
return 0;
}
/* Find the interval containing text position POSITION in the text /* Find the interval containing text position POSITION in the text
represented by the interval tree TREE. POSITION is a buffer represented by the interval tree TREE. POSITION is a buffer
position; the earliest position is 1. If POSITION is at the end of position (starting from 1) or a string index (starting from 0).
the buffer, return the interval containing the last character. If POSITION is at the end of the buffer or string,
return the interval containing the last character.
The `position' field, which is a cache of an interval's position, The `position' field, which is a cache of an interval's position,
is updated in the interval found. Other functions (e.g., next_interval) is updated in the interval found. Other functions (e.g., next_interval)
...@@ -556,11 +581,17 @@ find_interval (tree, position) ...@@ -556,11 +581,17 @@ find_interval (tree, position)
{ {
/* The distance from the left edge of the subtree at TREE /* The distance from the left edge of the subtree at TREE
to POSITION. */ to POSITION. */
register int relative_position = position - BEG; register int relative_position;
Lisp_Object parent;
if (NULL_INTERVAL_P (tree)) if (NULL_INTERVAL_P (tree))
return NULL_INTERVAL; return NULL_INTERVAL;
XSETFASTINT (parent, (EMACS_INT) tree->parent);
relative_position = position;
if (BUFFERP (parent))
relative_position -= BUF_BEG (XBUFFER (parent));
if (relative_position > TOTAL_LENGTH (tree)) if (relative_position > TOTAL_LENGTH (tree))
abort (); /* Paranoia */ abort (); /* Paranoia */
...@@ -582,9 +613,9 @@ find_interval (tree, position) ...@@ -582,9 +613,9 @@ find_interval (tree, position)
} }
else else
{ {
tree->position = tree->position
(position - relative_position /* the left edge of *tree */ = (position - relative_position /* the left edge of *tree */
+ LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */ + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */
return tree; return tree;
} }
...@@ -800,16 +831,22 @@ adjust_intervals_for_insertion (tree, position, length) ...@@ -800,16 +831,22 @@ adjust_intervals_for_insertion (tree, position, length)
register INTERVAL i; register INTERVAL i;
register INTERVAL temp; register INTERVAL temp;
int eobp = 0; int eobp = 0;
Lisp_Object parent;
int offset;
if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
abort (); abort ();
XSETFASTINT (parent, (EMACS_INT) tree->parent);
offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
/* If inserting at point-max of a buffer, that position will be out /* If inserting at point-max of a buffer, that position will be out
of range. Remember that buffer positions are 1-based. */ of range. Remember that buffer positions are 1-based. */
if (position >= BEG + TOTAL_LENGTH (tree)){ if (position >= TOTAL_LENGTH (tree) + offset)
position = BEG + TOTAL_LENGTH (tree); {
eobp = 1; position = TOTAL_LENGTH (tree) + offset;
} eobp = 1;
}
i = find_interval (tree, position); i = find_interval (tree, position);
...@@ -1249,12 +1286,17 @@ adjust_intervals_for_deletion (buffer, start, length) ...@@ -1249,12 +1286,17 @@ adjust_intervals_for_deletion (buffer, start, length)
register int left_to_delete = length; register int left_to_delete = length;
register INTERVAL tree = BUF_INTERVALS (buffer); register INTERVAL tree = BUF_INTERVALS (buffer);
register int deleted; register int deleted;
Lisp_Object parent;
int offset;
XSETFASTINT (parent, (EMACS_INT) tree->parent);
offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
if (NULL_INTERVAL_P (tree)) if (NULL_INTERVAL_P (tree))
return; return;
if (start > BEG + TOTAL_LENGTH (tree) if (start > offset + TOTAL_LENGTH (tree)
|| start + length > BEG + TOTAL_LENGTH (tree)) || start + length > offset + TOTAL_LENGTH (tree))
abort (); abort ();
if (length == TOTAL_LENGTH (tree)) if (length == TOTAL_LENGTH (tree))
...@@ -1269,11 +1311,11 @@ adjust_intervals_for_deletion (buffer, start, length) ...@@ -1269,11 +1311,11 @@ adjust_intervals_for_deletion (buffer, start, length)
return; return;
} }
if (start > BEG + TOTAL_LENGTH (tree)) if (start > offset + TOTAL_LENGTH (tree))
start = BEG + TOTAL_LENGTH (tree); start = offset + TOTAL_LENGTH (tree);
while (left_to_delete > 0) while (left_to_delete > 0)
{ {
left_to_delete -= interval_deletion_adjustment (tree, start - 1, left_to_delete -= interval_deletion_adjustment (tree, start - offset,
left_to_delete); left_to_delete);
tree = BUF_INTERVALS (buffer); tree = BUF_INTERVALS (buffer);
if (left_to_delete == tree->total_length) if (left_to_delete == tree->total_length)
...@@ -1481,6 +1523,11 @@ make_new_interval (intervals, start, length) ...@@ -1481,6 +1523,11 @@ make_new_interval (intervals, start, length)
/* Insert the intervals of SOURCE into BUFFER at POSITION. /* Insert the intervals of SOURCE into BUFFER at POSITION.
LENGTH is the length of the text in SOURCE. LENGTH is the length of the text in SOURCE.
The `position' field of the SOURCE intervals is assumed to be
consistent with its parent; therefore, SOURCE must be an
interval tree made with copy_interval or must be the whole
tree of a buffer or a string.
This is used in insdel.c when inserting Lisp_Strings into the This is used in insdel.c when inserting Lisp_Strings into the
buffer. The text corresponding to SOURCE is already in the buffer buffer. The text corresponding to SOURCE is already in the buffer
when this is called. The intervals of new tree are a copy of those 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,7 +1598,9 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
Lisp_Object buf; Lisp_Object buf;
XSETBUFFER (buf, buffer); XSETBUFFER (buf, buffer);
BUF_INTERVALS (buffer) = reproduce_tree (source, buf); BUF_INTERVALS (buffer) = reproduce_tree (source, buf);
/* Explicitly free the old tree here. */ BUF_INTERVALS (buffer)->position = 1;
/* Explicitly free the old tree here? */
return; return;
} }
...@@ -1571,6 +1620,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit) ...@@ -1571,6 +1620,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
about inserting properly. For now, just waste the old intervals. */ about inserting properly. For now, just waste the old intervals. */
{ {
BUF_INTERVALS (buffer) = reproduce_tree (source, tree->parent); BUF_INTERVALS (buffer) = reproduce_tree (source, tree->parent);
BUF_INTERVALS (buffer)->position = 1;
/* Explicitly free the old tree here. */ /* Explicitly free the old tree here. */
return; return;
...@@ -1583,7 +1633,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit) ...@@ -1583,7 +1633,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
this = under = find_interval (tree, position); this = under = find_interval (tree, position);
if (NULL_INTERVAL_P (under)) /* Paranoia */ if (NULL_INTERVAL_P (under)) /* Paranoia */
abort (); abort ();
over = find_interval (source, 1); over = find_interval (source, interval_start_pos (source));
/* Here for insertion in the middle of an interval. /* Here for insertion in the middle of an interval.
Split off an equivalent interval to the right, Split off an equivalent interval to the right,
...@@ -2017,7 +2067,8 @@ get_local_map (position, buffer) ...@@ -2017,7 +2067,8 @@ get_local_map (position, buffer)
} }
/* Produce an interval tree reflecting the intervals in /* Produce an interval tree reflecting the intervals in
TREE from START to START + LENGTH. */ TREE from START to START + LENGTH.
The new interval tree has no parent and has a starting-position of 0. */
INTERVAL INTERVAL
copy_intervals (tree, start, length) copy_intervals (tree, start, length)
...@@ -2040,7 +2091,7 @@ copy_intervals (tree, start, length) ...@@ -2040,7 +2091,7 @@ copy_intervals (tree, start, length)
return NULL_INTERVAL; return NULL_INTERVAL;
new = make_interval (); new = make_interval ();
new->position = 1; new->position = 0;
got = (LENGTH (i) - (start - i->position)); got = (LENGTH (i) - (start - i->position));
new->total_length = length; new->total_length = length;
copy_properties (i, new); copy_properties (i, new);
...@@ -2076,7 +2127,7 @@ copy_intervals_to_string (string, buffer, position, length) ...@@ -2076,7 +2127,7 @@ copy_intervals_to_string (string, buffer, position, length)
XSTRING (string)->intervals = interval_copy; XSTRING (string)->intervals = interval_copy;
} }
/* Return 1 if string S1 and S2 have identical properties; 0 otherwise. /* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
Assume they have identical characters. */ Assume they have identical characters. */
int int
...@@ -2084,13 +2135,11 @@ compare_string_intervals (s1, s2) ...@@ -2084,13 +2135,11 @@ compare_string_intervals (s1, s2)
Lisp_Object s1, s2; Lisp_Object s1, s2;
{ {
INTERVAL i1, i2; INTERVAL i1, i2;
int pos = 1; int pos = 0;
int end = XSTRING (s1)->size + 1; int end = XSTRING (s1)->size;
/* We specify 1 as position because the interval functions i1 = find_interval (XSTRING (s1)->intervals, 0);
always use positions starting at 1. */ i2 = find_interval (XSTRING (s2)->intervals, 0);
i1 = find_interval (XSTRING (s1)->intervals, 1);
i2 = find_interval (XSTRING (s2)->intervals, 1);
while (pos < end) while (pos < end)
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment