Auto-commit of loaddefs files.
[bpt/emacs.git] / src / intervals.c
index 4464b77..5a47cac 100644 (file)
@@ -1,6 +1,5 @@
 /* Code for doing intervals.
-   Copyright (C) 1993, 1994, 1995, 1997, 1998, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012  Free Software Foundation, Inc.
+   Copyright (C) 1993-1995, 1997-1998, 2001-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -39,9 +38,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
-#include <setjmp.h>
+
+#define INTERVALS_INLINE EXTERN_INLINE
+
+#include <intprops.h>
 #include "lisp.h"
 #include "intervals.h"
+#include "character.h"
 #include "buffer.h"
 #include "puresize.h"
 #include "keyboard.h"
@@ -52,18 +55,49 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define TMEM(sym, set) (CONSP (set) ? ! NILP (Fmemq (sym, set)) : ! NILP (set))
 
-Lisp_Object merge_properties_sticky ();
-static INTERVAL reproduce_tree P_ ((INTERVAL, INTERVAL));
-static INTERVAL reproduce_tree_obj P_ ((INTERVAL, Lisp_Object));
+static Lisp_Object merge_properties_sticky (Lisp_Object, Lisp_Object);
+static INTERVAL merge_interval_right (INTERVAL);
+static INTERVAL reproduce_tree (INTERVAL, INTERVAL);
 \f
 /* Utility functions for intervals.  */
 
+/* Use these functions to set Lisp_Object
+   or pointer slots of struct interval.  */
+
+static inline void
+set_interval_object (INTERVAL i, Lisp_Object obj)
+{
+  eassert (BUFFERP (obj) || STRINGP (obj));
+  i->up_obj = 1;
+  i->up.obj = obj;
+}
+
+static inline void
+set_interval_left (INTERVAL i, INTERVAL left)
+{
+  i->left = left;
+}
+
+static inline void
+set_interval_right (INTERVAL i, INTERVAL right)
+{
+  i->right = right;
+}
+
+/* Make the parent of D be whatever the parent of S is, regardless
+   of the type.  This is used when balancing an interval tree.  */
+
+static inline void
+copy_interval_parent (INTERVAL d, INTERVAL s)
+{
+  d->up = s->up;
+  d->up_obj = s->up_obj;
+}
 
 /* Create the root interval of some object, a buffer or string.  */
 
 INTERVAL
-create_root_interval (parent)
-     Lisp_Object parent;
+create_root_interval (Lisp_Object parent)
 {
   INTERVAL new;
 
@@ -75,19 +109,19 @@ create_root_interval (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));
+      set_buffer_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));
+      set_string_intervals (parent, new);
       new->position = 0;
     }
 
-  SET_INTERVAL_OBJECT (new, parent);
+  set_interval_object (new, parent);
 
   return new;
 }
@@ -95,14 +129,13 @@ create_root_interval (parent)
 /* Make the interval TARGET have exactly the properties of SOURCE */
 
 void
-copy_properties (source, target)
-     register INTERVAL source, target;
+copy_properties (register INTERVAL source, register INTERVAL target)
 {
   if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target))
     return;
 
   COPY_INTERVAL_CACHE (source, target);
-  target->plist = Fcopy_sequence (source->plist);
+  set_interval_plist (target, Fcopy_sequence (source->plist));
 }
 
 /* Merge the properties of interval SOURCE into the properties
@@ -110,8 +143,7 @@ copy_properties (source, target)
    is added to TARGET if TARGET has no such property as yet.  */
 
 static void
-merge_properties (source, target)
-     register INTERVAL source, target;
+merge_properties (register INTERVAL source, register INTERVAL target)
 {
   register Lisp_Object o, sym, val;
 
@@ -139,21 +171,19 @@ merge_properties (source, target)
       if (NILP (val))
        {
          val = XCAR (o);
-         target->plist = Fcons (sym, Fcons (val, target->plist));
+         set_interval_plist (target, Fcons (sym, Fcons (val, target->plist)));
        }
       o = XCDR (o);
     }
 }
 
-/* Return 1 if the two intervals have the same properties,
-   0 otherwise.  */
+/* Return true if the two intervals have the same properties.  */
 
-int
-intervals_equal (i0, i1)
-     INTERVAL i0, i1;
+bool
+intervals_equal (INTERVAL i0, INTERVAL i1)
 {
-  register Lisp_Object i0_cdr, i0_sym;
-  register Lisp_Object i1_cdr, i1_val;
+  Lisp_Object i0_cdr, i0_sym;
+  Lisp_Object i1_cdr, i1_val;
 
   if (DEFAULT_INTERVAL_P (i0) && DEFAULT_INTERVAL_P (i1))
     return 1;
@@ -168,13 +198,13 @@ intervals_equal (i0, i1)
       i0_sym = XCAR (i0_cdr);
       i0_cdr = XCDR (i0_cdr);
       if (!CONSP (i0_cdr))
-       return 0;               /* abort (); */
+       return 0;
       i1_val = i1->plist;
       while (CONSP (i1_val) && !EQ (XCAR (i1_val), i0_sym))
        {
          i1_val = XCDR (i1_val);
          if (!CONSP (i1_val))
-           return 0;           /* abort (); */
+           return 0;
          i1_val = XCDR (i1_val);
        }
 
@@ -192,7 +222,7 @@ intervals_equal (i0, i1)
 
       i1_cdr = XCDR (i1_cdr);
       if (!CONSP (i1_cdr))
-       return 0;               /* abort (); */
+       return 0;
       i1_cdr = XCDR (i1_cdr);
     }
 
