[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 116aceb: Fix spurious fontification of "for (; a *
From: |
Alan Mackenzie |
Subject: |
[Emacs-diffs] master 116aceb: Fix spurious fontification of "for (; a * b; )" in CC Mode. |
Date: |
Mon, 16 May 2016 11:34:12 +0000 (UTC) |
branch: master
commit 116acebfbd28649b6ccf34e5c9046738d57aa28e
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>
Fix spurious fontification of "for (; a * b;)" in CC Mode.
This fixes bug #7918 (again).
* lisp/progmodes/cc-engine.el (c-delq-from-dotted-list): New function.
(c-forward-decl-or-cast-1): Return a 4 element list in place of the previous
cons cell - additionally, return a flag indicating whether the declaration
parsed might have been an expression, and the position of the type
identifier
in the said declaration.
* lisp/progmodes/cc-fonts.el (c-font-lock-declarations): When
c-forward-decl-or-cast-1 has indicated it might have parsed an expression,
check for it being a spurious declaration in a "for" statement.
---
lisp/progmodes/cc-engine.el | 44 ++++++++++++++++++++++++++++++++++++-------
lisp/progmodes/cc-fonts.el | 32 ++++++++++++++++++++++++++++---
2 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index d19d2da..2450a5d 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -385,6 +385,25 @@ comment at the start of cc-engine.el for more info."
;;; Basic utility functions.
+(defun c-delq-from-dotted-list (elt dlist)
+ ;; If ELT is a member of the (possibly dotted) list DLIST, remove all
+ ;; occurrences of it (except for any in the last cdr of DLIST).
+ ;;
+ ;; Call this as (setq DLIST (c-delq-from-dotted-list ELT DLIST)), as
+ ;; sometimes the original structure is changed, sometimes it's not.
+ ;;
+ ;; This function is needed in Emacs < 24.5, and possibly XEmacs, because
+ ;; `delq' throws an error in these versions when given a dotted list.
+ (let ((tail dlist) prev)
+ (while (consp tail)
+ (if (eq (car tail) elt)
+ (if prev
+ (setcdr prev (cdr tail))
+ (setq dlist (cdr dlist)))
+ (setq prev tail))
+ (setq tail (cdr tail)))
+ dlist))
+
(defun c-syntactic-content (from to paren-level)
;; Return the given region as a string where all syntactic
;; whitespace is removed or, where necessary, replaced with a single
@@ -7020,9 +7039,9 @@ comment at the start of cc-engine.el for more info."
;; If a declaration is parsed:
;;
;; The point is left at the first token after the first complete
- ;; declarator, if there is one. The return value is a cons where
- ;; the car is the position of the first token in the declarator. (See
- ;; below for the cdr.)
+ ;; declarator, if there is one. The return value is a list of 4 elements,
+ ;; where the first is the position of the first token in the declarator.
+ ;; (See below for the other three.)
;; Some examples:
;;
;; void foo (int a, char *b) stuff ...
@@ -7053,7 +7072,7 @@ comment at the start of cc-engine.el for more info."
;;
;;
;;
- ;; The cdr of the return value is non-nil when a
+ ;; The second element of the return value is non-nil when a
;; `c-typedef-decl-kwds' specifier is found in the declaration.
;; Specifically it is a dotted pair (A . B) where B is t when a
;; `c-typedef-kwds' ("typedef") is present, and A is t when some
@@ -7061,6 +7080,10 @@ comment at the start of cc-engine.el for more info."
;; specifier is present. I.e., (some of) the declared
;; identifier(s) are types.
;;
+ ;; The third element of the return value is non-nil when the declaration
+ ;; parsed might be an expression. The fourth element is the position of
+ ;; the start of the type identifier.
+ ;;
;; If a cast is parsed:
;;
;; The point is left at the first token after the closing paren of
@@ -7161,7 +7184,10 @@ comment at the start of cc-engine.el for more info."
;; speculatively and should be thrown away if it turns out
;; that it isn't a declaration or cast.
(save-rec-type-ids c-record-type-identifiers)
- (save-rec-ref-ids c-record-ref-identifiers))
+ (save-rec-ref-ids c-record-ref-identifiers)
+ ;; Set when we parse a declaration which might also be an expression,
+ ;; such as "a *b". See CASE 16 and CASE 17.
+ maybe-expression)
(save-excursion
(goto-char preceding-token-end)
@@ -7799,6 +7825,7 @@ comment at the start of cc-engine.el for more info."
;; the construct look like a function call) when
;; `at-decl-start' provides additional evidence that we do
;; have a declaration.
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t))
;; CASE 17
@@ -7810,6 +7837,7 @@ comment at the start of cc-engine.el for more info."
;; be an odd expression or it could be a declaration. Treat
;; it as a declaration if "a" has been used as a type
;; somewhere else (if it's a known type we won't get here).
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t)))
;; CASE 18
@@ -7933,9 +7961,11 @@ comment at the start of cc-engine.el for more info."
(goto-char type-start)
(c-forward-type))))
- (cons id-start
+ (list id-start
(and (or at-type-decl at-typedef)
- (cons at-type-decl at-typedef))))
+ (cons at-type-decl at-typedef))
+ maybe-expression
+ type-start))
(t
;; False alarm. Restore the recorded ranges.
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index e171b20..4e83d6d 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1336,6 +1336,32 @@ casts and declarations are fontified. Used on level 2
and higher."
(when (> (point) max-type-decl-end)
(setq max-type-decl-end (point))))
+ ;; Do we have an expression as the second or third clause of
+ ;; a "for" paren expression?
+ (if (save-excursion
+ (and
+ (car (cddr decl-or-cast)) ; maybe-expression flag.
+ (goto-char start-pos)
+ (c-go-up-list-backward)
+ (eq (char-after) ?\()
+ (progn (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))
+ (looking-at c-paren-stmt-key)
+ (progn (goto-char match-pos)
+ (while (and (eq (char-before) ?\))
+ (c-go-list-backward))
+ (c-backward-syntactic-ws))
+ (eq (char-before) ?\;))))
+ ;; We've got an expression in "for" parens. Remove the
+ ;; "type" that would spuriously get fontified.
+ (let ((elt (and (consp c-record-type-identifiers)
+ (assq (cadr (cddr decl-or-cast))
+ c-record-type-identifiers))))
+ (when elt
+ (setq c-record-type-identifiers
+ (c-delq-from-dotted-list
+ elt c-record-type-identifiers)))
+ t)
;; Back up to the type to fontify the declarator(s).
(goto-char (car decl-or-cast))
@@ -1361,17 +1387,17 @@ casts and declarations are fontified. Used on level 2
and higher."
(c-backward-syntactic-ws)
(unless (bobp)
(c-put-char-property (1- (point)) 'c-type
- (if (cdr decl-or-cast)
+ (if (cadr decl-or-cast)
'c-decl-type-start
'c-decl-id-start)))))
(c-font-lock-declarators
- (point-max) decl-list (cdr decl-or-cast)))
+ (point-max) decl-list (cadr decl-or-cast)))
;; A declaration has been successfully identified, so do all the
;; fontification of types and refs that've been recorded.
(c-fontify-recorded-types-and-refs)
- nil)
+ nil))
;; Restore point, since at this point in the code it has been
;; left undefined by c-forward-decl-or-cast-1 above.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 116aceb: Fix spurious fontification of "for (; a * b; )" in CC Mode.,
Alan Mackenzie <=