Another merge from trunk.
[bpt/emacs.git] / src / intervals.c
index 2dcf208..0e3b684 100644 (file)
@@ -1,5 +1,6 @@
 /* Code for doing intervals.
-   Copyright (C) 1993-1995, 1997-1998, 2001-2012  Free Software Foundation, Inc.
+   Copyright (C) 1993-1995, 1997-1998, 2001-2013 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -39,9 +40,6 @@ 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"
@@ -65,7 +63,7 @@ static INTERVAL reproduce_tree (INTERVAL, INTERVAL);
 /* Use these functions to set Lisp_Object
    or pointer slots of struct interval.  */
 
-static inline void
+static void
 set_interval_object (INTERVAL i, Lisp_Object obj)
 {
   eassert (BUFFERP (obj) || STRINGP (obj));
@@ -73,13 +71,13 @@ set_interval_object (INTERVAL i, Lisp_Object obj)
   i->up.obj = obj;
 }
 
-static inline void
+static void
 set_interval_left (INTERVAL i, INTERVAL left)
 {
   i->left = left;
 }
 
-static inline void
+static void
 set_interval_right (INTERVAL i, INTERVAL right)
 {
   i->right = right;
@@ -88,7 +86,7 @@ set_interval_right (INTERVAL i, INTERVAL 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
+static void
 copy_interval_parent (INTERVAL d, INTERVAL s)
 {
   d->up = s->up;
@@ -110,14 +108,14 @@ create_root_interval (Lisp_Object parent)
     {
       new->total_length = (BUF_Z (XBUFFER (parent))
                           - BUF_BEG (XBUFFER (parent)));
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
       set_buffer_intervals (XBUFFER (parent), new);
       new->position = BEG;
     }
   else if (STRINGP (parent))
     {
       new->total_length = SCHARS (parent);
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
       set_string_intervals (parent, new);
       new->position = 0;
     }
@@ -178,14 +176,13 @@ merge_properties (register INTERVAL source, register INTERVAL target)
     }
 }
 
-/* Return 1 if the two intervals have the same properties,
-   0 otherwise.  */
+/* Return true if the two intervals have the same properties.  */
 
-int
+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;
@@ -200,13 +197,13 @@ intervals_equal (INTERVAL i0, INTERVAL 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);
        }
 
@@ -224,7 +221,7 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
 
       i1_cdr = XCDR (i1_cdr);
       if (!CONSP (i1_cdr))
-       return 0;               /* abort (); */
+       return 0;
       i1_cdr = XCDR (i1_cdr);
     }
 
@@ -343,7 +340,7 @@ root_interval (INTERVAL interval)
      c           c
 */
 
-static inline INTERVAL
+static INTERVAL
 rotate_right (INTERVAL interval)
 {
   INTERVAL i;
@@ -372,11 +369,11 @@ rotate_right (INTERVAL 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);
-  eassert (0 <= TOTAL_LENGTH (interval));
+  eassert (TOTAL_LENGTH (interval) >= 0);
 
   /* B must have the same total length of A.  */
   B->total_length = old_total;
-  eassert (0 <= TOTAL_LENGTH (B));
+  eassert (TOTAL_LENGTH (B) >= 0);
 
   return B;
 }
@@ -390,7 +387,7 @@ rotate_right (INTERVAL interval)
     c               c
 */
 
-static inline INTERVAL
+static INTERVAL
 rotate_left (INTERVAL interval)
 {
   INTERVAL i;
@@ -419,11 +416,11 @@ rotate_left (INTERVAL 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);
-  eassert (0 <= TOTAL_LENGTH (interval));
+  eassert (TOTAL_LENGTH (interval) >= 0);
 
   /* B must have the same total length of A.  */
   B->total_length = old_total;
-  eassert (0 <= TOTAL_LENGTH (B));
+  eassert (TOTAL_LENGTH (B) >= 0);
 
   return B;
 }
@@ -468,11 +465,11 @@ balance_an_interval (INTERVAL i)
 /* Balance INTERVAL, potentially stuffing it back into its parent
    Lisp Object.  */
 
