(end-of-defun): Protect against infloops (Bug#2106).

This commit is contained in:
Chong Yidong 2009-01-31 16:19:46 +00:00
parent a1f062078e
commit 45545d6875

View file

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