emacs-diffs
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]