Basic functions to set Lisp_Object and pointer slots of intervals.
* intervals.h (interval_set_parent, interval_set_object): (interval_set_left, interval_set_right, interval_set_plist): (interval_copy_parent): New function. (SET_INTERVAL_OBJECT, SET_INTERVAL_PARENT, INTERVAL_PTR_SIZE): Remove. (RESET_INTERVAL, COPY_INTERVAL_CACHE, MERGE_INTERVAL_CACHE): Adjust indentation. (INTERVAL_SIZE): Remove. Adjust users. * alloc.c, intervals.c, lread.c, textprop.c: Use new functions.
This commit is contained in:
parent
c395097f51
commit
6a3d20cc46
6 changed files with 140 additions and 91 deletions
|
@ -1,3 +1,15 @@
|
|||
2012-08-07 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
Basic functions to set Lisp_Object and pointer slots of intervals.
|
||||
* intervals.h (interval_set_parent, interval_set_object):
|
||||
(interval_set_left, interval_set_right, interval_set_plist):
|
||||
(interval_copy_parent): New function.
|
||||
(SET_INTERVAL_OBJECT, SET_INTERVAL_PARENT, INTERVAL_PTR_SIZE): Remove.
|
||||
(RESET_INTERVAL, COPY_INTERVAL_CACHE, MERGE_INTERVAL_CACHE): Adjust
|
||||
indentation.
|
||||
(INTERVAL_SIZE): Remove. Adjust users.
|
||||
* alloc.c, intervals.c, lread.c, textprop.c: Use new functions.
|
||||
|
||||
2012-08-07 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
Drop PGET and revert read access to Lisp_Objects slots of Lisp_Process.
|
||||
|
|
|
@ -6416,7 +6416,7 @@ gc_sweep (void)
|
|||
{
|
||||
if (!iblk->intervals[i].gcmarkbit)
|
||||
{
|
||||
SET_INTERVAL_PARENT (&iblk->intervals[i], interval_free_list);
|
||||
interval_set_parent (&iblk->intervals[i], interval_free_list);
|
||||
interval_free_list = &iblk->intervals[i];
|
||||
this_free++;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ create_root_interval (Lisp_Object parent)
|
|||
new->position = 0;
|
||||
}
|
||||
|
||||
SET_INTERVAL_OBJECT (new, parent);
|
||||
interval_set_object (new, parent);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ copy_properties (register INTERVAL source, register INTERVAL target)
|
|||
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
|
||||
|
@ -138,7 +138,7 @@ merge_properties (register INTERVAL source, register INTERVAL target)
|
|||
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);
|
||||
}
|
||||
|
@ -320,21 +320,21 @@ rotate_right (INTERVAL 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;
|
||||
interval_set_left (interval, i);
|
||||
if (! NULL_INTERVAL_P (i))
|
||||
SET_INTERVAL_PARENT (i, interval);
|
||||
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);
|
||||
|
@ -367,21 +367,21 @@ rotate_left (INTERVAL 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->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;
|
||||
interval_set_right (interval, i);
|
||||
if (! NULL_INTERVAL_P (i))
|
||||
SET_INTERVAL_PARENT (i, interval);
|
||||
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);
|
||||
|
@ -507,20 +507,20 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
|
|||
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);
|
||||
}
|
||||
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);
|
||||
balance_an_interval (new);
|
||||
|
@ -552,20 +552,20 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
|
|||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
balance_an_interval (new);
|
||||
|
@ -940,21 +940,20 @@ adjust_intervals_for_insertion (INTERVAL tree,
|
|||
RESET_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);
|
||||
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;
|
||||
prev = split_interval_right (prev, position - prev->position);
|
||||
interval_set_plist (prev, newi.plist);
|
||||
if (! NULL_INTERVAL_P (i)
|
||||
&& intervals_equal (prev, i))
|
||||
merge_interval_right (prev);
|
||||
|
@ -1180,8 +1179,8 @@ delete_node (register INTERVAL i)
|
|||
this->total_length += migrate_amt;
|
||||
}
|
||||
CHECK_TOTAL_LENGTH (this);
|
||||
this->left = migrate;
|
||||
SET_INTERVAL_PARENT (migrate, this);
|
||||
interval_set_left (this, migrate);
|
||||
interval_set_parent (migrate, this);
|
||||
|
||||
return i->right;
|
||||
}
|
||||
|
@ -1206,7 +1205,7 @@ delete_interval (register INTERVAL i)
|
|||
GET_INTERVAL_OBJECT (owner, i);
|
||||
parent = delete_node (i);
|
||||
if (! NULL_INTERVAL_P (parent))
|
||||
SET_INTERVAL_OBJECT (parent, owner);
|
||||
interval_set_object (parent, owner);
|
||||
|
||||
if (BUFFERP (owner))
|
||||
BUF_INTERVALS (XBUFFER (owner)) = parent;
|
||||
|
@ -1221,15 +1220,15 @@ delete_interval (register INTERVAL i)
|
|||
parent = INTERVAL_PARENT (i);
|
||||
if (AM_LEFT_CHILD (i))
|
||||
{
|
||||
parent->left = delete_node (i);
|
||||
interval_set_left (parent, delete_node (i));
|
||||
if (! NULL_INTERVAL_P (parent->left))
|
||||
SET_INTERVAL_PARENT (parent->left, parent);
|
||||
interval_set_parent (parent->left, parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->right = delete_node (i);
|
||||
interval_set_right (parent, delete_node (i));
|
||||
if (! NULL_INTERVAL_P (parent->right))
|
||||
SET_INTERVAL_PARENT (parent->right, parent);
|
||||
interval_set_parent (parent->right, parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1500,13 +1499,13 @@ reproduce_tree (INTERVAL source, INTERVAL parent)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -1516,13 +1515,13 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -2264,7 +2263,7 @@ copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
|
|||
if (NULL_INTERVAL_P (interval_copy))
|
||||
return;
|
||||
|
||||
SET_INTERVAL_OBJECT (interval_copy, string);
|
||||
interval_set_object (interval_copy, string);
|
||||
STRING_SET_INTERVALS (string, interval_copy);
|
||||
}
|
||||
|
||||
|
@ -2404,13 +2403,13 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
110
src/intervals.h
110
src/intervals.h
|
@ -18,6 +18,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#include "dispextern.h"
|
||||
|
||||
INLINE_HEADER_BEGIN
|
||||
|
||||
#define NULL_INTERVAL ((INTERVAL)0)
|
||||
#define INTERVAL_DEFAULT NULL_INTERVAL
|
||||
|
||||
|
@ -61,12 +63,6 @@ struct interval
|
|||
|
||||
/* These are macros for dealing with the interval tree. */
|
||||
|
||||
/* Size of the structure used to represent an interval. */
|
||||
#define INTERVAL_SIZE (sizeof (struct interval))
|
||||
|
||||
/* Size of a pointer to an interval structure. */
|
||||
#define INTERVAL_PTR_SIZE (sizeof (struct interval *))
|
||||
|
||||
#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL)
|
||||
|
||||
/* True if this interval has no right child. */
|
||||
|
@ -131,23 +127,63 @@ struct interval
|
|||
#define INTERVAL_HAS_PARENT(i) ((i)->up_obj == 0 && (i)->up.interval != 0)
|
||||
#define INTERVAL_HAS_OBJECT(i) ((i)->up_obj)
|
||||
|
||||
/* Set/get parent of an interval.
|
||||
/* Use these macros to get parent of an interval.
|
||||
|
||||
The choice of macros is dependent on the type needed. Don't add
|
||||
casts to get around this, it will break some development work in
|
||||
progress. */
|
||||
#define SET_INTERVAL_PARENT(i,p) \
|
||||
((i)->up_obj = 0, (i)->up.interval = (p))
|
||||
#define SET_INTERVAL_OBJECT(i,o) \
|
||||
(eassert (BUFFERP (o) || STRINGP (o)), (i)->up_obj = 1, (i)->up.obj = (o))
|
||||
#define INTERVAL_PARENT(i) \
|
||||
(eassert ((i) != 0 && (i)->up_obj == 0),(i)->up.interval)
|
||||
#define GET_INTERVAL_OBJECT(d,s) (eassert((s)->up_obj == 1), (d) = (s)->up.obj)
|
||||
|
||||
/* Make the parent of D be whatever the parent of S is, regardless of
|
||||
type. This is used when balancing an interval tree. */
|
||||
#define COPY_INTERVAL_PARENT(d,s) \
|
||||
((d)->up = (s)->up, (d)->up_obj = (s)->up_obj)
|
||||
#define INTERVAL_PARENT(i) \
|
||||
(eassert ((i) != 0 && (i)->up_obj == 0), (i)->up.interval)
|
||||
|
||||
#define GET_INTERVAL_OBJECT(d,s) (eassert ((s)->up_obj == 1), (d) = (s)->up.obj)
|
||||
|
||||
/* Use these functions to set Lisp_Object
|
||||
or pointer slots of struct interval. */
|
||||
|
||||
LISP_INLINE void
|
||||
interval_set_parent (INTERVAL i, INTERVAL parent)
|
||||
{
|
||||
i->up_obj = 0;
|
||||
i->up.interval = parent;
|
||||
}
|
||||
|
||||
LISP_INLINE void
|
||||
interval_set_object (INTERVAL i, Lisp_Object obj)
|
||||
{
|
||||
eassert (BUFFERP (obj) || STRINGP (obj));
|
||||
i->up_obj = 1;
|
||||
i->up.obj = obj;
|
||||
}
|
||||
|
||||
LISP_INLINE void
|
||||
interval_set_left (INTERVAL i, INTERVAL left)
|
||||
{
|
||||
i->left = left;
|
||||
}
|
||||
|
||||
LISP_INLINE void
|
||||
interval_set_right (INTERVAL i, INTERVAL right)
|
||||
{
|
||||
i->right = right;
|
||||
}
|
||||
|
||||
LISP_INLINE Lisp_Object
|
||||
interval_set_plist (INTERVAL i, Lisp_Object plist)
|
||||
{
|
||||
i->plist = plist;
|
||||
return plist;
|
||||
}
|
||||
|
||||
/* Make the parent of D be whatever the parent of S is, regardless
|
||||
of the type. This is used when balancing an interval tree. */
|
||||
|
||||
LISP_INLINE void
|
||||
interval_copy_parent (INTERVAL d, INTERVAL s)
|
||||
{
|
||||
d->up = s->up;
|
||||
d->up_obj = s->up_obj;
|
||||
}
|
||||
|
||||
/* Get the parent interval, if any, otherwise a null pointer. Useful
|
||||
for walking up to the root in a "for" loop; use this to get the
|
||||
|
@ -165,31 +201,31 @@ struct interval
|
|||
while (0)
|
||||
|
||||
/* Reset this interval to its vanilla, or no-property state. */
|
||||
#define RESET_INTERVAL(i) \
|
||||
{ \
|
||||
(i)->total_length = (i)->position = 0; \
|
||||
(i)->left = (i)->right = NULL_INTERVAL; \
|
||||
SET_INTERVAL_PARENT (i, NULL_INTERVAL); \
|
||||
(i)->write_protect = 0; \
|
||||
(i)->visible = 0; \
|
||||
(i)->front_sticky = (i)->rear_sticky = 0; \
|
||||
(i)->plist = Qnil; \
|
||||
#define RESET_INTERVAL(i) \
|
||||
{ \
|
||||
(i)->total_length = (i)->position = 0; \
|
||||
(i)->left = (i)->right = NULL_INTERVAL; \
|
||||
interval_set_parent (i, NULL_INTERVAL); \
|
||||
(i)->write_protect = 0; \
|
||||
(i)->visible = 0; \
|
||||
(i)->front_sticky = (i)->rear_sticky = 0; \
|
||||
interval_set_plist (i, Qnil); \
|
||||
}
|
||||
|
||||
/* Copy the cached property values of interval FROM to interval TO. */
|
||||
#define COPY_INTERVAL_CACHE(from,to) \
|
||||
{ \
|
||||
(to)->write_protect = (from)->write_protect; \
|
||||
(to)->visible = (from)->visible; \
|
||||
(to)->front_sticky = (from)->front_sticky; \
|
||||
(to)->rear_sticky = (from)->rear_sticky; \
|
||||
#define COPY_INTERVAL_CACHE(from,to) \
|
||||
{ \
|
||||
(to)->write_protect = (from)->write_protect; \
|
||||
(to)->visible = (from)->visible; \
|
||||
(to)->front_sticky = (from)->front_sticky; \
|
||||
(to)->rear_sticky = (from)->rear_sticky; \
|
||||
}
|
||||
|
||||
/* Copy only the set bits of FROM's cache. */
|
||||
#define MERGE_INTERVAL_CACHE(from,to) \
|
||||
{ \
|
||||
#define MERGE_INTERVAL_CACHE(from,to) \
|
||||
{ \
|
||||
if ((from)->write_protect) (to)->write_protect = 1; \
|
||||
if ((from)->visible) (to)->visible = 1; \
|
||||
if ((from)->visible) (to)->visible = 1; \
|
||||
if ((from)->front_sticky) (to)->front_sticky = 1; \
|
||||
if ((from)->rear_sticky) (to)->rear_sticky = 1; \
|
||||
}
|
||||
|
@ -326,3 +362,5 @@ extern Lisp_Object get_pos_property (Lisp_Object pos, Lisp_Object prop,
|
|||
extern void syms_of_textprop (void);
|
||||
|
||||
#include "composite.h"
|
||||
|
||||
INLINE_HEADER_END
|
||||
|
|
|
@ -3211,7 +3211,7 @@ substitute_in_interval (INTERVAL interval, Lisp_Object arg)
|
|||
Lisp_Object object = Fcar (arg);
|
||||
Lisp_Object placeholder = Fcdr (arg);
|
||||
|
||||
SUBSTITUTE (interval->plist, interval->plist = true_value);
|
||||
SUBSTITUTE (interval->plist, interval_set_plist (interval, true_value));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ set_properties (Lisp_Object properties, INTERVAL interval, Lisp_Object object)
|
|||
}
|
||||
|
||||
/* Store new properties. */
|
||||
interval->plist = Fcopy_sequence (properties);
|
||||
interval_set_plist (interval, Fcopy_sequence (properties));
|
||||
}
|
||||
|
||||
/* Add the properties of PLIST to the interval I, or set
|
||||
|
@ -411,7 +411,7 @@ add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object)
|
|||
record_property_change (i->position, LENGTH (i),
|
||||
sym1, Qnil, object);
|
||||
}
|
||||
i->plist = Fcons (sym1, Fcons (val1, i->plist));
|
||||
interval_set_plist (i, Fcons (sym1, Fcons (val1, i->plist)));
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ remove_properties (Lisp_Object plist, Lisp_Object list, INTERVAL i, Lisp_Object
|
|||
}
|
||||
|
||||
if (changed)
|
||||
i->plist = current_plist;
|
||||
interval_set_plist (i, current_plist);
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue