diff src/intervals.c @ 52577:0f4f05ddd3df

(graft_intervals_into_buffer): Correct the main loop in the case where OVER is longer than UNDER.
author Richard M. Stallman <rms@gnu.org>
date Mon, 22 Sep 2003 15:51:19 +0000
parents 695cf19ef79e
children 32ebe48159a6
line wrap: on
line diff
--- a/src/intervals.c	Mon Sep 22 15:50:15 2003 +0000
+++ b/src/intervals.c	Mon Sep 22 15:51:19 2003 +0000
@@ -1712,6 +1712,7 @@
 {
   register INTERVAL under, over, this, prev;
   register INTERVAL tree;
+  int over_used;
 
   tree = BUF_INTERVALS (buffer);
 
@@ -1814,8 +1815,14 @@
      adjust_intervals_for_insertion, so stickiness has
      already been taken care of.  */
 
+  /* OVER is the interval we are copying from next.
+     OVER_USED says how many characters' worth of OVER
+     have already been copied into target intervals.
+     UNDER is the next interval in the target.  */
+  over_used = 0;
   while (! NULL_INTERVAL_P (over))
     {
+      /* If UNDER is longer than OVER, split it.  */
       if (LENGTH (over) < LENGTH (under))
 	{
 	  this = split_interval_left (under, LENGTH (over));
@@ -1823,12 +1830,27 @@
 	}
       else
 	this = under;
-      copy_properties (over, this);
+
+      /* THIS is now the interval to copy or merge into.
+	 OVER covers all of it.  */
       if (inherit)
 	merge_properties (over, this);
       else
 	copy_properties (over, this);
-      over = next_interval (over);
+
+      /* If THIS and OVER end at the same place,
+	 advance OVER to a new source interval.  */
+      if (LENGTH (this) == LENGTH (over) - over_used)
+	{
+	  over = next_interval (over);
+	  over_used = 0;
+	}
+      else
+	/* Otherwise just record that more of OVER has been used.  */
+	over_used += LENGTH (this);
+
+      /* Always advance to a new target interval.  */
+      under = next_interval (this);
     }
 
   if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))