]> git.eshelyaron.com Git - emacs.git/commitdiff
(end-of-defun): Protect against infloops (Bug#2106).
authorChong Yidong <cyd@stupidchicken.com>
Sat, 31 Jan 2009 16:19:46 +0000 (16:19 +0000)
committerChong Yidong <cyd@stupidchicken.com>
Sat, 31 Jan 2009 16:19:46 +0000 (16:19 +0000)
lisp/emacs-lisp/lisp.el

index beb0d85d74a9ac8fd2f8c1b766801a1dc39a0e18..76141c5627432fe8cd9f1ea7f8517b1ab52e7e32 100644 (file)
@@ -342,7 +342,8 @@ is called as a function to find the defun's end."
       (push-mark))
   (if (or (null arg) (= arg 0)) (setq arg 1))
   (while (> arg 0)
-    (let ((pos (point)))
+    (let ((pos (point))
+         retry-point)
       (end-of-line 1)
       (beginning-of-defun-raw 1)
       (while (unless (eobp)
@@ -350,28 +351,37 @@ is called as a function to find the defun's end."
                (skip-chars-forward " \t")
                (if (looking-at "\\s<\\|\n")
                    (forward-line 1))
-               ;; If we started after the end of the previous function, then
-               ;; try again with the next one.
-               (when (<= (point) pos)
-                 (or (bobp) (forward-char -1))
-                 (beginning-of-defun-raw -1)
-                 'try-again))))
+               ;; If we started after the end of the previous
+               ;; function, try again with the next one.
+               (unless (or (> (point) pos)
+                          (eq (point) retry-point))
+                (or (bobp) (forward-char -1))
+                (beginning-of-defun-raw -1)
+                (setq retry-point (point)))))
+      ;; Ensure that we move forward.
+      (when (< (point) pos)
+       (goto-char pos)))
     (setq arg (1- arg)))
   (while (< arg 0)
     (let ((pos (point)))
       (while (unless (bobp)
                (beginning-of-line 1)
                (beginning-of-defun-raw 1)
-               (let ((beg (point)))
+               (let ((beg (point))
+                    retry-point)
                  (funcall end-of-defun-function)
                  (skip-chars-forward " \t")
                  (if (looking-at "\\s<\\|\n")
                      (forward-line 1))
-                 ;; If we started from within the function just found, then
+                 ;; If we started from within the function just found,
                  ;; try again with the previous one.
-                 (when (>= (point) pos)
+                 (unless (or (< (point) pos)
+                            (eq (point) retry-point))
                    (goto-char beg)
-                   'try-again)))))
+                   (setq retry-point (point))))))
+      ;; Ensure that we move backward.
+      (when (> (point) pos)
+       (goto-char pos)))
     (setq arg (1+ arg))))
 
 (defun mark-defun (&optional allow-extend)