From: Alan Mackenzie Date: Sat, 14 Oct 2023 19:14:57 +0000 (+0000) Subject: Fix an infinite loop in c-beginning-of-defun-1 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=64850eaf989cdf3a69abc9b0c2fa37e098e7b0b9;p=emacs.git Fix an infinite loop in c-beginning-of-defun-1 This fixes bug#61436. The loop manifested itself in c-get-fallback-scan-pos as the position returned wasn't at a {, so the search back in c-beginning-of-defun-1 with a defun-prompt-regexp found the same BOL and moved forward to after the match, repeat. * lisp/progmodes/cc-defs.el (c-beginning-of-defun-1): Accept a position found by beginning-of-defun (which uses defun-prompt-regexp) only when the \\s( following it is a {. Repeat the backward search when this isn't the case. --- diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 8662e0cade6..e15ce54da7f 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -927,7 +927,8 @@ be after it." (when dest (goto-char dest) t))) (defmacro c-beginning-of-defun-1 () - ;; Wrapper around beginning-of-defun. + ;; Wrapper around beginning-of-defun. Note that the return value from this + ;; macro has no significance. ;; ;; NOTE: This function should contain the only explicit use of ;; beginning-of-defun in CC Mode. Eventually something better than @@ -940,44 +941,49 @@ be after it." ;; `c-parse-state'. `(progn - (if (and ,(fboundp 'buffer-syntactic-context-depth) - c-enable-xemacs-performance-kludge-p) - ,(when (fboundp 'buffer-syntactic-context-depth) - ;; XEmacs only. This can improve the performance of - ;; c-parse-state to between 3 and 60 times faster when - ;; braces are hung. It can also degrade performance by - ;; about as much when braces are not hung. - '(let (beginning-of-defun-function end-of-defun-function - pos) - (while (not pos) - (save-restriction - (widen) - (setq pos (c-safe-scan-lists - (point) -1 (buffer-syntactic-context-depth)))) - (cond - ((bobp) (setq pos (point-min))) - ((not pos) - (let ((distance (skip-chars-backward "^{"))) - ;; unbalanced parenthesis, while invalid C code, - ;; shouldn't cause an infloop! See unbal.c - (when (zerop distance) - ;; Punt! - (beginning-of-defun) - (setq pos (point))))) - ((= pos 0)) - ((not (eq (char-after pos) ?{)) - (goto-char pos) - (setq pos nil)) - )) - (goto-char pos))) - ;; Emacs, which doesn't have buffer-syntactic-context-depth - (let (beginning-of-defun-function end-of-defun-function) - (beginning-of-defun))) - ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at the - ;; open brace. - (and defun-prompt-regexp - (looking-at defun-prompt-regexp) - (goto-char (match-end 0))))) + (while + (progn + (if (and ,(fboundp 'buffer-syntactic-context-depth) + c-enable-xemacs-performance-kludge-p) + ,(when (fboundp 'buffer-syntactic-context-depth) + ;; XEmacs only. This can improve the performance of + ;; c-parse-state to between 3 and 60 times faster when + ;; braces are hung. It can also degrade performance by + ;; about as much when braces are not hung. + '(let (beginning-of-defun-function end-of-defun-function + pos) + (while (not pos) + (save-restriction + (widen) + (setq pos (c-safe-scan-lists + (point) -1 (buffer-syntactic-context-depth)))) + (cond + ((bobp) (setq pos (point-min))) + ((not pos) + (let ((distance (skip-chars-backward "^{"))) + ;; unbalanced parenthesis, while invalid C code, + ;; shouldn't cause an infloop! See unbal.c + (when (zerop distance) + ;; Punt! + (beginning-of-defun) + (setq pos (point))))) + ((= pos 0)) + ((not (eq (char-after pos) ?{)) + (goto-char pos) + (setq pos nil)) + )) + (goto-char pos))) + ;; Emacs, which doesn't have buffer-syntactic-context-depth + (let (beginning-of-defun-function end-of-defun-function) + (beginning-of-defun))) + (and (not (bobp)) + ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at + ;; the open brace. + defun-prompt-regexp + (looking-at (concat defun-prompt-regexp "\\s(")) + (or (not (eq (char-before (match-end 0)) ?{)) + (progn (goto-char (1- (match-end 0))) + nil))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;