Use BSET for write access to Lisp_Object members of struct buffer.
[bpt/emacs.git] / src / intervals.c
index 88f47f5..145882f 100644 (file)
@@ -38,10 +38,14 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #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"
@@ -75,19 +79,19 @@ create_root_interval (Lisp_Object parent)
     {
       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;
 }
@@ -101,7 +105,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 +141,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 +210,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
        {
@@ -223,10 +227,10 @@ traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, Lisp_Obje
    Pass FUNCTION two args: an interval, and ARG.  */
 
 void
-traverse_intervals (INTERVAL tree, EMACS_INT position,
+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 +265,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;
 }
@@ -313,35 +317,35 @@ rotate_right (INTERVAL interval)
 {
   INTERVAL i;
   INTERVAL B = interval->left;
-  EMACS_INT old_total = interval->total_length;
+  ptrdiff_t old_total = interval->total_length;
 
   /* Deal with any Parent of A;  make it point to 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->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;
 }
@@ -360,35 +364,35 @@ rotate_left (INTERVAL interval)
 {
   INTERVAL i;
   INTERVAL B = interval->right;
-  EMACS_INT old_total = interval->total_length;
+  ptrdiff_t old_total = interval->total_length;
 
   /* Deal with any parent of A;  make it point to 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;
 }
@@ -399,7 +403,7 @@ rotate_left (INTERVAL interval)
 static INTERVAL
 balance_an_interval (INTERVAL i)
 {
-  register EMACS_INT old_diff, new_diff;
+  register ptrdiff_t old_diff, new_diff;
 
   while (1)
     {
@@ -452,9 +456,9 @@ balance_possible_root_interval (register INTERVAL interval)
   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;
@@ -479,12 +483,22 @@ balance_intervals_internal (register INTERVAL tree)
 INTERVAL
 balance_intervals (INTERVAL tree)
 {
-  if (tree == NULL_INTERVAL)
-    return NULL_INTERVAL;
+  return tree ? balance_intervals_internal (tree) : NULL;
+}
 
-  return balance_intervals_internal (tree);
+/* Rebalance text properties of B.  */
+
+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
@@ -499,29 +513,29 @@ balance_intervals (INTERVAL tree)
    it is still a root after this operation.  */
 
 INTERVAL
-split_interval_right (INTERVAL interval, EMACS_INT offset)
+split_interval_right (INTERVAL interval, ptrdiff_t offset)
 {
   INTERVAL new = make_interval ();
-  EMACS_INT position = interval->position;
-  EMACS_INT new_length = LENGTH (interval) - offset;
+  ptrdiff_t position = interval->position;
+  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);
     }
 
@@ -544,29 +558,29 @@ split_interval_right (INTERVAL interval, EMACS_INT offset)
    it is still a root after this operation.  */
 
 INTERVAL
-split_interval_left (INTERVAL interval, EMACS_INT offset)
+split_interval_left (INTERVAL interval, ptrdiff_t offset)
 {
   INTERVAL new = make_interval ();
-  EMACS_INT new_length = offset;
+  ptrdiff_t new_length = 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 +602,7 @@ interval_start_pos (INTERVAL source)
 {
   Lisp_Object parent;
 
-  if (NULL_INTERVAL_P (source))
+  if (!source)
     return 0;
 
   if (! INTERVAL_HAS_OBJECT (source))
@@ -610,14 +624,14 @@ interval_start_pos (INTERVAL source)
    will update this cache based on the result of find_interval.  */
 
 INTERVAL
-find_interval (register INTERVAL tree, register EMACS_INT position)
+find_interval (register INTERVAL tree, register ptrdiff_t position)
 {
   /* The distance from the left edge of the subtree at TREE
                     to POSITION.  */
-  register EMACS_INT relative_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 +642,7 @@ find_interval (register INTERVAL tree, register EMACS_INT 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);
@@ -667,10 +680,10 @@ INTERVAL
 next_interval (register INTERVAL interval)
 {
   register INTERVAL i = interval;
-  register EMACS_INT next_position;
+  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 +708,7 @@ next_interval (register INTERVAL interval)
       i = INTERVAL_PARENT (i);
     }
 
-  return NULL_INTERVAL;
+  return NULL;
 }
 
 /* Find the preceding interval (lexicographically) to INTERVAL.
@@ -707,8 +720,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 +746,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
@@ -742,10 +755,10 @@ previous_interval (register INTERVAL interval)
    To speed up the process, we assume that the ->position of
    I and all its parents is already uptodate.  */
 INTERVAL
-update_interval (register INTERVAL i, EMACS_INT pos)
+update_interval (register INTERVAL i, ptrdiff_t pos)
 {
-  if (NULL_INTERVAL_P (i))
-    return NULL_INTERVAL;
+  if (!i)
+    return NULL;
 
   while (1)
     {
@@ -774,7 +787,7 @@ update_interval (register INTERVAL i, EMACS_INT pos)
              i = i->right;             /* Move to the right child */
            }
          else if (NULL_PARENT (i))
-           error ("Point %"pI"d after end of properties", pos);
+           error ("Point %"pD"d after end of properties", pos);
          else
             i = INTERVAL_PARENT (i);
          continue;
@@ -784,68 +797,6 @@ update_interval (register INTERVAL i, EMACS_INT 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, EMACS_INT position,
-                               EMACS_INT length)
-{
-  register EMACS_INT 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
@@ -861,16 +812,15 @@ adjust_intervals_for_insertion (INTERVAL tree, EMACS_INT position,
 
 static INTERVAL
 adjust_intervals_for_insertion (INTERVAL tree,
-                               EMACS_INT position, EMACS_INT length)
+                               ptrdiff_t position, ptrdiff_t length)
 {
   register INTERVAL i;
   register INTERVAL temp;
   int eobp = 0;
   Lisp_Object parent;
-  EMACS_INT offset;
+  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 +931,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);
        }
 
@@ -1000,25 +950,24 @@ adjust_intervals_for_insertion (INTERVAL tree,
          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);
            }
 
@@ -1038,7 +987,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);
        }
     }
