]> code.delx.au - gnu-emacs/blobdiff - src/intervals.c
Fix bug #12242 with crashes in ralloc.c on OpenBSD.
[gnu-emacs] / src / intervals.c
index 351677ad27e33b98c44469302933916ab36b093e..88f47f58b5233cd8186addbba75c90fdc0ad84db 100644 (file)
@@ -1,5 +1,5 @@
 /* Code for doing intervals.
-   Copyright (C) 1993-1995, 1997-1998, 2001-2011  Free Software Foundation, Inc.
+   Copyright (C) 1993-1995, 1997-1998, 2001-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -39,6 +39,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <setjmp.h>
+#include <intprops.h>
 #include "lisp.h"
 #include "intervals.h"
 #include "buffer.h"
@@ -51,7 +52,8 @@ 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 (Lisp_Object pleft, Lisp_Object pright);
+static Lisp_Object merge_properties_sticky (Lisp_Object, Lisp_Object);
+static INTERVAL merge_interval_right (INTERVAL);
 static INTERVAL reproduce_tree (INTERVAL, INTERVAL);
 static INTERVAL reproduce_tree_obj (INTERVAL, Lisp_Object);
 \f
@@ -245,8 +247,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)
     {
@@ -256,8 +257,7 @@ 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;
@@ -267,8 +267,7 @@ search_for_interval (i, tree)
 }
 
 static void
-inc_interval_count (i)
-     INTERVAL i;
+inc_interval_count (INTERVAL i)
 {
   icount++;
   if (LENGTH (i) == 0)
@@ -278,8 +277,7 @@ inc_interval_count (i)
 }
 
 int
-count_intervals (i)
-     register INTERVAL i;
+count_intervals (INTERVAL i)
 {
   icount = 0;
   idepth = 0;
@@ -290,8 +288,7 @@ count_intervals (i)
 }
 
 static INTERVAL
-root_interval (interval)
-     INTERVAL interval;
+root_interval (INTERVAL interval)
 {
   register INTERVAL i = interval;
 
@@ -311,7 +308,7 @@ root_interval (interval)
      c           c
 */
 
