changeset 4005:da8962f65741

* intervals.c (find_interval): Doc fixes, computation of tree->position rearranged for clarity. * intervals.c (find_interval): Consistently treat POSITION as an actual buffer position, i.e. origin 1. The old code seemed undecided on this point. Treat the end of the buffer as being part of the rightmost interval. (adjust_intervals_for_insertion): Consistently treat POSITION as origin 1. (interval_deletion_adjustment): The exception: FROM should be origin zero here. Consistently treat it as such. Simplify code which shrinks and possibly deletes intervals. (adjust_intervals_for_deletion): Treat start as origin 1; our caller does. (set_point): Use buffer positions throughout, not a mix of buffer posns and origin zero posns. (get_local_map): Remove special case for POSITION at end of buffer; find_interval handles that case correctly. (verify_interval_modification): Remove special case for START at end of buffer. * textprop.c (validate_interval_range): End-of-buffer/string positions no longer need special handling. * intervals.c (make_new_interval): #if 0 this out. Nobody calls it.
author Jim Blandy <jimb@redhat.com>
date Tue, 06 Jul 1993 14:53:54 +0000
parents 71541ea16adf
children 98eb9ca25031
files src/intervals.c
diffstat 1 files changed, 59 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/intervals.c	Tue Jul 06 14:43:32 1993 +0000
+++ b/src/intervals.c	Tue Jul 06 14:53:54 1993 +0000
@@ -432,8 +432,9 @@
 }
 
 /* Find the interval containing text position POSITION in the text
-   represented by the interval tree TREE.  POSITION is relative to
-   the beginning of that text.
+   represented by the interval tree TREE.  POSITION is a buffer
+   position; the earliest position is 1.  If POSITION is at the end of
+   the buffer, return the interval containing the last character.
 
    The `position' field, which is a cache of an interval's position,
    is updated in the interval found.  Other functions (e.g., next_interval)
@@ -444,25 +445,25 @@
      register INTERVAL tree;
      register int position;
 {
-  register int relative_position = position;
+  /* The distance from the left edge of the subtree at TREE
+                    to POSITION.  */
+  register int relative_position = position - BEG;
 
   if (NULL_INTERVAL_P (tree))
     return NULL_INTERVAL;
 
-  if (position > TOTAL_LENGTH (tree))
+  if (relative_position > TOTAL_LENGTH (tree))
     abort ();			/* Paranoia */
-#if 0
-    position = TOTAL_LENGTH (tree);
-#endif
 
   while (1)
     {
-      if (relative_position <= LEFT_TOTAL_LENGTH (tree))
+      if (relative_position < LEFT_TOTAL_LENGTH (tree))
 	{
 	  tree = tree->left;
 	}
-      else if (relative_position > (TOTAL_LENGTH (tree)
-				    - RIGHT_TOTAL_LENGTH (tree)))
+      else if (! NULL_RIGHT_CHILD (tree)
+	       && relative_position >= (TOTAL_LENGTH (tree)
+					- RIGHT_TOTAL_LENGTH (tree)))
 	{
 	  relative_position -= (TOTAL_LENGTH (tree)
 				- RIGHT_TOTAL_LENGTH (tree));
@@ -470,8 +471,10 @@
 	}
       else
 	{
-	  tree->position = LEFT_TOTAL_LENGTH (tree)
-	                   + position - relative_position + 1;
+	  tree->position =
+	    (position - relative_position /* the left edge of *tree */
+	     + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */
+
 	  return tree;
 	}
     }
@@ -639,16 +642,16 @@
   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);
+  /* If inserting at point-max of a buffer, that position will be out
+     of range.  Remember that buffer positions are 1-based.  */
+  if (position > BEG + TOTAL_LENGTH (tree))
+    position = BEG + TOTAL_LENGTH (tree);
 
   i = find_interval (tree, position);
   /* If we are positioned between intervals, check the stickiness of
      both of them. */
   if (position == i->position
-      && position != 1)
+      && position != BEG)
     {
       register INTERVAL prev = previous_interval (i);
 
@@ -747,11 +750,14 @@
     }
 }
 
-/* Find the interval in TREE corresponding to the character position FROM
-   and delete as much as possible of AMOUNT from that interval, starting
-   after the relative position of FROM within it.  Return the amount
-   actually deleted, and if the interval was zeroed-out, delete that
-   interval node from the tree.
+/* Find the interval in TREE corresponding to the relative position
+   FROM and delete as much as possible of AMOUNT from that interval.
+   Return the amount actually deleted, and if the interval was
+   zeroed-out, delete that interval node from the tree.
+
+   Note that FROM is actually origin zero, aka relative to the
+   leftmost edge of tree.  This is appropriate since we call ourselves
+   recursively on subtrees.
 
    Do this by recursing down TREE to the interval in question, and
    deleting the appropriate amount of text. */
@@ -767,7 +773,7 @@
     return 0;
 
   /* Left branch */