@@ -206,16 +236,13 @@ intervals_equal (i0, i1)
    Pass FUNCTION two args: an interval, and ARG.  */
 
 void
-traverse_intervals_noorder (tree, function, arg)
-     INTERVAL tree;
-     void (* function) P_ ((INTERVAL, Lisp_Object));
-     Lisp_Object arg;
+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
        {
@@ -229,13 +256,10 @@ traverse_intervals_noorder (tree, function, arg)
    Pass FUNCTION two args: an interval, and ARG.  */
 
 void
-traverse_intervals (tree, position, function, arg)
-     INTERVAL tree;
-     int position;
-     void (* function) P_ ((INTERVAL, Lisp_Object));
-     Lisp_Object arg;
+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);
@@ -256,8 +280,7 @@ static int zero_length;
 INTERVAL search_interval, found_interval;
 
 void
-check_for_interval (i)
-     register INTERVAL i;
+check_for_interval (INTERVAL i)
 {
   if (i == search_interval)
     {
@@ -267,19 +290,17 @@ check_for_interval (i)
 }
 
 INTERVAL
-search_for_interval (i, tree)
-     register INTERVAL i, tree;
+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;
 }
 
 static void
-inc_interval_count (i)
-     INTERVAL i;
+inc_interval_count (INTERVAL i)
 {
   icount++;
   if (LENGTH (i) == 0)
@@ -289,8 +310,7 @@ inc_interval_count (i)
 }
 
 int
-count_intervals (i)
-     register INTERVAL i;
+count_intervals (INTERVAL i)
 {
   icount = 0;
   idepth = 0;
@@ -301,8 +321,7 @@ count_intervals (i)
 }
 
 static INTERVAL
-root_interval (interval)
-     INTERVAL interval;
+root_interval (INTERVAL interval)
 {
   register INTERVAL i = interval;
 
@@ -322,41 +341,40 @@ root_interval (interval)
      c           c
 */
 
-static INLINE INTERVAL
-rotate_right (interval)
-     INTERVAL interval;
+static inline INTERVAL
+rotate_right (INTERVAL interval)
 {
   INTERVAL i;
   INTERVAL B = interval->left;
-  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;
+       set_interval_left (INTERVAL_PARENT (interval), B);
       else
-       INTERVAL_PARENT (interval)->right = B;
+       set_interval_right (INTERVAL_PARENT (interval), B);
     }
-  COPY_INTERVAL_PARENT (B, interval);
+  copy_interval_parent (B, interval);
 
   /* Make B the parent of A */
   i = B->right;
-  B->right = interval;
-  SET_INTERVAL_PARENT (interval, B);
+  set_interval_right (B, interval);
+  set_interval_parent (interval, B);
 
   /* Make A point to c */
-  interval->left = i;
-  if (! NULL_INTERVAL_P (i))
-    SET_INTERVAL_PARENT (i, interval);
+  set_interval_left (interval, i);
+  if (i)
+    set_interval_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;
 }
@@ -370,41 +388,40 @@ rotate_right (interval)
     c               c
 */
 
-static INLINE INTERVAL
-rotate_left (interval)
-     INTERVAL interval;
+static inline INTERVAL
+rotate_left (INTERVAL interval)
 {
   INTERVAL i;
   INTERVAL B = interval->right;
-  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;
+       set_interval_left (INTERVAL_PARENT (interval), B);
       else
-       INTERVAL_PARENT (interval)->right = B;
+       set_interval_right (INTERVAL_PARENT (interval), B);
     }
-  COPY_INTERVAL_PARENT (B, interval);
+  copy_interval_parent (B, interval);
 
   /* Make B the parent of A */
   i = B->left;
-  B->left = interval;
-  SET_INTERVAL_PARENT (interval, B);
+  set_interval_left (B, interval);
+  set_interval_parent (interval, B);
 
   /* Make A point to c */
-  interval->right = i;
-  if (! NULL_INTERVAL_P (i))
-    SET_INTERVAL_PARENT (i, interval);
+  set_interval_right (interval, i);
+  if (i)
+    set_interval_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;
 }
@@ -413,10 +430,9 @@ rotate_left (interval)
    themselves are already balanced.  */
 
 static INTERVAL
