Commit 439d5cb4 authored by Ken Raeburn's avatar Ken Raeburn

Changes towards better type safety regarding intervals, primarily

regarding the "parent" handle.  These just separate out the different
usages based on the type of parent (interval vs lisp object); later
changes will do type checking and enforcement.

	* intervals.h (NULL_INTERVAL): Cast to INTERVAL type.
	(INT_LISPLIKE): New macro.
	(NULL_INTERVAL_P): Use it.
	(INTERVAL_HAS_PARENT, INTERVAL_HAS_OBJECT, SET_INTERVAL_PARENT,
	SET_INTERVAL_OBJECT, INTERVAL_PARENT, COPY_INTERVAL_PARENT,
	GET_INTERVAL_OBJECT, INTERVAL_PARENT_OR_NULL): New macros.

	* alloc.c (make_interval, gc_sweep): Use new macros; eliminate all
	explicit references to "parent" field of struct interval and
	associated unclean type conversions.
	* intervals.c (create_root_interval, root_interval, rotate_right,
	rotate_left, balance_possible_root_interval, split_interval_right,
	split_interval_left, interval_start_pos, find_interval,
	next_interval, previous_interval, update_interval,
	adjust_intervals_for_insertion, delete_node, delete_interval,
	adjust_intervals_for_deletion, merge_interval_right,
	merge_interval_left, reproduce_tree, graft_intervals_into_buffer,
	copy_intervals_to_string): Likewise.
	* intervals.h (AM_LEFT_CHILD, AM_RIGHT_CHILD, RESET_INTERVAL):
	Likewise.
	* syntax.c (update_syntax_table): Likewise.

	* intervals.c (reproduce_tree_obj): New function, like
	reproduce_tree but takes a Lisp_Object for the parent.  Declare
	with prototype.
	(graft_intervals_into_buffer): Use it when appropriate.
	(reproduce_tree): Declare with prototype.
	(balance_possible_root_interval): Check that the parent is a lisp
	object before trying to examine its type.
parent 89084293
No preview for this file type
......@@ -711,7 +711,7 @@ make_interval ()
if (interval_free_list)
{
val = interval_free_list;
interval_free_list = interval_free_list->parent;
interval_free_list = INTERVAL_PARENT (interval_free_list);
}
else
{
......@@ -4215,7 +4215,7 @@ gc_sweep ()
{
if (! XMARKBIT (iblk->intervals[i].plist))
{
iblk->intervals[i].parent = interval_free_list;
SET_INTERVAL_PARENT (&iblk->intervals[i], interval_free_list);
interval_free_list = &iblk->intervals[i];
this_free++;
}
......@@ -4233,7 +4233,7 @@ gc_sweep ()
{
*iprev = iblk->next;
/* Unhook from the free list. */
interval_free_list = iblk->intervals[0].parent;
interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]);
lisp_free (iblk);
n_interval_blocks--;
}
......
This diff is collapsed.
......@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
#include "dispextern.h"
#endif
#define NULL_INTERVAL 0
#define NULL_INTERVAL ((INTERVAL)0)
#define INTERVAL_DEFAULT NULL_INTERVAL
/* These are macros for dealing with the interval tree. */
......@@ -37,14 +37,13 @@ Boston, MA 02111-1307, USA. */
Lisp_String pointer (meaning it points to the owner of this
interval tree). */
#ifdef NO_UNION_TYPE
#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL \
|| BUFFERP ((Lisp_Object)(i)) \
|| STRINGP ((Lisp_Object)(i)))
#define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object)(i)) \
|| STRINGP ((Lisp_Object)(i)))
#else
#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL \
|| BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \
|| STRINGP ((Lisp_Object){(EMACS_INT)(i)}))
#define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \
|| STRINGP ((Lisp_Object){(EMACS_INT)(i)}))
#endif
#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL || INT_LISPLIKE (i))
/* True if this interval has no right child. */
#define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL)
......@@ -56,12 +55,12 @@ Boston, MA 02111-1307, USA. */
#define NULL_PARENT(i) (NULL_INTERVAL_P ((i)->parent))
/* True if this interval is the left child of some other interval. */
#define AM_LEFT_CHILD(i) (! NULL_INTERVAL_P ((i)->parent) \
&& (i)->parent->left == (i))
#define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \
&& INTERVAL_PARENT (i)->left == (i))
/* True if this interval is the right child of some other interval. */
#define AM_RIGHT_CHILD(i) (! NULL_INTERVAL_P ((i)->parent) \
&& (i)->parent->right == (i))
#define AM_RIGHT_CHILD(i) (! NULL_PARENT (i) \
&& INTERVAL_PARENT (i)->right == (i))
/* True if this interval has no children. */
#define LEAF_INTERVAL_P(i) ((i)->left == NULL_INTERVAL \
......@@ -103,12 +102,38 @@ Boston, MA 02111-1307, USA. */
or having no properties. */
#define DEFAULT_INTERVAL_P(i) (NULL_INTERVAL_P (i) || EQ ((i)->plist, Qnil))
/* Test what type of parent we have. Three possibilities: another
interval, a buffer or string object, or NULL_INTERVAL. */
#define INTERVAL_HAS_PARENT(i) ((i)->parent && ! INT_LISPLIKE ((i)->parent))
#define INTERVAL_HAS_OBJECT(i) ((i)->parent && INT_LISPLIKE ((i)->parent))
/* Set/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)->parent = (p))
#define SET_INTERVAL_OBJECT(i,o) ((i)->parent = (INTERVAL) XFASTINT (o))
#define INTERVAL_PARENT(i) ((i)->parent)
/* Because XSETFASTINT has to be used, this can't simply be
value-returning. */
#define GET_INTERVAL_OBJECT(d,s) XSETFASTINT((d), (EMACS_INT) (s)->parent)
/* 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)->parent = (s)->parent)
/* 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
"next" value, and test the result to see if it's NULL_INTERVAL. */
#define INTERVAL_PARENT_OR_NULL(i) (INTERVAL_HAS_PARENT (i) ? INTERVAL_PARENT (i) : 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; \
(i)->parent = NULL_INTERVAL; \
SET_INTERVAL_PARENT (i, NULL_INTERVAL); \
(i)->write_protect = 0; \
(i)->visible = 0; \
(i)->front_sticky = (i)->rear_sticky = 0; \
......
......@@ -140,14 +140,14 @@ update_syntax_table (charpos, count, init, object)
while (!NULL_PARENT (i))
{
if (AM_RIGHT_CHILD (i))
i->parent->position = i->position
INTERVAL_PARENT (i)->position = i->position
- LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */
- TOTAL_LENGTH (i->parent)
+ LEFT_TOTAL_LENGTH (i->parent);
- TOTAL_LENGTH (INTERVAL_PARENT (i))
+ LEFT_TOTAL_LENGTH (INTERVAL_PARENT (i));
else
i->parent->position = i->position - LEFT_TOTAL_LENGTH (i)
INTERVAL_PARENT (i)->position = i->position - LEFT_TOTAL_LENGTH (i)
+ TOTAL_LENGTH (i);
i = i->parent;
i = INTERVAL_PARENT (i);
}
i = gl_state.forward_i;
gl_state.b_property = i->position - 1 - gl_state.offset;
......
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