/* Code for doing intervals.
- Copyright (C) 1993-1995, 1997-1998, 2001-2011 Free Software Foundation, Inc.
+ Copyright (C) 1993-1995, 1997-1998, 2001-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
+
+#define INTERVALS_INLINE EXTERN_INLINE
+
#include <setjmp.h>
#include <intprops.h>
#include "lisp.h"
#include "intervals.h"
+#include "character.h"
#include "buffer.h"
#include "puresize.h"
#include "keyboard.h"
{
new->total_length = (BUF_Z (XBUFFER (parent))
- BUF_BEG (XBUFFER (parent)));
- CHECK_TOTAL_LENGTH (new);
- BUF_INTERVALS (XBUFFER (parent)) = new;
+ eassert (0 <= TOTAL_LENGTH (new));
+ buffer_set_intervals (XBUFFER (parent), new);
new->position = BEG;
}
else if (STRINGP (parent))
{
new->total_length = SCHARS (parent);
- CHECK_TOTAL_LENGTH (new);
- STRING_SET_INTERVALS (parent, new);
+ eassert (0 <= TOTAL_LENGTH (new));
+ string_set_intervals (parent, new);
new->position = 0;
}
- SET_INTERVAL_OBJECT (new, parent);
+ interval_set_object (new, parent);
return new;
}
return;
COPY_INTERVAL_CACHE (source, target);
- target->plist = Fcopy_sequence (source->plist);
+ interval_set_plist (target, Fcopy_sequence (source->plist));
}
/* Merge the properties of interval SOURCE into the properties
if (NILP (val))
{
val = XCAR (o);
- target->plist = Fcons (sym, Fcons (val, target->plist));
+ interval_set_plist (target, Fcons (sym, Fcons (val, target->plist)));
}
o = XCDR (o);
}
traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg)
{
/* Minimize stack usage. */
- while (!NULL_INTERVAL_P (tree))
+ while (tree)
{
(*function) (tree, arg);
- if (NULL_INTERVAL_P (tree->right))
+ if (!tree->right)
tree = tree->left;
else
{
traverse_intervals (INTERVAL tree, ptrdiff_t position,
void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg)
{
- while (!NULL_INTERVAL_P (tree))
+ while (tree)
{
traverse_intervals (tree->left, position, function, arg);
position += LEFT_TOTAL_LENGTH (tree);
{
icount = 0;
search_interval = i;
- found_interval = NULL_INTERVAL;
+ found_interval = NULL;
traverse_intervals_noorder (tree, &check_for_interval, Qnil);
return found_interval;
}
if (! ROOT_INTERVAL_P (interval))
{
if (AM_LEFT_CHILD (interval))
- INTERVAL_PARENT (interval)->left = B;
+ interval_set_left (INTERVAL_PARENT (interval), B);
else
- INTERVAL_PARENT (interval)->right = B;
+ interval_set_right (INTERVAL_PARENT (interval), B);
}
- COPY_INTERVAL_PARENT (B, interval);
+ interval_copy_parent (B, interval);
/* Make B the parent of A */
i = B->right;
- B->right = interval;
- SET_INTERVAL_PARENT (interval, B);
+ interval_set_right (B, interval);
+ interval_set_parent (interval, B);
/* Make A point to c */
- interval->left = i;
- if (! NULL_INTERVAL_P (i))
- SET_INTERVAL_PARENT (i, interval);
+ interval_set_left (interval, i);
+ if (i)
+ interval_set_parent (i, interval);
/* A's total length is decreased by the length of B and its left child. */
interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
- CHECK_TOTAL_LENGTH (interval);
+ eassert (0 <= TOTAL_LENGTH (interval));
/* B must have the same total length of A. */
B->total_length = old_total;
- CHECK_TOTAL_LENGTH (B);
+ eassert (0 <= TOTAL_LENGTH (B));
return B;
}
if (! ROOT_INTERVAL_P (interval))
{
if (AM_LEFT_CHILD (interval))
- INTERVAL_PARENT (interval)->left = B;
+ interval_set_left (INTERVAL_PARENT (interval), B);
else
- INTERVAL_PARENT (interval)->right = B;
+ interval_set_right (INTERVAL_PARENT (interval), B);
}
- COPY_INTERVAL_PARENT (B, interval);
+ interval_copy_parent (B, interval);
/* Make B the parent of A */
i = B->left;
- B->left = interval;
- SET_INTERVAL_PARENT (interval, B);
+ interval_set_left (B, interval);
+ interval_set_parent (interval, B);
/* Make A point to c */
- interval->right = i;
- if (! NULL_INTERVAL_P (i))
- SET_INTERVAL_PARENT (i, interval);
+ interval_set_right (interval, i);
+ if (i)
+ interval_set_parent (i, interval);
/* A's total length is decreased by the length of B and its right child. */
interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
- CHECK_TOTAL_LENGTH (interval);
+ eassert (0 <= TOTAL_LENGTH (interval));
/* B must have the same total length of A. */
B->total_length = old_total;
- CHECK_TOTAL_LENGTH (B);
+ eassert (0 <= TOTAL_LENGTH (B));
return B;
}
if (have_parent)
{
if (BUFFERP (parent))
- BUF_INTERVALS (XBUFFER (parent)) = interval;
+ buffer_set_intervals (XBUFFER (parent), interval);
else if (STRINGP (parent))
- STRING_SET_INTERVALS (parent, interval);
+ string_set_intervals (parent, interval);
}
return interval;
INTERVAL
balance_intervals (INTERVAL tree)
{
- if (tree == NULL_INTERVAL)
- return NULL_INTERVAL;
+ return tree ? balance_intervals_internal (tree) : NULL;
+}
+
+/* Rebalance text properties of B. */
- return balance_intervals_internal (tree);
+static void
+buffer_balance_intervals (struct buffer *b)
+{
+ INTERVAL i;
+
+ eassert (b != NULL);
+ i = buffer_get_intervals (b);
+ if (i)
+ buffer_set_intervals (b, balance_an_interval (i));
}
-\f
+
/* Split INTERVAL into two pieces, starting the second piece at
character position OFFSET (counting from 0), relative to INTERVAL.
INTERVAL becomes the left-hand piece, and the right-hand piece
ptrdiff_t new_length = LENGTH (interval) - offset;
new->position = position + offset;
- SET_INTERVAL_PARENT (new, interval);
+ interval_set_parent (new, interval);
if (NULL_RIGHT_CHILD (interval))
{
- interval->right = new;
+ interval_set_right (interval, new);
new->total_length = new_length;
- CHECK_TOTAL_LENGTH (new);
+ eassert (0 <= TOTAL_LENGTH (new));
}
else
{
/* Insert the new node between INTERVAL and its right child. */
- new->right = interval->right;
- SET_INTERVAL_PARENT (interval->right, new);
- interval->right = new;
+ interval_set_right (new, interval->right);
+ interval_set_parent (interval->right, new);
+ interval_set_right (interval, new);
new->total_length = new_length + new->right->total_length;
- CHECK_TOTAL_LENGTH (new);
+ eassert (0 <= TOTAL_LENGTH (new));
balance_an_interval (new);
}
new->position = interval->position;
interval->position = interval->position + offset;
- SET_INTERVAL_PARENT (new, interval);
+ interval_set_parent (new, interval);
if (NULL_LEFT_CHILD (interval))
{
- interval->left = new;
+ interval_set_left (interval, new);
new->total_length = new_length;
- CHECK_TOTAL_LENGTH (new);
+ eassert (0 <= TOTAL_LENGTH (new));
}
else
{
/* Insert the new node between INTERVAL and its left child. */
- new->left = interval->left;
- SET_INTERVAL_PARENT (new->left, new);
- interval->left = new;
+ interval_set_left (new, interval->left);
+ interval_set_parent (new->left, new);
+ interval_set_left (interval, new);
new->total_length = new_length + new->left->total_length;
- CHECK_TOTAL_LENGTH (new);
+ eassert (0 <= TOTAL_LENGTH (new));
balance_an_interval (new);
}
{
Lisp_Object parent;
- if (NULL_INTERVAL_P (source))
+ if (!source)
return 0;
if (! INTERVAL_HAS_OBJECT (source))
to POSITION. */
register ptrdiff_t relative_position;
- if (NULL_INTERVAL_P (tree))
- return NULL_INTERVAL;
+ if (!tree)
+ return NULL;
relative_position = position;
if (INTERVAL_HAS_OBJECT (tree))
relative_position -= BUF_BEG (XBUFFER (parent));
}
- if (relative_position > TOTAL_LENGTH (tree))
- abort (); /* Paranoia */
+ eassert (relative_position <= TOTAL_LENGTH (tree));
if (!handling_signal)
tree = balance_possible_root_interval (tree);
register INTERVAL i = interval;
register ptrdiff_t next_position;
- if (NULL_INTERVAL_P (i))
- return NULL_INTERVAL;
+ if (!i)
+ return NULL;
next_position = interval->position + LENGTH (interval);
if (! NULL_RIGHT_CHILD (i))
i = INTERVAL_PARENT (i);
}
- return NULL_INTERVAL;
+ return NULL;
}
/* Find the preceding interval (lexicographically) to INTERVAL.
{
register INTERVAL i;
- if (NULL_INTERVAL_P (interval))
- return NULL_INTERVAL;
+ if (!interval)
+ return NULL;
if (! NULL_LEFT_CHILD (interval))
{
i = INTERVAL_PARENT (i);
}
- return NULL_INTERVAL;
+ return NULL;
}
/* Find the interval containing POS given some non-NULL INTERVAL
INTERVAL
update_interval (register INTERVAL i, ptrdiff_t pos)
{
- if (NULL_INTERVAL_P (i))
- return NULL_INTERVAL;
+ if (!i)
+ return NULL;
while (1)
{
}
}
-\f
-#if 0
-/* Traverse a path down the interval tree TREE to the interval
- containing POSITION, adjusting all nodes on the path for
- an addition of LENGTH characters. Insertion between two intervals
- (i.e., point == i->position, where i is second interval) means
- text goes into second interval.
-
- Modifications are needed to handle the hungry bits -- after simply
- finding the interval at position (don't add length going down),
- if it's the beginning of the interval, get the previous interval
- and check the hungry bits of both. Then add the length going back up
- to the root. */
-
-static INTERVAL
-adjust_intervals_for_insertion (INTERVAL tree, ptrdiff_t position,
- ptrdiff_t length)
-{
- register ptrdiff_t relative_position;
- register INTERVAL this;
-
- if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
- abort ();
-
- /* If inserting at point-max of a buffer, that position
- will be out of range */
- if (position > TOTAL_LENGTH (tree))
- position = TOTAL_LENGTH (tree);
- relative_position = position;
- this = tree;
-
- while (1)
- {
- if (relative_position <= LEFT_TOTAL_LENGTH (this))
- {
- this->total_length += length;
- CHECK_TOTAL_LENGTH (this);
- this = this->left;
- }
- else if (relative_position > (TOTAL_LENGTH (this)
- - RIGHT_TOTAL_LENGTH (this)))
- {
- relative_position -= (TOTAL_LENGTH (this)
- - RIGHT_TOTAL_LENGTH (this));
- this->total_length += length;
- CHECK_TOTAL_LENGTH (this);
- this = this->right;
- }
- else
- {
- /* If we are to use zero-length intervals as buffer pointers,
- then this code will have to change. */
- this->total_length += length;
- CHECK_TOTAL_LENGTH (this);
- this->position = LEFT_TOTAL_LENGTH (this)
- + position - relative_position + 1;
- return tree;
- }
- }
-}
-#endif
-
/* Effect an adjustment corresponding to the addition of LENGTH characters
of text. Do this by finding the interval containing POSITION in the
interval tree TREE, and then adjusting all of its ancestors by adding
Lisp_Object parent;
ptrdiff_t offset;
- if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
- abort ();
+ eassert (TOTAL_LENGTH (tree) > 0);
GET_INTERVAL_OBJECT (parent, tree);
offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
{
temp->total_length += length;
- CHECK_TOTAL_LENGTH (temp);
+ eassert (0 <= TOTAL_LENGTH (temp));
temp = balance_possible_root_interval (temp);
}
Lisp_Object pleft, pright;
struct interval newi;
- pleft = NULL_INTERVAL_P (prev) ? Qnil : prev->plist;
- pright = NULL_INTERVAL_P (i) ? Qnil : i->plist;
- newi.plist = merge_properties_sticky (pleft, pright);
+ RESET_INTERVAL (&newi);
+ pleft = prev ? prev->plist : Qnil;
+ pright = i ? i->plist : Qnil;
+ interval_set_plist (&newi, merge_properties_sticky (pleft, pright));
if (! prev) /* i.e. position == BEG */
{
if (! intervals_equal (i, &newi))
{
i = split_interval_left (i, length);
- i->plist = newi.plist;
+ interval_set_plist (i, newi.plist);
}
}
else if (! intervals_equal (prev, &newi))
{
- prev = split_interval_right (prev,
- position - prev->position);
- prev->plist = newi.plist;
- if (! NULL_INTERVAL_P (i)
- && intervals_equal (prev, i))
+ prev = split_interval_right (prev, position - prev->position);
+ interval_set_plist (prev, newi.plist);
+ if (i && intervals_equal (prev, i))
merge_interval_right (prev);
}
for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
{
temp->total_length += length;
- CHECK_TOTAL_LENGTH (temp);
+ eassert (0 <= TOTAL_LENGTH (temp));
temp = balance_possible_root_interval (temp);
}
}
register INTERVAL migrate, this;
register ptrdiff_t migrate_amt;
- if (NULL_INTERVAL_P (i->left))
+ if (!i->left)
return i->right;
- if (NULL_INTERVAL_P (i->right))
+ if (!i->right)
return i->left;
migrate = i->left;
migrate_amt = i->left->total_length;
this = i->right;
this->total_length += migrate_amt;
- while (! NULL_INTERVAL_P (this->left))
+ while (this->left)
{
this = this->left;
this->total_length += migrate_amt;
}
- CHECK_TOTAL_LENGTH (this);
- this->left = migrate;
- SET_INTERVAL_PARENT (migrate, this);
+ eassert (0 <= TOTAL_LENGTH (this));
+ interval_set_left (this, migrate);
+ interval_set_parent (migrate, this);
return i->right;
}
register INTERVAL parent;
ptrdiff_t amt = LENGTH (i);
- if (amt > 0) /* Only used on zero-length intervals now. */
- abort ();
+ eassert (amt == 0); /* Only used on zero-length intervals now. */
if (ROOT_INTERVAL_P (i))
{
Lisp_Object owner;
GET_INTERVAL_OBJECT (owner, i);
parent = delete_node (i);
- if (! NULL_INTERVAL_P (parent))
- SET_INTERVAL_OBJECT (parent, owner);
+ if (parent)
+ interval_set_object (parent, owner);
if (BUFFERP (owner))
- BUF_INTERVALS (XBUFFER (owner)) = parent;
+ buffer_set_intervals (XBUFFER (owner), parent);
else if (STRINGP (owner))
- STRING_SET_INTERVALS (owner, parent);
+ string_set_intervals (owner, parent);
else
abort ();
parent = INTERVAL_PARENT (i);
if (AM_LEFT_CHILD (i))
{
- parent->left = delete_node (i);
- if (! NULL_INTERVAL_P (parent->left))
- SET_INTERVAL_PARENT (parent->left, parent);
+ interval_set_left (parent, delete_node (i));
+ if (parent->left)
+ interval_set_parent (parent->left, parent);
}
else
{
- parent->right = delete_node (i);
- if (! NULL_INTERVAL_P (parent->right))
- SET_INTERVAL_PARENT (parent->right, parent);
+ interval_set_right (parent, delete_node (i));
+ if (parent->right)
+ interval_set_parent (parent->right, parent);
}
}
\f
{
register ptrdiff_t relative_position = from;
- if (NULL_INTERVAL_P (tree))
+ if (!tree)
return 0;
- /* Left branch */
+ /* Left branch. */
if (relative_position < LEFT_TOTAL_LENGTH (tree))
{
ptrdiff_t subtract = interval_deletion_adjustment (tree->left,
relative_position,
amount);
tree->total_length -= subtract;
- CHECK_TOTAL_LENGTH (tree);
+ eassert (0 <= TOTAL_LENGTH (tree));
return subtract;
}
- /* Right branch */
+ /* Right branch. */
else if (relative_position >= (TOTAL_LENGTH (tree)
- RIGHT_TOTAL_LENGTH (tree)))
{
relative_position,
amount);
tree->total_length -= subtract;
- CHECK_TOTAL_LENGTH (tree);
+ eassert (0 <= TOTAL_LENGTH (tree));
return subtract;
}
/* Here -- this node. */
amount = my_amount;
tree->total_length -= amount;
- CHECK_TOTAL_LENGTH (tree);
+ eassert (0 <= TOTAL_LENGTH (tree));
if (LENGTH (tree) == 0)
delete_interval (tree);
ptrdiff_t start, ptrdiff_t length)
{
register ptrdiff_t left_to_delete = length;
- register INTERVAL tree = BUF_INTERVALS (buffer);
+ register INTERVAL tree = buffer_get_intervals (buffer);
Lisp_Object parent;
ptrdiff_t offset;
GET_INTERVAL_OBJECT (parent, tree);
offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
- if (NULL_INTERVAL_P (tree))
+ if (!tree)
return;
- if (start > offset + TOTAL_LENGTH (tree)
- || start + length > offset + TOTAL_LENGTH (tree))
- abort ();
+ eassert (start <= offset + TOTAL_LENGTH (tree)
+ && start + length <= offset + TOTAL_LENGTH (tree));
if (length == TOTAL_LENGTH (tree))
{
- BUF_INTERVALS (buffer) = NULL_INTERVAL;
+ buffer_set_intervals (buffer, NULL);
return;
}
if (ONLY_INTERVAL_P (tree))
{
tree->total_length -= length;
- CHECK_TOTAL_LENGTH (tree);
+ eassert (0 <= TOTAL_LENGTH (tree));
return;
}
{
left_to_delete -= interval_deletion_adjustment (tree, start - offset,
left_to_delete);
- tree = BUF_INTERVALS (buffer);
+ tree = buffer_get_intervals (buffer);
if (left_to_delete == tree->total_length)
{
- BUF_INTERVALS (buffer) = NULL_INTERVAL;
+ buffer_set_intervals (buffer, NULL);
return;
}
}
compiler that does not allow calling a static function (here,
adjust_intervals_for_deletion) from a non-static inline function. */
-static inline void
-static_offset_intervals (struct buffer *buffer, ptrdiff_t start,
- ptrdiff_t length)
+void
+offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
{
- if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) || length == 0)
+ if (!buffer_get_intervals (buffer) || length == 0)
return;
if (length > 0)
- adjust_intervals_for_insertion (BUF_INTERVALS (buffer), start, length);
+ adjust_intervals_for_insertion (buffer_get_intervals (buffer),
+ start, length);
else
{
IF_LINT (if (length < - TYPE_MAXIMUM (ptrdiff_t)) abort ();)
adjust_intervals_for_deletion (buffer, start, -length);
}
}
-
-inline void
-offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
-{
- static_offset_intervals (buffer, start, length);
-}
\f
/* Merge interval I with its lexicographic successor. The resulting
interval is returned, and has the properties of the original
register ptrdiff_t absorb = LENGTH (i);
register INTERVAL successor;
- /* Zero out this interval. */
- i->total_length -= absorb;
- CHECK_TOTAL_LENGTH (i);
-
/* Find the succeeding interval. */
if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb
as we descend. */
while (! NULL_LEFT_CHILD (successor))
{
successor->total_length += absorb;
- CHECK_TOTAL_LENGTH (successor);
+ eassert (0 <= TOTAL_LENGTH (successor));
successor = successor->left;
}
successor->total_length += absorb;
- CHECK_TOTAL_LENGTH (successor);
+ eassert (0 <= TOTAL_LENGTH (successor));
delete_interval (i);
return successor;
}
+ /* Zero out this interval. */
+ i->total_length -= absorb;
+ eassert (0 <= TOTAL_LENGTH (i));
+
successor = i;
while (! NULL_PARENT (successor)) /* It's above us. Subtract as
we ascend. */
successor = INTERVAL_PARENT (successor);
successor->total_length -= absorb;
- CHECK_TOTAL_LENGTH (successor);
+ eassert (0 <= TOTAL_LENGTH (successor));
}
/* This must be the rightmost or last interval and cannot
register ptrdiff_t absorb = LENGTH (i);
register INTERVAL predecessor;
- /* Zero out this interval. */
- i->total_length -= absorb;
- CHECK_TOTAL_LENGTH (i);
-
/* Find the preceding interval. */
if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down,
adding ABSORB as we go. */
while (! NULL_RIGHT_CHILD (predecessor))
{
predecessor->total_length += absorb;
- CHECK_TOTAL_LENGTH (predecessor);
+ eassert (0 <= TOTAL_LENGTH (predecessor));
predecessor = predecessor->right;
}
predecessor->total_length += absorb;
- CHECK_TOTAL_LENGTH (predecessor);
+ eassert (0 <= TOTAL_LENGTH (predecessor));
delete_interval (i);
return predecessor;
}
+ /* Zero out this interval. */
+ i->total_length -= absorb;
+ eassert (0 <= TOTAL_LENGTH (i));
+
predecessor = i;
while (! NULL_PARENT (predecessor)) /* It's above us. Go up,
- subtracting ABSORB. */
+ subtracting ABSORB. */
{
if (AM_RIGHT_CHILD (predecessor))
{
predecessor = INTERVAL_PARENT (predecessor);
predecessor->total_length -= absorb;
- CHECK_TOTAL_LENGTH (predecessor);
+ eassert (0 <= TOTAL_LENGTH (predecessor));
}
/* This must be the leftmost or first interval and cannot
{
register INTERVAL t = make_interval ();
- memcpy (t, source, INTERVAL_SIZE);
+ memcpy (t, source, sizeof *t);
copy_properties (source, t);
- SET_INTERVAL_PARENT (t, parent);
+ interval_set_parent (t, parent);
if (! NULL_LEFT_CHILD (source))
- t->left = reproduce_tree (source->left, t);
+ interval_set_left (t, reproduce_tree (source->left, t));
if (! NULL_RIGHT_CHILD (source))
- t->right = reproduce_tree (source->right, t);
+ interval_set_right (t, reproduce_tree (source->right, t));
return t;
}
{
register INTERVAL t = make_interval ();
- memcpy (t, source, INTERVAL_SIZE);
+ memcpy (t, source, sizeof *t);
copy_properties (source, t);
- SET_INTERVAL_OBJECT (t, parent);
+ interval_set_object (t, parent);
if (! NULL_LEFT_CHILD (source))
- t->left = reproduce_tree (source->left, t);
+ interval_set_left (t, reproduce_tree (source->left, t));
if (! NULL_RIGHT_CHILD (source))
- t->right = reproduce_tree (source->right, t);
+ interval_set_right (t, reproduce_tree (source->right, t));
return t;
}
-
-#if 0
-/* Nobody calls this. Perhaps it's a vestige of an earlier design. */
-
-/* Make a new interval of length LENGTH starting at START in the
- group of intervals INTERVALS, which is actually an interval tree.
- Returns the new interval.
-
- Generate an error if the new positions would overlap an existing
- interval. */
-
-static INTERVAL
-make_new_interval (INTERVAL intervals, ptrdiff_t start, ptrdiff_t length)
-{
- INTERVAL slot;
-
- slot = find_interval (intervals, start);
- if (start + length > slot->position + LENGTH (slot))
- error ("Interval would overlap");
-
- if (start == slot->position && length == LENGTH (slot))
- return slot;
-
- if (slot->position == start)
- {
- /* New right node. */
- split_interval_right (slot, length);
- return slot;
- }
-
- if (slot->position + LENGTH (slot) == start + length)
- {
- /* New left node. */
- split_interval_left (slot, LENGTH (slot) - length);
- return slot;
- }
-
- /* Convert interval SLOT into three intervals. */
- split_interval_left (slot, start - slot->position);
- split_interval_right (slot, length);
- return slot;
-}
-#endif
\f
/* Insert the intervals of SOURCE into BUFFER at POSITION.
LENGTH is the length of the text in SOURCE.
cases -- either insertion happened in the middle of some interval,
or between two intervals.
- If the text goes into the middle of an interval, then new
- intervals are created in the middle with only the properties of
- the new text, *unless* the macro MERGE_INSERTIONS is true, in
- which case the new text has the union of its properties and those
- of the text into which it was inserted.
+ If the text goes into the middle of an interval, then new intervals
+ are created in the middle, and new text has the union of its properties
+ and those of the text into which it was inserted.
If the text goes between two intervals, then if neither interval
had its appropriate sticky property set (front_sticky, rear_sticky),
register INTERVAL tree;
ptrdiff_t over_used;
- tree = BUF_INTERVALS (buffer);
+ tree = buffer_get_intervals (buffer);
/* If the new text has no properties, then with inheritance it
becomes part of whatever interval it was inserted into.
To prevent inheritance, we must clear out the properties
of the newly inserted text. */
- if (NULL_INTERVAL_P (source))
+ if (!source)
{
Lisp_Object buf;
- if (!inherit && !NULL_INTERVAL_P (tree) && length > 0)
+ if (!inherit && tree && length > 0)
{
XSETBUFFER (buf, buffer);
set_text_properties_1 (make_number (position),
make_number (position + length),
Qnil, buf, 0);
}
- if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
- /* Shouldn't be necessary. -stef */
- BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
+ /* Shouldn't be necessary. --Stef */
+ buffer_balance_intervals (buffer);
return;
}
- if (NULL_INTERVAL_P (tree))
- {
+ eassert (length == TOTAL_LENGTH (source));
+
+ if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length)
+ {
/* The inserted text constitutes the whole buffer, so
simply copy over the interval structure. */
- if ((BUF_Z (buffer) - BUF_BEG (buffer)) == TOTAL_LENGTH (source))
- {
- Lisp_Object buf;
- XSETBUFFER (buf, buffer);
- BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf);
- BUF_INTERVALS (buffer)->position = BEG;
- BUF_INTERVALS (buffer)->up_obj = 1;
-
- return;
- }
+ Lisp_Object buf;
+ XSETBUFFER (buf, buffer);
+ buffer_set_intervals (buffer, reproduce_tree_obj (source, buf));
+ buffer_get_intervals (buffer)->position = BUF_BEG (buffer);
+ eassert (buffer_get_intervals (buffer)->up_obj == 1);
+ return;
+ }
+ else if (!tree)
+ {
/* Create an interval tree in which to place a copy
of the intervals of the inserted string. */
- {
Lisp_Object buf;
+
XSETBUFFER (buf, buffer);
tree = create_root_interval (buf);
- }
}
- else if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source))
- /* If the buffer contains only the new string, but
- there was already some interval tree there, then it may be
- some zero length intervals. Eventually, do something clever
- about inserting properly. For now, just waste the old intervals. */
- {
- BUF_INTERVALS (buffer) = reproduce_tree (source, INTERVAL_PARENT (tree));
- BUF_INTERVALS (buffer)->position = BEG;
- BUF_INTERVALS (buffer)->up_obj = 1;
- /* Explicitly free the old tree here. */
-
- return;
- }
- /* Paranoia -- the text has already been added, so this buffer
- should be of non-zero length. */
- else if (TOTAL_LENGTH (tree) == 0)
- abort ();
+ /* Paranoia -- the text has already been added, so
+ this buffer should be of non-zero length. */
+ eassert (TOTAL_LENGTH (tree) > 0);
this = under = find_interval (tree, position);
- if (NULL_INTERVAL_P (under)) /* Paranoia */
- abort ();
+ eassert (under);
over = find_interval (source, interval_start_pos (source));
/* Here for insertion in the middle of an interval.
have already been copied into target intervals.
UNDER is the next interval in the target. */
over_used = 0;
- while (! NULL_INTERVAL_P (over))
+ while (over)
{
/* If UNDER is longer than OVER, split it. */
if (LENGTH (over) - over_used < LENGTH (under))
under = next_interval (this);
}
- if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
- BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
- return;
+ buffer_balance_intervals (buffer);
}
/* Get the value of property PROP from PLIST,
/* Set point in BUFFER "temporarily" to CHARPOS, which corresponds to
byte position BYTEPOS. */
-inline void
+void
temp_set_point_both (struct buffer *buffer,
ptrdiff_t charpos, ptrdiff_t bytepos)
{
/* In a single-byte buffer, the two positions must be equal. */
- if (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer)
- && charpos != bytepos)
- abort ();
-
- if (charpos > bytepos)
- abort ();
+ if (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer))
+ eassert (charpos == bytepos);
- if (charpos > BUF_ZV (buffer) || charpos < BUF_BEGV (buffer))
- abort ();
+ eassert (charpos <= bytepos);
+ eassert (charpos <= BUF_ZV (buffer) || BUF_BEGV (buffer) <= charpos);
SET_BUF_PT_BOTH (buffer, charpos, bytepos);
}
/* Set point "temporarily", without checking any text properties. */
-inline void
+void
temp_set_point (struct buffer *buffer, ptrdiff_t charpos)
{
temp_set_point_both (buffer, charpos,
current buffer, and the invisible property has a `stickiness' such that
inserting a character at position POS would inherit the property it,
return POS + ADJ, otherwise return POS. If TEST_INTANG is non-zero,
- then intangibility is required as well as invisibleness.
+ then intangibility is required as well as invisibility.
TEST_OFFS should be either 0 or -1, and ADJ should be either 1 or -1.
int have_overlays;
ptrdiff_t original_position;
- BVAR (current_buffer, point_before_scroll) = Qnil;
+ BSET (current_buffer, point_before_scroll, Qnil);
if (charpos == PT)
return;
whether or not there are intervals in the buffer. */
eassert (charpos <= ZV && charpos >= BEGV);
- have_overlays = (current_buffer->overlays_before
- || current_buffer->overlays_after);
+ have_overlays = buffer_has_overlays ();
/* If we have no text properties and overlays,
then we can do it quickly. */
- if (NULL_INTERVAL_P (BUF_INTERVALS (current_buffer)) && ! have_overlays)
+ if (!buffer_get_intervals (current_buffer) && ! have_overlays)
{
temp_set_point_both (current_buffer, charpos, bytepos);
return;
/* Set TO to the interval containing the char after CHARPOS,
and TOPREV to the interval containing the char before CHARPOS.
Either one may be null. They may be equal. */
- to = find_interval (BUF_INTERVALS (current_buffer), charpos);
+ to = find_interval (buffer_get_intervals (current_buffer), charpos);
if (charpos == BEGV)
toprev = 0;
else if (to && to->position == charpos)
and FROMPREV to the interval containing the char before PT.
Either one may be null. They may be equal. */
/* We could cache this and save time. */
- from = find_interval (BUF_INTERVALS (current_buffer), buffer_point);
+ from = find_interval (buffer_get_intervals (current_buffer), buffer_point);
if (buffer_point == BEGV)
fromprev = 0;
else if (from && from->position == PT)
with the same intangible property value,
move forward or backward until a change in that property. */
if (NILP (Vinhibit_point_motion_hooks)
- && ((! NULL_INTERVAL_P (to) && ! NULL_INTERVAL_P (toprev))
+ && ((to && toprev)
|| have_overlays)
/* Intangibility never stops us from positioning at the beginning
or end of the buffer, so don't bother checking in that case. */
/* Set TO to the interval containing the char after CHARPOS,
and TOPREV to the interval containing the char before CHARPOS.
Either one may be null. They may be equal. */
- to = find_interval (BUF_INTERVALS (current_buffer), charpos);
+ to = find_interval (buffer_get_intervals (current_buffer), charpos);
if (charpos == BEGV)
toprev = 0;
else if (to && to->position == charpos)
INTERVAL i, prev, next;
if (NILP (object))
- i = find_interval (BUF_INTERVALS (current_buffer), pos);
+ i = find_interval (buffer_get_intervals (current_buffer), pos);
else if (BUFFERP (object))
- i = find_interval (BUF_INTERVALS (XBUFFER (object)), pos);
+ i = find_interval (buffer_get_intervals (XBUFFER (object)), pos);
else if (STRINGP (object))
- i = find_interval (STRING_INTERVALS (object), pos);
+ i = find_interval (string_get_intervals (object), pos);
else
abort ();
- if (NULL_INTERVAL_P (i) || (i->position + LENGTH (i) <= pos))
+ if (!i || (i->position + LENGTH (i) <= pos))
return 0;
*val = textget (i->plist, prop);
if (NILP (*val))
next = i; /* remember it in advance */
prev = previous_interval (i);
- while (! NULL_INTERVAL_P (prev)
+ while (prev
&& EQ (*val, textget (prev->plist, prop)))
i = prev, prev = previous_interval (prev);
*start = i->position;
next = next_interval (i);
- while (! NULL_INTERVAL_P (next)
- && EQ (*val, textget (next->plist, prop)))
+ while (next && EQ (*val, textget (next->plist, prop)))
i = next, next = next_interval (next);
*end = i->position + LENGTH (i);
register INTERVAL i, new, t;
register ptrdiff_t got, prevlen;
- if (NULL_INTERVAL_P (tree) || length <= 0)
- return NULL_INTERVAL;
+ if (!tree || length <= 0)
+ return NULL;
i = find_interval (tree, start);
- if (NULL_INTERVAL_P (i) || LENGTH (i) == 0)
- abort ();
+ eassert (i && LENGTH (i) > 0);
/* If there is only one interval and it's the default, return nil. */
if ((start - i->position + 1 + length) < LENGTH (i)
&& DEFAULT_INTERVAL_P (i))
- return NULL_INTERVAL;
+ return NULL;
new = make_interval ();
new->position = 0;
got = (LENGTH (i) - (start - i->position));
new->total_length = length;
- CHECK_TOTAL_LENGTH (new);
+ eassert (0 <= TOTAL_LENGTH (new));
copy_properties (i, new);
t = new;
/* Give STRING the properties of BUFFER from POSITION to LENGTH. */
-inline void
+void
copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
ptrdiff_t position, ptrdiff_t length)
{
- INTERVAL interval_copy = copy_intervals (BUF_INTERVALS (buffer),
+ INTERVAL interval_copy = copy_intervals (buffer_get_intervals (buffer),
position, length);
- if (NULL_INTERVAL_P (interval_copy))
+ if (!interval_copy)
return;
- SET_INTERVAL_OBJECT (interval_copy, string);
- STRING_SET_INTERVALS (string, interval_copy);
+ interval_set_object (interval_copy, string);
+ string_set_intervals (string, interval_copy);
}
\f
/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
ptrdiff_t pos = 0;
ptrdiff_t end = SCHARS (s1);
- i1 = find_interval (STRING_INTERVALS (s1), 0);
- i2 = find_interval (STRING_INTERVALS (s2), 0);
+ i1 = find_interval (string_get_intervals (s1), 0);
+ i2 = find_interval (string_get_intervals (s2), 0);
while (pos < end)
{
i->total_length = end - start;
else
i->total_length = end_byte - start_byte;
- CHECK_TOTAL_LENGTH (i);
+ eassert (0 <= TOTAL_LENGTH (i));
if (TOTAL_LENGTH (i) == 0)
{
{
if ((i)->left)
{
- (i)->plist = (i)->left->plist;
+ interval_set_plist (i, i->left->plist);
(i)->left->total_length = 0;
delete_interval ((i)->left);
}
else
{
- (i)->plist = (i)->right->plist;
+ interval_set_plist (i, i->right->plist);
(i)->right->total_length = 0;
delete_interval ((i)->right);
}
void
set_intervals_multibyte (int multi_flag)
{
- if (BUF_INTERVALS (current_buffer))
- set_intervals_multibyte_1 (BUF_INTERVALS (current_buffer), multi_flag,
- BEG, BEG_BYTE, Z, Z_BYTE);
+ INTERVAL i = buffer_get_intervals (current_buffer);
+
+ if (i)
+ set_intervals_multibyte_1 (i, multi_flag, BEG, BEG_BYTE, Z, Z_BYTE);
}