-static inline INTERVAL
-balance_possible_root_interval (register INTERVAL interval)
+static 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;
@@ -557,7 +554,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
     {
       set_interval_right (interval, new);
       new->total_length = new_length;
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
     }
   else
     {
@@ -566,7 +563,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
       set_interval_parent (interval->right, new);
       set_interval_right (interval, new);
       new->total_length = new_length + new->right->total_length;
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
       balance_an_interval (new);
     }
 
@@ -602,7 +599,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
     {
       set_interval_left (interval, new);
       new->total_length = new_length;
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
     }
   else
     {
@@ -611,7 +608,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
       set_interval_parent (new->left, new);
       set_interval_left (interval, new);
       new->total_length = new_length + new->left->total_length;
-      eassert (0 <= TOTAL_LENGTH (new));
+      eassert (TOTAL_LENGTH (new) >= 0);
       balance_an_interval (new);
     }
 
@@ -675,8 +672,7 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
 
   eassert (relative_position <= TOTAL_LENGTH (tree));
 
-  if (!handling_signal)
-    tree = balance_possible_root_interval (tree);
+  tree = balance_possible_root_interval (tree);
 
   while (1)
     {
@@ -845,9 +841,9 @@ static INTERVAL
 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;
   ptrdiff_t offset;
 
@@ -962,7 +958,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
       for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
        {
          temp->total_length += length;
-         eassert (0 <= TOTAL_LENGTH (temp));
+         eassert (TOTAL_LENGTH (temp) >= 0);
          temp = balance_possible_root_interval (temp);
        }
 
@@ -1018,7 +1014,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
       for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
        {
          temp->total_length += length;
-         eassert (0 <= TOTAL_LENGTH (temp));
+         eassert (TOTAL_LENGTH (temp) >= 0);
          temp = balance_possible_root_interval (temp);
        }
     }
@@ -1068,11 +1064,10 @@ FR     8  9  A  B
 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;
@@ -1221,7 +1216,7 @@ delete_node (register INTERVAL i)
       this = this->left;
       this->total_length += migrate_amt;
     }
-  eassert (0 <= TOTAL_LENGTH (this));
+  eassert (TOTAL_LENGTH (this) >= 0);
   set_interval_left (this, migrate);
   set_interval_parent (migrate, this);
 
@@ -1255,7 +1250,7 @@ delete_interval (register INTERVAL i)
       else if (STRINGP (owner))
        set_string_intervals (owner, parent);
       else
-       abort ();
+       emacs_abort ();
 
       return;
     }
@@ -1303,7 +1298,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
                                                         relative_position,
                                                         amount);
       tree->total_length -= subtract;
-      eassert (0 <= TOTAL_LENGTH (tree));
+      eassert (TOTAL_LENGTH (tree) >= 0);
       return subtract;
     }
   /* Right branch.  */
@@ -1318,7 +1313,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
                                               relative_position,
                                               amount);
       tree->total_length -= subtract;
-      eassert (0 <= TOTAL_LENGTH (tree));
+      eassert (TOTAL_LENGTH (tree) >= 0);
       return subtract;
     }
   /* Here -- this node.  */
@@ -1333,7 +1328,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
        amount = my_amount;
 
       tree->total_length -= amount;
-      eassert (0 <= TOTAL_LENGTH (tree));
+      eassert (TOTAL_LENGTH (tree) >= 0);
       if (LENGTH (tree) == 0)
        delete_interval (tree);
 
@@ -1375,7 +1370,7 @@ adjust_intervals_for_deletion (struct buffer *buffer,
   if (ONLY_INTERVAL_P (tree))
     {
       tree->total_length -= length;
-      eassert (0 <= TOTAL_LENGTH (tree));
+      eassert (TOTAL_LENGTH (tree) >= 0);
       return;
     }
 
@@ -1409,10 +1404,7 @@ offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
     adjust_intervals_for_insertion (buffer_intervals (buffer),
                                    start, length);
   else
-    {
-      IF_LINT (if (length < - TYPE_MAXIMUM (ptrdiff_t)) abort ();)
-      adjust_intervals_for_deletion (buffer, start, -length);
-    }
+    adjust_intervals_for_deletion (buffer, start, -length);
 }
 \f
 /* Merge interval I with its lexicographic successor. The resulting
@@ -1438,19 +1430,19 @@ merge_interval_right (register INTERVAL i)
       while (! NULL_LEFT_CHILD (successor))
        {
          successor->total_length += absorb;
-         eassert (0 <= TOTAL_LENGTH (successor));
+         eassert (TOTAL_LENGTH (successor) >= 0);
          successor = successor->left;
        }
 
       successor->total_length += absorb;
-      eassert (0 <= TOTAL_LENGTH (successor));
+      eassert (TOTAL_LENGTH (successor) >= 0);
       delete_interval (i);
       return successor;
     }
 
   /* Zero out this interval.  */
   i->total_length -= absorb;
-  eassert (0 <= TOTAL_LENGTH (i));
+  eassert (TOTAL_LENGTH (i) >= 0);
 
   successor = i;
   while (! NULL_PARENT (successor))       /* It's above us.  Subtract as
@@ -1465,12 +1457,12 @@ merge_interval_right (register INTERVAL i)
 
       successor = INTERVAL_PARENT (successor);
       successor->total_length -= absorb;
-      eassert (0 <= TOTAL_LENGTH (successor));
+      eassert (TOTAL_LENGTH (successor) >= 0);
     }
 
   /* 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
@@ -1494,19 +1486,19 @@ merge_interval_left (register INTERVAL i)
       while (! NULL_RIGHT_CHILD (predecessor))
        {
          predecessor->total_length += absorb;
-         eassert (0 <= TOTAL_LENGTH (predecessor));
+         eassert (TOTAL_LENGTH (predecessor) >= 0);
          predecessor = predecessor->right;
        }
 
       predecessor->total_length += absorb;
-      eassert (0 <= TOTAL_LENGTH (predecessor));
+      eassert (TOTAL_LENGTH (predecessor) >= 0);
       delete_interval (i);
       return predecessor;
     }
 
   /* Zero out this interval.  */
   i->total_length -= absorb;
-  eassert (0 <= TOTAL_LENGTH (i));
+  eassert (TOTAL_LENGTH (i) >= 0);
 
   predecessor = i;
   while (! NULL_PARENT (predecessor))  /* It's above us.  Go up,
@@ -1521,12 +1513,12 @@ merge_interval_left (register INTERVAL i)
 
       predecessor = INTERVAL_PARENT (predecessor);
       predecessor->total_length -= absorb;
-      eassert (0 <= TOTAL_LENGTH (predecessor));
+      eassert (TOTAL_LENGTH (predecessor) >= 0);
     }
 
   /* This must be the leftmost or first interval and cannot
      be merged left.  The caller should have known.  */
-  abort ();
+  emacs_abort ();
 }
 \f
 /* Create a copy of SOURCE but with the default value of UP.  */
@@ -1610,7 +1602,7 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
 void
 graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
                             ptrdiff_t length, struct buffer *buffer,
-                            int inherit)
+                            bool inherit)
 {
   INTERVAL tree = buffer_intervals (buffer);
   INTERVAL under, over, this;
@@ -1628,7 +1620,8 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
          XSETBUFFER (buf, buffer);
          set_text_properties_1 (make_number (position),
                                 make_number (position + length),
-                                Qnil, buf, 0);
+                                Qnil, buf,
+                                find_interval (tree, position));
        }
       /* Shouldn't be necessary.  --Stef  */
       buffer_balance_intervals (buffer);
@@ -1753,9 +1746,9 @@ textget (Lisp_Object plist, register Lisp_Object prop)
 }
 
 Lisp_Object
-lookup_char_property (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)))
     {
@@ -1796,8 +1789,7 @@ temp_set_point_both (struct buffer *buffer,
                     ptrdiff_t charpos, ptrdiff_t bytepos)
 {
   /* In a single-byte buffer, the two positions must be equal.  */
-  if (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer))
-    eassert (charpos == bytepos);
+  eassert (BUF_ZV (buffer) != BUF_ZV_BYTE (buffer) || charpos == bytepos);
 
   eassert (charpos <= bytepos);
   eassert (charpos <= BUF_ZV (buffer) || BUF_BEGV (buffer) <= charpos);
@@ -1823,11 +1815,23 @@ set_point (ptrdiff_t charpos)
   set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos));
 }
 
+/* Set PT from MARKER's clipped position.  */
+
+void
+set_point_from_marker (Lisp_Object marker)
+{
+  if (XMARKER (marker)->buffer != current_buffer)
+    signal_error ("Marker points into wrong buffer", marker);
+  set_point_both
+    (clip_to_bounds (BEGV, marker_position (marker), ZV),
+     clip_to_bounds (BEGV_BYTE, marker_byte_position (marker), ZV_BYTE));
+}
+
 /* 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 invisibility.
+   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.
 
@@ -1836,7 +1840,7 @@ set_point (ptrdiff_t charpos)
 
 static ptrdiff_t
 adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj,
-                        int test_intang)
+                        bool test_intang)
 {
   Lisp_Object invis_propval, invis_overlay;
   Lisp_Object test_pos;
@@ -1883,11 +1887,11 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
      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;
+  bool backwards = charpos < old_position;
+  bool have_overlays;
   ptrdiff_t original_position;
 
-  BSET (current_buffer, point_before_scroll, Qnil);
+  bset_point_before_scroll (current_buffer, Qnil);
 
   if (charpos == PT)
     return;
@@ -2154,12 +2158,12 @@ move_if_not_intangible (ptrdiff_t 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
+bool
 get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
                        ptrdiff_t *start, ptrdiff_t *end, Lisp_Object object)
 {
@@ -2172,7 +2176,7 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
   else if (STRINGP (object))
     i = find_interval (string_intervals (object), pos);
   else
-    abort ();
+    emacs_abort ();
 
   if (!i || (i->position + LENGTH (i) <= pos))
     return 0;
@@ -2198,20 +2202,15 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
 /* Return the proper local keymap TYPE for position POSITION in
    BUFFER; TYPE should be one of `keymap' or `local-map'.  Use the map
    specified by the PROP property, if any.  Otherwise, if TYPE is
-   `local-map' use BUFFER's local map.
-
-   POSITION must be in the accessible part of BUFFER.  */
+   `local-map' use BUFFER's local map.  */
 
 Lisp_Object
-get_local_map (register ptrdiff_t position, register struct buffer *buffer,
-              Lisp_Object type)
+get_local_map (ptrdiff_t position, struct buffer *buffer, Lisp_Object type)
 {
   Lisp_Object prop, lispy_position, lispy_buffer;
   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 ();
+  position = clip_to_bounds (BUF_BEGV (buffer), position, BUF_ZV (buffer));
 
   /* Ignore narrowing, so that a local map continues to be valid even if
      the visible region contains no characters and hence no properties.  */
@@ -2233,7 +2232,7 @@ get_local_map (register ptrdiff_t position, register struct buffer *buffer,
      editing a field with a `local-map' property, we want insertion at the end
      to obey the `local-map' property.  */
   if (NILP (prop))
-    prop = get_pos_property (lispy_position, type, lispy_buffer);
+    prop = Fget_pos_property (lispy_position, type, lispy_buffer);
 
   SET_BUF_BEGV_BOTH (buffer, old_begv, old_begv_byte);
   SET_BUF_ZV_BOTH (buffer, old_zv, old_zv_byte);
@@ -2274,7 +2273,7 @@ copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
   new->position = 0;
   got = (LENGTH (i) - (start - i->position));
   new->total_length = length;
-  eassert (0 <= TOTAL_LENGTH (new));
+  eassert (TOTAL_LENGTH (new) >= 0);
   copy_properties (i, new);
 
   t = new;
@@ -2306,10 +2305,10 @@ copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
   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
+bool
 compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
 {
   INTERVAL i1, i2;
@@ -2348,7 +2347,7 @@ compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
    START_BYTE ... END_BYTE in bytes.  */
 
 static void
-set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
+set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
                           ptrdiff_t start, ptrdiff_t start_byte,
                           ptrdiff_t end, ptrdiff_t end_byte)
 {
@@ -2357,7 +2356,7 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
     i->total_length = end - start;
   else
     i->total_length = end_byte - start_byte;
-  eassert (0 <= TOTAL_LENGTH (i));
+  eassert (TOTAL_LENGTH (i) >= 0);
 
   if (TOTAL_LENGTH (i) == 0)
     {
@@ -2456,11 +2455,11 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
 }
 
 /* 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 (int multi_flag)
+set_intervals_multibyte (bool multi_flag)
 {
   INTERVAL i = buffer_intervals (current_buffer);