@@ -1225,25 +1174,25 @@ static INTERVAL
 delete_node (register INTERVAL i)
 {
   register INTERVAL migrate, this;
-  register EMACS_INT migrate_amt;
+  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;
 }
@@ -1258,23 +1207,22 @@ static void
 delete_interval (register INTERVAL i)
 {
   register INTERVAL parent;
-  EMACS_INT amt = LENGTH (i);
+  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 ();
 
@@ -1284,15 +1232,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
@@ -1308,30 +1256,30 @@ delete_interval (register INTERVAL i)
    Do this by recursing down TREE to the interval in question, and
    deleting the appropriate amount of text.  */
 
-static EMACS_INT
-interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
-                             register EMACS_INT amount)
+static ptrdiff_t
+interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
+                             register ptrdiff_t amount)
 {
-  register EMACS_INT relative_position = from;
+  register ptrdiff_t relative_position = from;
 
-  if (NULL_INTERVAL_P (tree))
+  if (!tree)
     return 0;
 
   /* Left branch.  */
   if (relative_position < LEFT_TOTAL_LENGTH (tree))
     {
-      EMACS_INT subtract = interval_deletion_adjustment (tree->left,
+      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.  */
   else if (relative_position >= (TOTAL_LENGTH (tree)
                                 - RIGHT_TOTAL_LENGTH (tree)))
     {
-      EMACS_INT subtract;
+      ptrdiff_t subtract;
 
       relative_position -= (tree->total_length
                            - RIGHT_TOTAL_LENGTH (tree));
@@ -1339,14 +1287,14 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
                                               relative_position,
                                               amount);
       tree->total_length -= subtract;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return subtract;
     }
   /* Here -- this node.  */
   else
     {
       /* How much can we delete from this interval?  */
-      EMACS_INT my_amount = ((tree->total_length
+      ptrdiff_t my_amount = ((tree->total_length
                               - RIGHT_TOTAL_LENGTH (tree))
                              - relative_position);
 
@@ -1354,7 +1302,7 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
        amount = my_amount;
 
       tree->total_length -= amount;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       if (LENGTH (tree) == 0)
        delete_interval (tree);
 
@@ -1371,33 +1319,32 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
 
 static void
 adjust_intervals_for_deletion (struct buffer *buffer,
-                              EMACS_INT start, EMACS_INT length)
+                              ptrdiff_t start, ptrdiff_t length)
 {
-  register EMACS_INT left_to_delete = length;
-  register INTERVAL tree = BUF_INTERVALS (buffer);
+  register ptrdiff_t left_to_delete = length;
+  register INTERVAL tree = buffer_get_intervals (buffer);
   Lisp_Object parent;
-  EMACS_INT offset;
+  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;
     }
 
@@ -1407,10 +1354,10 @@ adjust_intervals_for_deletion (struct buffer *buffer,
     {
       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;
        }
     }
@@ -1426,16 +1373,17 @@ adjust_intervals_for_deletion (struct buffer *buffer,
    adjust_intervals_for_deletion) from a non-static inline function.  */
 
 void
-offset_intervals (struct buffer *buffer, EMACS_INT start, EMACS_INT length)
+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 (EMACS_INT)) abort ();)
+      IF_LINT (if (length < - TYPE_MAXIMUM (ptrdiff_t)) abort ();)
       adjust_intervals_for_deletion (buffer, start, -length);
     }
 }
