From 988f45a75b745dc1fee6315749ddb48f00b000eb Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Sun, 20 Sep 2020 12:24:16 +0200 Subject: [PATCH] Fix printing of hash tables with removed elements * src/print.c (print_vectorlike): Keep track of the actual number of elements printed rather than attempting to use hash bucket indices (bug#38892). --- src/print.c | 17 ++++++++++++----- test/src/print-tests.el | 28 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/print.c b/src/print.c index bd1769144e0..0ecc98f37bf 100644 --- a/src/print.c +++ b/src/print.c @@ -1590,27 +1590,34 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, /* Print the data here as a plist. */ ptrdiff_t real_size = HASH_TABLE_SIZE (h); - ptrdiff_t size = real_size; + ptrdiff_t size = h->count; /* Don't print more elements than the specified maximum. */ if (FIXNATP (Vprint_length) && XFIXNAT (Vprint_length) < size) size = XFIXNAT (Vprint_length); printchar ('(', printcharfun); - for (ptrdiff_t i = 0; i < size; i++) + ptrdiff_t j = 0; + for (ptrdiff_t i = 0; i < real_size; i++) { Lisp_Object key = HASH_KEY (h, i); if (!EQ (key, Qunbound)) { - if (i) printchar (' ', printcharfun); + if (j++) printchar (' ', printcharfun); print_object (key, printcharfun, escapeflag); printchar (' ', printcharfun); print_object (HASH_VALUE (h, i), printcharfun, escapeflag); + if (j == size) + break; } } - if (size < real_size) - print_c_string (" ...", printcharfun); + if (j < h->count) + { + if (j) + printchar (' ', printcharfun); + print_c_string ("...", printcharfun); + } print_c_string ("))", printcharfun); } diff --git a/test/src/print-tests.el b/test/src/print-tests.el index 42e5962137c..51ef16dd85a 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el @@ -355,5 +355,33 @@ otherwise, use a different charset." (setcdr err err) (should-error (error-message-string err) :type 'circular-list))) +(print-tests--deftest print-hash-table-test () + (should + (string-match + "data (2 3)" + (let ((h (make-hash-table))) + (puthash 1 2 h) + (puthash 2 3 h) + (remhash 1 h) + (format "%S" h)))) + + (should + (string-match + "data ()" + (let ((h (make-hash-table))) + (let ((print-length 0)) + (format "%S" h))))) + + (should + (string-match + "data (99 99" + (let ((h (make-hash-table))) + (dotimes (i 100) + (puthash i i h)) + (dotimes (i 99) + (remhash i h)) + (let ((print-length 1)) + (format "%S" h)))))) + (provide 'print-tests) ;;; print-tests.el ends here -- 2.39.2