aboutsummaryrefslogtreecommitdiffstats
path: root/src/intervals.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/intervals.c')
-rw-r--r--src/intervals.c522
1 files changed, 206 insertions, 316 deletions
diff --git a/src/intervals.c b/src/intervals.c
index 2c652cd9ad9..09949bbbd45 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -38,6 +38,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
38 38
39 39
40#include <config.h> 40#include <config.h>
41
42#define INTERVALS_INLINE EXTERN_INLINE
43
41#include <setjmp.h> 44#include <setjmp.h>
42#include <intprops.h> 45#include <intprops.h>
43#include "lisp.h" 46#include "lisp.h"
@@ -76,19 +79,19 @@ create_root_interval (Lisp_Object parent)
76 { 79 {
77 new->total_length = (BUF_Z (XBUFFER (parent)) 80 new->total_length = (BUF_Z (XBUFFER (parent))
78 - BUF_BEG (XBUFFER (parent))); 81 - BUF_BEG (XBUFFER (parent)));
79 CHECK_TOTAL_LENGTH (new); 82 eassert (0 <= TOTAL_LENGTH (new));
80 BUF_INTERVALS (XBUFFER (parent)) = new; 83 buffer_set_intervals (XBUFFER (parent), new);
81 new->position = BEG; 84 new->position = BEG;
82 } 85 }
83 else if (STRINGP (parent)) 86 else if (STRINGP (parent))
84 { 87 {
85 new->total_length = SCHARS (parent); 88 new->total_length = SCHARS (parent);
86 CHECK_TOTAL_LENGTH (new); 89 eassert (0 <= TOTAL_LENGTH (new));
87 STRING_SET_INTERVALS (parent, new); 90 string_set_intervals (parent, new);
88 new->position = 0; 91 new->position = 0;
89 } 92 }
90 93
91 SET_INTERVAL_OBJECT (new, parent); 94 interval_set_object (new, parent);
92 95
93 return new; 96 return new;
94} 97}
@@ -102,7 +105,7 @@ copy_properties (register INTERVAL source, register INTERVAL target)
102 return; 105 return;
103 106
104 COPY_INTERVAL_CACHE (source, target); 107 COPY_INTERVAL_CACHE (source, target);
105 target->plist = Fcopy_sequence (source->plist); 108 interval_set_plist (target, Fcopy_sequence (source->plist));
106} 109}
107 110
108/* Merge the properties of interval SOURCE into the properties 111/* Merge the properties of interval SOURCE into the properties
@@ -138,7 +141,7 @@ merge_properties (register INTERVAL source, register INTERVAL target)
138 if (NILP (val)) 141 if (NILP (val))
139 { 142 {
140 val = XCAR (o); 143 val = XCAR (o);
141 target->plist = Fcons (sym, Fcons (val, target->plist)); 144 interval_set_plist (target, Fcons (sym, Fcons (val, target->plist)));
142 } 145 }
143 o = XCDR (o); 146 o = XCDR (o);
144 } 147 }
@@ -207,10 +210,10 @@ void
207traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg) 210traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg)
208{ 211{
209 /* Minimize stack usage. */ 212 /* Minimize stack usage. */
210 while (!NULL_INTERVAL_P (tree)) 213 while (tree)
211 { 214 {
212 (*function) (tree, arg); 215 (*function) (tree, arg);
213 if (NULL_INTERVAL_P (tree->right)) 216 if (!tree->right)
214 tree = tree->left; 217 tree = tree->left;
215 else 218 else
216 { 219 {
@@ -227,7 +230,7 @@ void
227traverse_intervals (INTERVAL tree, ptrdiff_t position, 230traverse_intervals (INTERVAL tree, ptrdiff_t position,
228 void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg) 231 void (*function) (INTERVAL, Lisp_Object), Lisp_Object arg)
229{ 232{
230 while (!NULL_INTERVAL_P (tree)) 233 while (tree)
231 { 234 {
232 traverse_intervals (tree->left, position, function, arg); 235 traverse_intervals (tree->left, position, function, arg);
233 position += LEFT_TOTAL_LENGTH (tree); 236 position += LEFT_TOTAL_LENGTH (tree);
@@ -262,7 +265,7 @@ search_for_interval (INTERVAL i, INTERVAL tree)
262{ 265{
263 icount = 0; 266 icount = 0;
264 search_interval = i; 267 search_interval = i;
265 found_interval = NULL_INTERVAL; 268 found_interval = NULL;
266 traverse_intervals_noorder (tree, &check_for_interval, Qnil); 269 traverse_intervals_noorder (tree, &check_for_interval, Qnil);
267 return found_interval; 270 return found_interval;
268} 271}
@@ -320,29 +323,29 @@ rotate_right (INTERVAL interval)
320 if (! ROOT_INTERVAL_P (interval)) 323 if (! ROOT_INTERVAL_P (interval))
321 { 324 {
322 if (AM_LEFT_CHILD (interval)) 325 if (AM_LEFT_CHILD (interval))
323 INTERVAL_PARENT (interval)->left = B; 326 interval_set_left (INTERVAL_PARENT (interval), B);
324 else 327 else
325 INTERVAL_PARENT (interval)->right = B; 328 interval_set_right (INTERVAL_PARENT (interval), B);
326 } 329 }
327 COPY_INTERVAL_PARENT (B, interval); 330 interval_copy_parent (B, interval);
328 331
329 /* Make B the parent of A */ 332 /* Make B the parent of A */
330 i = B->right; 333 i = B->right;
331 B->right = interval; 334 interval_set_right (B, interval);
332 SET_INTERVAL_PARENT (interval, B); 335 interval_set_parent (interval, B);
333 336
334 /* Make A point to c */ 337 /* Make A point to c */
335 interval->left = i; 338 interval_set_left (interval, i);
336 if (! NULL_INTERVAL_P (i)) 339 if (i)
337 SET_INTERVAL_PARENT (i, interval); 340 interval_set_parent (i, interval);
338 341
339 /* A's total length is decreased by the length of B and its left child. */ 342 /* A's total length is decreased by the length of B and its left child. */
340 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval); 343 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
341 CHECK_TOTAL_LENGTH (interval); 344 eassert (0 <= TOTAL_LENGTH (interval));
342 345
343 /* B must have the same total length of A. */ 346 /* B must have the same total length of A. */
344 B->total_length = old_total; 347 B->total_length = old_total;
345 CHECK_TOTAL_LENGTH (B); 348 eassert (0 <= TOTAL_LENGTH (B));
346 349
347 return B; 350 return B;
348} 351}
@@ -367,29 +370,29 @@ rotate_left (INTERVAL interval)
367 if (! ROOT_INTERVAL_P (interval)) 370 if (! ROOT_INTERVAL_P (interval))
368 { 371 {
369 if (AM_LEFT_CHILD (interval)) 372 if (AM_LEFT_CHILD (interval))
370 INTERVAL_PARENT (interval)->left = B; 373 interval_set_left (INTERVAL_PARENT (interval), B);
371 else 374 else
372 INTERVAL_PARENT (interval)->right = B; 375 interval_set_right (INTERVAL_PARENT (interval), B);
373 } 376 }
374 COPY_INTERVAL_PARENT (B, interval); 377 interval_copy_parent (B, interval);
375 378
376 /* Make B the parent of A */ 379 /* Make B the parent of A */
377 i = B->left; 380 i = B->left;
378 B->left = interval; 381 interval_set_left (B, interval);
379 SET_INTERVAL_PARENT (interval, B); 382 interval_set_parent (interval, B);
380 383
381 /* Make A point to c */ 384 /* Make A point to c */
382 interval->right = i; 385 interval_set_right (interval, i);
383 if (! NULL_INTERVAL_P (i)) 386 if (i)
384 SET_INTERVAL_PARENT (i, interval); 387 interval_set_parent (i, interval);
385 388
386 /* A's total length is decreased by the length of B and its right child. */ 389 /* A's total length is decreased by the length of B and its right child. */
387 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); 390 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
388 CHECK_TOTAL_LENGTH (interval); 391 eassert (0 <= TOTAL_LENGTH (interval));
389 392
390 /* B must have the same total length of A. */ 393 /* B must have the same total length of A. */
391 B->total_length = old_total; 394 B->total_length = old_total;
392 CHECK_TOTAL_LENGTH (B); 395 eassert (0 <= TOTAL_LENGTH (B));
393 396
394 return B; 397 return B;
395} 398}
@@ -453,9 +456,9 @@ balance_possible_root_interval (register INTERVAL interval)
453 if (have_parent) 456 if (have_parent)
454 { 457 {
455 if (BUFFERP (parent)) 458 if (BUFFERP (parent))
456 BUF_INTERVALS (XBUFFER (parent)) = interval; 459 buffer_set_intervals (XBUFFER (parent), interval);
457 else if (STRINGP (parent)) 460 else if (STRINGP (parent))
458 STRING_SET_INTERVALS (parent, interval); 461 string_set_intervals (parent, interval);
459 } 462 }
460 463
461 return interval; 464 return interval;
@@ -480,12 +483,22 @@ balance_intervals_internal (register INTERVAL tree)
480INTERVAL 483INTERVAL
481balance_intervals (INTERVAL tree) 484balance_intervals (INTERVAL tree)
482{ 485{
483 if (tree == NULL_INTERVAL) 486 return tree ? balance_intervals_internal (tree) : NULL;
484 return NULL_INTERVAL; 487}
488
489/* Rebalance text properties of B. */
490
491static void
492buffer_balance_intervals (struct buffer *b)
493{
494 INTERVAL i;
485 495
486 return balance_intervals_internal (tree); 496 eassert (b != NULL);
497 i = buffer_get_intervals (b);
498 if (i)
499 buffer_set_intervals (b, balance_an_interval (i));
487} 500}
488 501
489/* Split INTERVAL into two pieces, starting the second piece at 502/* Split INTERVAL into two pieces, starting the second piece at
490 character position OFFSET (counting from 0), relative to INTERVAL. 503 character position OFFSET (counting from 0), relative to INTERVAL.
491 INTERVAL becomes the left-hand piece, and the right-hand piece 504 INTERVAL becomes the left-hand piece, and the right-hand piece
@@ -507,22 +520,22 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
507 ptrdiff_t new_length = LENGTH (interval) - offset; 520 ptrdiff_t new_length = LENGTH (interval) - offset;
508 521
509 new->position = position + offset; 522 new->position = position + offset;
510 SET_INTERVAL_PARENT (new, interval); 523 interval_set_parent (new, interval);
511 524
512 if (NULL_RIGHT_CHILD (interval)) 525 if (NULL_RIGHT_CHILD (interval))
513 { 526 {
514 interval->right = new; 527 interval_set_right (interval, new);
515 new->total_length = new_length; 528 new->total_length = new_length;
516 CHECK_TOTAL_LENGTH (new); 529 eassert (0 <= TOTAL_LENGTH (new));
517 } 530 }
518 else 531 else
519 { 532 {
520 /* Insert the new node between INTERVAL and its right child. */ 533 /* Insert the new node between INTERVAL and its right child. */
521 new->right = interval->right; 534 interval_set_right (new, interval->right);
522 SET_INTERVAL_PARENT (interval->right, new); 535 interval_set_parent (interval->right, new);
523 interval->right = new; 536 interval_set_right (interval, new);
524 new->total_length = new_length + new->right->total_length; 537 new->total_length = new_length + new->right->total_length;
525 CHECK_TOTAL_LENGTH (new); 538 eassert (0 <= TOTAL_LENGTH (new));
526 balance_an_interval (new); 539 balance_an_interval (new);
527 } 540 }
528 541
@@ -552,22 +565,22 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
552 565
553 new->position = interval->position; 566 new->position = interval->position;
554 interval->position = interval->position + offset; 567 interval->position = interval->position + offset;
555 SET_INTERVAL_PARENT (new, interval); 568 interval_set_parent (new, interval);
556 569
557 if (NULL_LEFT_CHILD (interval)) 570 if (NULL_LEFT_CHILD (interval))
558 { 571 {
559 interval->left = new; 572 interval_set_left (interval, new);
560 new->total_length = new_length; 573 new->total_length = new_length;
561 CHECK_TOTAL_LENGTH (new); 574 eassert (0 <= TOTAL_LENGTH (new));
562 } 575 }
563 else 576 else
564 { 577 {
565 /* Insert the new node between INTERVAL and its left child. */ 578 /* Insert the new node between INTERVAL and its left child. */
566 new->left = interval->left; 579 interval_set_left (new, interval->left);
567 SET_INTERVAL_PARENT (new->left, new); 580 interval_set_parent (new->left, new);
568 interval->left = new; 581 interval_set_left (interval, new);
569 new->total_length = new_length + new->left->total_length; 582 new->total_length = new_length + new->left->total_length;
570 CHECK_TOTAL_LENGTH (new); 583 eassert (0 <= TOTAL_LENGTH (new));
571 balance_an_interval (new); 584 balance_an_interval (new);
572 } 585 }
573 586
@@ -589,7 +602,7 @@ interval_start_pos (INTERVAL source)
589{ 602{
590 Lisp_Object parent; 603 Lisp_Object parent;
591 604
592 if (NULL_INTERVAL_P (source)) 605 if (!source)
593 return 0; 606 return 0;
594 607
595 if (! INTERVAL_HAS_OBJECT (source)) 608 if (! INTERVAL_HAS_OBJECT (source))
@@ -617,8 +630,8 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
617 to POSITION. */ 630 to POSITION. */
618 register ptrdiff_t relative_position; 631 register ptrdiff_t relative_position;
619 632
620 if (NULL_INTERVAL_P (tree)) 633 if (!tree)
621 return NULL_INTERVAL; 634 return NULL;
622 635
623 relative_position = position; 636 relative_position = position;
624 if (INTERVAL_HAS_OBJECT (tree)) 637 if (INTERVAL_HAS_OBJECT (tree))
@@ -629,8 +642,7 @@ find_interval (register INTERVAL tree, register ptrdiff_t position)
629 relative_position -= BUF_BEG (XBUFFER (parent)); 642 relative_position -= BUF_BEG (XBUFFER (parent));
630 } 643 }
631 644
632 if (relative_position > TOTAL_LENGTH (tree)) 645 eassert (relative_position <= TOTAL_LENGTH (tree));
633 abort (); /* Paranoia */
634 646
635 if (!handling_signal) 647 if (!handling_signal)
636 tree = balance_possible_root_interval (tree); 648 tree = balance_possible_root_interval (tree);
@@ -670,8 +682,8 @@ next_interval (register INTERVAL interval)
670 register INTERVAL i = interval; 682 register INTERVAL i = interval;
671 register ptrdiff_t next_position; 683 register ptrdiff_t next_position;
672 684
673 if (NULL_INTERVAL_P (i)) 685 if (!i)
674 return NULL_INTERVAL; 686 return NULL;
675 next_position = interval->position + LENGTH (interval); 687 next_position = interval->position + LENGTH (interval);
676 688
677 if (! NULL_RIGHT_CHILD (i)) 689 if (! NULL_RIGHT_CHILD (i))
@@ -696,7 +708,7 @@ next_interval (register INTERVAL interval)
696 i = INTERVAL_PARENT (i); 708 i = INTERVAL_PARENT (i);
697 } 709 }
698 710
699 return NULL_INTERVAL; 711 return NULL;
700} 712}
701 713
702/* Find the preceding interval (lexicographically) to INTERVAL. 714/* Find the preceding interval (lexicographically) to INTERVAL.
@@ -708,8 +720,8 @@ previous_interval (register INTERVAL interval)
708{ 720{
709 register INTERVAL i; 721 register INTERVAL i;
710 722
711 if (NULL_INTERVAL_P (interval)) 723 if (!interval)
712 return NULL_INTERVAL; 724 return NULL;
713 725
714 if (! NULL_LEFT_CHILD (interval)) 726 if (! NULL_LEFT_CHILD (interval))
715 { 727 {
@@ -734,7 +746,7 @@ previous_interval (register INTERVAL interval)
734 i = INTERVAL_PARENT (i); 746 i = INTERVAL_PARENT (i);
735 } 747 }
736 748
737 return NULL_INTERVAL; 749 return NULL;
738} 750}
739 751
740/* Find the interval containing POS given some non-NULL INTERVAL 752/* Find the interval containing POS given some non-NULL INTERVAL
@@ -745,8 +757,8 @@ previous_interval (register INTERVAL interval)
745INTERVAL 757INTERVAL
746update_interval (register INTERVAL i, ptrdiff_t pos) 758update_interval (register INTERVAL i, ptrdiff_t pos)
747{ 759{
748 if (NULL_INTERVAL_P (i)) 760 if (!i)
749 return NULL_INTERVAL; 761 return NULL;
750 762
751 while (1) 763 while (1)
752 { 764 {
@@ -785,68 +797,6 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
785 } 797 }
786} 798}
787 799
788
789#if 0
790/* Traverse a path down the interval tree TREE to the interval
791 containing POSITION, adjusting all nodes on the path for
792 an addition of LENGTH characters. Insertion between two intervals
793 (i.e., point == i->position, where i is second interval) means
794 text goes into second interval.
795
796 Modifications are needed to handle the hungry bits -- after simply
797 finding the interval at position (don't add length going down),
798 if it's the beginning of the interval, get the previous interval
799 and check the hungry bits of both. Then add the length going back up
800 to the root. */
801
802static INTERVAL
803adjust_intervals_for_insertion (INTERVAL tree, ptrdiff_t position,
804 ptrdiff_t length)
805{
806 register ptrdiff_t relative_position;
807 register INTERVAL this;
808
809 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
810 abort ();
811
812 /* If inserting at point-max of a buffer, that position
813 will be out of range */
814 if (position > TOTAL_LENGTH (tree))
815 position = TOTAL_LENGTH (tree);
816 relative_position = position;
817 this = tree;
818
819 while (1)
820 {
821 if (relative_position <= LEFT_TOTAL_LENGTH (this))
822 {
823 this->total_length += length;
824 CHECK_TOTAL_LENGTH (this);
825 this = this->left;
826 }
827 else if (relative_position > (TOTAL_LENGTH (this)
828 - RIGHT_TOTAL_LENGTH (this)))
829 {
830 relative_position -= (TOTAL_LENGTH (this)
831 - RIGHT_TOTAL_LENGTH (this));
832 this->total_length += length;
833 CHECK_TOTAL_LENGTH (this);
834 this = this->right;
835 }
836 else
837 {
838 /* If we are to use zero-length intervals as buffer pointers,
839 then this code will have to change. */
840 this->total_length += length;
841 CHECK_TOTAL_LENGTH (this);
842 this->position = LEFT_TOTAL_LENGTH (this)
843 + position - relative_position + 1;
844 return tree;
845 }
846 }
847}
848#endif
849
850/* Effect an adjustment corresponding to the addition of LENGTH characters 800/* Effect an adjustment corresponding to the addition of LENGTH characters
851 of text. Do this by finding the interval containing POSITION in the 801 of text. Do this by finding the interval containing POSITION in the
852 interval tree TREE, and then adjusting all of its ancestors by adding 802 interval tree TREE, and then adjusting all of its ancestors by adding
@@ -870,8 +820,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
870 Lisp_Object parent; 820 Lisp_Object parent;
871 ptrdiff_t offset; 821 ptrdiff_t offset;
872 822
873 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ 823 eassert (TOTAL_LENGTH (tree) > 0);
874 abort ();
875 824
876 GET_INTERVAL_OBJECT (parent, tree); 825 GET_INTERVAL_OBJECT (parent, tree);
877 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0); 826 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
@@ -982,7 +931,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
982 for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) 931 for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
983 { 932 {
984 temp->total_length += length; 933 temp->total_length += length;
985 CHECK_TOTAL_LENGTH (temp); 934 eassert (0 <= TOTAL_LENGTH (temp));
986 temp = balance_possible_root_interval (temp); 935 temp = balance_possible_root_interval (temp);
987 } 936 }
988 937
@@ -1002,25 +951,23 @@ adjust_intervals_for_insertion (INTERVAL tree,
1002 struct interval newi; 951 struct interval newi;
1003 952
1004 RESET_INTERVAL (&newi); 953 RESET_INTERVAL (&newi);
1005 pleft = NULL_INTERVAL_P (prev) ? Qnil : prev->plist; 954 pleft = prev ? prev->plist : Qnil;
1006 pright = NULL_INTERVAL_P (i) ? Qnil : i->plist; 955 pright = i ? i->plist : Qnil;
1007 newi.plist = merge_properties_sticky (pleft, pright); 956 interval_set_plist (&newi, merge_properties_sticky (pleft, pright));
1008 957
1009 if (! prev) /* i.e. position == BEG */ 958 if (! prev) /* i.e. position == BEG */
1010 { 959 {
1011 if (! intervals_equal (i, &newi)) 960 if (! intervals_equal (i, &newi))
1012 { 961 {
1013 i = split_interval_left (i, length); 962 i = split_interval_left (i, length);
1014 i->plist = newi.plist; 963 interval_set_plist (i, newi.plist);
1015 } 964 }
1016 } 965 }
1017 else if (! intervals_equal (prev, &newi)) 966 else if (! intervals_equal (prev, &newi))
1018 { 967 {
1019 prev = split_interval_right (prev, 968 prev = split_interval_right (prev, position - prev->position);
1020 position - prev->position); 969 interval_set_plist (prev, newi.plist);
1021 prev->plist = newi.plist; 970 if (i && intervals_equal (prev, i))
1022 if (! NULL_INTERVAL_P (i)
1023 && intervals_equal (prev, i))
1024 merge_interval_right (prev); 971 merge_interval_right (prev);
1025 } 972 }
1026 973
@@ -1040,7 +987,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
1040 for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) 987 for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
1041 { 988 {
1042 temp->total_length += length; 989 temp->total_length += length;
1043 CHECK_TOTAL_LENGTH (temp); 990 eassert (0 <= TOTAL_LENGTH (temp));
1044 temp = balance_possible_root_interval (temp); 991 temp = balance_possible_root_interval (temp);
1045 } 992 }
1046 } 993 }
@@ -1229,23 +1176,23 @@ delete_node (register INTERVAL i)
1229 register INTERVAL migrate, this; 1176 register INTERVAL migrate, this;
1230 register ptrdiff_t migrate_amt; 1177 register ptrdiff_t migrate_amt;
1231 1178
1232 if (NULL_INTERVAL_P (i->left)) 1179 if (!i->left)
1233 return i->right; 1180 return i->right;
1234 if (NULL_INTERVAL_P (i->right)) 1181 if (!i->right)
1235 return i->left; 1182 return i->left;
1236 1183
1237 migrate = i->left; 1184 migrate = i->left;
1238 migrate_amt = i->left->total_length; 1185 migrate_amt = i->left->total_length;
1239 this = i->right; 1186 this = i->right;
1240 this->total_length += migrate_amt; 1187 this->total_length += migrate_amt;
1241 while (! NULL_INTERVAL_P (this->left)) 1188 while (this->left)
1242 { 1189 {
1243 this = this->left; 1190 this = this->left;
1244 this->total_length += migrate_amt; 1191 this->total_length += migrate_amt;
1245 } 1192 }
1246 CHECK_TOTAL_LENGTH (this); 1193 eassert (0 <= TOTAL_LENGTH (this));
1247 this->left = migrate; 1194 interval_set_left (this, migrate);
1248 SET_INTERVAL_PARENT (migrate, this); 1195 interval_set_parent (migrate, this);
1249 1196
1250 return i->right; 1197 return i->right;
1251} 1198}
@@ -1262,21 +1209,20 @@ delete_interval (register INTERVAL i)
1262 register INTERVAL parent; 1209 register INTERVAL parent;
1263 ptrdiff_t amt = LENGTH (i); 1210 ptrdiff_t amt = LENGTH (i);
1264 1211
1265 if (amt > 0) /* Only used on zero-length intervals now. */ 1212 eassert (amt == 0); /* Only used on zero-length intervals now. */
1266 abort ();
1267 1213
1268 if (ROOT_INTERVAL_P (i)) 1214 if (ROOT_INTERVAL_P (i))
1269 { 1215 {
1270 Lisp_Object owner; 1216 Lisp_Object owner;
1271 GET_INTERVAL_OBJECT (owner, i); 1217 GET_INTERVAL_OBJECT (owner, i);
1272 parent = delete_node (i); 1218 parent = delete_node (i);
1273 if (! NULL_INTERVAL_P (parent)) 1219 if (parent)
1274 SET_INTERVAL_OBJECT (parent, owner); 1220 interval_set_object (parent, owner);
1275 1221
1276 if (BUFFERP (owner)) 1222 if (BUFFERP (owner))
1277 BUF_INTERVALS (XBUFFER (owner)) = parent; 1223 buffer_set_intervals (XBUFFER (owner), parent);
1278 else if (STRINGP (owner)) 1224 else if (STRINGP (owner))
1279 STRING_SET_INTERVALS (owner, parent); 1225 string_set_intervals (owner, parent);
1280 else 1226 else
1281 abort (); 1227 abort ();
1282 1228
@@ -1286,15 +1232,15 @@ delete_interval (register INTERVAL i)
1286 parent = INTERVAL_PARENT (i); 1232 parent = INTERVAL_PARENT (i);
1287 if (AM_LEFT_CHILD (i)) 1233 if (AM_LEFT_CHILD (i))
1288 { 1234 {
1289 parent->left = delete_node (i); 1235 interval_set_left (parent, delete_node (i));
1290 if (! NULL_INTERVAL_P (parent->left)) 1236 if (parent->left)
1291 SET_INTERVAL_PARENT (parent->left, parent); 1237 interval_set_parent (parent->left, parent);
1292 } 1238 }
1293 else 1239 else
1294 { 1240 {
1295 parent->right = delete_node (i); 1241 interval_set_right (parent, delete_node (i));
1296 if (! NULL_INTERVAL_P (parent->right)) 1242 if (parent->right)
1297 SET_INTERVAL_PARENT (parent->right, parent); 1243 interval_set_parent (parent->right, parent);
1298 } 1244 }
1299} 1245}
1300 1246
@@ -1316,7 +1262,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1316{ 1262{
1317 register ptrdiff_t relative_position = from; 1263 register ptrdiff_t relative_position = from;
1318 1264
1319 if (NULL_INTERVAL_P (tree)) 1265 if (!tree)
1320 return 0; 1266 return 0;
1321 1267
1322 /* Left branch. */ 1268 /* Left branch. */
@@ -1326,7 +1272,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1326 relative_position, 1272 relative_position,
1327 amount); 1273 amount);
1328 tree->total_length -= subtract; 1274 tree->total_length -= subtract;
1329 CHECK_TOTAL_LENGTH (tree); 1275 eassert (0 <= TOTAL_LENGTH (tree));
1330 return subtract; 1276 return subtract;
1331 } 1277 }
1332 /* Right branch. */ 1278 /* Right branch. */
@@ -1341,7 +1287,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1341 relative_position, 1287 relative_position,
1342 amount); 1288 amount);
1343 tree->total_length -= subtract; 1289 tree->total_length -= subtract;
1344 CHECK_TOTAL_LENGTH (tree); 1290 eassert (0 <= TOTAL_LENGTH (tree));
1345 return subtract; 1291 return subtract;
1346 } 1292 }
1347 /* Here -- this node. */ 1293 /* Here -- this node. */
@@ -1356,7 +1302,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1356 amount = my_amount; 1302 amount = my_amount;
1357 1303
1358 tree->total_length -= amount; 1304 tree->total_length -= amount;
1359 CHECK_TOTAL_LENGTH (tree); 1305 eassert (0 <= TOTAL_LENGTH (tree));
1360 if (LENGTH (tree) == 0) 1306 if (LENGTH (tree) == 0)
1361 delete_interval (tree); 1307 delete_interval (tree);
1362 1308
@@ -1376,30 +1322,29 @@ adjust_intervals_for_deletion (struct buffer *buffer,
1376 ptrdiff_t start, ptrdiff_t length) 1322 ptrdiff_t start, ptrdiff_t length)
1377{ 1323{
1378 register ptrdiff_t left_to_delete = length; 1324 register ptrdiff_t left_to_delete = length;
1379 register INTERVAL tree = BUF_INTERVALS (buffer); 1325 register INTERVAL tree = buffer_get_intervals (buffer);
1380 Lisp_Object parent; 1326 Lisp_Object parent;
1381 ptrdiff_t offset; 1327 ptrdiff_t offset;
1382 1328
1383 GET_INTERVAL_OBJECT (parent, tree); 1329 GET_INTERVAL_OBJECT (parent, tree);
1384 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0); 1330 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
1385 1331
1386 if (NULL_INTERVAL_P (tree)) 1332 if (!tree)
1387 return; 1333 return;
1388 1334
1389 if (start > offset + TOTAL_LENGTH (tree) 1335 eassert (start <= offset + TOTAL_LENGTH (tree)
1390 || start + length > offset + TOTAL_LENGTH (tree)) 1336 && start + length <= offset + TOTAL_LENGTH (tree));
1391 abort ();
1392 1337
1393 if (length == TOTAL_LENGTH (tree)) 1338 if (length == TOTAL_LENGTH (tree))
1394 { 1339 {
1395 BUF_INTERVALS (buffer) = NULL_INTERVAL; 1340 buffer_set_intervals (buffer, NULL);
1396 return; 1341 return;
1397 } 1342 }
1398 1343
1399 if (ONLY_INTERVAL_P (tree)) 1344 if (ONLY_INTERVAL_P (tree))
1400 { 1345 {
1401 tree->total_length -= length; 1346 tree->total_length -= length;
1402 CHECK_TOTAL_LENGTH (tree); 1347 eassert (0 <= TOTAL_LENGTH (tree));
1403 return; 1348 return;
1404 } 1349 }
1405 1350
@@ -1409,10 +1354,10 @@ adjust_intervals_for_deletion (struct buffer *buffer,
1409 { 1354 {
1410 left_to_delete -= interval_deletion_adjustment (tree, start - offset, 1355 left_to_delete -= interval_deletion_adjustment (tree, start - offset,
1411 left_to_delete); 1356 left_to_delete);
1412 tree = BUF_INTERVALS (buffer); 1357 tree = buffer_get_intervals (buffer);
1413 if (left_to_delete == tree->total_length) 1358 if (left_to_delete == tree->total_length)
1414 { 1359 {
1415 BUF_INTERVALS (buffer) = NULL_INTERVAL; 1360 buffer_set_intervals (buffer, NULL);
1416 return; 1361 return;
1417 } 1362 }
1418 } 1363 }
@@ -1421,20 +1366,17 @@ adjust_intervals_for_deletion (struct buffer *buffer,
1421/* Make the adjustments necessary to the interval tree of BUFFER to 1366/* Make the adjustments necessary to the interval tree of BUFFER to
1422 represent an addition or deletion of LENGTH characters starting 1367 represent an addition or deletion of LENGTH characters starting
1423 at position START. Addition or deletion is indicated by the sign 1368 at position START. Addition or deletion is indicated by the sign
1424 of LENGTH. 1369 of LENGTH. */
1425
1426 The two inline functions (one static) pacify Sun C 5.8, a pre-C99
1427 compiler that does not allow calling a static function (here,
1428 adjust_intervals_for_deletion) from a non-static inline function. */
1429 1370
1430void 1371void
1431offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length) 1372offset_intervals (struct buffer *buffer, ptrdiff_t start, ptrdiff_t length)
1432{ 1373{
1433 if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) || length == 0) 1374 if (!buffer_get_intervals (buffer) || length == 0)
1434 return; 1375 return;
1435 1376
1436 if (length > 0) 1377 if (length > 0)
1437 adjust_intervals_for_insertion (BUF_INTERVALS (buffer), start, length); 1378 adjust_intervals_for_insertion (buffer_get_intervals (buffer),
1379 start, length);
1438 else 1380 else
1439 { 1381 {
1440 IF_LINT (if (length < - TYPE_MAXIMUM (ptrdiff_t)) abort ();) 1382 IF_LINT (if (length < - TYPE_MAXIMUM (ptrdiff_t)) abort ();)
@@ -1457,10 +1399,6 @@ merge_interval_right (register INTERVAL i)
1457 register ptrdiff_t absorb = LENGTH (i); 1399 register ptrdiff_t absorb = LENGTH (i);
1458 register INTERVAL successor; 1400 register INTERVAL successor;
1459 1401
1460 /* Zero out this interval. */
1461 i->total_length -= absorb;
1462 CHECK_TOTAL_LENGTH (i);
1463
1464 /* Find the succeeding interval. */ 1402 /* Find the succeeding interval. */
1465 if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb 1403 if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb
1466 as we descend. */ 1404 as we descend. */
@@ -1469,16 +1407,20 @@ merge_interval_right (register INTERVAL i)
1469 while (! NULL_LEFT_CHILD (successor)) 1407 while (! NULL_LEFT_CHILD (successor))
1470 { 1408 {
1471 successor->total_length += absorb; 1409 successor->total_length += absorb;
1472 CHECK_TOTAL_LENGTH (successor); 1410 eassert (0 <= TOTAL_LENGTH (successor));
1473 successor = successor->left; 1411 successor = successor->left;
1474 } 1412 }
1475 1413
1476 successor->total_length += absorb; 1414 successor->total_length += absorb;
1477 CHECK_TOTAL_LENGTH (successor); 1415 eassert (0 <= TOTAL_LENGTH (successor));
1478 delete_interval (i); 1416 delete_interval (i);
1479 return successor; 1417 return successor;
1480 } 1418 }
1481 1419
1420 /* Zero out this interval. */
1421 i->total_length -= absorb;
1422 eassert (0 <= TOTAL_LENGTH (i));
1423
1482 successor = i; 1424 successor = i;
1483 while (! NULL_PARENT (successor)) /* It's above us. Subtract as 1425 while (! NULL_PARENT (successor)) /* It's above us. Subtract as
1484 we ascend. */ 1426 we ascend. */
@@ -1492,7 +1434,7 @@ merge_interval_right (register INTERVAL i)
1492 1434
1493 successor = INTERVAL_PARENT (successor); 1435 successor = INTERVAL_PARENT (successor);
1494 successor->total_length -= absorb; 1436 successor->total_length -= absorb;
1495 CHECK_TOTAL_LENGTH (successor); 1437 eassert (0 <= TOTAL_LENGTH (successor));
1496 } 1438 }
1497 1439
1498 /* This must be the rightmost or last interval and cannot 1440 /* This must be the rightmost or last interval and cannot
@@ -1513,10 +1455,6 @@ merge_interval_left (register INTERVAL i)
1513 register ptrdiff_t absorb = LENGTH (i); 1455 register ptrdiff_t absorb = LENGTH (i);
1514 register INTERVAL predecessor; 1456 register INTERVAL predecessor;
1515 1457
1516 /* Zero out this interval. */
1517 i->total_length -= absorb;
1518 CHECK_TOTAL_LENGTH (i);
1519
1520 /* Find the preceding interval. */ 1458 /* Find the preceding interval. */
1521 if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down, 1459 if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down,
1522 adding ABSORB as we go. */ 1460 adding ABSORB as we go. */
@@ -1525,19 +1463,23 @@ merge_interval_left (register INTERVAL i)
1525 while (! NULL_RIGHT_CHILD (predecessor)) 1463 while (! NULL_RIGHT_CHILD (predecessor))
1526 { 1464 {
1527 predecessor->total_length += absorb; 1465 predecessor->total_length += absorb;
1528 CHECK_TOTAL_LENGTH (predecessor); 1466 eassert (0 <= TOTAL_LENGTH (predecessor));
1529 predecessor = predecessor->right; 1467 predecessor = predecessor->right;
1530 } 1468 }
1531 1469
1532 predecessor->total_length += absorb; 1470 predecessor->total_length += absorb;
1533 CHECK_TOTAL_LENGTH (predecessor); 1471 eassert (0 <= TOTAL_LENGTH (predecessor));
1534 delete_interval (i); 1472 delete_interval (i);
1535 return predecessor; 1473 return predecessor;
1536 } 1474 }
1537 1475
1476 /* Zero out this interval. */
1477 i->total_length -= absorb;
1478 eassert (0 <= TOTAL_LENGTH (i));
1479
1538 predecessor = i; 1480 predecessor = i;
1539 while (! NULL_PARENT (predecessor)) /* It's above us. Go up, 1481 while (! NULL_PARENT (predecessor)) /* It's above us. Go up,
1540 subtracting ABSORB. */ 1482 subtracting ABSORB. */
1541 { 1483 {
1542 if (AM_RIGHT_CHILD (predecessor)) 1484 if (AM_RIGHT_CHILD (predecessor))
1543 { 1485 {
@@ -1548,7 +1490,7 @@ merge_interval_left (register INTERVAL i)
1548 1490
1549 predecessor = INTERVAL_PARENT (predecessor); 1491 predecessor = INTERVAL_PARENT (predecessor);
1550 predecessor->total_length -= absorb; 1492 predecessor->total_length -= absorb;
1551 CHECK_TOTAL_LENGTH (predecessor); 1493 eassert (0 <= TOTAL_LENGTH (predecessor));
1552 } 1494 }
1553 1495
1554 /* This must be the leftmost or first interval and cannot 1496 /* This must be the leftmost or first interval and cannot
@@ -1566,13 +1508,13 @@ reproduce_tree (INTERVAL source, INTERVAL parent)
1566{ 1508{
1567 register INTERVAL t = make_interval (); 1509 register INTERVAL t = make_interval ();
1568 1510
1569 memcpy (t, source, INTERVAL_SIZE); 1511 memcpy (t, source, sizeof *t);
1570 copy_properties (source, t); 1512 copy_properties (source, t);
1571 SET_INTERVAL_PARENT (t, parent); 1513 interval_set_parent (t, parent);
1572 if (! NULL_LEFT_CHILD (source)) 1514 if (! NULL_LEFT_CHILD (source))
1573 t->left = reproduce_tree (source->left, t); 1515 interval_set_left (t, reproduce_tree (source->left, t));
1574 if (! NULL_RIGHT_CHILD (source)) 1516 if (! NULL_RIGHT_CHILD (source))
1575 t->right = reproduce_tree (source->right, t); 1517 interval_set_right (t, reproduce_tree (source->right, t));
1576 1518
1577 return t; 1519 return t;
1578} 1520}
@@ -1582,59 +1524,16 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
1582{ 1524{
1583 register INTERVAL t = make_interval (); 1525 register INTERVAL t = make_interval ();
1584 1526
1585 memcpy (t, source, INTERVAL_SIZE); 1527 memcpy (t, source, sizeof *t);
1586 copy_properties (source, t); 1528 copy_properties (source, t);
1587 SET_INTERVAL_OBJECT (t, parent); 1529 interval_set_object (t, parent);
1588 if (! NULL_LEFT_CHILD (source)) 1530 if (! NULL_LEFT_CHILD (source))
1589 t->left = reproduce_tree (source->left, t); 1531 interval_set_left (t, reproduce_tree (source->left, t));
1590 if (! NULL_RIGHT_CHILD (source)) 1532 if (! NULL_RIGHT_CHILD (source))
1591 t->right = reproduce_tree (source->right, t); 1533 interval_set_right (t, reproduce_tree (source->right, t));
1592 1534
1593 return t; 1535 return t;
1594} 1536}
1595
1596#if 0
1597/* Nobody calls this. Perhaps it's a vestige of an earlier design. */
1598
1599/* Make a new interval of length LENGTH starting at START in the
1600 group of intervals INTERVALS, which is actually an interval tree.
1601 Returns the new interval.
1602
1603 Generate an error if the new positions would overlap an existing
1604 interval. */
1605
1606static INTERVAL
1607make_new_interval (INTERVAL intervals, ptrdiff_t start, ptrdiff_t length)
1608{
1609 INTERVAL slot;
1610
1611 slot = find_interval (intervals, start);
1612 if (start + length > slot->position + LENGTH (slot))
1613 error ("Interval would overlap");
1614
1615 if (start == slot->position && length == LENGTH (slot))
1616 return slot;
1617
1618 if (slot->position == start)
1619 {
1620 /* New right node. */
1621 split_interval_right (slot, length);
1622 return slot;
1623 }
1624
1625 if (slot->position + LENGTH (slot) == start + length)
1626 {
1627 /* New left node. */
1628 split_interval_left (slot, LENGTH (slot) - length);
1629 return slot;
1630 }
1631
1632 /* Convert interval SLOT into three intervals. */
1633 split_interval_left (slot, start - slot->position);
1634 split_interval_right (slot, length);
1635 return slot;
1636}
1637#endif
1638 1537
1639/* Insert the intervals of SOURCE into BUFFER at POSITION. 1538/* Insert the intervals of SOURCE into BUFFER at POSITION.
1640 LENGTH is the length of the text in SOURCE. 1539 LENGTH is the length of the text in SOURCE.
@@ -1659,11 +1558,9 @@ make_new_interval (INTERVAL intervals, ptrdiff_t start, ptrdiff_t length)
1659 cases -- either insertion happened in the middle of some interval, 1558 cases -- either insertion happened in the middle of some interval,
1660 or between two intervals. 1559 or between two intervals.
1661 1560
1662 If the text goes into the middle of an interval, then new 1561 If the text goes into the middle of an interval, then new intervals
1663 intervals are created in the middle with only the properties of 1562 are created in the middle, and new text has the union of its properties
1664 the new text, *unless* the macro MERGE_INSERTIONS is true, in 1563 and those of the text into which it was inserted.
1665 which case the new text has the union of its properties and those
1666 of the text into which it was inserted.
1667 1564
1668 If the text goes between two intervals, then if neither interval 1565 If the text goes between two intervals, then if neither interval
1669 had its appropriate sticky property set (front_sticky, rear_sticky), 1566 had its appropriate sticky property set (front_sticky, rear_sticky),
@@ -1684,55 +1581,56 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
1684 register INTERVAL tree; 1581 register INTERVAL tree;
1685 ptrdiff_t over_used; 1582 ptrdiff_t over_used;
1686 1583
1687 tree = BUF_INTERVALS (buffer); 1584 tree = buffer_get_intervals (buffer);
1688 1585
1689 /* If the new text has no properties, then with inheritance it 1586 /* If the new text has no properties, then with inheritance it
1690 becomes part of whatever interval it was inserted into. 1587 becomes part of whatever interval it was inserted into.
1691 To prevent inheritance, we must clear out the properties 1588 To prevent inheritance, we must clear out the properties
1692 of the newly inserted text. */ 1589 of the newly inserted text. */
1693 if (NULL_INTERVAL_P (source)) 1590 if (!source)
1694 { 1591 {
1695 Lisp_Object buf; 1592 Lisp_Object buf;
1696 if (!inherit && !NULL_INTERVAL_P (tree) && length > 0) 1593 if (!inherit && tree && length > 0)
1697 { 1594 {
1698 XSETBUFFER (buf, buffer); 1595 XSETBUFFER (buf, buffer);
1699 set_text_properties_1 (make_number (position), 1596 set_text_properties_1 (make_number (position),
1700 make_number (position + length), 1597 make_number (position + length),
1701 Qnil, buf, 0); 1598 Qnil, buf, 0);
1702 } 1599 }
1703 if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer))) 1600 /* Shouldn't be necessary. --Stef */
1704 /* Shouldn't be necessary. --Stef */ 1601 buffer_balance_intervals (buffer);
1705 BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
1706 return; 1602 return;
1707 } 1603 }
1708 1604
1709 eassert (length == TOTAL_LENGTH (source)); 1605 eassert (length == TOTAL_LENGTH (source));
1710 1606
1711 if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length) 1607 if ((BUF_Z (buffer) - BUF_BEG (buffer)) == length)
1712 { /* The inserted text constitutes the whole buffer, so 1608 {
1609 /* The inserted text constitutes the whole buffer, so
1713 simply copy over the interval structure. */ 1610 simply copy over the interval structure. */
1714 Lisp_Object buf; 1611 Lisp_Object buf;
1715 XSETBUFFER (buf, buffer); 1612
1716 BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf); 1613 XSETBUFFER (buf, buffer);
1717 BUF_INTERVALS (buffer)->position = BUF_BEG (buffer); 1614 buffer_set_intervals (buffer, reproduce_tree_obj (source, buf));
1718 eassert (BUF_INTERVALS (buffer)->up_obj == 1); 1615 buffer_get_intervals (buffer)->position = BUF_BEG (buffer);
1719 return; 1616 eassert (buffer_get_intervals (buffer)->up_obj == 1);
1720 } 1617 return;
1721 else if (NULL_INTERVAL_P (tree)) 1618 }
1722 { /* Create an interval tree in which to place a copy 1619 else if (!tree)
1620 {
1621 /* Create an interval tree in which to place a copy
1723 of the intervals of the inserted string. */ 1622 of the intervals of the inserted string. */
1724 Lisp_Object buf; 1623 Lisp_Object buf;
1624
1725 XSETBUFFER (buf, buffer); 1625 XSETBUFFER (buf, buffer);
1726 tree = create_root_interval (buf); 1626 tree = create_root_interval (buf);
1727 } 1627 }
1728 /* Paranoia -- the text has already been added, so this buffer 1628 /* Paranoia -- the text has already been added, so
1729 should be of non-zero length. */ 1629 this buffer should be of non-zero length. */
1730 else if (TOTAL_LENGTH (tree) == 0) 1630 eassert (TOTAL_LENGTH (tree) > 0);
1731 abort ();
1732 1631
1733 this = under = find_interval (tree, position); 1632 this = under = find_interval (tree, position);
1734 if (NULL_INTERVAL_P (under)) /* Paranoia. */ 1633 eassert (under);
1735 abort ();
1736 over = find_interval (source, interval_start_pos (source)); 1634 over = find_interval (source, interval_start_pos (source));
1737 1635
1738 /* Here for insertion in the middle of an interval. 1636 /* Here for insertion in the middle of an interval.
@@ -1774,7 +1672,7 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
1774 have already been copied into target intervals. 1672 have already been copied into target intervals.
1775 UNDER is the next interval in the target. */ 1673 UNDER is the next interval in the target. */
1776 over_used = 0; 1674 over_used = 0;
1777 while (! NULL_INTERVAL_P (over)) 1675 while (over)
1778 { 1676 {
1779 /* If UNDER is longer than OVER, split it. */ 1677 /* If UNDER is longer than OVER, split it. */
1780 if (LENGTH (over) - over_used < LENGTH (under)) 1678 if (LENGTH (over) - over_used < LENGTH (under))
@@ -1807,9 +1705,7 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
1807 under = next_interval (this); 1705 under = next_interval (this);
1808 } 1706 }
1809 1707
1810 if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer))) 1708 buffer_balance_intervals (buffer);
1811 BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
1812 return;
1813} 1709}
1814 1710
1815/* Get the value of property PROP from PLIST, 1711/* Get the value of property PROP from PLIST,
@@ -1867,15 +1763,11 @@ temp_set_point_both (struct buffer *buffer,
1867 ptrdiff_t charpos, ptrdiff_t bytepos) 1763 ptrdiff_t charpos, ptrdiff_t bytepos)
1868{ 1764{
1869 /* In a single-byte buffer, the two positions must be equal. */ 1765 /* In a single-byte buffer, the two positions must be equal. */
1870 if (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer) 1766 if (BUF_ZV (buffer) == BUF_ZV_BYTE (buffer))
1871 && charpos != bytepos) 1767 eassert (charpos == bytepos);
1872 abort ();
1873 1768
1874 if (charpos > bytepos) 1769 eassert (charpos <= bytepos);
1875 abort (); 1770 eassert (charpos <= BUF_ZV (buffer) || BUF_BEGV (buffer) <= charpos);
1876
1877 if (charpos > BUF_ZV (buffer) || charpos < BUF_BEGV (buffer))
1878 abort ();
1879 1771
1880 SET_BUF_PT_BOTH (buffer, charpos, bytepos); 1772 SET_BUF_PT_BOTH (buffer, charpos, bytepos);
1881} 1773}
@@ -1962,7 +1854,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
1962 int have_overlays; 1854 int have_overlays;
1963 ptrdiff_t original_position; 1855 ptrdiff_t original_position;
1964 1856
1965 BVAR (current_buffer, point_before_scroll) = Qnil; 1857 BSET (current_buffer, point_before_scroll, Qnil);
1966 1858
1967 if (charpos == PT) 1859 if (charpos == PT)
1968 return; 1860 return;
@@ -1975,12 +1867,11 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
1975 whether or not there are intervals in the buffer. */ 1867 whether or not there are intervals in the buffer. */
1976 eassert (charpos <= ZV && charpos >= BEGV); 1868 eassert (charpos <= ZV && charpos >= BEGV);
1977 1869
1978 have_overlays = (current_buffer->overlays_before 1870 have_overlays = buffer_has_overlays ();
1979 || current_buffer->overlays_after);
1980 1871
1981 /* If we have no text properties and overlays, 1872 /* If we have no text properties and overlays,
1982 then we can do it quickly. */ 1873 then we can do it quickly. */
1983 if (NULL_INTERVAL_P (BUF_INTERVALS (current_buffer)) && ! have_overlays) 1874 if (!buffer_get_intervals (current_buffer) && ! have_overlays)
1984 { 1875 {
1985 temp_set_point_both (current_buffer, charpos, bytepos); 1876 temp_set_point_both (current_buffer, charpos, bytepos);
1986 return; 1877 return;
@@ -1989,7 +1880,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
1989 /* Set TO to the interval containing the char after CHARPOS, 1880 /* Set TO to the interval containing the char after CHARPOS,
1990 and TOPREV to the interval containing the char before CHARPOS. 1881 and TOPREV to the interval containing the char before CHARPOS.
1991 Either one may be null. They may be equal. */ 1882 Either one may be null. They may be equal. */
1992 to = find_interval (BUF_INTERVALS (current_buffer), charpos); 1883 to = find_interval (buffer_get_intervals (current_buffer), charpos);
1993 if (charpos == BEGV) 1884 if (charpos == BEGV)
1994 toprev = 0; 1885 toprev = 0;
1995 else if (to && to->position == charpos) 1886 else if (to && to->position == charpos)
@@ -2003,7 +1894,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
2003 and FROMPREV to the interval containing the char before PT. 1894 and FROMPREV to the interval containing the char before PT.
2004 Either one may be null. They may be equal. */ 1895 Either one may be null. They may be equal. */
2005 /* We could cache this and save time. */ 1896 /* We could cache this and save time. */
2006 from = find_interval (BUF_INTERVALS (current_buffer), buffer_point); 1897 from = find_interval (buffer_get_intervals (current_buffer), buffer_point);
2007 if (buffer_point == BEGV) 1898 if (buffer_point == BEGV)
2008 fromprev = 0; 1899 fromprev = 0;
2009 else if (from && from->position == PT) 1900 else if (from && from->position == PT)
@@ -2027,7 +1918,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
2027 with the same intangible property value, 1918 with the same intangible property value,
2028 move forward or backward until a change in that property. */ 1919 move forward or backward until a change in that property. */
2029 if (NILP (Vinhibit_point_motion_hooks) 1920 if (NILP (Vinhibit_point_motion_hooks)
2030 && ((! NULL_INTERVAL_P (to) && ! NULL_INTERVAL_P (toprev)) 1921 && ((to && toprev)
2031 || have_overlays) 1922 || have_overlays)
2032 /* Intangibility never stops us from positioning at the beginning 1923 /* Intangibility never stops us from positioning at the beginning
2033 or end of the buffer, so don't bother checking in that case. */ 1924 or end of the buffer, so don't bother checking in that case. */
@@ -2109,7 +2000,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
2109 /* Set TO to the interval containing the char after CHARPOS, 2000 /* Set TO to the interval containing the char after CHARPOS,
2110 and TOPREV to the interval containing the char before CHARPOS. 2001 and TOPREV to the interval containing the char before CHARPOS.
2111 Either one may be null. They may be equal. */ 2002 Either one may be null. They may be equal. */
2112 to = find_interval (BUF_INTERVALS (current_buffer), charpos); 2003 to = find_interval (buffer_get_intervals (current_buffer), charpos);
2113 if (charpos == BEGV) 2004 if (charpos == BEGV)
2114 toprev = 0; 2005 toprev = 0;
2115 else if (to && to->position == charpos) 2006 else if (to && to->position == charpos)
@@ -2242,15 +2133,15 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
2242 INTERVAL i, prev, next; 2133 INTERVAL i, prev, next;
2243 2134
2244 if (NILP (object)) 2135 if (NILP (object))
2245 i = find_interval (BUF_INTERVALS (current_buffer), pos); 2136 i = find_interval (buffer_get_intervals (current_buffer), pos);
2246 else if (BUFFERP (object)) 2137 else if (BUFFERP (object))
2247 i = find_interval (BUF_INTERVALS (XBUFFER (object)), pos); 2138 i = find_interval (buffer_get_intervals (XBUFFER (object)), pos);
2248 else if (STRINGP (object)) 2139 else if (STRINGP (object))
2249 i = find_interval (STRING_INTERVALS (object), pos); 2140 i = find_interval (string_get_intervals (object), pos);
2250 else 2141 else
2251 abort (); 2142 abort ();
2252 2143
2253 if (NULL_INTERVAL_P (i) || (i->position + LENGTH (i) <= pos)) 2144 if (!i || (i->position + LENGTH (i) <= pos))
2254 return 0; 2145 return 0;
2255 *val = textget (i->plist, prop); 2146 *val = textget (i->plist, prop);
2256 if (NILP (*val)) 2147 if (NILP (*val))
@@ -2258,14 +2149,13 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
2258 2149
2259 next = i; /* remember it in advance */ 2150 next = i; /* remember it in advance */
2260 prev = previous_interval (i); 2151 prev = previous_interval (i);
2261 while (! NULL_INTERVAL_P (prev) 2152 while (prev
2262 && EQ (*val, textget (prev->plist, prop))) 2153 && EQ (*val, textget (prev->plist, prop)))
2263 i = prev, prev = previous_interval (prev); 2154 i = prev, prev = previous_interval (prev);
2264 *start = i->position; 2155 *start = i->position;
2265 2156
2266 next = next_interval (i); 2157 next = next_interval (i);
2267 while (! NULL_INTERVAL_P (next) 2158 while (next && EQ (*val, textget (next->plist, prop)))
2268 && EQ (*val, textget (next->plist, prop)))
2269 i = next, next = next_interval (next); 2159 i = next, next = next_interval (next);
2270 *end = i->position + LENGTH (i); 2160 *end = i->position + LENGTH (i);
2271 2161
@@ -2336,23 +2226,22 @@ copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
2336 register INTERVAL i, new, t; 2226 register INTERVAL i, new, t;
2337 register ptrdiff_t got, prevlen; 2227 register ptrdiff_t got, prevlen;
2338 2228
2339 if (NULL_INTERVAL_P (tree) || length <= 0) 2229 if (!tree || length <= 0)
2340 return NULL_INTERVAL; 2230 return NULL;
2341 2231
2342 i = find_interval (tree, start); 2232 i = find_interval (tree, start);
2343 if (NULL_INTERVAL_P (i) || LENGTH (i) == 0) 2233 eassert (i && LENGTH (i) > 0);
2344 abort ();
2345 2234
2346 /* If there is only one interval and it's the default, return nil. */ 2235 /* If there is only one interval and it's the default, return nil. */
2347 if ((start - i->position + 1 + length) < LENGTH (i) 2236 if ((start - i->position + 1 + length) < LENGTH (i)
2348 && DEFAULT_INTERVAL_P (i)) 2237 && DEFAULT_INTERVAL_P (i))
2349 return NULL_INTERVAL; 2238 return NULL;
2350 2239
2351 new = make_interval (); 2240 new = make_interval ();
2352 new->position = 0; 2241 new->position = 0;
2353 got = (LENGTH (i) - (start - i->position)); 2242 got = (LENGTH (i) - (start - i->position));
2354 new->total_length = length; 2243 new->total_length = length;
2355 CHECK_TOTAL_LENGTH (new); 2244 eassert (0 <= TOTAL_LENGTH (new));
2356 copy_properties (i, new); 2245 copy_properties (i, new);
2357 2246
2358 t = new; 2247 t = new;
@@ -2375,13 +2264,13 @@ void
2375copy_intervals_to_string (Lisp_Object string, struct buffer *buffer, 2264copy_intervals_to_string (Lisp_Object string, struct buffer *buffer,
2376 ptrdiff_t position, ptrdiff_t length) 2265 ptrdiff_t position, ptrdiff_t length)
2377{ 2266{
2378 INTERVAL interval_copy = copy_intervals (BUF_INTERVALS (buffer), 2267 INTERVAL interval_copy = copy_intervals (buffer_get_intervals (buffer),
2379 position, length); 2268 position, length);
2380 if (NULL_INTERVAL_P (interval_copy)) 2269 if (!interval_copy)
2381 return; 2270 return;
2382 2271
2383 SET_INTERVAL_OBJECT (interval_copy, string); 2272 interval_set_object (interval_copy, string);
2384 STRING_SET_INTERVALS (string, interval_copy); 2273 string_set_intervals (string, interval_copy);
2385} 2274}
2386 2275
2387/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise. 2276/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
@@ -2394,8 +2283,8 @@ compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
2394 ptrdiff_t pos = 0; 2283 ptrdiff_t pos = 0;
2395 ptrdiff_t end = SCHARS (s1); 2284 ptrdiff_t end = SCHARS (s1);
2396 2285
2397 i1 = find_interval (STRING_INTERVALS (s1), 0); 2286 i1 = find_interval (string_get_intervals (s1), 0);
2398 i2 = find_interval (STRING_INTERVALS (s2), 0); 2287 i2 = find_interval (string_get_intervals (s2), 0);
2399 2288
2400 while (pos < end) 2289 while (pos < end)
2401 { 2290 {
@@ -2435,7 +2324,7 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
2435 i->total_length = end - start; 2324 i->total_length = end - start;
2436 else 2325 else
2437 i->total_length = end_byte - start_byte; 2326 i->total_length = end_byte - start_byte;
2438 CHECK_TOTAL_LENGTH (i); 2327 eassert (0 <= TOTAL_LENGTH (i));
2439 2328
2440 if (TOTAL_LENGTH (i) == 0) 2329 if (TOTAL_LENGTH (i) == 0)
2441 { 2330 {
@@ -2520,13 +2409,13 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
2520 { 2409 {
2521 if ((i)->left) 2410 if ((i)->left)
2522 { 2411 {
2523 (i)->plist = (i)->left->plist; 2412 interval_set_plist (i, i->left->plist);
2524 (i)->left->total_length = 0; 2413 (i)->left->total_length = 0;
2525 delete_interval ((i)->left); 2414 delete_interval ((i)->left);
2526 } 2415 }
2527 else 2416 else
2528 { 2417 {
2529 (i)->plist = (i)->right->plist; 2418 interval_set_plist (i, i->right->plist);
2530 (i)->right->total_length = 0; 2419 (i)->right->total_length = 0;
2531 delete_interval ((i)->right); 2420 delete_interval ((i)->right);
2532 } 2421 }
@@ -2540,7 +2429,8 @@ set_intervals_multibyte_1 (INTERVAL i, int multi_flag,
2540void 2429void
2541set_intervals_multibyte (int multi_flag) 2430set_intervals_multibyte (int multi_flag)
2542{ 2431{
2543 if (BUF_INTERVALS (current_buffer)) 2432 INTERVAL i = buffer_get_intervals (current_buffer);
2544 set_intervals_multibyte_1 (BUF_INTERVALS (current_buffer), multi_flag, 2433
2545 BEG, BEG_BYTE, Z, Z_BYTE); 2434 if (i)
2435 set_intervals_multibyte_1 (i, multi_flag, BEG, BEG_BYTE, Z, Z_BYTE);
2546} 2436}