@@ -1452,13 +1400,9 @@ offset_intervals (struct buffer *buffer, EMACS_INT start, EMACS_INT length)
 static INTERVAL
 merge_interval_right (register INTERVAL i)
 {
-  register EMACS_INT absorb = LENGTH (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.  */
@@ -1467,16 +1411,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.  */
@@ -1490,7 +1438,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
@@ -1508,13 +1456,9 @@ merge_interval_right (register INTERVAL i)
 INTERVAL
 merge_interval_left (register INTERVAL i)
 {
-  register EMACS_INT absorb = LENGTH (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.  */
@@ -1523,19 +1467,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))
        {
@@ -1546,7 +1494,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
@@ -1564,13 +1512,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;
 }
@@ -1580,59 +1528,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, EMACS_INT start, EMACS_INT 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.
@@ -1657,11 +1562,9 @@ make_new_interval (INTERVAL intervals, EMACS_INT start, EMACS_INT length)
    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),
@@ -1674,63 +1577,64 @@ make_new_interval (INTERVAL intervals, EMACS_INT start, EMACS_INT length)
    text...  */
 
 void
-graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
-                            EMACS_INT length, struct buffer *buffer,
+graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
+                            ptrdiff_t length, struct buffer *buffer,
                             int inherit)
 {
   register INTERVAL under, over, this;
   register INTERVAL tree;
-  EMACS_INT over_used;
+  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;
     }
 
   eassert (length == TOTAL_LENGTH (source));
 
   if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length)
-    {  /* The inserted text constitutes the whole buffer, so
+    { 
+      /* The inserted text constitutes the whole buffer, so
         simply copy over the interval structure.  */
-         Lisp_Object buf;
-         XSETBUFFER (buf, buffer);
-         BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf);
-      BUF_INTERVALS (buffer)->position = BUF_BEG (buffer);
-      eassert (BUF_INTERVALS (buffer)->up_obj == 1);
-         return;
-       }
-  else if (NULL_INTERVAL_P (tree))
-    { /* Create an interval tree in which to place a copy
+      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);
-      }
-  /* 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.
@@ -1772,7 +1676,7 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT 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))
@@ -1805,9 +1709,7 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
       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,
@@ -1862,18 +1764,14 @@ lookup_char_property (Lisp_Object plist, register Lisp_Object prop, int textprop
 
 void
 temp_set_point_both (struct buffer *buffer,
-                    EMACS_INT charpos, EMACS_INT bytepos)
+                    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);
 }
@@ -1881,7 +1779,7 @@ temp_set_point_both (struct buffer *buffer,
 /* Set point "temporarily", without checking any text properties.  */
 
 void
-temp_set_point (struct buffer *buffer, EMACS_INT charpos)
+temp_set_point (struct buffer *buffer, ptrdiff_t charpos)
 {
   temp_set_point_both (buffer, charpos,
                       buf_charpos_to_bytepos (buffer, charpos));
@@ -1891,7 +1789,7 @@ temp_set_point (struct buffer *buffer, EMACS_INT charpos)
    before an intangible character, move to an ok place.  */
 
 void
-set_point (EMACS_INT charpos)
+set_point (ptrdiff_t charpos)
 {
   set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos));
 }
