]> code.delx.au - gnu-emacs/blobdiff - src/intervals.c
Merge language/persian.el into language/misc-lang.el
[gnu-emacs] / src / intervals.c
index 0b332caf8975eb44fa903286a342649f49020b9d..504557dadb79ace1d63b19c059de036b7856504c 100644 (file)
@@ -42,6 +42,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <intprops.h>
 #include "lisp.h"
 #include "intervals.h"
+#include "character.h"
 #include "buffer.h"
 #include "puresize.h"
 #include "keyboard.h"
@@ -75,19 +76,19 @@ create_root_interval (Lisp_Object parent)
     {
       new->total_length = (BUF_Z (XBUFFER (parent))
                           - BUF_BEG (XBUFFER (parent)));
-      CHECK_TOTAL_LENGTH (new);
+      eassert (0 <= TOTAL_LENGTH (new));
       BUF_INTERVALS (XBUFFER (parent)) = new;
       new->position = BEG;
     }
   else if (STRINGP (parent))
     {
       new->total_length = SCHARS (parent);
-      CHECK_TOTAL_LENGTH (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;
 }
@@ -101,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
@@ -137,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);
     }
@@ -206,10 +207,10 @@ void
 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
        {
@@ -226,7 +227,7 @@ void
 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);
@@ -261,7 +262,7 @@ search_for_interval (INTERVAL i, INTERVAL tree)
 {
   icount = 0;
   search_interval = i;
-  found_interval = NULL_INTERVAL;
+  found_interval = NULL;
   traverse_intervals_noorder (tree, &check_for_interval, Qnil);
   return found_interval;
 }
@@ -319,29 +320,29 @@ 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;
-  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;
 }
@@ -366,29 +367,29 @@ 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;
-  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;
 }
@@ -479,12 +480,9 @@ balance_intervals_internal (register INTERVAL tree)
 INTERVAL
 balance_intervals (INTERVAL tree)
 {
-  if (tree == NULL_INTERVAL)
-    return NULL_INTERVAL;
-
-  return balance_intervals_internal (tree);
+  return tree ? balance_intervals_internal (tree) : NULL;
 }
-\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
@@ -506,22 +504,22 @@ 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);
+      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);
     }
 
@@ -551,22 +549,22 @@ 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);
+      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);
     }
 
@@ -588,7 +586,7 @@ interval_start_pos (INTERVAL source)
 {
   Lisp_Object parent;
 
-  if (NULL_INTERVAL_P (source))
+  if (!source)
     return 0;
 
   if (! INTERVAL_HAS_OBJECT (source))
@@ -616,8 +614,8 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
                     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))
@@ -628,8 +626,7 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
        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);
@@ -669,8 +666,8 @@ next_interval (register INTERVAL interval)
   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))
@@ -695,7 +692,7 @@ next_interval (register INTERVAL interval)
       i = INTERVAL_PARENT (i);
     }
 
-  return NULL_INTERVAL;
+  return NULL;
 }
 
 /* Find the preceding interval (lexicographically) to INTERVAL.
@@ -707,8 +704,8 @@ previous_interval (register INTERVAL interval)
 {
   register INTERVAL i;
 
-  if (NULL_INTERVAL_P (interval))
-    return NULL_INTERVAL;
+  if (!interval)
+    return NULL;
 
   if (! NULL_LEFT_CHILD (interval))
     {
@@ -733,7 +730,7 @@ previous_interval (register INTERVAL interval)
       i = INTERVAL_PARENT (i);
     }
 
-  return NULL_INTERVAL;
+  return NULL;
 }
 
 /* Find the interval containing POS given some non-NULL INTERVAL
@@ -744,8 +741,8 @@ previous_interval (register INTERVAL interval)
 INTERVAL
 update_interval (register INTERVAL i, ptrdiff_t pos)
 {
-  if (NULL_INTERVAL_P (i))
-    return NULL_INTERVAL;
+  if (!i)
+    return NULL;
 
   while (1)
     {
@@ -784,68 +781,6 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
     }
 }
 
-\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
@@ -869,8 +804,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
   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);
@@ -981,7 +915,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
       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);
        }
 
@@ -1001,25 +935,23 @@ adjust_intervals_for_insertion (INTERVAL tree,
          struct interval newi;
 
          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);
+         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);
            }
 
@@ -1039,7 +971,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
       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);
        }
     }
@@ -1228,23 +1160,23 @@ delete_node (register INTERVAL i)
   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;
 }
@@ -1261,16 +1193,15 @@ delete_interval (register INTERVAL i)
   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;
@@ -1285,15 +1216,15 @@ delete_interval (register INTERVAL i)
   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
@@ -1315,7 +1246,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
 {
   register ptrdiff_t relative_position = from;
 
-  if (NULL_INTERVAL_P (tree))
+  if (!tree)
     return 0;
 
   /* Left branch.  */
