diff options
author | Mattias EngdegÄrd <mattiase@acm.org> | 2023-03-12 17:00:25 +0100 |
---|---|---|
committer | Mattias EngdegÄrd <mattiase@acm.org> | 2023-03-12 18:12:18 +0100 |
commit | 75f04848a653e70f12f0e5a62b756c5bba0dd204 (patch) | |
tree | d0d857342f3e9078e9e0bec82c1951ce79d17e72 /lisp/subr.el | |
parent | f5f13495f5dac4148c1da8b0ba18c22daf77bb04 (diff) | |
download | emacs-75f04848a653e70f12f0e5a62b756c5bba0dd204.tar.gz |
Repair and speed up safe-copy-tree and make it internal (bug#61962)
There is no particular requirement for safe-copy-tree so let's make it
internal for now. The new implementation is faster and more correct.
* doc/lispref/lists.texi (Building Lists):
* etc/NEWS: Remove doc and announcement.
* lisp/subr.el (safe-copy-tree--seen, safe-copy-tree--1)
(safe-copy-tree): Remove old version.
* lisp/emacs-lisp/bytecomp.el (bytecomp--copy-tree-seen)
(bytecomp--copy-tree-1, bytecomp--copy-tree): Add new version.
(byte-compile-initial-macro-environment): Use it.
* test/lisp/subr-tests.el (subr--safe-copy-tree):
* test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp--copy-tree):
Move and improve tests.
Diffstat (limited to 'lisp/subr.el')
-rw-r--r-- | lisp/subr.el | 55 |
1 files changed, 0 insertions, 55 deletions
diff --git a/lisp/subr.el b/lisp/subr.el index 40bec544b73..8aedce934d1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -846,61 +846,6 @@ argument VECP, this copies vectors as well as conses." tree) tree))) -(defvar safe-copy-tree--seen nil - "A hash table for conses/vectors/records already seen by safe-copy-tree-1. -Its key is a cons or vector/record seen by the algorithm, and its -value is the corresponding cons/vector/record in the copy.") - -(defun safe-copy-tree--1 (tree &optional vecp) - "Make a copy of TREE, taking circular structure into account. -If TREE is a cons cell, this recursively copies both its car and its cdr. -Contrast to `copy-sequence', which copies only along the cdrs. With second -argument VECP, this copies vectors and records as well as conses." - (cond - ((gethash tree safe-copy-tree--seen)) - ((consp tree) - (let* ((result (cons (car tree) (cdr tree))) - (newcons result) - hash) - (while (and (not hash) (consp tree)) - (if (setq hash (gethash tree safe-copy-tree--seen)) - (setq newcons hash) - (puthash tree newcons safe-copy-tree--seen)) - (setq tree newcons) - (unless hash - (if (or (consp (car tree)) - (and vecp (or (vectorp (car tree)) (recordp (car tree))))) - (let ((newcar (safe-copy-tree--1 (car tree) vecp))) - (setcar tree newcar))) - (setq newcons (if (consp (cdr tree)) - (cons (cadr tree) (cddr tree)) - (cdr tree))) - (setcdr tree newcons) - (setq tree (cdr tree)))) - (nconc result - (if (and vecp (or (vectorp tree) (recordp tree))) - (safe-copy-tree--1 tree vecp) tree)))) - ((and vecp (or (vectorp tree) (recordp tree))) - (let* ((newvec (copy-sequence tree)) - (i (length newvec))) - (puthash tree newvec safe-copy-tree--seen) - (setq tree newvec) - (while (>= (setq i (1- i)) 0) - (aset tree i (safe-copy-tree--1 (aref tree i) vecp))) - tree)) - (t tree))) - -(defun safe-copy-tree (tree &optional vecp) - "Make a copy of TREE, taking circular structure into account. -If TREE is a cons cell, this recursively copies both its car and its cdr. -Contrast to `copy-sequence', which copies only along the cdrs. With second -argument VECP, this copies vectors and records as well as conses." - (setq safe-copy-tree--seen (make-hash-table :test #'eq)) - (unwind-protect - (safe-copy-tree--1 tree vecp) - (clrhash safe-copy-tree--seen) - (setq safe-copy-tree--seen nil))) - ;;;; Various list-search functions. |