aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2014-04-19 14:13:26 -0400
committerStefan Monnier2014-04-19 14:13:26 -0400
commitd7b659bb0615d326f79b2ea96b2acd90b816c3c0 (patch)
tree60049dd8d53b55ed2fedee179cdb99fe413ec0f6
parentfe36068f12b959de7c368b7e50cded27e76c0245 (diff)
downloademacs-d7b659bb0615d326f79b2ea96b2acd90b816c3c0.tar.gz
emacs-d7b659bb0615d326f79b2ea96b2acd90b816c3c0.zip
* src/intervals.c (rotate_right, rotate_left): Fix up length computation.
Also change identifiers to match the comments, and add more assertions. Fixes: debbugs:16234
-rw-r--r--src/ChangeLog6
-rw-r--r--src/intervals.c88
2 files changed, 54 insertions, 40 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e7b8384b431..c42679d54f4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12014-04-19 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * intervals.c (rotate_right, rotate_left): Fix up length computation.
4 Also change identifiers to match the comments, and add more assertions
5 (bug#16234).
6
12014-04-18 Eli Zaretskii <eliz@gnu.org> 72014-04-18 Eli Zaretskii <eliz@gnu.org>
2 8
3 * xdisp.c (insert_left_trunc_glyphs): Ensure the left truncation 9 * xdisp.c (insert_left_trunc_glyphs): Ensure the left truncation
diff --git a/src/intervals.c b/src/intervals.c
index 703c0cefbd5..8544ed94b79 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -332,39 +332,43 @@ root_interval (INTERVAL interval)
332*/ 332*/
333 333
334static INTERVAL 334static INTERVAL
335rotate_right (INTERVAL interval) 335rotate_right (INTERVAL A)
336{ 336{
337 INTERVAL i; 337 INTERVAL B = A->left;
338 INTERVAL B = interval->left; 338 INTERVAL c = B->right;
339 ptrdiff_t old_total = interval->total_length; 339 ptrdiff_t old_total = A->total_length;
340
341 eassert (old_total > 0);
342 eassert (old_total
343 > TOTAL_LENGTH (B) + TOTAL_LENGTH (A->right));
344 eassert (TOTAL_LENGTH (B)
345 > TOTAL_LENGTH (B->left) + TOTAL_LENGTH (c));
340 346
341 /* Deal with any Parent of A; make it point to B. */ 347 /* Deal with any Parent of A; make it point to B. */
342 if (! ROOT_INTERVAL_P (interval)) 348 if (! ROOT_INTERVAL_P (A))
343 { 349 {
344 if (AM_LEFT_CHILD (interval)) 350 if (AM_LEFT_CHILD (A))
345 set_interval_left (INTERVAL_PARENT (interval), B); 351 set_interval_left (INTERVAL_PARENT (A), B);
346 else 352 else
347 set_interval_right (INTERVAL_PARENT (interval), B); 353 set_interval_right (INTERVAL_PARENT (A), B);
348 } 354 }
349 copy_interval_parent (B, interval); 355 copy_interval_parent (B, A);
350 356
351 /* Make B the parent of A */ 357 /* Make B the parent of A. */
352 i = B->right; 358 set_interval_right (B, A);
353 set_interval_right (B, interval); 359 set_interval_parent (A, B);
354 set_interval_parent (interval, B);
355 360
356 /* Make A point to c */ 361 /* Make A point to c. */
357 set_interval_left (interval, i); 362 set_interval_left (A, c);
358 if (i) 363 if (c)
359 set_interval_parent (i, interval); 364 set_interval_parent (c, A);
360 365
361 /* A's total length is decreased by the length of B and its left child. */ 366 /* A's total length is decreased by the length of B and its left child. */
362 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval); 367 A->total_length -= B->total_length - TOTAL_LENGTH (c);
363 eassert (TOTAL_LENGTH (interval) >= 0); 368 eassert (TOTAL_LENGTH (A) > 0);
364 369
365 /* B must have the same total length of A. */ 370 /* B must have the same total length of A. */
366 B->total_length = old_total; 371 B->total_length = old_total;
367 eassert (TOTAL_LENGTH (B) >= 0);
368 372
369 return B; 373 return B;
370} 374}
@@ -379,39 +383,43 @@ rotate_right (INTERVAL interval)
379*/ 383*/
380 384
381static INTERVAL 385static INTERVAL
382rotate_left (INTERVAL interval) 386rotate_left (INTERVAL A)
383{ 387{
384 INTERVAL i; 388 INTERVAL B = A->right;
385 INTERVAL B = interval->right; 389 INTERVAL c = B->left;
386 ptrdiff_t old_total = interval->total_length; 390 ptrdiff_t old_total = A->total_length;
391
392 eassert (old_total > 0);
393 eassert (old_total
394 > TOTAL_LENGTH (B) + TOTAL_LENGTH (A->left));
395 eassert (TOTAL_LENGTH (B)
396 > TOTAL_LENGTH (B->right) + TOTAL_LENGTH (c));
387 397
388 /* Deal with any parent of A; make it point to B. */ 398 /* Deal with any parent of A; make it point to B. */
389 if (! ROOT_INTERVAL_P (interval)) 399 if (! ROOT_INTERVAL_P (A))
390 { 400 {
391 if (AM_LEFT_CHILD (interval)) 401 if (AM_LEFT_CHILD (A))
392 set_interval_left (INTERVAL_PARENT (interval), B); 402 set_interval_left (INTERVAL_PARENT (A), B);
393 else 403 else
394 set_interval_right (INTERVAL_PARENT (interval), B); 404 set_interval_right (INTERVAL_PARENT (A), B);
395 } 405 }
396 copy_interval_parent (B, interval); 406 copy_interval_parent (B, A);
397 407
398 /* Make B the parent of A */ 408 /* Make B the parent of A. */
399 i = B->left; 409 set_interval_left (B, A);
400 set_interval_left (B, interval); 410 set_interval_parent (A, B);
401 set_interval_parent (interval, B);
402 411
403 /* Make A point to c */ 412 /* Make A point to c. */
404 set_interval_right (interval, i); 413 set_interval_right (A, c);
405 if (i) 414 if (c)
406 set_interval_parent (i, interval); 415 set_interval_parent (c, A);
407 416
408 /* A's total length is decreased by the length of B and its right child. */ 417 /* A's total length is decreased by the length of B and its right child. */
409 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); 418 A->total_length -= B->total_length - TOTAL_LENGTH (c);
410 eassert (TOTAL_LENGTH (interval) >= 0); 419 eassert (TOTAL_LENGTH (A) > 0);
411 420
412 /* B must have the same total length of A. */ 421 /* B must have the same total length of A. */
413 B->total_length = old_total; 422 B->total_length = old_total;
414 eassert (TOTAL_LENGTH (B) >= 0);
415 423
416 return B; 424 return B;
417} 425}