@@ -1325,7 +1256,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
                                                         relative_position,
                                                         amount);
       tree->total_length -= subtract;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return subtract;
     }
   /* Right branch.  */
@@ -1340,7 +1271,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
                                               relative_position,
                                               amount);
       tree->total_length -= subtract;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return subtract;
     }
   /* Here -- this node.  */
@@ -1355,7 +1286,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
        amount = my_amount;
 
       tree->total_length -= amount;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       if (LENGTH (tree) == 0)
        delete_interval (tree);
 
@@ -1382,23 +1313,22 @@ adjust_intervals_for_deletion (struct buffer *buffer,
   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;
+      BUF_INTERVALS (buffer) = NULL;
       return;
     }
 
   if (ONLY_INTERVAL_P (tree))
     {
       tree->total_length -= length;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return;
     }
 
@@ -1411,7 +1341,7 @@ adjust_intervals_for_deletion (struct buffer *buffer,
       tree = BUF_INTERVALS (buffer);
       if (left_to_delete == tree->total_length)
        {
-         BUF_INTERVALS (buffer) = NULL_INTERVAL;
+         BUF_INTERVALS (buffer) = NULL;
          return;
        }
     }
@@ -1429,7 +1359,7 @@ adjust_intervals_for_deletion (struct buffer *buffer,
 void
 offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
 {
-  if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) || length == 0)
+  if (!BUF_INTERVALS (buffer) || length == 0)
     return;
 
   if (length > 0)
@@ -1456,10 +1386,6 @@ merge_interval_right (register INTERVAL i)
   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.  */
@@ -1468,16 +1394,20 @@ merge_interval_right (register INTERVAL i)
       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.  */
@@ -1491,7 +1421,7 @@ merge_interval_right (register INTERVAL i)
 
       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
@@ -1512,10 +1442,6 @@ merge_interval_left (register INTERVAL i)
   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.  */
@@ -1524,19 +1450,23 @@ merge_interval_left (register INTERVAL i)
       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))
        {
@@ -1547,7 +1477,7 @@ merge_interval_left (register INTERVAL i)
 
       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
@@ -1565,13 +1495,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;
 }
@@ -1581,59 +1511,16 @@ 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;
 }
-
-#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.
@@ -1689,17 +1576,17 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
      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)))
+      if (BUF_INTERVALS (buffer))
        /* Shouldn't be necessary.  --Stef  */
        BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
       return;
@@ -1717,21 +1604,19 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
       eassert (BUF_INTERVALS (buffer)->up_obj == 1);
          return;
        }
-  else if (NULL_INTERVAL_P (tree))
+  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);
       }
-  /* 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.
@@ -1773,7 +1658,7 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
      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))
@@ -1806,7 +1691,7 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
       under = next_interval (this);
     }
 
-  if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
+  if (BUF_INTERVALS (buffer))
     BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
   return;
 }
@@ -1866,15 +1751,11 @@ 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 (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer))
+    eassert (charpos == bytepos);
 
-  if (charpos > bytepos)
-    abort ();
-
-  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);
 }
@@ -1979,7 +1860,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
 
   /* 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 (!BUF_INTERVALS (current_buffer) && ! have_overlays)
     {
       temp_set_point_both (current_buffer, charpos, bytepos);
       return;
@@ -2026,7 +1907,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
      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.  */
@@ -2249,7 +2130,7 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
   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))
@@ -2257,14 +2138,13 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *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);
 
@@ -2335,23 +2215,22 @@ copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
   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;
@@ -2376,10 +2255,10 @@ copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
 {
   INTERVAL interval_copy = copy_intervals (BUF_INTERVALS (buffer),
                                           position, length);
-  if (NULL_INTERVAL_P (interval_copy))
+  if (!interval_copy)
     return;
 
-  SET_INTERVAL_OBJECT (interval_copy, string);
+  interval_set_object (interval_copy, string);
   STRING_SET_INTERVALS (string, interval_copy);
 }
 \f
@@ -2434,7 +2313,7 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
     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)
     {
@@ -2519,13 +2398,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);
        }