branch: master commit 5d009764de8caf393f1591c886e6c96c3b7dcfc1 Author: Michael Heerdegen <michael_heerde...@web.de> Commit: Michael Heerdegen <michael_heerde...@web.de>
Avoid infinite recursion in circular programs Prevent heuristic matching go into an infinite recursion in circular programs like '#1=(1 . #1#). --- packages/el-search/el-search.el | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index dfe3b78..601ce4d 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -958,19 +958,25 @@ non-nil else." atom-list)))))) (defun el-search--flatten-tree (tree) - (let ((elements ())) + (let ((elements ()) + (walked-objects ;to avoid infinite recursion for circular TREEs + (make-hash-table :test #'eq)) + (gc-cons-percentage 0.8)) ;Why is binding it here more effective than binding it more top-level? (cl-labels ((walker (object) (if (or (not (sequencep object)) (stringp object) (null object) (char-table-p object) (bool-vector-p object)) (push object elements) - (if (consp object) - (progn - (while (consp object) - (walker (car object)) - (setq object (cdr object))) - (when object ;dotted list - (walker object))) - (cl-loop for elt being the elements of object do (walker elt)))))) + (unless (gethash object walked-objects) + (puthash object t walked-objects) + (if (consp object) + (progn + (while (consp object) + (walker (car object)) + (setq object (cdr object)) + (when (gethash object walked-objects) (setq object nil))) + (when object ;dotted list + (walker object))) + (cl-loop for elt being the elements of object do (walker elt))))))) (walker tree) elements)))