diff options
| author | Richard M. Stallman | 2003-04-06 20:32:52 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2003-04-06 20:32:52 +0000 |
| commit | 727fec2d40c0eaffc9f48e9d2da0cb33c5ccff0f (patch) | |
| tree | 1f2839ee002a6e0db18cf7a35dd1d044ebd9f645 | |
| parent | e5a9c92a9f5d70d1beda4337d00b57f7d2bc7dca (diff) | |
| download | emacs-727fec2d40c0eaffc9f48e9d2da0cb33c5ccff0f.tar.gz emacs-727fec2d40c0eaffc9f48e9d2da0cb33c5ccff0f.zip | |
Add many calls to CHECK_TOTAL_LENGTH.
(set_intervals_multibyte_1): When becoming
multibyte, adjust right and left child sizes to a whole set of
characters. If an interval gets zero total-length, delete it.
If an interval consists of just its children, delete one of them.
| -rw-r--r-- | src/intervals.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/intervals.c b/src/intervals.c index 3b8327b96d8..c393628dc4f 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -75,12 +75,14 @@ create_root_interval (parent) | |||
| 75 | { | 75 | { |
| 76 | new->total_length = (BUF_Z (XBUFFER (parent)) | 76 | new->total_length = (BUF_Z (XBUFFER (parent)) |
| 77 | - BUF_BEG (XBUFFER (parent))); | 77 | - BUF_BEG (XBUFFER (parent))); |
| 78 | CHECK_TOTAL_LENGTH (new); | ||
| 78 | BUF_INTERVALS (XBUFFER (parent)) = new; | 79 | BUF_INTERVALS (XBUFFER (parent)) = new; |
| 79 | new->position = 1; | 80 | new->position = 1; |
| 80 | } | 81 | } |
| 81 | else if (STRINGP (parent)) | 82 | else if (STRINGP (parent)) |
| 82 | { | 83 | { |
| 83 | new->total_length = SCHARS (parent); | 84 | new->total_length = SCHARS (parent); |
| 85 | CHECK_TOTAL_LENGTH (new); | ||
| 84 | STRING_SET_INTERVALS (parent, new); | 86 | STRING_SET_INTERVALS (parent, new); |
| 85 | new->position = 0; | 87 | new->position = 0; |
| 86 | } | 88 | } |
| @@ -338,9 +340,11 @@ rotate_right (interval) | |||
| 338 | 340 | ||
| 339 | /* A's total length is decreased by the length of B and its left child. */ | 341 | /* 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); | 342 | interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval); |
| 343 | CHECK_TOTAL_LENGTH (interval); | ||
| 341 | 344 | ||
| 342 | /* B must have the same total length of A. */ | 345 | /* B must have the same total length of A. */ |
| 343 | B->total_length = old_total; | 346 | B->total_length = old_total; |
| 347 | CHECK_TOTAL_LENGTH (B); | ||
| 344 | 348 | ||
| 345 | return B; | 349 | return B; |
| 346 | } | 350 | } |
| @@ -384,9 +388,11 @@ rotate_left (interval) | |||
| 384 | 388 | ||
| 385 | /* 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. */ |
| 386 | interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); | 390 | interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); |
| 391 | CHECK_TOTAL_LENGTH (interval); | ||
| 387 | 392 | ||
| 388 | /* B must have the same total length of A. */ | 393 | /* B must have the same total length of A. */ |
| 389 | B->total_length = old_total; | 394 | B->total_length = old_total; |
| 395 | CHECK_TOTAL_LENGTH (B); | ||
| 390 | 396 | ||
| 391 | return B; | 397 | return B; |
| 392 | } | 398 | } |
| @@ -405,6 +411,7 @@ balance_an_interval (i) | |||
| 405 | old_diff = LEFT_TOTAL_LENGTH (i) - RIGHT_TOTAL_LENGTH (i); | 411 | old_diff = LEFT_TOTAL_LENGTH (i) - RIGHT_TOTAL_LENGTH (i); |
| 406 | if (old_diff > 0) | 412 | if (old_diff > 0) |
| 407 | { | 413 | { |
| 414 | /* Since the left child is longer, there must be one. */ | ||
| 408 | new_diff = i->total_length - i->left->total_length | 415 | new_diff = i->total_length - i->left->total_length |
| 409 | + RIGHT_TOTAL_LENGTH (i->left) - LEFT_TOTAL_LENGTH (i->left); | 416 | + RIGHT_TOTAL_LENGTH (i->left) - LEFT_TOTAL_LENGTH (i->left); |
| 410 | if (abs (new_diff) >= old_diff) | 417 | if (abs (new_diff) >= old_diff) |
| @@ -414,6 +421,7 @@ balance_an_interval (i) | |||
| 414 | } | 421 | } |
| 415 | else if (old_diff < 0) | 422 | else if (old_diff < 0) |
| 416 | { | 423 | { |
| 424 | /* Since the right child is longer, there must be one. */ | ||
| 417 | new_diff = i->total_length - i->right->total_length | 425 | new_diff = i->total_length - i->right->total_length |
| 418 | + LEFT_TOTAL_LENGTH (i->right) - RIGHT_TOTAL_LENGTH (i->right); | 426 | + LEFT_TOTAL_LENGTH (i->right) - RIGHT_TOTAL_LENGTH (i->right); |
| 419 | if (abs (new_diff) >= -old_diff) | 427 | if (abs (new_diff) >= -old_diff) |
| @@ -514,6 +522,7 @@ split_interval_right (interval, offset) | |||
| 514 | { | 522 | { |
| 515 | interval->right = new; | 523 | interval->right = new; |
| 516 | new->total_length = new_length; | 524 | new->total_length = new_length; |
| 525 | CHECK_TOTAL_LENGTH (new); | ||
| 517 | } | 526 | } |
| 518 | else | 527 | else |
| 519 | { | 528 | { |
| @@ -522,6 +531,7 @@ split_interval_right (interval, offset) | |||
| 522 | SET_INTERVAL_PARENT (interval->right, new); | 531 | SET_INTERVAL_PARENT (interval->right, new); |
| 523 | interval->right = new; | 532 | interval->right = new; |
| 524 | new->total_length = new_length + new->right->total_length; | 533 | new->total_length = new_length + new->right->total_length; |
| 534 | CHECK_TOTAL_LENGTH (new); | ||
| 525 | balance_an_interval (new); | 535 | balance_an_interval (new); |
| 526 | } | 536 | } |
| 527 | 537 | ||
| @@ -559,6 +569,7 @@ split_interval_left (interval, offset) | |||
| 559 | { | 569 | { |
| 560 | interval->left = new; | 570 | interval->left = new; |
| 561 | new->total_length = new_length; | 571 | new->total_length = new_length; |
| 572 | CHECK_TOTAL_LENGTH (new); | ||
| 562 | } | 573 | } |
| 563 | else | 574 | else |
| 564 | { | 575 | { |
| @@ -567,6 +578,7 @@ split_interval_left (interval, offset) | |||
| 567 | SET_INTERVAL_PARENT (new->left, new); | 578 | SET_INTERVAL_PARENT (new->left, new); |
| 568 | interval->left = new; | 579 | interval->left = new; |
| 569 | new->total_length = new_length + new->left->total_length; | 580 | new->total_length = new_length + new->left->total_length; |
| 581 | CHECK_TOTAL_LENGTH (new); | ||
| 570 | balance_an_interval (new); | 582 | balance_an_interval (new); |
| 571 | } | 583 | } |
| 572 | 584 | ||
| @@ -828,6 +840,7 @@ adjust_intervals_for_insertion (tree, position, length) | |||
| 828 | if (relative_position <= LEFT_TOTAL_LENGTH (this)) | 840 | if (relative_position <= LEFT_TOTAL_LENGTH (this)) |
| 829 | { | 841 | { |
| 830 | this->total_length += length; | 842 | this->total_length += length; |
| 843 | CHECK_TOTAL_LENGTH (this); | ||
| 831 | this = this->left; | 844 | this = this->left; |
| 832 | } | 845 | } |
| 833 | else if (relative_position > (TOTAL_LENGTH (this) | 846 | else if (relative_position > (TOTAL_LENGTH (this) |
| @@ -836,6 +849,7 @@ adjust_intervals_for_insertion (tree, position, length) | |||
| 836 | relative_position -= (TOTAL_LENGTH (this) | 849 | relative_position -= (TOTAL_LENGTH (this) |
| 837 | - RIGHT_TOTAL_LENGTH (this)); | 850 | - RIGHT_TOTAL_LENGTH (this)); |
| 838 | this->total_length += length; | 851 | this->total_length += length; |
| 852 | CHECK_TOTAL_LENGTH (this); | ||
| 839 | this = this->right; | 853 | this = this->right; |
| 840 | } | 854 | } |
| 841 | else | 855 | else |
| @@ -843,6 +857,7 @@ adjust_intervals_for_insertion (tree, position, length) | |||
| 843 | /* If we are to use zero-length intervals as buffer pointers, | 857 | /* If we are to use zero-length intervals as buffer pointers, |
| 844 | then this code will have to change. */ | 858 | then this code will have to change. */ |
| 845 | this->total_length += length; | 859 | this->total_length += length; |
| 860 | CHECK_TOTAL_LENGTH (this); | ||
| 846 | this->position = LEFT_TOTAL_LENGTH (this) | 861 | this->position = LEFT_TOTAL_LENGTH (this) |
| 847 | + position - relative_position + 1; | 862 | + position - relative_position + 1; |
| 848 | return tree; | 863 | return tree; |
| @@ -987,6 +1002,7 @@ adjust_intervals_for_insertion (tree, position, length) | |||
| 987 | for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) | 1002 | for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) |
| 988 | { | 1003 | { |
| 989 | temp->total_length += length; | 1004 | temp->total_length += length; |
| 1005 | CHECK_TOTAL_LENGTH (temp); | ||
| 990 | temp = balance_possible_root_interval (temp); | 1006 | temp = balance_possible_root_interval (temp); |
| 991 | } | 1007 | } |
| 992 | 1008 | ||
| @@ -1043,6 +1059,7 @@ adjust_intervals_for_insertion (tree, position, length) | |||
| 1043 | for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) | 1059 | for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) |
| 1044 | { | 1060 | { |
| 1045 | temp->total_length += length; | 1061 | temp->total_length += length; |
| 1062 | CHECK_TOTAL_LENGTH (temp); | ||
| 1046 | temp = balance_possible_root_interval (temp); | 1063 | temp = balance_possible_root_interval (temp); |
| 1047 | } | 1064 | } |
| 1048 | } | 1065 | } |
| @@ -1247,6 +1264,7 @@ delete_node (i) | |||
| 1247 | this = this->left; | 1264 | this = this->left; |
| 1248 | this->total_length += migrate_amt; | 1265 | this->total_length += migrate_amt; |
| 1249 | } | 1266 | } |
| 1267 | CHECK_TOTAL_LENGTH (this); | ||
| 1250 | this->left = migrate; | 1268 | this->left = migrate; |
| 1251 | SET_INTERVAL_PARENT (migrate, this); | 1269 | SET_INTERVAL_PARENT (migrate, this); |
| 1252 | 1270 | ||
| @@ -1331,6 +1349,7 @@ interval_deletion_adjustment (tree, from, amount) | |||
| 1331 | relative_position, | 1349 | relative_position, |
| 1332 | amount); | 1350 | amount); |
| 1333 | tree->total_length -= subtract; | 1351 | tree->total_length -= subtract; |
| 1352 | CHECK_TOTAL_LENGTH (tree); | ||
| 1334 | return subtract; | 1353 | return subtract; |
| 1335 | } | 1354 | } |
| 1336 | /* Right branch */ | 1355 | /* Right branch */ |
| @@ -1345,6 +1364,7 @@ interval_deletion_adjustment (tree, from, amount) | |||
| 1345 | relative_position, | 1364 | relative_position, |
| 1346 | amount); | 1365 | amount); |
| 1347 | tree->total_length -= subtract; | 1366 | tree->total_length -= subtract; |
| 1367 | CHECK_TOTAL_LENGTH (tree); | ||
| 1348 | return subtract; | 1368 | return subtract; |
| 1349 | } | 1369 | } |
| 1350 | /* Here -- this node. */ | 1370 | /* Here -- this node. */ |
| @@ -1359,6 +1379,7 @@ interval_deletion_adjustment (tree, from, amount) | |||
| 1359 | amount = my_amount; | 1379 | amount = my_amount; |
| 1360 | 1380 | ||
| 1361 | tree->total_length -= amount; | 1381 | tree->total_length -= amount; |
| 1382 | CHECK_TOTAL_LENGTH (tree); | ||
| 1362 | if (LENGTH (tree) == 0) | 1383 | if (LENGTH (tree) == 0) |
| 1363 | delete_interval (tree); | 1384 | delete_interval (tree); |
| 1364 | 1385 | ||
| @@ -1402,6 +1423,7 @@ adjust_intervals_for_deletion (buffer, start, length) | |||
| 1402 | if (ONLY_INTERVAL_P (tree)) | 1423 | if (ONLY_INTERVAL_P (tree)) |
| 1403 | { | 1424 | { |
| 1404 | tree->total_length -= length; | 1425 | tree->total_length -= length; |
| 1426 | CHECK_TOTAL_LENGTH (tree); | ||
| 1405 | return; | 1427 | return; |
| 1406 | } | 1428 | } |
| 1407 | 1429 | ||
| @@ -1457,6 +1479,7 @@ merge_interval_right (i) | |||
| 1457 | 1479 | ||
| 1458 | /* Zero out this interval. */ | 1480 | /* Zero out this interval. */ |
| 1459 | i->total_length -= absorb; | 1481 | i->total_length -= absorb; |
| 1482 | CHECK_TOTAL_LENGTH (i); | ||
| 1460 | 1483 | ||
| 1461 | /* Find the succeeding interval. */ | 1484 | /* Find the succeeding interval. */ |
| 1462 | if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb | 1485 | if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb |
| @@ -1466,10 +1489,12 @@ merge_interval_right (i) | |||
| 1466 | while (! NULL_LEFT_CHILD (successor)) | 1489 | while (! NULL_LEFT_CHILD (successor)) |
| 1467 | { | 1490 | { |
| 1468 | successor->total_length += absorb; | 1491 | successor->total_length += absorb; |
| 1492 | CHECK_TOTAL_LENGTH (successor); | ||
| 1469 | successor = successor->left; | 1493 | successor = successor->left; |
| 1470 | } | 1494 | } |
| 1471 | 1495 | ||
| 1472 | successor->total_length += absorb; | 1496 | successor->total_length += absorb; |
| 1497 | CHECK_TOTAL_LENGTH (successor); | ||
| 1473 | delete_interval (i); | 1498 | delete_interval (i); |
| 1474 | return successor; | 1499 | return successor; |
| 1475 | } | 1500 | } |
| @@ -1487,6 +1512,7 @@ merge_interval_right (i) | |||
| 1487 | 1512 | ||
| 1488 | successor = INTERVAL_PARENT (successor); | 1513 | successor = INTERVAL_PARENT (successor); |
| 1489 | successor->total_length -= absorb; | 1514 | successor->total_length -= absorb; |
| 1515 | CHECK_TOTAL_LENGTH (successor); | ||
| 1490 | } | 1516 | } |
| 1491 | 1517 | ||
| 1492 | /* This must be the rightmost or last interval and cannot | 1518 | /* This must be the rightmost or last interval and cannot |
| @@ -1510,6 +1536,7 @@ merge_interval_left (i) | |||
| 1510 | 1536 | ||
| 1511 | /* Zero out this interval. */ | 1537 | /* Zero out this interval. */ |
| 1512 | i->total_length -= absorb; | 1538 | i->total_length -= absorb; |
| 1539 | CHECK_TOTAL_LENGTH (i); | ||
| 1513 | 1540 | ||
| 1514 | /* Find the preceding interval. */ | 1541 | /* Find the preceding interval. */ |
| 1515 | if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down, | 1542 | if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down, |
| @@ -1519,10 +1546,12 @@ merge_interval_left (i) | |||
| 1519 | while (! NULL_RIGHT_CHILD (predecessor)) | 1546 | while (! NULL_RIGHT_CHILD (predecessor)) |
| 1520 | { | 1547 | { |
| 1521 | predecessor->total_length += absorb; | 1548 | predecessor->total_length += absorb; |
| 1549 | CHECK_TOTAL_LENGTH (predecessor); | ||
| 1522 | predecessor = predecessor->right; | 1550 | predecessor = predecessor->right; |
| 1523 | } | 1551 | } |
| 1524 | 1552 | ||
| 1525 | predecessor->total_length += absorb; | 1553 | predecessor->total_length += absorb; |
| 1554 | CHECK_TOTAL_LENGTH (predecessor); | ||
| 1526 | delete_interval (i); | 1555 | delete_interval (i); |
| 1527 | return predecessor; | 1556 | return predecessor; |
| 1528 | } | 1557 | } |
| @@ -1540,6 +1569,7 @@ merge_interval_left (i) | |||
| 1540 | 1569 | ||
| 1541 | predecessor = INTERVAL_PARENT (predecessor); | 1570 | predecessor = INTERVAL_PARENT (predecessor); |
| 1542 | predecessor->total_length -= absorb; | 1571 | predecessor->total_length -= absorb; |
| 1572 | CHECK_TOTAL_LENGTH (predecessor); | ||
| 1543 | } | 1573 | } |
| 1544 | 1574 | ||
| 1545 | /* This must be the leftmost or first interval and cannot | 1575 | /* This must be the leftmost or first interval and cannot |
| @@ -2354,6 +2384,7 @@ copy_intervals (tree, start, length) | |||
| 2354 | new->position = 0; | 2384 | new->position = 0; |
| 2355 | got = (LENGTH (i) - (start - i->position)); | 2385 | got = (LENGTH (i) - (start - i->position)); |
| 2356 | new->total_length = length; | 2386 | new->total_length = length; |
| 2387 | CHECK_TOTAL_LENGTH (new); | ||
| 2357 | copy_properties (i, new); | 2388 | copy_properties (i, new); |
| 2358 | 2389 | ||
| 2359 | t = new; | 2390 | t = new; |
| @@ -2440,6 +2471,13 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte) | |||
| 2440 | i->total_length = end - start; | 2471 | i->total_length = end - start; |
| 2441 | else | 2472 | else |
| 2442 | i->total_length = end_byte - start_byte; | 2473 | i->total_length = end_byte - start_byte; |
| 2474 | CHECK_TOTAL_LENGTH (i); | ||
| 2475 | |||
| 2476 | if (TOTAL_LENGTH (i) == 0) | ||
| 2477 | { | ||
| 2478 | delete_interval (i); | ||
| 2479 | return; | ||
| 2480 | } | ||
| 2443 | 2481 | ||
| 2444 | /* Recursively fix the length of the subintervals. */ | 2482 | /* Recursively fix the length of the subintervals. */ |
| 2445 | if (i->left) | 2483 | if (i->left) |
| @@ -2448,8 +2486,23 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte) | |||
| 2448 | 2486 | ||
| 2449 | if (multi_flag) | 2487 | if (multi_flag) |
| 2450 | { | 2488 | { |
| 2489 | int temp; | ||
| 2451 | left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i); | 2490 | left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i); |
| 2452 | left_end = BYTE_TO_CHAR (left_end_byte); | 2491 | left_end = BYTE_TO_CHAR (left_end_byte); |
| 2492 | |||
| 2493 | temp = CHAR_TO_BYTE (left_end); | ||
| 2494 | |||
| 2495 | /* If LEFT_END_BYTE is in the middle of a character, | ||
| 2496 | adjust it and LEFT_END to a char boundary. */ | ||
| 2497 | if (left_end_byte > temp) | ||
| 2498 | { | ||
| 2499 | left_end_byte = temp; | ||
| 2500 | } | ||
| 2501 | if (left_end_byte < temp) | ||
| 2502 | { | ||
| 2503 | left_end--; | ||
| 2504 | left_end_byte = CHAR_TO_BYTE (left_end); | ||
| 2505 | } | ||
| 2453 | } | 2506 | } |
| 2454 | else | 2507 | else |
| 2455 | { | 2508 | { |
| @@ -2466,8 +2519,24 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte) | |||
| 2466 | 2519 | ||
| 2467 | if (multi_flag) | 2520 | if (multi_flag) |
| 2468 | { | 2521 | { |
| 2522 | int temp; | ||
| 2523 | |||
| 2469 | right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i); | 2524 | right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i); |
| 2470 | right_start = BYTE_TO_CHAR (right_start_byte); | 2525 | right_start = BYTE_TO_CHAR (right_start_byte); |
| 2526 | |||
| 2527 | /* If RIGHT_START_BYTE is in the middle of a character, | ||
| 2528 | adjust it and RIGHT_START to a char boundary. */ | ||
| 2529 | temp = CHAR_TO_BYTE (right_start); | ||
| 2530 | |||
| 2531 | if (right_start_byte < temp) | ||
| 2532 | { | ||
| 2533 | right_start_byte = temp; | ||
| 2534 | } | ||
| 2535 | if (right_start_byte > temp) | ||
| 2536 | { | ||
| 2537 | right_start++; | ||
| 2538 | right_start_byte = CHAR_TO_BYTE (right_start); | ||
| 2539 | } | ||
| 2471 | } | 2540 | } |
| 2472 | else | 2541 | else |
| 2473 | { | 2542 | { |
| @@ -2479,6 +2548,25 @@ set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte) | |||
| 2479 | right_start, right_start_byte, | 2548 | right_start, right_start_byte, |
| 2480 | end, end_byte); | 2549 | end, end_byte); |
| 2481 | } | 2550 | } |
| 2551 | |||
| 2552 | /* Rounding to char boundaries can theoretically ake this interval | ||
| 2553 | spurious. If so, delete one child, and copy its property list | ||
| 2554 | to this interval. */ | ||
| 2555 | if (LEFT_TOTAL_LENGTH (i) + RIGHT_TOTAL_LENGTH (i) >= TOTAL_LENGTH (i)) | ||
| 2556 | { | ||
| 2557 | if ((i)->left) | ||
| 2558 | { | ||
| 2559 | (i)->plist = (i)->left->plist; | ||
| 2560 | (i)->left->total_length = 0; | ||
| 2561 | delete_interval ((i)->left); | ||
| 2562 | } | ||
| 2563 | else | ||
| 2564 | { | ||
| 2565 | (i)->plist = (i)->right->plist; | ||
| 2566 | (i)->right->total_length = 0; | ||
| 2567 | delete_interval ((i)->right); | ||
| 2568 | } | ||
| 2569 | } | ||
| 2482 | } | 2570 | } |
| 2483 | 2571 | ||
| 2484 | /* Update the intervals of the current buffer | 2572 | /* Update the intervals of the current buffer |