changeset 108742:36dd9f97c404

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.
author Alan Mackenzie <acm@muc.de>
date Fri, 21 May 2010 19:51:48 +0000
parents 9480d787845f
children 4b1caf0bded6
files lisp/ChangeLog lisp/progmodes/cc-engine.el
diffstat 2 files changed, 102 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Fri May 21 13:29:27 2010 -0400
+++ b/lisp/ChangeLog	Fri May 21 19:51:48 2010 +0000
@@ -1,3 +1,12 @@
+2010-05-21  Alan Mackenzie  <acm@muc.de>
+
+	* 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  <michael.albinus@gmx.de>
 
 	* net/tramp.el (tramp-do-copy-or-rename-file)
--- a/lisp/progmodes/cc-engine.el	Fri May 21 13:29:27 2010 -0400
+++ b/lisp/progmodes/cc-engine.el	Fri May 21 19:51:48 2010 +0000
@@ -2245,50 +2245,50 @@
 	    (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 @@
 	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 @@
     ;; 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)))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;