-balance_an_interval (i)
-     INTERVAL i;
+balance_an_interval (INTERVAL i)
 {
-  register int old_diff, new_diff;
+  register ptrdiff_t old_diff, new_diff;
 
   while (1)
     {
@@ -450,12 +466,11 @@ balance_an_interval (i)
 /* Balance INTERVAL, potentially stuffing it back into its parent
    Lisp Object.  */
 
-static INLINE INTERVAL
-balance_possible_root_interval (interval)
-     register INTERVAL interval;
+static inline INTERVAL
+balance_possible_root_interval (INTERVAL interval)
 {
   Lisp_Object parent;
-  int have_parent = 0;
+  bool have_parent = 0;
 
   if (!INTERVAL_HAS_OBJECT (interval) && !INTERVAL_HAS_PARENT (interval))
     return interval;
@@ -470,9 +485,9 @@ balance_possible_root_interval (interval)
   if (have_parent)
     {
       if (BUFFERP (parent))
-       BUF_INTERVALS (XBUFFER (parent)) = interval;
+       set_buffer_intervals (XBUFFER (parent), interval);
       else if (STRINGP (parent))
-       STRING_SET_INTERVALS (parent, interval);
+       set_string_intervals (parent, interval);
     }
 
   return interval;
@@ -482,8 +497,7 @@ balance_possible_root_interval (interval)
    (the amount of text).  */
 
 static INTERVAL
-balance_intervals_internal (tree)
-     register INTERVAL tree;
+balance_intervals_internal (register INTERVAL tree)
 {
   /* Balance within each side.  */
   if (tree->left)
@@ -496,15 +510,24 @@ balance_intervals_internal (tree)
 /* Advertised interface to balance intervals.  */
 
 INTERVAL
-balance_intervals (tree)
-     INTERVAL tree;
+balance_intervals (INTERVAL tree)
 {
-  if (tree == NULL_INTERVAL)
-    return NULL_INTERVAL;
+  return tree ? balance_intervals_internal (tree) : NULL;
+}
+
+/* Rebalance text properties of B.  */
 
-  return balance_intervals_internal (tree);
+static void
+buffer_balance_intervals (struct buffer *b)
+{
+  INTERVAL i;
+
+  eassert (b != NULL);
+  i = buffer_intervals (b);
+  if (i)
+    set_buffer_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
@@ -519,31 +542,29 @@ balance_intervals (tree)
    it is still a root after this operation.  */
 
 INTERVAL
-split_interval_right (interval, offset)
-     INTERVAL interval;
-     int offset;
+split_interval_right (INTERVAL interval, ptrdiff_t offset)
 {
   INTERVAL new = make_interval ();
-  int position = interval->position;
-  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);
+  set_interval_parent (new, interval);
 
   if (NULL_RIGHT_CHILD (interval))
     {
-      interval->right = new;
+      set_interval_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;
+      set_interval_right (new, interval->right);
+      set_interval_parent (interval->right, new);
+      set_interval_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);
     }
 
@@ -566,31 +587,29 @@ split_interval_right (interval, offset)
    it is still a root after this operation.  */
 
 INTERVAL
-split_interval_left (interval, offset)
-     INTERVAL interval;
-     int offset;
+split_interval_left (INTERVAL interval, ptrdiff_t offset)
 {
   INTERVAL new = make_interval ();
-  int new_length = offset;
+  ptrdiff_t new_length = offset;
 
   new->position = interval->position;
   interval->position = interval->position + offset;
-  SET_INTERVAL_PARENT (new, interval);
+  set_interval_parent (new, interval);
 
   if (NULL_LEFT_CHILD (interval))
     {
-      interval->left = new;
+      set_interval_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;
+      set_interval_left (new, interval->left);
+      set_interval_parent (new->left, new);
+      set_interval_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);
     }
 
@@ -607,13 +626,12 @@ split_interval_left (interval, offset)
    Don't use this function on an interval which is the child
    of another interval!  */
 
-int
-interval_start_pos (source)
-     INTERVAL source;
+static int
+interval_start_pos (INTERVAL source)
 {
   Lisp_Object parent;
 
-  if (NULL_INTERVAL_P (source))
+  if (!source)
     return 0;
 
   if (! INTERVAL_HAS_OBJECT (source))
@@ -635,16 +653,14 @@ interval_start_pos (source)
    will update this cache based on the result of find_interval.  */
 
 INTERVAL
-find_interval (tree, position)
-     register INTERVAL tree;
-     register 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 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))
@@ -655,8 +671,7 @@ find_interval (tree, 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);
@@ -691,14 +706,13 @@ find_interval (tree, position)
    find_interval).  */
 
 INTERVAL
-next_interval (interval)
-     register INTERVAL interval;
+next_interval (register INTERVAL interval)
 {
   register INTERVAL i = interval;
-  register 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))
@@ -723,7 +737,7 @@ next_interval (interval)
       i = INTERVAL_PARENT (i);
     }
 
-  return NULL_INTERVAL;
+  return NULL;
 }
 
 /* Find the preceding interval (lexicographically) to INTERVAL.
@@ -731,13 +745,12 @@ next_interval (interval)
    find_interval).  */
 
 INTERVAL
-previous_interval (interval)
-     register INTERVAL interval;
+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))
     {
@@ -762,7 +775,7 @@ previous_interval (interval)
       i = INTERVAL_PARENT (i);
     }
 
-  return NULL_INTERVAL;
+  return NULL;
 }
 
 /* Find the interval containing POS given some non-NULL INTERVAL
@@ -771,12 +784,10 @@ previous_interval (interval)
    To speed up the process, we assume that the ->position of
    I and all its parents is already uptodate.  */
 INTERVAL
-update_interval (i, pos)
-     register INTERVAL i;
-     int pos;
+update_interval (register INTERVAL i, ptrdiff_t pos)
 {
-  if (NULL_INTERVAL_P (i))
-    return NULL_INTERVAL;
+  if (!i)
+    return NULL;
 
   while (1)
     {
@@ -805,7 +816,7 @@ update_interval (i, pos)
              i = i->right;             /* Move to the right child */
            }
          else if (NULL_PARENT (i))
-           error ("Point %d after end of properties", pos);
+           error ("Point %"pD"d after end of properties", pos);
          else
             i = INTERVAL_PARENT (i);
          continue;
@@ -815,69 +826,6 @@ update_interval (i, 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 (tree, position, length)
-     INTERVAL tree;
-     int position, length;
-{
-  register 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
@@ -892,18 +840,16 @@ adjust_intervals_for_insertion (tree, position, length)
    this text, and make it have the merged properties of both ends.  */
 
 static INTERVAL
-adjust_intervals_for_insertion (tree, position, length)
-     INTERVAL tree;
-     int position, length;
+adjust_intervals_for_insertion (INTERVAL tree,
+                               ptrdiff_t position, ptrdiff_t length)
 {
-  register INTERVAL i;
-  register INTERVAL temp;
-  int eobp = 0;
+  INTERVAL i;
+  INTERVAL temp;
+  bool eobp = 0;
   Lisp_Object parent;
-  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);
@@ -1014,7 +960,7 @@ adjust_intervals_for_insertion (tree, position, length)
       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);
        }
 
@@ -1033,25 +979,24 @@ adjust_intervals_for_insertion (tree, position, length)
          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;
+         set_interval_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;
+                 set_interval_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);
+             set_interval_plist (prev, newi.plist);
+             if (i && intervals_equal (prev, i))
                merge_interval_right (prev);
            }
 
@@ -1071,7 +1016,7 @@ adjust_intervals_for_insertion (tree, position, length)
       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);
        }
     }
@@ -1118,15 +1063,13 @@ FR     8  9  A  B
        left rear-nonsticky = t,   right front-sticky = nil (inherit none)
 */
 
-Lisp_Object
-merge_properties_sticky (pleft, pright)
-     Lisp_Object pleft, pright;
+static Lisp_Object
+merge_properties_sticky (Lisp_Object pleft, Lisp_Object pright)
 {
-  register Lisp_Object props, front, rear;
+  Lisp_Object props, front, rear;
   Lisp_Object lfront, lrear, rfront, rrear;
-  register Lisp_Object tail1, tail2, sym, lval, rval, cat;
-  int use_left, use_right;
-  int lpresent;
+  Lisp_Object tail1, tail2, sym, lval, rval, cat;
+  bool use_left, use_right, lpresent;
 
   props = Qnil;
   front = Qnil;
@@ -1256,29 +1199,28 @@ merge_properties_sticky (pleft, pright)
    storing the resulting subtree into its parent.  */
 
 static INTERVAL
-delete_node (i)
-     register INTERVAL i;
+delete_node (register INTERVAL i)
 {
   register INTERVAL migrate, this;
-  register 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));
+  set_interval_left (this, migrate);
+  set_interval_parent (migrate, this);
 
   return i->right;
 }
@@ -1289,30 +1231,28 @@ delete_node (i)
    I is presumed to be empty; that is, no adjustments are made
    for the length of I.  */
 
-void
-delete_interval (i)
-     register INTERVAL i;
+static void
+delete_interval (register INTERVAL i)
 {
   register INTERVAL parent;
-  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)
+       set_interval_object (parent, owner);
 
       if (BUFFERP (owner))
-       BUF_INTERVALS (XBUFFER (owner)) = parent;
+       set_buffer_intervals (XBUFFER (owner), parent);
       else if (STRINGP (owner))
-       STRING_SET_INTERVALS (owner, parent);
+       set_string_intervals (owner, parent);
       else
-       abort ();
+       emacs_abort ();
 
       return;
     }
@@ -1320,15 +1260,15 @@ delete_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);
+      set_interval_left (parent, delete_node (i));
+      if (parent->left)
+       set_interval_parent (parent->left, parent);
     }
   else
     {
-      parent->right = delete_node (i);
-      if (! NULL_INTERVAL_P (parent->right))
-       SET_INTERVAL_PARENT (parent->right, parent);
+      set_interval_right (parent, delete_node (i));
+      if (parent->right)
+       set_interval_parent (parent->right, parent);
     }
 }
 \f
@@ -1344,31 +1284,30 @@ delete_interval (i)
    Do this by recursing down TREE to the interval in question, and
    deleting the appropriate amount of text.  */
 
-static int
-interval_deletion_adjustment (tree, from, amount)
-     register INTERVAL tree;
-     register int from, amount;
+static ptrdiff_t
+interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
+                             register ptrdiff_t amount)
 {
-  register int relative_position = from;
+  register ptrdiff_t relative_position = from;
 
-  if (NULL_INTERVAL_P (tree))
+  if (!tree)
     return 0;
 
-  /* Left branch */
+  /* Left branch */
   if (relative_position < LEFT_TOTAL_LENGTH (tree))
     {
-      int subtract = interval_deletion_adjustment (tree->left,
-                                                  relative_position,
-                                                  amount);
+      ptrdiff_t subtract = interval_deletion_adjustment (tree->left,
+                                                        relative_position,
+                                                        amount);
       tree->total_length -= subtract;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return subtract;
     }
-  /* Right branch */
+  /* Right branch */
   else if (relative_position >= (TOTAL_LENGTH (tree)
                                 - RIGHT_TOTAL_LENGTH (tree)))
     {
-      int subtract;
+      ptrdiff_t subtract;
 
       relative_position -= (tree->total_length
                            - RIGHT_TOTAL_LENGTH (tree));
@@ -1376,22 +1315,22 @@ interval_deletion_adjustment (tree, from, amount)
                                               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?  */
-      int my_amount = ((tree->total_length
-                       - RIGHT_TOTAL_LENGTH (tree))
-                      - relative_position);
+      ptrdiff_t my_amount = ((tree->total_length
+                              - RIGHT_TOTAL_LENGTH (tree))
+                             - relative_position);
 
       if (amount > my_amount)
        amount = my_amount;
 
       tree->total_length -= amount;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       if (LENGTH (tree) == 0)
        delete_interval (tree);
 
@@ -1407,35 +1346,33 @@ interval_deletion_adjustment (tree, from, amount)
    buffer position, i.e. origin 1).  */
 
 static void
-adjust_intervals_for_deletion (buffer, start, length)
-     struct buffer *buffer;
-     int start, length;
+adjust_intervals_for_deletion (struct buffer *buffer,
+                              ptrdiff_t start, ptrdiff_t length)
 {
-  register int left_to_delete = length;
-  register INTERVAL tree = BUF_INTERVALS (buffer);
+  ptrdiff_t left_to_delete = length;
+  INTERVAL tree = buffer_intervals (buffer);
   Lisp_Object parent;
-  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;
+      set_buffer_intervals (buffer, NULL);
       return;
     }
 
   if (ONLY_INTERVAL_P (tree))
     {
       tree->total_length -= length;
-      CHECK_TOTAL_LENGTH (tree);
+      eassert (0 <= TOTAL_LENGTH (tree));
       return;
     }
 
@@ -1445,10 +1382,10 @@ adjust_intervals_for_deletion (buffer, start, length)
     {
       left_to_delete -= interval_deletion_adjustment (tree, start - offset,
                                                      left_to_delete);
-      tree = BUF_INTERVALS (buffer);
+      tree = buffer_intervals (buffer);
       if (left_to_delete == tree->total_length)
        {
-         BUF_INTERVALS (buffer) = NULL_INTERVAL;
+         set_buffer_intervals (buffer, NULL);
          return;
        }
     }
@@ -1459,18 +1396,20 @@ adjust_intervals_for_deletion (buffer, start, length)
    at position START.  Addition or deletion is indicated by the sign
    of LENGTH.  */
 
-INLINE void
-offset_intervals (buffer, start, length)
-     struct buffer *buffer;
-     int start, length;
+void
+offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
 {
-  if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) || length == 0)
+  if (!buffer_intervals (buffer) || length == 0)
     return;
 
   if (length > 0)
-    adjust_intervals_for_insertion (BUF_INTERVALS (buffer), start, length);
+    adjust_intervals_for_insertion (buffer_intervals (buffer),
+                                   start, length);
   else
-    adjust_intervals_for_deletion (buffer, start, -length);
+    {
+      lint_assume (- TYPE_MAXIMUM (ptrdiff_t) <= length);
+      adjust_intervals_for_deletion (buffer, start, -length);
+    }
 }
 \f
 /* Merge interval I with its lexicographic successor. The resulting
@@ -1482,17 +1421,12 @@ offset_intervals (buffer, start, length)
    The caller must verify that this is not the last (rightmost)
    interval.  */
 
-INTERVAL
-merge_interval_right (i)
-     register INTERVAL i;
+static INTERVAL
+merge_interval_right (register INTERVAL i)
 {
-  register 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.  */
@@ -1501,16 +1435,20 @@ merge_interval_right (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.  */
@@ -1524,12 +1462,12 @@ merge_interval_right (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
      be merged right.  The caller should have known.  */
-  abort ();
+  emacs_abort ();
 }
 \f
 /* Merge interval I with its lexicographic predecessor. The resulting
@@ -1540,16 +1478,11 @@ merge_interval_right (i)
    The caller must verify that this is not the first (leftmost) interval.  */
 
 INTERVAL
-merge_interval_left (i)
-     register INTERVAL i;
+merge_interval_left (register INTERVAL i)
 {
-  register 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.  */
@@ -1558,19 +1491,23 @@ merge_interval_left (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))
        {
@@ -1581,98 +1518,54 @@ merge_interval_left (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
      be merged left.  The caller should have known.  */
-  abort ();
+  emacs_abort ();
 }
 \f
-/* Make an exact copy of interval tree SOURCE which descends from
-   PARENT.  This is done by recursing through SOURCE, copying
-   the current interval and its properties, and then adjusting
-   the pointers of the copy.  */
+/* Create a copy of SOURCE but with the default value of UP.  */
 
 static INTERVAL
-reproduce_tree (source, parent)
-     INTERVAL source, parent;
+reproduce_interval (INTERVAL source)
 {
-  register INTERVAL t = make_interval ();
-
-  bcopy (source, t, INTERVAL_SIZE);
-  copy_properties (source, t);
-  SET_INTERVAL_PARENT (t, parent);
-  if (! NULL_LEFT_CHILD (source))
-    t->left = reproduce_tree (source->left, t);
-  if (! NULL_RIGHT_CHILD (source))
-    t->right = reproduce_tree (source->right, t);
+  register INTERVAL target = make_interval ();
 
-  return t;
-}
+  target->total_length = source->total_length;
+  target->position = source->position;
 
-static INTERVAL
-reproduce_tree_obj (source, parent)
-     INTERVAL source;
-     Lisp_Object parent;
-{
-  register INTERVAL t = make_interval ();
+  copy_properties (source, target);
 
-  bcopy (source, t, INTERVAL_SIZE);
-  copy_properties (source, t);
-  SET_INTERVAL_OBJECT (t, parent);
   if (! NULL_LEFT_CHILD (source))
-    t->left = reproduce_tree (source->left, t);
+    set_interval_left (target, reproduce_tree (source->left, target));
   if (! NULL_RIGHT_CHILD (source))
-    t->right = reproduce_tree (source->right, t);
+    set_interval_right (target, reproduce_tree (source->right, target));
 
-  return t;
+  return target;
 }
 
-#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.  */
+/* Make an exact copy of interval tree SOURCE which descends from
+   PARENT.  This is done by recursing through SOURCE, copying
+   the current interval and its properties, and then adjusting
+   the pointers of the copy.  */
 
 static INTERVAL
-make_new_interval (intervals, start, length)
-     INTERVAL intervals;
-     int start, length;
+reproduce_tree (INTERVAL source, INTERVAL parent)
 {
-  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;
-    }
+  INTERVAL target = reproduce_interval (source);
+  set_interval_parent (target, parent);
+  return target;
+}
 
-  /* Convert interval SLOT into three intervals.  */
-  split_interval_left (slot, start - slot->position);
-  split_interval_right (slot, length);
-  return slot;
+static INTERVAL
+reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
+{
+  INTERVAL target = reproduce_interval (source);
+  set_interval_object (target, parent);
+  return target;
 }
-#endif
 \f
 /* Insert the intervals of SOURCE into BUFFER at POSITION.
    LENGTH is the length of the text in SOURCE.
@@ -1697,11 +1590,9 @@ make_new_interval (intervals, start, 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),
@@ -1714,84 +1605,62 @@ make_new_interval (intervals, start, length)
    text...  */
 
 void
-graft_intervals_into_buffer (source, position, length, buffer, inherit)
-     INTERVAL source;
-     int position, length;
-     struct buffer *buffer;
-     int inherit;
+graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
+                            ptrdiff_t length, struct buffer *buffer,
+                            bool inherit)
 {
-  register INTERVAL under, over, this, prev;
-  register INTERVAL tree;
-  int over_used;
-
-  tree = BUF_INTERVALS (buffer);
+  INTERVAL tree = buffer_intervals (buffer);
+  INTERVAL under, over, this;
+  ptrdiff_t over_used;
 
   /* If the new text has no properties, then with inheritance it
      becomes part of whatever interval it was inserted into.
      To prevent inheritance, we must clear out the properties
      of the newly inserted text.  */
-  if (NULL_INTERVAL_P (source))
+  if (!source)
     {
       Lisp_Object buf;
-      if (!inherit && !NULL_INTERVAL_P (tree) && length > 0)
+      if (!inherit && tree && length > 0)
        {
          XSETBUFFER (buf, buffer);
          set_text_properties_1 (make_number (position),
                                 make_number (position + length),
                                 Qnil, buf, 0);
        }
-      if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
-       /* Shouldn't be necessary.  -stef  */
-       BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
+      /* Shouldn't be necessary.  --Stef  */
+      buffer_balance_intervals (buffer);
       return;
     }
 
-  if (NULL_INTERVAL_P (tree))
+  eassert (length == TOTAL_LENGTH (source));
+
+  if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length)
     {
       /* The inserted text constitutes the whole buffer, so
         simply copy over the interval structure.  */
-      if ((BUF_Z (buffer) - BUF_BEG (buffer)) == TOTAL_LENGTH (source))
-       {
-         Lisp_Object buf;
-         XSETBUFFER (buf, buffer);
-         BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf);
-         BUF_INTERVALS (buffer)->position = BEG;
-         BUF_INTERVALS (buffer)->up_obj = 1;
-
-         /* Explicitly free the old tree here?  */
-
-         return;
-       }
+      Lisp_Object buf;
 
+      XSETBUFFER (buf, buffer);
+      set_buffer_intervals (buffer, reproduce_tree_obj (source, buf));
+      buffer_intervals (buffer)->position = BUF_BEG (buffer);
+      eassert (buffer_intervals (buffer)->up_obj == 1);
+      return;
+    }
+  else if (!tree)
+    {
       /* Create an interval tree in which to place a copy
         of the intervals of the inserted string.  */
-      {
        Lisp_Object buf;
+
        XSETBUFFER (buf, buffer);
        tree = create_root_interval (buf);
-      }
     }
-  else if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source))
-    /* If the buffer contains only the new string, but
-       there was already some interval tree there, then it may be
-       some zero length intervals.  Eventually, do something clever
-       about inserting properly.  For now, just waste the old intervals.  */
-    {
-      BUF_INTERVALS (buffer) = reproduce_tree (source, INTERVAL_PARENT (tree));
-      BUF_INTERVALS (buffer)->position = BEG;
-      BUF_INTERVALS (buffer)->up_obj = 1;
-      /* Explicitly free the old tree here.  */
-
-      return;
-    }
-  /* Paranoia -- the text has already been added, so this buffer
-     should be of non-zero length.  */
-  else if (TOTAL_LENGTH (tree) == 0)
-    abort ();
+  /* Paranoia -- the text has already been added, so
+     this buffer should be of non-zero length.  */
+  eassert (TOTAL_LENGTH (tree) > 0);
 
   this = under = find_interval (tree, position);
-  if (NULL_INTERVAL_P (under)) /* Paranoia */
-    abort ();
+  eassert (under);
   over = find_interval (source, interval_start_pos (source));
 
   /* Here for insertion in the middle of an interval.
@@ -1810,7 +1679,8 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
       /* This call may have some effect because previous_interval may
          update `position' fields of intervals.  Thus, don't ignore it
          for the moment.  Someone please tell me the truth (K.Handa).  */
-      prev = previous_interval (under);
+      INTERVAL prev = previous_interval (under);
+      (void) prev;
 #if 0
       /* But, this code surely has no effect.  And, anyway,
          END_NONSTICKY_P is unreliable now.  */
@@ -1832,7 +1702,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
      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))
@@ -1865,9 +1735,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
       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,
@@ -1876,20 +1744,15 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
    and for PROP appearing on the default-text-properties list.  */
 
 Lisp_Object
-textget (plist, prop)
-     Lisp_Object plist;
-     register Lisp_Object prop;
+textget (Lisp_Object plist, register Lisp_Object prop)
 {
   return lookup_char_property (plist, prop, 1);
 }
 
 Lisp_Object
-lookup_char_property (plist, prop, textprop)
-     Lisp_Object plist;
-     register Lisp_Object prop;
-     int textprop;
+lookup_char_property (Lisp_Object plist, Lisp_Object prop, bool textprop)
 {
-  register Lisp_Object tail, fallback = Qnil;
+  Lisp_Object tail, fallback = Qnil;
 
   for (tail = plist; CONSP (tail); tail = Fcdr (XCDR (tail)))
     {
@@ -1922,41 +1785,37 @@ lookup_char_property (plist, prop, textprop)
 }
 
 \f
-/* Set point "temporarily", without checking any text properties.  */
-
-INLINE void
-temp_set_point (struct buffer *buffer, EMACS_INT charpos)
-{
-  temp_set_point_both (buffer, charpos,
-                      buf_charpos_to_bytepos (buffer, charpos));
-}
-
 /* Set point in BUFFER "temporarily" to CHARPOS, which corresponds to
    byte position BYTEPOS.  */
 
-INLINE void
+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);
 }
 
+/* Set point "temporarily", without checking any text properties.  */
+
+void
+temp_set_point (struct buffer *buffer, ptrdiff_t charpos)
+{
+  temp_set_point_both (buffer, charpos,
+                      buf_charpos_to_bytepos (buffer, charpos));
+}
+
 /* Set point in BUFFER to CHARPOS.  If the target position is
    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));
 }
@@ -1964,17 +1823,17 @@ set_point (EMACS_INT charpos)
 /* If there's an invisible character at position POS + TEST_OFFS in the
    current buffer, and the invisible property has a `stickiness' such that
    inserting a character at position POS would inherit the property it,
-   return POS + ADJ, otherwise return POS.  If TEST_INTANG is non-zero,
-   then intangibility is required as well as invisibleness.
+   return POS + ADJ, otherwise return POS.  If TEST_INTANG, intangibility
+   is required as well as invisibility.
 
    TEST_OFFS should be either 0 or -1, and ADJ should be either 1 or -1.
 
    Note that `stickiness' is determined by overlay marker insertion types,
    if the invisible property comes from an overlay.  */
 
-static int
-adjust_for_invis_intang (pos, test_offs, adj, test_intang)
-     int pos, test_offs, adj, test_intang;
+static ptrdiff_t
+adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj,
+                        bool test_intang)
 {
   Lisp_Object invis_propval, invis_overlay;
   Lisp_Object test_pos;
@@ -2012,20 +1871,20 @@ adjust_for_invis_intang (pos, test_offs, adj, test_intang)
    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;
+  bool backwards = charpos < old_position;
+  bool have_overlays;
+  ptrdiff_t original_position;
 
-  current_buffer->point_before_scroll = Qnil;
+  bset_point_before_scroll (current_buffer, Qnil);
 
   if (charpos == PT)
     return;
@@ -2038,12 +1897,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_intervals (current_buffer) && ! have_overlays)
     {
       temp_set_point_both (current_buffer, charpos, bytepos);
       return;
@@ -2052,7 +1910,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_intervals (current_buffer), charpos);
   if (charpos == BEGV)
     toprev = 0;
   else if (to && to->position == charpos)
@@ -2066,7 +1924,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_intervals (current_buffer), buffer_point);
   if (buffer_point == BEGV)
     fromprev = 0;
   else if (from && from->position == PT)
@@ -2090,7 +1948,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.  */
@@ -2172,7 +2030,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_intervals (current_buffer), charpos);
       if (charpos == BEGV)
        toprev = 0;
       else if (to && to->position == charpos)
@@ -2236,8 +2094,7 @@ set_point_both (EMACS_INT charpos, EMACS_INT bytepos)
    segment that reaches all the way to point.  */
 
 void
-move_if_not_intangible (position)
-     int position;
+move_if_not_intangible (ptrdiff_t position)
 {
   Lisp_Object pos;
   Lisp_Object intangible_propval;
@@ -2294,30 +2151,27 @@ move_if_not_intangible (position)
 \f
 /* If text at position POS has property PROP, set *VAL to the property
    value, *START and *END to the beginning and end of a region that
-   has the same property, and return 1.  Otherwise return 0.
+   has the same property, and return true.  Otherwise return false.
 
    OBJECT is the string or buffer to look for the property in;
    nil means the current buffer. */
 
-int
-get_property_and_range (pos, prop, val, start, end, object)
-     int pos;
-     Lisp_Object prop, *val;
-     EMACS_INT *start, *end;
-     Lisp_Object object;
+bool
+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_intervals (current_buffer), pos);
   else if (BUFFERP (object))
-    i = find_interval (BUF_INTERVALS (XBUFFER (object)), pos);
+    i = find_interval (buffer_intervals (XBUFFER (object)), pos);
   else if (STRINGP (object))
-    i = find_interval (STRING_INTERVALS (object), pos);
+    i = find_interval (string_intervals (object), pos);
   else
-    abort ();
+    emacs_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))
@@ -2325,14 +2179,13 @@ get_property_and_range (pos, prop, val, start, end, object)
 
   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);
 
@@ -2347,17 +2200,15 @@ get_property_and_range (pos, prop, val, start, end, object)
    POSITION must be in the accessible part of BUFFER.  */
 
 Lisp_Object
-get_local_map (position, buffer, type)
-     register int position;
-     register struct buffer *buffer;
-     Lisp_Object type;
+get_local_map (register ptrdiff_t position, register struct buffer *buffer,
+              Lisp_Object type)
 {
   Lisp_Object prop, lispy_position, lispy_buffer;
-  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))
-    abort ();
+    emacs_abort ();
 
   /* Ignore narrowing, so that a local map continues to be valid even if
      the visible region contains no characters and hence no properties.  */
@@ -2392,7 +2243,7 @@ get_local_map (position, buffer, type)
   if (EQ (type, Qkeymap))
     return Qnil;
   else
-    return buffer->keymap;
+    return BVAR (buffer, keymap);
 }
 \f
 /* Produce an interval tree reflecting the intervals in
@@ -2400,30 +2251,27 @@ get_local_map (position, buffer, type)
    The new interval tree has no parent and has a starting-position of 0.  */
 
 INTERVAL
-copy_intervals (tree, start, length)
-     INTERVAL tree;
-     int start, length;
+copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
 {
   register INTERVAL i, new, t;
-  register 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;
@@ -2442,41 +2290,38 @@ copy_intervals (tree, start, length)
 
 /* Give STRING the properties of BUFFER from POSITION to LENGTH.  */
 
-INLINE void
-copy_intervals_to_string (string, buffer, position, length)
-     Lisp_Object string;
-     struct buffer *buffer;
-     int position, length;
+void
+copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
+                         ptrdiff_t position, ptrdiff_t length)
 {
-  INTERVAL interval_copy = copy_intervals (BUF_INTERVALS (buffer),
+  INTERVAL interval_copy = copy_intervals (buffer_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);
+  set_interval_object (interval_copy, string);
+  set_string_intervals (string, interval_copy);
 }
 \f
-/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
+/* Return true if strings S1 and S2 have identical properties.
    Assume they have identical characters.  */
 
-int
-compare_string_intervals (s1, s2)
-     Lisp_Object s1, s2;
+bool
+compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
 {
   INTERVAL i1, i2;
-  int pos = 0;
-  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_intervals (s1), 0);
+  i2 = find_interval (string_intervals (s2), 0);
 
   while (pos < end)
     {
       /* Determine how far we can go before we reach the end of I1 or I2.  */
-      int len1 = (i1 != 0 ? INTERVAL_LAST_POS (i1) : end) - pos;
-      int len2 = (i2 != 0 ? INTERVAL_LAST_POS (i2) : end) - pos;
-      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.  */
@@ -2500,17 +2345,16 @@ compare_string_intervals (s1, s2)
    START_BYTE ... END_BYTE in bytes.  */
 
 static void
-set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
-     INTERVAL i;
-     int multi_flag;
-     int start, start_byte, end, end_byte;
+set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
+                          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)
     {
@@ -2521,11 +2365,11 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
   /* Recursively fix the length of the subintervals.  */
   if (i->left)
     {
-      int left_end, left_end_byte;
+      ptrdiff_t left_end, left_end_byte;
 
       if (multi_flag)
        {
-         int temp;
+         ptrdiff_t temp;
          left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
          left_end = BYTE_TO_CHAR (left_end_byte);
 
@@ -2554,11 +2398,11 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
     }
   if (i->right)
     {
-      int right_start_byte, right_start;
+      ptrdiff_t right_start_byte, right_start;
 
       if (multi_flag)
        {
-         int temp;
+         ptrdiff_t temp;
 
          right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
          right_start = BYTE_TO_CHAR (right_start_byte);
@@ -2595,13 +2439,13 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
     {
       if ((i)->left)
        {
-         (i)->plist = (i)->left->plist;
+         set_interval_plist (i, i->left->plist);
          (i)->left->total_length = 0;
          delete_interval ((i)->left);
        }
       else
        {
-         (i)->plist = (i)->right->plist;
+         set_interval_plist (i, i->right->plist);
          (i)->right->total_length = 0;
          delete_interval ((i)->right);
        }
@@ -2609,17 +2453,14 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
 }
 
 /* Update the intervals of the current buffer
-   to fit the contents as multibyte (if MULTI_FLAG is 1)
-   or to fit them as non-multibyte (if MULTI_FLAG is 0).  */
+   to fit the contents as multibyte (if MULTI_FLAG)
+   or to fit them as non-multibyte (if not MULTI_FLAG).  */
 
 void
-set_intervals_multibyte (multi_flag)
-     int multi_flag;
+set_intervals_multibyte (bool 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_intervals (current_buffer);
 
-/* arch-tag: 3d402b60-083c-4271-b4a3-ebd9a74bfe27
-   (do not change this comment) */
+  if (i)
+    set_intervals_multibyte_1 (i, multi_flag, BEG, BEG_BYTE, Z, Z_BYTE);
+}