From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#35454: 26.2.50; CC-Mode fontification fails inside macro Date: Wed, 1 May 2019 21:02:30 +0000 Message-ID: <20190501210230.GA3999@ACM> References: <20190427203646.GA11087@ACM> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="68631"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mutt/1.10.1 (2018-07-13) Cc: 35454@debbugs.gnu.org To: Mauro Aranda Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed May 01 23:03:14 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hLwNl-000Hev-V2 for geb-bug-gnu-emacs@m.gmane.org; Wed, 01 May 2019 23:03:14 +0200 Original-Received: from localhost ([127.0.0.1]:41345 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hLwNk-0008P1-VN for geb-bug-gnu-emacs@m.gmane.org; Wed, 01 May 2019 17:03:12 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:58430) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hLwNc-0008Mh-HF for bug-gnu-emacs@gnu.org; Wed, 01 May 2019 17:03:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hLwNb-0006m1-06 for bug-gnu-emacs@gnu.org; Wed, 01 May 2019 17:03:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:59738) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hLwNa-0006lm-MZ; Wed, 01 May 2019 17:03:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hLwNa-00015M-D2; Wed, 01 May 2019 17:03:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Wed, 01 May 2019 21:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 35454 X-GNU-PR-Package: emacs,cc-mode Original-Received: via spool by 35454-submit@debbugs.gnu.org id=B35454.15567445584140 (code B ref 35454); Wed, 01 May 2019 21:03:02 +0000 Original-Received: (at 35454) by debbugs.gnu.org; 1 May 2019 21:02:38 +0000 Original-Received: from localhost ([127.0.0.1]:45049 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hLwNB-00014i-Tj for submit@debbugs.gnu.org; Wed, 01 May 2019 17:02:38 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:48875 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1hLwN8-00014V-BV for 35454@debbugs.gnu.org; Wed, 01 May 2019 17:02:35 -0400 Original-Received: (qmail 26139 invoked by uid 3782); 1 May 2019 21:02:31 -0000 Original-Received: from acm.muc.de (p4FE15FD7.dip0.t-ipconnect.de [79.225.95.215]) by colin.muc.de (tmda-ofmipd) with ESMTP; Wed, 01 May 2019 23:02:30 +0200 Original-Received: (qmail 7161 invoked by uid 1000); 1 May 2019 21:02:30 -0000 Content-Disposition: inline In-Reply-To: <20190427203646.GA11087@ACM> X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:158605 Archived-At: 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).