summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2019-05-02 20:53:47 +0000
committerAlan Mackenzie <acm@muc.de>2019-05-02 20:53:47 +0000
commitd9f62fceaf2915c67f6917c668af6ff4aacc26a7 (patch)
treeb690acb6e6052d1d5e376654614475a58603e1ff
parent17a722982cca4e8e643c7a9102903e820e784cc6 (diff)
downloademacs-d9f62fceaf2915c67f6917c668af6ff4aacc26a7.tar.gz
Fix fontification of first item in CC Mode macro without parentheses
* lisp/progmodes/cc-engine.el (c-find-decl-prefix-search): Handle the new matching possibility (of a #define construct) in the new c-decl-prefix-or-start-re. (c-find-decl-spots): Allow the initial search for an in-macro starting point settle on the # of #define, to facilitate the regexp matching in c-find-decl-prefix-search. * lisp/progmodes/cc-langs.el (c-anchored-hash-define-no-parens): New lang const. (c-literal-start-regexp): Correct what was always supposed to be a "generic string" regexp element. (c-decl-prefix-or-start-re): Enhance also to match "#define <identifier>". (c-dposr-cpp-macro-depth): New lang variable and lang constant.
-rw-r--r--lisp/progmodes/cc-engine.el45
-rw-r--r--lisp/progmodes/cc-langs.el44
2 files changed, 67 insertions, 22 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index f9e570e9f3f..7e6a46ea6e0 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -5692,7 +5692,10 @@ comment at the start of cc-engine.el for more info."
(setq cfd-re-match cfd-limit)
nil)
((c-got-face-at
- (if (setq cfd-re-match (match-end 1))
+ (if (setq cfd-re-match
+ (or (match-end 1)
+ (and c-dposr-cpp-macro-depth
+ (match-end (1+ c-dposr-cpp-macro-depth)))))
;; Matched the end of a token preceding a decl spot.
(progn
(goto-char cfd-re-match)
@@ -5703,15 +5706,19 @@ comment at the start of cc-engine.el for more info."
c-literal-faces)
;; Pseudo match inside a comment or string literal. Skip out
;; of comments and string literals.
- (while (progn
- (unless
- (and (match-end 1)
- (c-got-face-at (1- (point)) c-literal-faces)
- (not (c-got-face-at (point) c-literal-faces)))
- (goto-char (c-next-single-property-change
- (point) 'face nil cfd-limit)))
- (and (< (point) cfd-limit)
- (c-got-face-at (point) c-literal-faces))))
+ (while
+ (progn
+ (unless
+ (and
+ (or (match-end 1)
+ (and c-dposr-cpp-macro-depth
+ (match-end (1+ c-dposr-cpp-macro-depth))))
+ (c-got-face-at (1- (point)) c-literal-faces)
+ (not (c-got-face-at (point) c-literal-faces)))
+ (goto-char (c-next-single-property-change
+ (point) 'face nil cfd-limit)))
+ (and (< (point) cfd-limit)
+ (c-got-face-at (point) c-literal-faces))))
t) ; Continue the loop over pseudo matches.
((and c-opt-identifier-concat-key
(match-string 1)
@@ -5863,7 +5870,7 @@ comment at the start of cc-engine.el for more info."
;; before the point, and do the first `c-decl-prefix-or-start-re'
;; search unless we're at bob.
- (let (start-in-literal start-in-macro syntactic-pos)
+ (let (start-in-literal start-in-macro syntactic-pos hash-define-pos)
;; Must back up a bit since we look for the end of the previous
;; statement or declaration, which is earlier than the first
;; returned match.
@@ -6018,7 +6025,21 @@ comment at the start of cc-engine.el for more info."
;; The only syntactic ws in macros are comments.
(c-backward-comments)
(or (bobp) (backward-char))
- (c-beginning-of-current-token))
+ (c-beginning-of-current-token)
+ ;; If we're in a macro without argument parentheses, we could have
+ ;; now ended up at the macro's identifier. We need to be at #define
+ ;; for `c-find-decl-prefix-search' to find the first token of the
+ ;; macro's expansion.
+ (when (and (c-on-identifier)
+ (setq hash-define-pos
+ (save-excursion
+ (and
+ (zerop (c-backward-token-2 2)) ; over define, #
+ (save-excursion
+ (beginning-of-line)
+ (looking-at c-opt-cpp-macro-define-id))
+ (point)))))
+ (goto-char hash-define-pos)))
(start-in-literal
;; If we're in a comment it can only be the closest
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 00c581a06a9..8b7e4ef7c09 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -979,6 +979,14 @@ definition, or nil if the language doesn't have any."
(c-lang-defvar c-opt-cpp-macro-define-id
(c-lang-const c-opt-cpp-macro-define-id))
+(c-lang-defconst c-anchored-hash-define-no-parens
+ ;; Regexp matching everything up to the end of a cpp define which has no
+ ;; argument parentheses. Or nil in languages which don't have them.
+ t (if (c-lang-const c-opt-cpp-macro-define)
+ (concat (c-lang-const c-anchored-cpp-prefix)
+ (c-lang-const c-opt-cpp-macro-define)
+ "[ \t]+\\(\\sw\\|_\\)+\\([^(a-zA-Z0-9_]\\|$\\)")))
+
(c-lang-defconst c-cpp-expr-directives
"List of cpp directives (without the prefix) that are followed by an
expression."
@@ -1614,7 +1622,7 @@ starter."
t (concat (c-lang-const c-comment-start-regexp)
"\\|"
(if (memq 'gen-string-delim c-emacs-features)
- "\"|"
+ "\"\\|\\s|"
"\"")))
(c-lang-defvar c-literal-start-regexp (c-lang-const c-literal-start-regexp))
@@ -3183,24 +3191,40 @@ constructs."
;; token that might precede such a construct, e.g. ';', '}' or '{'.
;; It's built from `c-decl-prefix-re'.
;;
- ;; If the first submatch did not match, the match of the whole
- ;; regexp is taken to be at the first token in the declaration.
- ;; `c-decl-start-re' is not checked in this case.
+ ;; If the first submatch did not match, we have either a #define construct
+ ;; without parentheses or the match of the whole regexp is taken to be at
+ ;; the first token in the declaration. `c-decl-start-re' is not checked in
+ ;; these cases.
;;
;; Design note: The reason the same regexp is used to match both
;; tokens that precede declarations and start them is to avoid an
;; extra regexp search from the previous declaration spot in
;; `c-find-decl-spots'. Users of `c-find-decl-spots' also count on
- ;; that it finds all declaration/cast/label starts in approximately
+ ;; it finding all declaration/cast/label starts in approximately
;; linear order, so we can't do the searches in two separate passes.
- t (if (c-lang-const c-decl-start-kwds)
- (concat (c-lang-const c-decl-prefix-re)
- "\\|"
- (c-make-keywords-re t (c-lang-const c-decl-start-kwds)))
- (c-lang-const c-decl-prefix-re)))
+ t (cond
+ ((and (c-lang-const c-decl-start-kwds)
+ (c-lang-const c-anchored-hash-define-no-parens))
+ (concat (c-lang-const c-decl-prefix-re)
+ "\\|" (c-lang-const c-anchored-hash-define-no-parens)
+ "\\|" (c-make-keywords-re t (c-lang-const c-decl-start-kwds))))
+ ((c-lang-const c-decl-start-kwds)
+ (concat (c-lang-const c-decl-prefix-re)
+ "\\|" (c-make-keywords-re t (c-lang-const c-decl-start-kwds))))
+ ((c-lang-const c-anchored-hash-define-no-parens)
+ (concat (c-lang-const c-decl-prefix-re)
+ "\\|" (c-lang-const c-anchored-hash-define-no-parens)))
+ (t (c-lang-const c-decl-prefix-re))))
(c-lang-defvar c-decl-prefix-or-start-re
(c-lang-const c-decl-prefix-or-start-re))
+(c-lang-defconst c-dposr-cpp-macro-depth
+ ;; The match number of `c-anchored-hash-define-no-parens''s first match
+ ;; within `c-decl-prefix-or-start-re', or nil if there is no such component.
+ t (if (c-lang-const c-anchored-hash-define-no-parens)
+ (1+ (regexp-opt-depth (c-lang-const c-decl-prefix-re)))))
+(c-lang-defvar c-dposr-cpp-macro-depth (c-lang-const c-dposr-cpp-macro-depth))
+
(c-lang-defconst c-cast-parens
;; List containing the paren characters that can open a cast, or nil in
;; languages without casts.