-static INLINE INTERVAL
+static inline INTERVAL
 rotate_right (INTERVAL interval)
 {
   INTERVAL i;
@@ -358,7 +355,7 @@ rotate_right (INTERVAL interval)
     c               c
 */
 
-static INLINE INTERVAL
+static inline INTERVAL
 rotate_left (INTERVAL interval)
 {
   INTERVAL i;
@@ -436,7 +433,7 @@ balance_an_interval (INTERVAL i)
 /* Balance INTERVAL, potentially stuffing it back into its parent
    Lisp Object.  */
 
-static INLINE INTERVAL
+static inline INTERVAL
 balance_possible_root_interval (register INTERVAL interval)
 {
   Lisp_Object parent;
@@ -777,7 +774,7 @@ update_interval (register INTERVAL i, EMACS_INT pos)
              i = i->right;             /* Move to the right child */
            }
          else if (NULL_PARENT (i))
-           error ("Point %d after end of properties", pos);
+           error ("Point %"pI"d after end of properties", pos);
          else
             i = INTERVAL_PARENT (i);
          continue;
@@ -802,11 +799,10 @@ update_interval (register INTERVAL i, EMACS_INT pos)
    to the root.  */
 
 static INTERVAL
-adjust_intervals_for_insertion (tree, position, length)
-     INTERVAL tree;
-     int position, length;
+adjust_intervals_for_insertion (INTERVAL tree, EMACS_INT position,
+                               EMACS_INT length)
 {
-  register int relative_position;
+  register EMACS_INT relative_position;
   register INTERVAL this;
 
   if (TOTAL_LENGTH (tree) == 0)        /* Paranoia */
@@ -1089,7 +1085,7 @@ FR     8  9  A  B
        left rear-nonsticky = t,   right front-sticky = nil (inherit none)
 */
 
-Lisp_Object
+static Lisp_Object
 merge_properties_sticky (Lisp_Object pleft, Lisp_Object pright)
 {
   register Lisp_Object props, front, rear;
@@ -1258,7 +1254,7 @@ delete_node (register INTERVAL i)
    I is presumed to be empty; that is, no adjustments are made
    for the length of I.  */
 
-void
+static void
 delete_interval (register INTERVAL i)
 {
   register INTERVAL parent;
@@ -1321,17 +1317,17 @@ interval_deletion_adjustment (register INTERVAL tree, register EMACS_INT from,
   if (NULL_INTERVAL_P (tree))
     return 0;
 
-  /* Left branch */
+  /* Left branch */
   if (relative_position < LEFT_TOTAL_LENGTH (tree))
     {
       EMACS_INT subtract = interval_deletion_adjustment (tree->left,
-                                                         relative_position,
-                                                         amount);
+                                                        relative_position,
+                                                        amount);
       tree->total_length -= subtract;
       CHECK_TOTAL_LENGTH (tree);
       return subtract;
     }
-  /* Right branch */
+  /* Right branch */
   else if (relative_position >= (TOTAL_LENGTH (tree)
                                 - RIGHT_TOTAL_LENGTH (tree)))
     {
@@ -1423,9 +1419,13 @@ adjust_intervals_for_deletion (struct buffer *buffer,
 /* Make the adjustments necessary to the interval tree of BUFFER to
    represent an addition or deletion of LENGTH characters starting
    at position START.  Addition or deletion is indicated by the sign
-   of LENGTH.  */
+   of LENGTH.
 
-INLINE void
+   The two inline functions (one static) pacify Sun C 5.8, a pre-C99
+   compiler that does not allow calling a static function (here,
+   adjust_intervals_for_deletion) from a non-static inline function.  */
+
+void
 offset_intervals (struct buffer *buffer, EMACS_INT start, EMACS_INT length)
 {
   if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) || length == 0)
@@ -1434,7 +1434,10 @@ offset_intervals (struct buffer *buffer, EMACS_INT start, EMACS_INT length)
   if (length > 0)
     adjust_intervals_for_insertion (BUF_INTERVALS (buffer), start, length);
   else
-    adjust_intervals_for_deletion (buffer, start, -length);
+    {
+      IF_LINT (if (length < - TYPE_MAXIMUM (EMACS_INT)) abort ();)
+      adjust_intervals_for_deletion (buffer, start, -length);
+    }
 }
 \f
 /* Merge interval I with its lexicographic successor. The resulting
@@ -1446,7 +1449,7 @@ offset_intervals (struct buffer *buffer, EMACS_INT start, EMACS_INT length)
    The caller must verify that this is not the last (rightmost)
    interval.  */
 
-INTERVAL
+static INTERVAL
 merge_interval_right (register INTERVAL i)
 {
   register EMACS_INT absorb = LENGTH (i);
@@ -1599,9 +1602,7 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
    interval.  */
 
 static INTERVAL
-make_new_interval (intervals, start, length)
-     INTERVAL intervals;
-     EMACS_INT start, length;
+make_new_interval (INTERVAL intervals, EMACS_INT start, EMACS_INT length)
 {
   INTERVAL slot;
 
@@ -1677,7 +1678,7 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
                             EMACS_INT length, struct buffer *buffer,
                             int inherit)
 {
-  register INTERVAL under, over, this, prev;
+  register INTERVAL under, over, this;
   register INTERVAL tree;
   EMACS_INT over_used;
 
@@ -1698,56 +1699,37 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
                                 Qnil, buf, 0);
        }
       if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
-       /* Shouldn't be necessary.  -stef  */
+       /* Shouldn't be necessary.  --Stef  */
        BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
       return;
     }
 
-  if (NULL_INTERVAL_P (tree))
-    {
-      /* The inserted text constitutes the whole buffer, so
+  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?  */
-
+      BUF_INTERVALS (buffer)->position = BUF_BEG (buffer);
+      eassert (BUF_INTERVALS (buffer)->up_obj == 1);
          return;
        }
-
-      /* Create an interval tree in which to place a copy
+  else if (NULL_INTERVAL_P (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 ();
 
   this = under = find_interval (tree, position);
-  if (NULL_INTERVAL_P (under)) /* Paranoia */
+  if (NULL_INTERVAL_P (under)) /* Paranoia */
     abort ();
   over = find_interval (source, interval_start_pos (source));
 
@@ -1767,7 +1749,8 @@ graft_intervals_into_buffer (INTERVAL source, EMACS_INT position,
       /* 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.  */
@@ -1877,7 +1860,7 @@ lookup_char_property (Lisp_Object plist, register Lisp_Object prop, int textprop
 /* 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)
 {
@@ -1897,7 +1880,7 @@ temp_set_point_both (struct buffer *buffer,
 
 /* Set point "temporarily", without checking any text properties.  */
 
-INLINE void
+void
 temp_set_point (struct buffer *buffer, EMACS_INT charpos)
 {
   temp_set_point_both (buffer, charpos,
@@ -1917,7 +1900,7 @@ set_point (EMACS_INT charpos)
    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.
+   then intangibility is required as well as invisibility.
 
    TEST_OFFS should be either 0 or -1, and ADJ should be either 1 or -1.
 
@@ -2386,7 +2369,7 @@ copy_intervals (INTERVAL tree, EMACS_INT start, EMACS_INT length)
 
 /* Give STRING the properties of BUFFER from POSITION to LENGTH.  */
 
-INLINE void
+void
 copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
                          EMACS_INT position, EMACS_INT length)
 {