diff options
| author | Wilfred Hughes <me@wilfred.me.uk> | 2021-12-10 21:38:58 -0800 |
|---|---|---|
| committer | Wilfred Hughes <me@wilfred.me.uk> | 2021-12-10 21:39:49 -0800 |
| commit | 217b38398bfa523c48f630b06b21427974d93e1d (patch) | |
| tree | 4cc482b830e5f704a0884defae75db6aae77112d | |
| parent | 8df39c15d290cd499ef261de868191d3fc84f75a (diff) | |
Rewrite helpful--tree-any-p as a loop
Fixes #279
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | helpful.el | 18 | ||||
| -rw-r--r-- | test/helpful-unit-test.el | 4 |
3 files changed, 17 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c0d1d4..8d757f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Fixed issue with displaying circular data structures. Fixed a crash in `helpful-variable` in files that weren't syntactically valid lisp. +Fixed stack overflow in macroexpanding large s-expressions (#279). + # v0.18 Show the original value for custom variables whose value has changed. @@ -1317,13 +1317,17 @@ If it fails, attempt to partially macroexpand FORM." (defun helpful--tree-any-p (pred tree) "Walk TREE, applying PRED to every subtree. Return t if PRED ever returns t." - (cond - ((null tree) nil) - ((funcall pred tree) t) - ((not (consp tree)) nil) - (t (or - (helpful--tree-any-p pred (car tree)) - (helpful--tree-any-p pred (cdr tree)))))) + (catch 'found + (let ((stack (list tree))) + (while stack + (let ((next (pop stack))) + (cond + ((funcall pred next) + (throw 'found t)) + ((consp next) + (push (car next) stack) + (push (cdr next) stack)))))) + nil)) (defun helpful--find-by-macroexpanding (buf sym callable-p) "Search BUF for the definition of SYM by macroexpanding diff --git a/test/helpful-unit-test.el b/test/helpful-unit-test.el index 1fbf87c..510396c 100644 --- a/test/helpful-unit-test.el +++ b/test/helpful-unit-test.el @@ -1072,3 +1072,7 @@ find the source code." "Ensure that we can describe an autoloaded function that has advice attached before it is loadedl." (helpful-function 'ruby-mode)) + +(ert-deftest helpful--tree-any-p () + (should (helpful--tree-any-p (lambda (x) (eq x 1)) '((((1)))))) + (should (helpful--tree-any-p (lambda (x) (eq x 1)) (cons 2 1)))) |