-  if (relative_position <= LEFT_TOTAL_LENGTH (tree))
+  if (relative_position < LEFT_TOTAL_LENGTH (tree))
     {
       int subtract = interval_deletion_adjustment (tree->left,
 						   relative_position,
@@ -776,8 +782,8 @@
       return subtract;
     }
   /* Right branch */
-  else if (relative_position > (TOTAL_LENGTH (tree)
-				- RIGHT_TOTAL_LENGTH (tree)))
+  else if (relative_position >= (TOTAL_LENGTH (tree)
+				 - RIGHT_TOTAL_LENGTH (tree)))
     {
       int subtract;
 
@@ -792,55 +798,28 @@
   /* Here -- this node */
   else
     {
-      /* If this is a zero-length, marker interval, then
-	 we must skip it. */
-
-      if (relative_position == LEFT_TOTAL_LENGTH (tree) + 1)
-	{
-	  /* This means we're deleting from the beginning of this interval. */
-	  register int my_amount = LENGTH (tree);
-
-	  if (amount < my_amount)
-	    {
-	      tree->total_length -= amount;
-	      return amount;
-	    }
-	  else
-	    {
-	      tree->total_length -= my_amount;
-	      if (LENGTH (tree) != 0)
-		abort ();	/* Paranoia */
+      /* How much can we delete from this interval?  */
+      int my_amount = ((tree->total_length 
+			- RIGHT_TOTAL_LENGTH (tree))
+		       - relative_position);
 
-	      delete_interval (tree);
-	      return my_amount;
-	    }
-	}
-      else			/* Deleting starting in the middle. */
-	{
-	  register int my_amount = ((tree->total_length
-				     - RIGHT_TOTAL_LENGTH (tree))
-				    - relative_position + 1);
+      if (amount > my_amount)
+	amount = my_amount;
 
-	  if (amount <= my_amount)
-	    {
-	      tree->total_length -= amount;
-	      return amount;
-	    }
-	  else
-	    {
-	      tree->total_length -= my_amount;
-	      return my_amount;
-	    }
-	}
+      tree->total_length -= amount;
+      if (LENGTH (tree) == 0)
+	delete_interval (tree);
+      
+      return amount;
     }
 
   /* Never reach here */
 }
 
-/* Effect the adjustments necessary to the interval tree of BUFFER
-   to correspond to the deletion of LENGTH characters from that buffer
-   text.  The deletion is effected at position START (relative to the
-   buffer). */
+/* Effect the adjustments necessary to the interval tree of BUFFER to
+   correspond to the deletion of LENGTH characters from that buffer
+   text.  The deletion is effected at position START (which is a
+   buffer position, i.e. origin 1). */
 
 static void
 adjust_intervals_for_deletion (buffer, start, length)
@@ -854,6 +833,10 @@
   if (NULL_INTERVAL_P (tree))
     return;
 
+  if (start > BEG + TOTAL_LENGTH (tree)
+      || start + length > BEG + TOTAL_LENGTH (tree))
+    abort ();
+
   if (length == TOTAL_LENGTH (tree))
     {
       buffer->intervals = NULL_INTERVAL;
@@ -866,11 +849,11 @@
       return;
     }
 
-  if (start > TOTAL_LENGTH (tree))
-    start = TOTAL_LENGTH (tree);
+  if (start > BEG + TOTAL_LENGTH (tree))
+    start = BEG + TOTAL_LENGTH (tree);
   while (left_to_delete > 0)
     {
-      left_to_delete -= interval_deletion_adjustment (tree, start,
+      left_to_delete -= interval_deletion_adjustment (tree, start - 1,
 						      left_to_delete);
       tree = buffer->intervals;
       if (left_to_delete == tree->total_length)
@@ -1030,6 +1013,9 @@
   return t;
 }
 
+#if 0
+/* Nobody calls this.  Perhaps it's a vestige of an earlier design.  */
+
 /* Make a new interval of length LENGTH starting at START in the
    group of intervals INTERVALS, which is actually an interval tree.
    Returns the new interval.
@@ -1070,6 +1056,7 @@
   split_interval_right (slot, length + 1);
   return slot;
 }
+#endif
 
 /* Insert the intervals of SOURCE into BUFFER at POSITION.
 
@@ -1244,7 +1231,6 @@
      register struct buffer *buffer;
 {
   register INTERVAL to, from, toprev, fromprev, target;
-  register int iposition = position;
   int buffer_point;
   register Lisp_Object obj;
   int backwards = (position < BUF_PT (buffer)) ? 1 : 0;
@@ -1265,20 +1251,14 @@
       return;
     }
 
-  /* Position Z is really one past the last char in the buffer.  */
-  if (position == BUF_ZV (buffer))
-    iposition = position - 1;
-
   /* Set TO to the interval containing the char after POSITION,
      and TOPREV to the interval containing the char before POSITION.
      Either one may be null.  They may be equal.  */
-  to = find_interval (buffer->intervals, iposition);
+  to = find_interval (buffer->intervals, position);
   if (position == BUF_BEGV (buffer))
     toprev = 0;
   else if (to->position == position)
     toprev = previous_interval (to);
-  else if (iposition != position)
-    toprev = to, to = 0;
   else
     toprev = to;
 
@@ -1390,10 +1370,6 @@
   if (position > BUF_Z (buffer) || position < BUF_BEG (buffer))
     abort ();
 
-  /* Position Z is really one past the last char in the buffer.  */
-  if (position == BUF_ZV (buffer))
-    return current_buffer->keymap;
-
   interval = find_interval (buffer->intervals, position);
   prop = textget (interval->plist, Qlocal_map);
   if (NILP (prop))
@@ -1465,8 +1441,7 @@
       /* Set I to the interval containing the char after START,
 	 and PREV to the interval containing the char before START.
 	 Either one may be null.  They may be equal.  */
-      i = find_interval (intervals,
-			 (start == BUF_ZV (buf) ? start - 1 : start));
+      i = find_interval (intervals, start);
 
       if (start == BUF_BEGV (buf))
 	prev = 0;