aboutsummaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-05-23 16:34:29 +0200
committerMattias EngdegÄrd2022-05-23 16:50:00 +0200
commit5a1a67a2562fab77856b48a38d89713d7f2c96d7 (patch)
treed1d73336589a33f9a6d61407c5f33c34a34d7289 /test/src
parentb3e4526f21749305b7f6b3f4a18e0df7cd0044a4 (diff)
downloademacs-5a1a67a2562fab77856b48a38d89713d7f2c96d7.tar.gz
emacs-5a1a67a2562fab77856b48a38d89713d7f2c96d7.zip
Less wrong printed circular list tail index (bug#55395)
When printing a circular list and `print-circle` is nil, use a somewhat more meaningful ". #N" tail index. The previous method for calculating that index was based on Floyd circularity detection being used so it had been broken ever since the change to Brent's algorithm. The new index is correct with respect to the start of the list itself which is what it used to be before being completely broken. It does not take into account the nesting depth of the list context. * src/print.c (struct print_stack_entry, print_object): Keep track of the tortoise index (which is cheap) instead of trying to derive it from the printed element index. * test/src/print-tests.el (print-test-rho, print-circular): New test.
Diffstat (limited to 'test/src')
-rw-r--r--test/src/print-tests.el46
1 files changed, 46 insertions, 0 deletions
diff --git a/test/src/print-tests.el b/test/src/print-tests.el
index 1b28fd19ee7..6ff7e997837 100644
--- a/test/src/print-tests.el
+++ b/test/src/print-tests.el
@@ -484,5 +484,51 @@ otherwise, use a different charset."
484 (apply #'concat suffix)))) 484 (apply #'concat suffix))))
485 (should (equal (prin1-to-string x) expected)))))) 485 (should (equal (prin1-to-string x) expected))))))
486 486
487(defun print-test-rho (lead loop)
488 "A circular iota list with LEAD elements followed by LOOP in circle."
489 (let ((l (number-sequence 1 (+ lead loop))))
490 (setcdr (nthcdr (+ lead loop -1) l) (nthcdr lead l))
491 l))
492
493(ert-deftest print-circular ()
494 ;; Check printing of rho-shaped circular lists such as (1 2 3 4 5 4 5 4 . #6)
495 ;; when `print-circle' is nil. The exact output may differ since the number
496 ;; of elements printed of the looping part can vary depending on when the
497 ;; circularity was detected.
498 (dotimes (lead 7)
499 (ert-info ((prin1-to-string lead) :prefix "lead: ")
500 (dolist (loop (number-sequence 1 7))
501 (ert-info ((prin1-to-string loop) :prefix "loop: ")
502 (let* ((rho (print-test-rho lead loop))
503 (print-circle nil)
504 (str (prin1-to-string rho)))
505 (should (string-match (rx "("
506 (group (+ (+ digit) " "))
507 ". #" (group (+ digit)) ")")
508 str))
509 (let* ((g1 (match-string 1 str))
510 (g2 (match-string 2 str))
511 (numbers (mapcar #'string-to-number (split-string g1)))
512 (loopback-index (string-to-number g2)))
513 ;; Split the numbers in the lead and loop part.
514 (should (< lead (length numbers)))
515 (should (<= lead loopback-index))
516 (should (< loopback-index (length numbers)))
517 (let ((lead-part (butlast numbers (- (length numbers) lead)))
518 (loop-part (nthcdr lead numbers)))
519 ;; The lead part must match exactly.
520 (should (equal lead-part (number-sequence 1 lead)))
521 ;; The loop part is at least LOOP long: make sure it matches.
522 (should (>= (length loop-part) loop))
523 (let ((expected-loop-part
524 (mapcar (lambda (x) (+ lead 1 (% x loop)))
525 (number-sequence 0 (1- (length loop-part))))))
526 (should (equal loop-part expected-loop-part))
527 ;; The loopback index must match the length of the
528 ;; loop part.
529 (should (equal (% (- (length numbers) loopback-index) loop)
530 0)))))))))))
531
532
487(provide 'print-tests) 533(provide 'print-tests)
488;;; print-tests.el ends here 534;;; print-tests.el ends here