From: Alan Mackenzie <acm@muc.de>
To: Mauro Aranda <maurooaranda@gmail.com>
Cc: 35454@debbugs.gnu.org
Subject: bug#35454: 26.2.50; CC-Mode fontification fails inside macro
Date: Wed, 1 May 2019 21:02:30 +0000 [thread overview]
Message-ID: <20190501210230.GA3999@ACM> (raw)
In-Reply-To: <20190427203646.GA11087@ACM>
Hello again, Mauro.
On Sat, Apr 27, 2019 at 20:36:46 +0000, Alan Mackenzie wrote:
> On Sat, Apr 27, 2019 at 12:57:05 -0300, Mauro Aranda wrote:
> > Hello.
> > Steps to reproduce:
> > 1) emacs -Q
> > 2) Open up a new .c file:
> > C-x C-f test.c
> > 3) Type this text:
> > #define FOO \
> > /* Some comms. */ \
> > struct foobar my_foo; \
> > struct foobar my_bar;
> > The first struct foobar after the comment is not fontified as the second
> > one. That is, the second foobar has face font-lock-type-face, and
> > my_bar has face font-lock-variable-name-face, but the first foobar and
> > my_foo don't get those face values.
> > I actually bumped into this issue while visiting the emacs source file
> > src/editfns.c. In that file, search for "#define EXTRA_CONTEXT_FIELDS"
> > and the problem should be evident.
> Thanks! I can reproduce this easily, and will look into it in the next
> day or two.
Please try out the patch below. On my system, it corrects the
fontification in both your test file and editfns.c.
> Of interest is the fact that if FOO is given an empty argument list
> (i.e. one writes
> #define FOO() \
> ...
> ), the bug doesn't happen.
> > I can reproduce it with the latest Emacs 26, as well as with the latest
> > master:
> > Repository revision: 8dc00b2f1e6523c634df3e24379afbe712a32b27
> > Repository branch: master
diff -r 9d58d1e3ab27 cc-engine.el
--- a/cc-engine.el Sat Apr 27 17:07:23 2019 +0000
+++ b/cc-engine.el Wed May 01 20:46:40 2019 +0000
@@ -5668,7 +5668,10 @@
(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)
@@ -5679,15 +5682,19 @@
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)
diff -r 9d58d1e3ab27 cc-langs.el
--- a/cc-langs.el Sat Apr 27 17:07:23 2019 +0000
+++ b/cc-langs.el Wed May 01 20:46:40 2019 +0000
@@ -964,6 +964,14 @@
(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."
@@ -1578,7 +1586,7 @@
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))
@@ -3152,24 +3160,40 @@
;; 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.
> > Best regards,
> > Mauro.
--
Alan Mackenzie (Nuremberg, Germany).
next prev parent reply other threads:[~2019-05-01 21:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-27 15:57 bug#35454: 26.2.50; CC-Mode fontification fails inside macro Mauro Aranda
2019-04-27 20:36 ` Alan Mackenzie
2019-05-01 21:02 ` Alan Mackenzie [this message]
2019-05-01 22:31 ` Mauro Aranda
2019-05-02 8:57 ` Alan Mackenzie
2019-05-02 14:42 ` Alan Mackenzie
2019-05-02 21:03 ` Alan Mackenzie
2019-05-02 21:44 ` Mauro Aranda
2019-05-03 7:41 ` Alan Mackenzie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190501210230.GA3999@ACM \
--to=acm@muc.de \
--cc=35454@debbugs.gnu.org \
--cc=maurooaranda@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.