From c0209c2c68aeb23ce0480d42e4bfcc7fd13ce374 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 21 May 2010 19:51:48 +0000 Subject: [PATCH] Fix a bug which happens when doing (c-parse-state) in a CPP construct: Exclude any "new" CPP construct from taking part in the scanning. --- lisp/ChangeLog | 9 ++ lisp/progmodes/cc-engine.el | 169 ++++++++++++++++++++---------------- 2 files changed, 102 insertions(+), 76 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 3671e2461aa..7c0fb21483f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2010-05-21 Alan Mackenzie + + * progmodes/cc-engine.el (c-parse-state-get-strategy): Replace + parameter `here' with `here-' and `here-plus', which sandwich any + pertinent CPP construct. + (c-remove-stale-state-cache-backwards): Fix a bug which happens + when doing (c-parse-state) in a CPP construct: Exclude any "new" + CPP construct from taking part in the scanning. + 2010-05-21 Michael Albinus * net/tramp.el (tramp-do-copy-or-rename-file) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 2d28d003fd5..1ee3c295fe1 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2245,50 +2245,50 @@ comment at the start of cc-engine.el for more info." (setq cnt (1- cnt))))) (point))) -(defun c-state-balance-parens-backwards (here top) - ;; Return the position of the opening paren/brace/bracket before HERE which - ;; matches the outermost close p/b/b between HERE and TOP, like this: - ;; - ;; ...................................... - ;; | | - ;; ( [ ( ........... ) ( ) ] ) - ;; ^ ^ ^ - ;; | | | - ;; return HERE TOP +(defun c-state-balance-parens-backwards (here- here+ top) + ;; Return the position of the opening paren/brace/bracket before HERE- which + ;; matches the outermost close p/b/b between HERE+ and TOP. Except when + ;; there's a macro, HERE- and HERE+ are the same. Like this: + ;; + ;; ............................................ + ;; | | + ;; ( [ ( .........#macro.. ) ( ) ] ) + ;; ^ ^ ^ ^ + ;; | | | | + ;; return HERE- HERE+ TOP ;; ;; If there aren't enough opening paren/brace/brackets, return the position - ;; of the outermost one found, or HERE it there are none. If there are no - ;; closeing p/b/bs between HERE and TOP, return HERE. HERE and TOP must not - ;; be inside literals. Only the accessible portion of the buffer will be - ;; scanned. - - ;; PART 1: scan from `here' up to `top', accumulating ")"s which enclose - ;; `here'. Go round the next loop each time we pass over such a ")". These - ;; probably match "("s before `here'. + ;; of the outermost one found, or HERE- if there are none. If there are no + ;; closeing p/b/bs between HERE+ and TOP, return HERE-. HERE-/+ and TOP + ;; must not be inside literals. Only the accessible portion of the buffer + ;; will be scanned. + + ;; PART 1: scan from `here+' up to `top', accumulating ")"s which enclose + ;; `here'. Go round the next loop each time we pass over such a ")". These + ;; probably match "("s before `here-'. (let (pos pa ren+1 lonely-rens) (save-excursion (save-restriction (narrow-to-region (point-min) top) ; This can move point, sometimes. - (setq pos here) + (setq pos here+) (c-safe (while (setq ren+1 (scan-lists pos 1 1)) ; might signal (setq lonely-rens (cons ren+1 lonely-rens) pos ren+1))))) - ;; PART 2: Scan back before `here' searching for the "("s + ;; PART 2: Scan back before `here-' searching for the "("s ;; matching/mismatching the ")"s found above. We only need to direct the ;; caller to scan when we've encountered unmatched right parens. - (when lonely-rens - (setq pos here) - (c-safe - (while - (and lonely-rens ; actual values aren't used. - (setq pa (scan-lists pos -1 1))) - (setq pos pa) - (setq lonely-rens (cdr lonely-rens)))) ;) - ) - pos)) + (setq pos here-) + (when lonely-rens + (c-safe + (while + (and lonely-rens ; actual values aren't used. + (setq pa (scan-lists pos -1 1))) + (setq pos pa) + (setq lonely-rens (cdr lonely-rens))))) + pos)) (defun c-parse-state-get-strategy (here good-pos) ;; Determine the scanning strategy for adjusting `c-parse-state', attempting @@ -2746,6 +2746,7 @@ comment at the start of cc-engine.el for more info." lit ; (START . END) of a literal containing some point. here-lit-start here-lit-end ; bounds of literal containing `here' ; or `here' itself. + here- here+ ; start/end of macro around HERE, or HERE (here-bol (c-point 'bol here)) (too-far-back (max (- here c-state-cache-too-far) 1))) @@ -2758,57 +2759,73 @@ comment at the start of cc-engine.el for more info." ;; At this stage, (> pos here); ;; (< (c-state-cache-top-lparen) here) (or is nil). - ;; CASE 1: The top of the cache is a brace pair which now encloses `here'. - ;; As good-pos, return the address. of the "{". - (if (and (consp (car c-state-cache)) - (> (cdar c-state-cache) here)) - ;; Since we've no knowledge of what's inside these braces, we have no - ;; alternative but to direct the caller to scan the buffer from the - ;; opening brace. - (progn - (setq pos (caar c-state-cache)) - (setcar c-state-cache pos) - (list (1+ pos) pos t)) ; return value. We've just converted a brace - ; pair entry into a { entry, so the caller - ; needs to search for a brace pair before the - ; {. - - ;; ;; `here' might be inside a literal. Check for this. - (setq lit (c-state-literal-at here) - here-lit-start (or (car lit) here) - here-lit-end (or (cdr lit) here)) - - ;; `here' might be nested inside any depth of parens (or brackets but - ;; not braces). Scan backwards to find the outermost such opening - ;; paren, if there is one. This will be the scan position to return. - (save-restriction - (narrow-to-region cache-pos (point-max)) - (setq pos (c-state-balance-parens-backwards here-lit-end pos))) - - (if (< pos here-lit-start) - ;; CASE 2: Address of outermost ( or [ which now encloses `here', - ;; but didn't enclose the (previous) `c-state-cache-good-pos'. If - ;; there is a brace pair preceding this, it will already be in - ;; `c-state-cache', unless there was a brace pair after it, - ;; i.e. there'll only be one to scan for if we've just deleted one. - (list pos (and dropped-cons pos) t) ; Return value. - - ;; `here' isn't enclosed in a (previously unrecorded) bracket/paren. - ;; Further forward scanning isn't needed, but we still need to find a - ;; GOOD-POS. Step out of all enclosing "("s on HERE's line. + (cond + ((and (consp (car c-state-cache)) + (> (cdar c-state-cache) here)) + ;; CASE 1: The top of the cache is a brace pair which now encloses + ;; `here'. As good-pos, return the address. of the "{". Since we've no + ;; knowledge of what's inside these braces, we have no alternative but + ;; to direct the caller to scan the buffer from the opening brace. + (setq pos (caar c-state-cache)) + (setcar c-state-cache pos) + (list (1+ pos) pos t)) ; return value. We've just converted a brace pair + ; entry into a { entry, so the caller needs to + ; search for a brace pair before the {. + + ;; `here' might be inside a literal. Check for this. + ((progn + (setq lit (c-state-literal-at here) + here-lit-start (or (car lit) here) + here-lit-end (or (cdr lit) here)) + ;; Has `here' just "newly entered" a macro? + (save-excursion + (goto-char here-lit-start) + (if (and (c-beginning-of-macro) + (or (null c-state-old-cpp-beg) + (not (= (point) c-state-old-cpp-beg)))) + (progn + (setq here- (point)) + (c-end-of-macro) + (setq here+ (point))) + (setq here- here-lit-start + here+ here-lit-end))) + + ;; `here' might be nested inside any depth of parens (or brackets but + ;; not braces). Scan backwards to find the outermost such opening + ;; paren, if there is one. This will be the scan position to return. + (save-restriction + (narrow-to-region cache-pos (point-max)) + (setq pos (c-state-balance-parens-backwards here- here+ pos))) + nil)) ; for the cond + + ((< pos here-lit-start) + ;; CASE 2: Address of outermost ( or [ which now encloses `here', but + ;; didn't enclose the (previous) `c-state-cache-good-pos'. If there is + ;; a brace pair preceding this, it will already be in `c-state-cache', + ;; unless there was a brace pair after it, i.e. there'll only be one to + ;; scan for if we've just deleted one. + (list pos (and dropped-cons pos) t)) ; Return value. + + ;; `here' isn't enclosed in a (previously unrecorded) bracket/paren. + ;; Further forward scanning isn't needed, but we still need to find a + ;; GOOD-POS. Step out of all enclosing "("s on HERE's line. + ((progn (save-restriction (narrow-to-region here-bol (point-max)) (setq pos here-lit-start) (c-safe (while (setq pa (scan-lists pos -1 1)) (setq pos pa)))) ; might signal - (if (setq ren (c-safe-scan-lists pos -1 -1 too-far-back)) - ;; CASE 3: After a }/)/] before `here''s BOL. - (list (1+ ren) (and dropped-cons pos) nil) ; Return value - - ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of - ;; literal containing it. - (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol))) - (list good-pos (and dropped-cons good-pos) nil)))))) + nil)) ; for the cond + + ((setq ren (c-safe-scan-lists pos -1 -1 too-far-back)) + ;; CASE 3: After a }/)/] before `here''s BOL. + (list (1+ ren) (and dropped-cons pos) nil)) ; Return value + + (t + ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of + ;; literal containing it. + (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol))) + (list good-pos (and dropped-cons good-pos) nil))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- 2.39.2