From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: C99 compound literals in c-mode Date: Sun, 20 Aug 2017 20:40:30 +0000 Message-ID: <20170820204030.GA8206@ACM> References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1503261767 27964 195.159.176.226 (20 Aug 2017 20:42:47 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 20 Aug 2017 20:42:47 +0000 (UTC) User-Agent: Mutt/1.7.2 (2016-11-26) Cc: Stefan Monnier , Emacs Developers To: Nikolai Weibull Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Aug 20 22:42:43 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1djX3M-0006dg-A3 for ged-emacs-devel@m.gmane.org; Sun, 20 Aug 2017 22:42:36 +0200 Original-Received: from localhost ([::1]:58056 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1djX3S-0000S7-S7 for ged-emacs-devel@m.gmane.org; Sun, 20 Aug 2017 16:42:42 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:38403) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1djX2i-0000RB-3Y for emacs-devel@gnu.org; Sun, 20 Aug 2017 16:41:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1djX2e-0006rg-5q for emacs-devel@gnu.org; Sun, 20 Aug 2017 16:41:56 -0400 Original-Received: from ocolin.muc.de ([193.149.48.4]:26045 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1djX2d-0006rK-S2 for emacs-devel@gnu.org; Sun, 20 Aug 2017 16:41:52 -0400 Original-Received: (qmail 53002 invoked by uid 3782); 20 Aug 2017 20:41:48 -0000 Original-Received: from acm.muc.de (p548C6BFC.dip0.t-ipconnect.de [84.140.107.252]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 20 Aug 2017 22:41:47 +0200 Original-Received: (qmail 8414 invoked by uid 1000); 20 Aug 2017 20:40:30 -0000 Content-Disposition: inline In-Reply-To: X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 193.149.48.4 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:217645 Archived-At: Hello, Nikolai. On Tue, Aug 15, 2017 at 11:57:25 +0200, Nikolai Weibull wrote: > On Tue, Aug 15, 2017 at 11:03 AM, Stefan Monnier > wrote: > >> C-mode doesn’t seem to understand C99’s compound literals, resulting in > >> rather broken indentation. Is this correct and, if so, how difficult would > >> it be to add support for it? > > Could you show some example problematic code? > Yes: > struct a { > int b; > }; This seems to be correctly analysed and indented by CC Mode. You can see this by doing C-c C-s on any line to get the syntactic analysis. On the middle line, this shows ((inclass 332) (topmost-intro 332)) (where the "332" may vary, depending on the position in the file). The "inclass" bit causes an indentation of c-basic-offset (here 8) columns. What indentation do you want here? > int > main(void) > { > return (struct a){ > 0 > }.b; > } Here, the "0" line is being wrongly analysed as a statement-block-intro, when it should be a brace-list-intro. The problem is that brace lists are recognised only by their context in the source code, rather than their internal structure. When a brace list can appear virtually anywhere, this doesn't make sense. The following patch causes brace lists to be recognised by their internal structure too. Would you please apply it to CC Mode (in directory .../lisp/progmodes), try it out, and let me know how well it solves the problems with compound literals. diff -r 9533dc4cbda3 cc-engine.el --- a/cc-engine.el Thu Jul 27 17:37:02 2017 +0000 +++ b/cc-engine.el Sun Aug 20 20:00:49 2017 +0000 @@ -10658,26 +10658,35 @@ (defun c-looking-at-statement-block () ;; Point is at an opening brace. If this is a statement block (i.e. the - ;; elements in it are terminated by semicolons) return t. Otherwise, return - ;; nil. + ;; elements in the block are terminated by semicolons, or the block is + ;; empty, or the block contains a keyword) return t. Otherwise, return nil. (let ((here (point))) (prog1 (if (c-go-list-forward) (let ((there (point))) (backward-char) - (c-syntactic-skip-backward - "^;," here t) + (c-syntactic-skip-backward "^;," here t) (cond ((eq (char-before) ?\;) t) ((eq (char-before) ?,) nil) - (t (goto-char here) - (forward-char) - (and (c-syntactic-re-search-forward "{" there t t) - (progn (backward-char) - (c-looking-at-statement-block)))))) + (t ; We're at (1+ here). + (cond + ((progn (c-forward-syntactic-ws) + (eq (point) (1- there))) + t) + ((c-syntactic-re-search-forward c-keywords-regexp there t) + t) + ((c-syntactic-re-search-forward "{" there t t) + (backward-char) + (c-looking-at-statement-block)) + (t nil))))) (forward-char) - (and (c-syntactic-re-search-forward "[;,]" nil t t) - (eq (char-before) ?\;))) + (cond + ((c-syntactic-re-search-forward "[;,]" nil t t) + (eq (char-before) ?\;)) + ((c-syntactic-re-search-forward c-keywords-regexp nil t t) + t) + (t nil))) (goto-char here)))) (defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end) @@ -12467,7 +12476,11 @@ (save-excursion (goto-char containing-sexp) (c-looking-at-special-brace-list))) - (c-inside-bracelist-p containing-sexp paren-state)))) + (c-inside-bracelist-p containing-sexp paren-state) + (save-excursion + (goto-char containing-sexp) + (and (eq (char-after) ?{) + (not (c-looking-at-statement-block))))))) (cond ;; CASE 9A: In the middle of a special brace list opener. [ .... ] > Nikolai -- Alan Mackenzie (Nuremberg, Germany).