@@ -1907,8 +1805,8 @@ set_point (EMACS_INT charpos)
    Note that `stickiness' is determined by overlay marker insertion types,
    if the invisible property comes from an overlay.  */
 
-static EMACS_INT
-adjust_for_invis_intang (EMACS_INT pos, EMACS_INT test_offs, EMACS_INT adj,
+static ptrdiff_t
+adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj,
                         int test_intang)
 {
   Lisp_Object invis_propval, invis_overlay;
@@ -1947,20 +1845,20 @@ adjust_for_invis_intang (EMACS_INT pos, EMACS_INT test_offs, EMACS_INT adj,
    before an intangible character, move to an ok place.  */
 
 void
-set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
+set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
 {
   register INTERVAL to, from, toprev, fromprev;
-  EMACS_INT buffer_point;
-  EMACS_INT old_position = PT;
+  ptrdiff_t buffer_point;
+  ptrdiff_t old_position = PT;
   /* This ensures that we move forward past intangible text when the
      initial position is the same as the destination, in the rare
      instances where this is important, e.g. in line-move-finish
      (simple.el).  */
   int backwards = (charpos < old_position ? 1 : 0);
   int have_overlays;
-  EMACS_INT original_position;
+  ptrdiff_t original_position;
 
-  BVAR (current_buffer, point_before_scroll) = Qnil;
+  BSET (current_buffer, point_before_scroll, Qnil);
 
   if (charpos == PT)
     return;
@@ -1973,12 +1871,11 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
      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;
@@ -1987,7 +1884,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
   /* 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)
@@ -2001,7 +1898,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
      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)
@@ -2025,7 +1922,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT 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.  */
@@ -2107,7 +2004,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
       /* 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)
@@ -2171,7 +2068,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
    segment that reaches all the way to point.  */
 
 void
-move_if_not_intangible (EMACS_INT position)
+move_if_not_intangible (ptrdiff_t position)
 {
   Lisp_Object pos;
   Lisp_Object intangible_propval;
@@ -2234,21 +2131,21 @@ move_if_not_intangible (EMACS_INT position)
    nil means the current buffer. */
 
 int
-get_property_and_range (EMACS_INT pos, Lisp_Object prop, Lisp_Object *val,
-                       EMACS_INT *start, EMACS_INT *end, Lisp_Object object)
+get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
+                       ptrdiff_t *start, ptrdiff_t *end, Lisp_Object object)
 {
   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))
@@ -2256,14 +2153,13 @@ get_property_and_range (EMACS_INT 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);
 
@@ -2278,11 +2174,11 @@ get_property_and_range (EMACS_INT pos, Lisp_Object prop, Lisp_Object *val,
    POSITION must be in the accessible part of BUFFER.  */
 
 Lisp_Object
-get_local_map (register EMACS_INT position, register struct buffer *buffer,
+get_local_map (register ptrdiff_t position, register struct buffer *buffer,
               Lisp_Object type)
 {
   Lisp_Object prop, lispy_position, lispy_buffer;
-  EMACS_INT old_begv, old_zv, old_begv_byte, old_zv_byte;
+  ptrdiff_t old_begv, old_zv, old_begv_byte, old_zv_byte;
 
   /* Perhaps we should just change `position' to the limit.  */
   if (position > BUF_ZV (buffer) || position < BUF_BEGV (buffer))
@@ -2329,28 +2225,27 @@ get_local_map (register EMACS_INT position, register struct buffer *buffer,
    The new interval tree has no parent and has a starting-position of 0.  */
 
 INTERVAL
-copy_intervals (INTERVAL tree, EMACS_INT start, EMACS_INT length)
+copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
 {
   register INTERVAL i, new, t;
-  register EMACS_INT got, prevlen;
+  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;
@@ -2371,15 +2266,15 @@ copy_intervals (INTERVAL tree, EMACS_INT start, EMACS_INT length)
 
 void
 copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
-                         EMACS_INT position, EMACS_INT length)
+                         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.
@@ -2389,18 +2284,18 @@ int
 compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
 {
   INTERVAL i1, i2;
-  EMACS_INT pos = 0;
-  EMACS_INT end = SCHARS (s1);
+  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)
     {
       /* Determine how far we can go before we reach the end of I1 or I2.  */
-      EMACS_INT len1 = (i1 != 0 ? INTERVAL_LAST_POS (i1) : end) - pos;
-      EMACS_INT len2 = (i2 != 0 ? INTERVAL_LAST_POS (i2) : end) - pos;
-      EMACS_INT distance = min (len1, len2);
+      ptrdiff_t len1 = (i1 != 0 ? INTERVAL_LAST_POS (i1) : end) - pos;
+      ptrdiff_t len2 = (i2 != 0 ? INTERVAL_LAST_POS (i2) : end) - pos;
+      ptrdiff_t distance = min (len1, len2);
 
       /* If we ever find a mismatch between the strings,
         they differ.  */
@@ -2425,15 +2320,15 @@ compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
 
 static void
 set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
-                          EMACS_INT start, EMACS_INT start_byte,
-                          EMACS_INT end, EMACS_INT end_byte)
+                          ptrdiff_t start, ptrdiff_t start_byte,
+                          ptrdiff_t end, ptrdiff_t end_byte)
 {
   /* Fix the length of this interval.  */
   if (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)
     {
@@ -2444,11 +2339,11 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
   /* Recursively fix the length of the subintervals.  */
   if (i->left)
     {
-      EMACS_INT left_end, left_end_byte;
+      ptrdiff_t left_end, left_end_byte;
 
       if (multi_flag)
        {
-         EMACS_INT temp;
+         ptrdiff_t temp;
          left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
          left_end = BYTE_TO_CHAR (left_end_byte);
 
@@ -2477,11 +2372,11 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
     }
   if (i->right)
     {
-      EMACS_INT right_start_byte, right_start;
+      ptrdiff_t right_start_byte, right_start;
 
       if (multi_flag)
        {
-         EMACS_INT temp;
+         ptrdiff_t temp;
 
          right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
          right_start = BYTE_TO_CHAR (right_start_byte);
@@ -2518,13 +2413,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);
        }
@@ -2538,7 +2433,8 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
 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);
 }