changeset 101715:800e02167df4

(end-of-defun): Protect against infloops (Bug#2106).
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 31 Jan 2009 16:19:46 +0000
parents 64b82d02b6c2
children 79f16674b60b
files lisp/emacs-lisp/lisp.el
diffstat 1 files changed, 21 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/emacs-lisp/lisp.el	Sat Jan 31 16:19:23 2009 +0000
+++ b/lisp/emacs-lisp/lisp.el	Sat Jan 31 16:19:46 2009 +0000
@@ -342,7 +342,8 @@
       (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 @@
                (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)