aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn2000-03-22 21:44:05 +0000
committerKen Raeburn2000-03-22 21:44:05 +0000
commit439d5cb4f7aa541a93c9c5003188918af097b82a (patch)
treead3ce3a953fa8442bd99f71544cf645dd6ecb6a6 /src
parent89084293988e60922e51698a441ec71ab0d2363b (diff)
downloademacs-439d5cb4f7aa541a93c9c5003188918af097b82a.tar.gz
emacs-439d5cb4f7aa541a93c9c5003188918af097b82a.zip
Changes towards better type safety regarding intervals, primarily
regarding the "parent" handle. These just separate out the different usages based on the type of parent (interval vs lisp object); later changes will do type checking and enforcement. * intervals.h (NULL_INTERVAL): Cast to INTERVAL type. (INT_LISPLIKE): New macro. (NULL_INTERVAL_P): Use it. (INTERVAL_HAS_PARENT, INTERVAL_HAS_OBJECT, SET_INTERVAL_PARENT, SET_INTERVAL_OBJECT, INTERVAL_PARENT, COPY_INTERVAL_PARENT, GET_INTERVAL_OBJECT, INTERVAL_PARENT_OR_NULL): New macros. * alloc.c (make_interval, gc_sweep): Use new macros; eliminate all explicit references to "parent" field of struct interval and associated unclean type conversions. * intervals.c (create_root_interval, root_interval, rotate_right, rotate_left, balance_possible_root_interval, split_interval_right, split_interval_left, interval_start_pos, find_interval, next_interval, previous_interval, update_interval, adjust_intervals_for_insertion, delete_node, delete_interval, adjust_intervals_for_deletion, merge_interval_right, merge_interval_left, reproduce_tree, graft_intervals_into_buffer, copy_intervals_to_string): Likewise. * intervals.h (AM_LEFT_CHILD, AM_RIGHT_CHILD, RESET_INTERVAL): Likewise. * syntax.c (update_syntax_table): Likewise. * intervals.c (reproduce_tree_obj): New function, like reproduce_tree but takes a Lisp_Object for the parent. Declare with prototype. (graft_intervals_into_buffer): Use it when appropriate. (reproduce_tree): Declare with prototype. (balance_possible_root_interval): Check that the parent is a lisp object before trying to examine its type.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog32
-rw-r--r--src/alloc.c6
-rw-r--r--src/intervals.c133
-rw-r--r--src/intervals.h49
-rw-r--r--src/syntax.c10
5 files changed, 159 insertions, 71 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1d1916b24bc..3ee198fecd3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,35 @@
12000-03-22 Ken Raeburn <raeburn@gnu.org>
2
3 * intervals.h (NULL_INTERVAL): Cast to INTERVAL type.
4 (INT_LISPLIKE): New macro.
5 (NULL_INTERVAL_P): Use it.
6 (INTERVAL_HAS_PARENT, INTERVAL_HAS_OBJECT, SET_INTERVAL_PARENT,
7 SET_INTERVAL_OBJECT, INTERVAL_PARENT, COPY_INTERVAL_PARENT,
8 GET_INTERVAL_OBJECT, INTERVAL_PARENT_OR_NULL): New macros.
9
10 * alloc.c (make_interval, gc_sweep): Use new macros; eliminate all
11 explicit references to "parent" field of struct interval and
12 associated unclean type conversions.
13 * intervals.c (create_root_interval, root_interval, rotate_right,
14 rotate_left, balance_possible_root_interval, split_interval_right,
15 split_interval_left, interval_start_pos, find_interval,
16 next_interval, previous_interval, update_interval,
17 adjust_intervals_for_insertion, delete_node, delete_interval,
18 adjust_intervals_for_deletion, merge_interval_right,
19 merge_interval_left, reproduce_tree, graft_intervals_into_buffer,
20 copy_intervals_to_string): Likewise.
21 * intervals.h (AM_LEFT_CHILD, AM_RIGHT_CHILD, RESET_INTERVAL):
22 Likewise.
23 * syntax.c (update_syntax_table): Likewise.
24
25 * intervals.c (reproduce_tree_obj): New function, like
26 reproduce_tree but takes a Lisp_Object for the parent. Declare
27 with prototype.
28 (graft_intervals_into_buffer): Use it when appropriate.
29 (reproduce_tree): Declare with prototype.
30 (balance_possible_root_interval): Check that the parent is a lisp
31 object before trying to examine its type.
32
12000-03-22 Gerd Moellmann <gerd@gnu.org> 332000-03-22 Gerd Moellmann <gerd@gnu.org>
2 34
3 * xfaces.c (lface_same_font_attributes_p): Compare font attributes 35 * xfaces.c (lface_same_font_attributes_p): Compare font attributes
diff --git a/src/alloc.c b/src/alloc.c
index ba8b3ffd6ed..3027e08b467 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -711,7 +711,7 @@ make_interval ()
711 if (interval_free_list) 711 if (interval_free_list)
712 { 712 {
713 val = interval_free_list; 713 val = interval_free_list;
714 interval_free_list = interval_free_list->parent; 714 interval_free_list = INTERVAL_PARENT (interval_free_list);
715 } 715 }
716 else 716 else
717 { 717 {
@@ -4215,7 +4215,7 @@ gc_sweep ()
4215 { 4215 {
4216 if (! XMARKBIT (iblk->intervals[i].plist)) 4216 if (! XMARKBIT (iblk->intervals[i].plist))
4217 { 4217 {
4218 iblk->intervals[i].parent = interval_free_list; 4218 SET_INTERVAL_PARENT (&iblk->intervals[i], interval_free_list);
4219 interval_free_list = &iblk->intervals[i]; 4219 interval_free_list = &iblk->intervals[i];
4220 this_free++; 4220 this_free++;
4221 } 4221 }
@@ -4233,7 +4233,7 @@ gc_sweep ()
4233 { 4233 {
4234 *iprev = iblk->next; 4234 *iprev = iblk->next;
4235 /* Unhook from the free list. */ 4235 /* Unhook from the free list. */
4236 interval_free_list = iblk->intervals[0].parent; 4236 interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]);
4237 lisp_free (iblk); 4237 lisp_free (iblk);
4238 n_interval_blocks--; 4238 n_interval_blocks--;
4239 } 4239 }
diff --git a/src/intervals.c b/src/intervals.c
index bba25d7de8c..2a03abbb762 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -54,6 +54,8 @@ Boston, MA 02111-1307, USA. */
54#define min(x, y) ((x) < (y) ? (x) : (y)) 54#define min(x, y) ((x) < (y) ? (x) : (y))
55 55
56Lisp_Object merge_properties_sticky (); 56Lisp_Object merge_properties_sticky ();
57static INTERVAL reproduce_tree P_ ((INTERVAL, INTERVAL));
58static INTERVAL reproduce_tree_obj P_ ((INTERVAL, Lisp_Object));
57 59
58/* Utility functions for intervals. */ 60/* Utility functions for intervals. */
59 61
@@ -84,7 +86,7 @@ create_root_interval (parent)
84 new->position = 0; 86 new->position = 0;
85 } 87 }
86 88
87 new->parent = (INTERVAL) XFASTINT (parent); 89 SET_INTERVAL_OBJECT (new, parent);
88 90
89 return new; 91 return new;
90} 92}
@@ -269,7 +271,7 @@ root_interval (interval)
269 register INTERVAL i = interval; 271 register INTERVAL i = interval;
270 272
271 while (! ROOT_INTERVAL_P (i)) 273 while (! ROOT_INTERVAL_P (i))
272 i = i->parent; 274 i = INTERVAL_PARENT (i);
273 275
274 return i; 276 return i;
275} 277}
@@ -296,21 +298,21 @@ rotate_right (interval)
296 if (! ROOT_INTERVAL_P (interval)) 298 if (! ROOT_INTERVAL_P (interval))
297 { 299 {
298 if (AM_LEFT_CHILD (interval)) 300 if (AM_LEFT_CHILD (interval))
299 interval->parent->left = B; 301 INTERVAL_PARENT (interval)->left = B;
300 else 302 else
301 interval->parent->right = B; 303 INTERVAL_PARENT (interval)->right = B;
302 } 304 }
303 B->parent = interval->parent; 305 COPY_INTERVAL_PARENT (B, interval);
304 306
305 /* Make B the parent of A */ 307 /* Make B the parent of A */
306 i = B->right; 308 i = B->right;
307 B->right = interval; 309 B->right = interval;
308 interval->parent = B; 310 SET_INTERVAL_PARENT (interval, B);
309 311
310 /* Make A point to c */ 312 /* Make A point to c */
311 interval->left = i; 313 interval->left = i;
312 if (! NULL_INTERVAL_P (i)) 314 if (! NULL_INTERVAL_P (i))
313 i->parent = interval; 315 SET_INTERVAL_PARENT (i, interval);
314 316
315 /* A's total length is decreased by the length of B and its left child. */ 317 /* A's total length is decreased by the length of B and its left child. */
316 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval); 318 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
@@ -342,21 +344,21 @@ rotate_left (interval)
342 if (! ROOT_INTERVAL_P (interval)) 344 if (! ROOT_INTERVAL_P (interval))
343 { 345 {
344 if (AM_LEFT_CHILD (interval)) 346 if (AM_LEFT_CHILD (interval))
345 interval->parent->left = B; 347 INTERVAL_PARENT (interval)->left = B;
346 else 348 else
347 interval->parent->right = B; 349 INTERVAL_PARENT (interval)->right = B;
348 } 350 }
349 B->parent = interval->parent; 351 COPY_INTERVAL_PARENT (B, interval);
350 352
351 /* Make B the parent of A */ 353 /* Make B the parent of A */
352 i = B->left; 354 i = B->left;
353 B->left = interval; 355 B->left = interval;
354 interval->parent = B; 356 SET_INTERVAL_PARENT (interval, B);
355 357
356 /* Make A point to c */ 358 /* Make A point to c */
357 interval->right = i; 359 interval->right = i;
358 if (! NULL_INTERVAL_P (i)) 360 if (! NULL_INTERVAL_P (i))
359 i->parent = interval; 361 SET_INTERVAL_PARENT (i, interval);
360 362
361 /* A's total length is decreased by the length of B and its right child. */ 363 /* A's total length is decreased by the length of B and its right child. */
362 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); 364 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
@@ -411,17 +413,25 @@ balance_possible_root_interval (interval)
411 register INTERVAL interval; 413 register INTERVAL interval;
412{ 414{
413 Lisp_Object parent; 415 Lisp_Object parent;
416 int have_parent = 0;
414 417
415 if (interval->parent == NULL_INTERVAL) 418 if (!INTERVAL_HAS_OBJECT (interval) && !INTERVAL_HAS_PARENT (interval))
416 return interval; 419 return interval;
417 420
418 XSETFASTINT (parent, (EMACS_INT) interval->parent); 421 if (INTERVAL_HAS_OBJECT (interval))
422 {
423 have_parent = 1;
424 GET_INTERVAL_OBJECT (parent, interval);
425 }
419 interval = balance_an_interval (interval); 426 interval = balance_an_interval (interval);
420 427
421 if (BUFFERP (parent)) 428 if (have_parent)
422 BUF_INTERVALS (XBUFFER (parent)) = interval; 429 {
423 else if (STRINGP (parent)) 430 if (BUFFERP (parent))
424 XSTRING (parent)->intervals = interval; 431 BUF_INTERVALS (XBUFFER (parent)) = interval;
432 else if (STRINGP (parent))
433 XSTRING (parent)->intervals = interval;
434 }
425 435
426 return interval; 436 return interval;
427} 437}
@@ -476,7 +486,7 @@ split_interval_right (interval, offset)
476 int new_length = LENGTH (interval) - offset; 486 int new_length = LENGTH (interval) - offset;
477 487
478 new->position = position + offset; 488 new->position = position + offset;
479 new->parent = interval; 489 SET_INTERVAL_PARENT (new, interval);
480 490
481 if (NULL_RIGHT_CHILD (interval)) 491 if (NULL_RIGHT_CHILD (interval))
482 { 492 {
@@ -487,7 +497,7 @@ split_interval_right (interval, offset)
487 { 497 {
488 /* Insert the new node between INTERVAL and its right child. */ 498 /* Insert the new node between INTERVAL and its right child. */
489 new->right = interval->right; 499 new->right = interval->right;
490 interval->right->parent = new; 500 SET_INTERVAL_PARENT (interval->right, new);
491 interval->right = new; 501 interval->right = new;
492 new->total_length = new_length + new->right->total_length; 502 new->total_length = new_length + new->right->total_length;
493 balance_an_interval (new); 503 balance_an_interval (new);
@@ -521,7 +531,7 @@ split_interval_left (interval, offset)
521 531
522 new->position = interval->position; 532 new->position = interval->position;
523 interval->position = interval->position + offset; 533 interval->position = interval->position + offset;
524 new->parent = interval; 534 SET_INTERVAL_PARENT (new, interval);
525 535
526 if (NULL_LEFT_CHILD (interval)) 536 if (NULL_LEFT_CHILD (interval))
527 { 537 {
@@ -532,7 +542,7 @@ split_interval_left (interval, offset)
532 { 542 {
533 /* Insert the new node between INTERVAL and its left child. */ 543 /* Insert the new node between INTERVAL and its left child. */
534 new->left = interval->left; 544 new->left = interval->left;
535 new->left->parent = new; 545 SET_INTERVAL_PARENT (new->left, new);
536 interval->left = new; 546 interval->left = new;
537 new->total_length = new_length + new->left->total_length; 547 new->total_length = new_length + new->left->total_length;
538 balance_an_interval (new); 548 balance_an_interval (new);
@@ -560,7 +570,7 @@ interval_start_pos (source)
560 if (NULL_INTERVAL_P (source)) 570 if (NULL_INTERVAL_P (source))
561 return 0; 571 return 0;
562 572
563 XSETFASTINT (parent, (EMACS_INT) source->parent); 573 GET_INTERVAL_OBJECT (parent, source);
564 if (BUFFERP (parent)) 574 if (BUFFERP (parent))
565 return BUF_BEG (XBUFFER (parent)); 575 return BUF_BEG (XBUFFER (parent));
566 return 0; 576 return 0;
@@ -584,15 +594,18 @@ find_interval (tree, position)
584 /* The distance from the left edge of the subtree at TREE 594 /* The distance from the left edge of the subtree at TREE
585 to POSITION. */ 595 to POSITION. */
586 register int relative_position; 596 register int relative_position;
587 Lisp_Object parent;
588 597
589 if (NULL_INTERVAL_P (tree)) 598 if (NULL_INTERVAL_P (tree))
590 return NULL_INTERVAL; 599 return NULL_INTERVAL;
591 600
592 XSETFASTINT (parent, (EMACS_INT) tree->parent);
593 relative_position = position; 601 relative_position = position;
594 if (BUFFERP (parent)) 602 if (INTERVAL_HAS_OBJECT (tree))
595 relative_position -= BUF_BEG (XBUFFER (parent)); 603 {
604 Lisp_Object parent;
605 GET_INTERVAL_OBJECT (parent, tree);
606 if (BUFFERP (parent))
607 relative_position -= BUF_BEG (XBUFFER (parent));
608 }
596 609
597 if (relative_position > TOTAL_LENGTH (tree)) 610 if (relative_position > TOTAL_LENGTH (tree))
598 abort (); /* Paranoia */ 611 abort (); /* Paranoia */
@@ -653,12 +666,12 @@ next_interval (interval)
653 { 666 {
654 if (AM_LEFT_CHILD (i)) 667 if (AM_LEFT_CHILD (i))
655 { 668 {
656 i = i->parent; 669 i = INTERVAL_PARENT (i);
657 i->position = next_position; 670 i->position = next_position;
658 return i; 671 return i;
659 } 672 }
660 673
661 i = i->parent; 674 i = INTERVAL_PARENT (i);
662 } 675 }
663 676
664 return NULL_INTERVAL; 677 return NULL_INTERVAL;
@@ -692,12 +705,12 @@ previous_interval (interval)
692 { 705 {
693 if (AM_RIGHT_CHILD (i)) 706 if (AM_RIGHT_CHILD (i))
694 { 707 {
695 i = i->parent; 708 i = INTERVAL_PARENT (i);
696 709
697 i->position = interval->position - LENGTH (i); 710 i->position = interval->position - LENGTH (i);
698 return i; 711 return i;
699 } 712 }
700 i = i->parent; 713 i = INTERVAL_PARENT (i);
701 } 714 }
702 715
703 return NULL_INTERVAL; 716 return NULL_INTERVAL;
@@ -728,7 +741,7 @@ update_interval (i, pos)
728 else if (NULL_PARENT (i)) 741 else if (NULL_PARENT (i))
729 error ("Point before start of properties"); 742 error ("Point before start of properties");
730 else 743 else
731 i = i->parent; 744 i = INTERVAL_PARENT (i);
732 continue; 745 continue;
733 } 746 }
734 else if (pos >= INTERVAL_LAST_POS (i)) 747 else if (pos >= INTERVAL_LAST_POS (i))
@@ -743,7 +756,7 @@ update_interval (i, pos)
743 else if (NULL_PARENT (i)) 756 else if (NULL_PARENT (i))
744 error ("Point after end of properties"); 757 error ("Point after end of properties");
745 else 758 else
746 i = i->parent; 759 i = INTERVAL_PARENT (i);
747 continue; 760 continue;
748 } 761 }
749 else 762 else
@@ -838,7 +851,7 @@ adjust_intervals_for_insertion (tree, position, length)
838 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ 851 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
839 abort (); 852 abort ();
840 853
841 XSETFASTINT (parent, (EMACS_INT) tree->parent); 854 GET_INTERVAL_OBJECT (parent, tree);
842 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0); 855 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
843 856
844 /* If inserting at point-max of a buffer, that position will be out 857 /* If inserting at point-max of a buffer, that position will be out
@@ -944,7 +957,7 @@ adjust_intervals_for_insertion (tree, position, length)
944 /* Even if we are positioned between intervals, we default 957 /* Even if we are positioned between intervals, we default
945 to the left one if it exists. We extend it now and split 958 to the left one if it exists. We extend it now and split
946 off a part later, if stickiness demands it. */ 959 off a part later, if stickiness demands it. */
947 for (temp = prev ? prev : i;! NULL_INTERVAL_P (temp); temp = temp->parent) 960 for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
948 { 961 {
949 temp->total_length += length; 962 temp->total_length += length;
950 temp = balance_possible_root_interval (temp); 963 temp = balance_possible_root_interval (temp);
@@ -1000,7 +1013,7 @@ adjust_intervals_for_insertion (tree, position, length)
1000 /* Otherwise just extend the interval. */ 1013 /* Otherwise just extend the interval. */
1001 else 1014 else
1002 { 1015 {
1003 for (temp = i; ! NULL_INTERVAL_P (temp); temp = temp->parent) 1016 for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
1004 { 1017 {
1005 temp->total_length += length; 1018 temp->total_length += length;
1006 temp = balance_possible_root_interval (temp); 1019 temp = balance_possible_root_interval (temp);
@@ -1208,7 +1221,7 @@ delete_node (i)
1208 this->total_length += migrate_amt; 1221 this->total_length += migrate_amt;
1209 } 1222 }
1210 this->left = migrate; 1223 this->left = migrate;
1211 migrate->parent = this; 1224 SET_INTERVAL_PARENT (migrate, this);
1212 1225
1213 return i->right; 1226 return i->right;
1214} 1227}
@@ -1232,10 +1245,10 @@ delete_interval (i)
1232 if (ROOT_INTERVAL_P (i)) 1245 if (ROOT_INTERVAL_P (i))
1233 { 1246 {
1234 Lisp_Object owner; 1247 Lisp_Object owner;
1235 XSETFASTINT (owner, (EMACS_INT) i->parent); 1248 GET_INTERVAL_OBJECT (owner, i);
1236 parent = delete_node (i); 1249 parent = delete_node (i);
1237 if (! NULL_INTERVAL_P (parent)) 1250 if (! NULL_INTERVAL_P (parent))
1238 parent->parent = (INTERVAL) XFASTINT (owner); 1251 SET_INTERVAL_OBJECT (parent, owner);
1239 1252
1240 if (BUFFERP (owner)) 1253 if (BUFFERP (owner))
1241 BUF_INTERVALS (XBUFFER (owner)) = parent; 1254 BUF_INTERVALS (XBUFFER (owner)) = parent;
@@ -1247,18 +1260,18 @@ delete_interval (i)
1247 return; 1260 return;
1248 } 1261 }
1249 1262
1250 parent = i->parent; 1263 parent = INTERVAL_PARENT (i);
1251 if (AM_LEFT_CHILD (i)) 1264 if (AM_LEFT_CHILD (i))
1252 { 1265 {
1253 parent->left = delete_node (i); 1266 parent->left = delete_node (i);
1254 if (! NULL_INTERVAL_P (parent->left)) 1267 if (! NULL_INTERVAL_P (parent->left))
1255 parent->left->parent = parent; 1268 SET_INTERVAL_PARENT (parent->left, parent);
1256 } 1269 }
1257 else 1270 else
1258 { 1271 {
1259 parent->right = delete_node (i); 1272 parent->right = delete_node (i);
1260 if (! NULL_INTERVAL_P (parent->right)) 1273 if (! NULL_INTERVAL_P (parent->right))
1261 parent->right->parent = parent; 1274 SET_INTERVAL_PARENT (parent->right, parent);
1262 } 1275 }
1263} 1276}
1264 1277
@@ -1343,7 +1356,7 @@ adjust_intervals_for_deletion (buffer, start, length)
1343 Lisp_Object parent; 1356 Lisp_Object parent;
1344 int offset; 1357 int offset;
1345 1358
1346 XSETFASTINT (parent, (EMACS_INT) tree->parent); 1359 GET_INTERVAL_OBJECT (parent, tree);
1347 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0); 1360 offset = (BUFFERP (parent) ? BUF_BEG (XBUFFER (parent)) : 0);
1348 1361
1349 if (NULL_INTERVAL_P (tree)) 1362 if (NULL_INTERVAL_P (tree))
@@ -1440,12 +1453,12 @@ merge_interval_right (i)
1440 { 1453 {
1441 if (AM_LEFT_CHILD (successor)) 1454 if (AM_LEFT_CHILD (successor))
1442 { 1455 {
1443 successor = successor->parent; 1456 successor = INTERVAL_PARENT (successor);
1444 delete_interval (i); 1457 delete_interval (i);
1445 return successor; 1458 return successor;
1446 } 1459 }
1447 1460
1448 successor = successor->parent; 1461 successor = INTERVAL_PARENT (successor);
1449 successor->total_length -= absorb; 1462 successor->total_length -= absorb;
1450 } 1463 }
1451 1464
@@ -1493,12 +1506,12 @@ merge_interval_left (i)
1493 { 1506 {
1494 if (AM_RIGHT_CHILD (predecessor)) 1507 if (AM_RIGHT_CHILD (predecessor))
1495 { 1508 {
1496 predecessor = predecessor->parent; 1509 predecessor = INTERVAL_PARENT (predecessor);
1497 delete_interval (i); 1510 delete_interval (i);
1498 return predecessor; 1511 return predecessor;
1499 } 1512 }
1500 1513
1501 predecessor = predecessor->parent; 1514 predecessor = INTERVAL_PARENT (predecessor);
1502 predecessor->total_length -= absorb; 1515 predecessor->total_length -= absorb;
1503 } 1516 }
1504 1517
@@ -1520,7 +1533,25 @@ reproduce_tree (source, parent)
1520 1533
1521 bcopy (source, t, INTERVAL_SIZE); 1534 bcopy (source, t, INTERVAL_SIZE);
1522 copy_properties (source, t); 1535 copy_properties (source, t);
1523 t->parent = parent; 1536 SET_INTERVAL_PARENT (t, parent);
1537 if (! NULL_LEFT_CHILD (source))
1538 t->left = reproduce_tree (source->left, t);
1539 if (! NULL_RIGHT_CHILD (source))
1540 t->right = reproduce_tree (source->right, t);
1541
1542 return t;
1543}
1544
1545static INTERVAL
1546reproduce_tree_obj (source, parent)
1547 INTERVAL source;
1548 Lisp_Object parent;
1549{
1550 register INTERVAL t = make_interval ();
1551
1552 bcopy (source, t, INTERVAL_SIZE);
1553 copy_properties (source, t);
1554 SET_INTERVAL_OBJECT (t, parent);
1524 if (! NULL_LEFT_CHILD (source)) 1555 if (! NULL_LEFT_CHILD (source))
1525 t->left = reproduce_tree (source->left, t); 1556 t->left = reproduce_tree (source->left, t);
1526 if (! NULL_RIGHT_CHILD (source)) 1557 if (! NULL_RIGHT_CHILD (source))
@@ -1654,7 +1685,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1654 { 1685 {
1655 Lisp_Object buf; 1686 Lisp_Object buf;
1656 XSETBUFFER (buf, buffer); 1687 XSETBUFFER (buf, buffer);
1657 BUF_INTERVALS (buffer) = reproduce_tree (source, buf); 1688 BUF_INTERVALS (buffer) = reproduce_tree_obj (source, buf);
1658 BUF_INTERVALS (buffer)->position = 1; 1689 BUF_INTERVALS (buffer)->position = 1;
1659 1690
1660 /* Explicitly free the old tree here? */ 1691 /* Explicitly free the old tree here? */
@@ -1676,7 +1707,7 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
1676 some zero length intervals. Eventually, do something clever 1707 some zero length intervals. Eventually, do something clever
1677 about inserting properly. For now, just waste the old intervals. */ 1708 about inserting properly. For now, just waste the old intervals. */
1678 { 1709 {
1679 BUF_INTERVALS (buffer) = reproduce_tree (source, tree->parent); 1710 BUF_INTERVALS (buffer) = reproduce_tree (source, INTERVAL_PARENT (tree));
1680 BUF_INTERVALS (buffer)->position = 1; 1711 BUF_INTERVALS (buffer)->position = 1;
1681 /* Explicitly free the old tree here. */ 1712 /* Explicitly free the old tree here. */
1682 1713
@@ -2236,7 +2267,7 @@ copy_intervals_to_string (string, buffer, position, length)
2236 if (NULL_INTERVAL_P (interval_copy)) 2267 if (NULL_INTERVAL_P (interval_copy))
2237 return; 2268 return;
2238 2269
2239 interval_copy->parent = (INTERVAL) XFASTINT (string); 2270 SET_INTERVAL_OBJECT (interval_copy, string);
2240 XSTRING (string)->intervals = interval_copy; 2271 XSTRING (string)->intervals = interval_copy;
2241} 2272}
2242 2273
diff --git a/src/intervals.h b/src/intervals.h
index 234df7d4112..eb50d723784 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
22#include "dispextern.h" 22#include "dispextern.h"
23#endif 23#endif
24 24
25#define NULL_INTERVAL 0 25#define NULL_INTERVAL ((INTERVAL)0)
26#define INTERVAL_DEFAULT NULL_INTERVAL 26#define INTERVAL_DEFAULT NULL_INTERVAL
27 27
28/* These are macros for dealing with the interval tree. */ 28/* These are macros for dealing with the interval tree. */
@@ -37,14 +37,13 @@ Boston, MA 02111-1307, USA. */
37 Lisp_String pointer (meaning it points to the owner of this 37 Lisp_String pointer (meaning it points to the owner of this
38 interval tree). */ 38 interval tree). */
39#ifdef NO_UNION_TYPE 39#ifdef NO_UNION_TYPE
40#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL \ 40#define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object)(i)) \
41 || BUFFERP ((Lisp_Object)(i)) \ 41 || STRINGP ((Lisp_Object)(i)))
42 || STRINGP ((Lisp_Object)(i)))
43#else 42#else
44#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL \ 43#define INT_LISPLIKE(i) (BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \
45 || BUFFERP ((Lisp_Object){(EMACS_INT)(i)}) \ 44 || STRINGP ((Lisp_Object){(EMACS_INT)(i)}))
46 || STRINGP ((Lisp_Object){(EMACS_INT)(i)}))
47#endif 45#endif
46#define NULL_INTERVAL_P(i) ((i) == NULL_INTERVAL || INT_LISPLIKE (i))
48 47
49/* True if this interval has no right child. */ 48/* True if this interval has no right child. */
50#define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL) 49#define NULL_RIGHT_CHILD(i) ((i)->right == NULL_INTERVAL)
@@ -56,12 +55,12 @@ Boston, MA 02111-1307, USA. */
56#define NULL_PARENT(i) (NULL_INTERVAL_P ((i)->parent)) 55#define NULL_PARENT(i) (NULL_INTERVAL_P ((i)->parent))
57 56
58/* True if this interval is the left child of some other interval. */ 57/* True if this interval is the left child of some other interval. */
59#define AM_LEFT_CHILD(i) (! NULL_INTERVAL_P ((i)->parent) \ 58#define AM_LEFT_CHILD(i) (! NULL_PARENT (i) \
60 && (i)->parent->left == (i)) 59 && INTERVAL_PARENT (i)->left == (i))
61 60
62/* True if this interval is the right child of some other interval. */ 61/* True if this interval is the right child of some other interval. */
63#define AM_RIGHT_CHILD(i) (! NULL_INTERVAL_P ((i)->parent) \ 62#define AM_RIGHT_CHILD(i) (! NULL_PARENT (i) \
64 && (i)->parent->right == (i)) 63 && INTERVAL_PARENT (i)->right == (i))
65 64
66/* True if this interval has no children. */ 65/* True if this interval has no children. */
67#define LEAF_INTERVAL_P(i) ((i)->left == NULL_INTERVAL \ 66#define LEAF_INTERVAL_P(i) ((i)->left == NULL_INTERVAL \
@@ -103,12 +102,38 @@ Boston, MA 02111-1307, USA. */
103 or having no properties. */ 102 or having no properties. */
104#define DEFAULT_INTERVAL_P(i) (NULL_INTERVAL_P (i) || EQ ((i)->plist, Qnil)) 103#define DEFAULT_INTERVAL_P(i) (NULL_INTERVAL_P (i) || EQ ((i)->plist, Qnil))
105 104
105/* Test what type of parent we have. Three possibilities: another
106 interval, a buffer or string object, or NULL_INTERVAL. */
107#define INTERVAL_HAS_PARENT(i) ((i)->parent && ! INT_LISPLIKE ((i)->parent))
108#define INTERVAL_HAS_OBJECT(i) ((i)->parent && INT_LISPLIKE ((i)->parent))
109
110/* Set/get parent of an interval.
111
112 The choice of macros is dependent on the type needed. Don't add
113 casts to get around this, it will break some development work in
114 progress. */
115#define SET_INTERVAL_PARENT(i,p) ((i)->parent = (p))
116#define SET_INTERVAL_OBJECT(i,o) ((i)->parent = (INTERVAL) XFASTINT (o))
117#define INTERVAL_PARENT(i) ((i)->parent)
118/* Because XSETFASTINT has to be used, this can't simply be
119 value-returning. */
120#define GET_INTERVAL_OBJECT(d,s) XSETFASTINT((d), (EMACS_INT) (s)->parent)
121
122/* Make the parent of D be whatever the parent of S is, regardless of
123 type. This is used when balancing an interval tree. */
124#define COPY_INTERVAL_PARENT(d,s) ((d)->parent = (s)->parent)
125
126/* Get the parent interval, if any, otherwise a null pointer. Useful
127 for walking up to the root in a "for" loop; use this to get the
128 "next" value, and test the result to see if it's NULL_INTERVAL. */
129#define INTERVAL_PARENT_OR_NULL(i) (INTERVAL_HAS_PARENT (i) ? INTERVAL_PARENT (i) : 0)
130
106/* Reset this interval to its vanilla, or no-property state. */ 131/* Reset this interval to its vanilla, or no-property state. */
107#define RESET_INTERVAL(i) \ 132#define RESET_INTERVAL(i) \
108{ \ 133{ \
109 (i)->total_length = (i)->position = 0; \ 134 (i)->total_length = (i)->position = 0; \
110 (i)->left = (i)->right = NULL_INTERVAL; \ 135 (i)->left = (i)->right = NULL_INTERVAL; \
111 (i)->parent = NULL_INTERVAL; \ 136 SET_INTERVAL_PARENT (i, NULL_INTERVAL); \
112 (i)->write_protect = 0; \ 137 (i)->write_protect = 0; \
113 (i)->visible = 0; \ 138 (i)->visible = 0; \
114 (i)->front_sticky = (i)->rear_sticky = 0; \ 139 (i)->front_sticky = (i)->rear_sticky = 0; \
diff --git a/src/syntax.c b/src/syntax.c
index 167e20ebed5..496693f7b23 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -140,14 +140,14 @@ update_syntax_table (charpos, count, init, object)
140 while (!NULL_PARENT (i)) 140 while (!NULL_PARENT (i))
141 { 141 {
142 if (AM_RIGHT_CHILD (i)) 142 if (AM_RIGHT_CHILD (i))
143 i->parent->position = i->position 143 INTERVAL_PARENT (i)->position = i->position
144 - LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */ 144 - LEFT_TOTAL_LENGTH (i) + TOTAL_LENGTH (i) /* right end */
145 - TOTAL_LENGTH (i->parent) 145 - TOTAL_LENGTH (INTERVAL_PARENT (i))
146 + LEFT_TOTAL_LENGTH (i->parent); 146 + LEFT_TOTAL_LENGTH (INTERVAL_PARENT (i));
147 else 147 else
148 i->parent->position = i->position - LEFT_TOTAL_LENGTH (i) 148 INTERVAL_PARENT (i)->position = i->position - LEFT_TOTAL_LENGTH (i)
149 + TOTAL_LENGTH (i); 149 + TOTAL_LENGTH (i);
150 i = i->parent; 150 i = INTERVAL_PARENT (i);
151 } 151 }
152 i = gl_state.forward_i; 152 i = gl_state.forward_i;
153 gl_state.b_property = i->position - 1 - gl_state.offset; 153 gl_state.b_property = i->position - 1 - gl_state.offset;