emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: C99 compound literals in c-mode


From: Alan Mackenzie
Subject: Re: C99 compound literals in c-mode
Date: Sun, 20 Aug 2017 20:40:30 +0000
User-agent: Mutt/1.7.2 (2016-11-26)

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
> <address@hidden> 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).



reply via email to

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