GNU bug report logs - #28050
CC Mode 5.33 (C/*l); indentation of array and enum in GNU style isn't right

Previous Next

Package: cc-mode;

Reported by: Mohammed Sadiq <sadiq <at> sadiqpk.org>

Date: Fri, 11 Aug 2017 17:23:02 UTC

Severity: normal

Done: Alan Mackenzie <acm <at> muc.de>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 28050 in the body.
You can then email your comments to 28050 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-cc-mode <at> gnu.org:
bug#28050; Package cc-mode. (Fri, 11 Aug 2017 17:23:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Mohammed Sadiq <sadiq <at> sadiqpk.org>:
New bug report received and forwarded. Copy sent to bug-cc-mode <at> gnu.org. (Fri, 11 Aug 2017 17:23:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Mohammed Sadiq <sadiq <at> sadiqpk.org>
To: submit <at> debbugs.gnu.org
Subject: CC Mode 5.33 (C/*l);
 indentation of array and enum in GNU style isn't right
Date: Fri, 11 Aug 2017 22:50:02 +0530

For the following code, the indentation of the code isn't right for GNU
style (C-x h TAB after writing the code):

/* Output after default (auto)indentation in GNU Emacs (TAB is used sometimes) */
char *words[] = {
		 "good",
		 "better",
		 "best"
};

The GNU style is (as done by the program GNU indent):

/* They should be indented with 2 spaces (and not TABs)
char *words[] = {
  "good",
  "better",
  "best"
};

Tabs are also add for indentation when defining enums:

typedef enum {
	      GOOD,
	      BETTER,
	      BEST
} test;


The following might be better (2 spaces, and no TABs):

typedef enum {
  GOOD,
  BETTER,
  BEST
} test;

Emacs  : GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-08-11
Package: CC Mode 5.33 (C/*l)
Buffer Style: gnu
c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)

current state:
==============
(setq
 c-basic-offset 2
 c-comment-only-line-offset '(0 . 0)
 c-indent-comment-alist '((anchored-comment column . 0) (end-block space . 1)
			  (cpp-end-block space . 2))
 c-indent-comments-syntactically-p nil
 c-block-comment-prefix ""
 c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+")
			   (other . "//+\\|\\**"))
 c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc)
		       (c-mode . gtkdoc))
 c-cleanup-list '(scope-operator)
 c-hanging-braces-alist '((substatement-open before after)
			  (arglist-cont-nonempty))
 c-hanging-colons-alist nil
 c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
 c-backslash-column 48
 c-backslash-max-column 72
 c-special-indent-hook '(c-gnu-impose-minimum)
 c-label-minimum-indentation 1
 c-offsets-alist '((inexpr-class . +)
		   (inexpr-statement . +)
		   (lambda-intro-cont . +)
		   (inlambda . c-lineup-inexpr-block)
		   (template-args-cont c-lineup-template-args +)
		   (incomposition . +)
		   (inmodule . +)
		   (innamespace . +)
		   (inextern-lang . +)
		   (composition-close . 0)
		   (module-close . 0)
		   (namespace-close . 0)
		   (extern-lang-close . 0)
		   (composition-open . 0)
		   (module-open . 0)
		   (namespace-open . 0)
		   (extern-lang-open . 0)
		   (objc-method-call-cont
		    c-lineup-ObjC-method-call-colons
		    c-lineup-ObjC-method-call
		    +
		    )
		   (objc-method-args-cont . c-lineup-ObjC-method-args)
		   (objc-method-intro . [0])
		   (friend . 0)
		   (cpp-define-intro c-lineup-cpp-define +)
		   (cpp-macro-cont . +)
		   (cpp-macro . [0])
		   (inclass . +)
		   (stream-op . c-lineup-streamop)
		   (arglist-cont-nonempty
		    c-lineup-gcc-asm-reg
		    c-lineup-arglist
		    )
		   (arglist-cont c-lineup-gcc-asm-reg 0)
		   (comment-intro c-lineup-knr-region-comment c-lineup-comment)
		   (catch-clause . 0)
		   (else-clause . 0)
		   (do-while-closure . 0)
		   (access-label . -)
		   (case-label . 0)
		   (substatement . +)
		   (statement-case-intro . +)
		   (statement . 0)
		   (brace-entry-open . 0)
		   (brace-list-entry . c-lineup-under-anchor)
		   (brace-list-close . 0)
		   (block-close . 0)
		   (block-open . 0)
		   (inher-cont . c-lineup-multi-inher)
		   (inher-intro . +)
		   (member-init-cont . c-lineup-multi-inher)
		   (member-init-intro . +)
		   (annotation-var-cont . +)
		   (annotation-top-cont . 0)
		   (topmost-intro . 0)
		   (knr-argdecl . 0)
		   (func-decl-cont . +)
		   (inline-close . 0)
		   (class-close . 0)
		   (class-open . 0)
		   (defun-block-intro . +)
		   (defun-close . 0)
		   (defun-open . 0)
		   (c . c-lineup-C-comments)
		   (string . c-lineup-dont-change)
		   (topmost-intro-cont
		    first
		    c-lineup-topmost-intro-cont
		    c-lineup-gnu-DEFUN-intro-cont
		    )
		   (brace-list-intro . c-lineup-arglist-intro-after-paren)
		   (brace-list-open . +)
		   (inline-open . 0)
		   (arglist-close . c-lineup-arglist)
		   (arglist-intro . c-lineup-arglist-intro-after-paren)
		   (statement-cont . +)
		   (statement-case-open . +)
		   (label . 0)
		   (substatement-label . 0)
		   (substatement-open . +)
		   (knr-argdecl-intro . 5)
		   (statement-block-intro . +)
		   )
 c-buffer-is-cc-mode 'c-mode
 c-tab-always-indent t
 c-syntactic-indentation t
 c-syntactic-indentation-in-macros t
 c-ignore-auto-fill '(string cpp code)
 c-auto-align-backslashes t
 c-backspace-function 'backward-delete-char-untabify
 c-delete-function 'delete-char
 c-electric-pound-behavior nil
 c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu"))
 c-enable-xemacs-performance-kludge-p nil
 c-old-style-variable-behavior nil
 defun-prompt-regexp nil
 tab-width 8
 comment-column 32
 parse-sexp-ignore-comments t
 parse-sexp-lookup-properties t
 auto-fill-function nil
 comment-multi-line t
 comment-start-skip "\\(//+\\|/\\*+\\)\\s *"
 fill-prefix nil
 fill-column 70
 paragraph-start "[ 	]*\\(//+\\|\\**\\)[ 	]*$\\|^\f"
 adaptive-fill-mode t
 adaptive-fill-regexp "[ 	]*\\(//+\\|\\**\\)[ 	]*\\([ 	]*\\([-–!|#%;>*·•‣⁃◦]+[ 	]*\\)*\\)"
 )




Information forwarded to bug-cc-mode <at> gnu.org:
bug#28050; Package cc-mode. (Sat, 22 Sep 2018 19:36:01 GMT) Full text and rfc822 format available.

Message #8 received at 28050 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Mohammed Sadiq <sadiq <at> sadiqpk.org>
Cc: 28050 <at> debbugs.gnu.org
Subject: Re: bug#28050: CC Mode 5.33 (C/*l); indentation of array and enum in
 GNU style isn't right
Date: Sat, 22 Sep 2018 19:30:59 +0000
Hello, Mohammed.

It's been over a year since you reported the bug below.  I'm top-posting
this, so that you see exactly what you wrote, it being so long ago.
Sorry about this delay.  Are you still interested in this bug?

This has been a difficult bug to solve, not for the cases you gave,
e.g.:

    typedef enum {
                  GOOD,
		  BETTER,
		  BEST
    };

but the case in which the first element inside the braces is on the same
line as the opening brace:

    typedef enum {GOOD,
        BETTER,
	BEST
    };

, which surely ought to be indented as above (I'm using a c-basic-offset
of 4 for clarity in the examples), and _not_ like this:

    typedef enum {GOOD,
                  BETTER,
		  BEST
    };

.  However, Emacs bug #24431 from Matthias Meulien, complained about the
exact opposite.  His case was that the following C++ was mis-aligned:

    set_line(line_t{point_t{0.4, 0.2},
          point_t{0.2, 0.5}}); // wrong identation

, and that the second line should line up with the "point_t" in the
first line.  I "fixed" this bug, hence the trouble with GOOD, BETTER,
and BEST.

My trouble with bug #24431 was I didn't realise that that was a special
case.  What makes it so was the opening paren after "set_line", a bit of
DWIM ("Do what I mean").

I think I've now (almost) got this sorted out.  I'm applying the
following rules to brace lists in "gnu" style and several other styles:

1. When the first entry is on the next line after the brace, it will be
indented by c-basic-offset ("+"), as will the following entries.

2. When the first entry is on the _same_ line as the brace, the
following entries are normally indented by c-basic-offset.

3. As an exception to 2., if the line with the opening brace and first
entry has a "(" or another "{" earlier on IN THE LINE, the second and
subsequent entries are lined up under the first entry:

    set_line(line_t{point_t{0.4, 0.2},
                    point_t{0.2, 0.5}});

4. As a further exception to 2, when a variable of a struct, union,
class, .... type is being declared like in the following example, the
second and subsequent entries are indented c-basic-offset from THE
VARIABLE, not from the start of the declaration:

1.    struct STR {
2.        int i; float f;
3.    } str_1 = /* ; */ {1, 1.7},
4.        str_2 = {2,
5.            3.1                  <================================
6.        };

Critical here is that the brace block of "struct STR" is present, and
one or more variables of this type are declared at the same place.  The
"3.1" on line 5 is indented from the "str_2" on line 4, NOT from the
anchor point which is "struct" on line 1.

However, the changes to implement these rules have produced a patch a
little under 600 lines long.  :-(  These changes are not quite finished:
some doc strings need writing, and some new line-up functions need to be
documented in the CC Mode manual.  However, other than that it is ready.

Are you still interested in this bug?  If so, would you be prepared to
apply this ~600 line patch, compile it, and test it?  If so, I would be
grateful.  :-)  If so 2, would you please tell me in your reply which CC
Mode sources you are using (I'm a bit sloppy with version numbers).  Are
you using the standalone CC Mode from sourceforge, or the version
distributed together with Emacs 26?  Knowing this would help me prepare
the patch for the version of CC Mode you're actually using.

-- 
Alan Mackenzie (Nuremberg, Germany).





On Fri, Aug 11, 2017 at 22:50:02 +0530, Mohammed Sadiq wrote:


> For the following code, the indentation of the code isn't right for GNU
> style (C-x h TAB after writing the code):

> /* Output after default (auto)indentation in GNU Emacs (TAB is used sometimes) */
> char *words[] = {
> 		 "good",
> 		 "better",
> 		 "best"
> };

> The GNU style is (as done by the program GNU indent):

> /* They should be indented with 2 spaces (and not TABs)
> char *words[] = {
>   "good",
>   "better",
>   "best"
> };

> Tabs are also add for indentation when defining enums:

> typedef enum {
> 	        GOOD,
> 	        BETTER,
> 	        BEST
> } test;


> The following might be better (2 spaces, and no TABs):

> typedef enum {
>   GOOD,
>   BETTER,
>   BEST
> } test;

> Emacs  : GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
>  of 2017-08-11
> Package: CC Mode 5.33 (C/*l)
> Buffer Style: gnu
> c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)

> current state:
> ==============
> (setq
>  c-basic-offset 2
>  c-comment-only-line-offset '(0 . 0)
>  c-indent-comment-alist '((anchored-comment column . 0) (end-block space . 1)
> 			  (cpp-end-block space . 2))
>  c-indent-comments-syntactically-p nil
>  c-block-comment-prefix ""
>  c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+")
> 			   (other . "//+\\|\\**"))
>  c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc)
> 		       (c-mode . gtkdoc))
>  c-cleanup-list '(scope-operator)
>  c-hanging-braces-alist '((substatement-open before after)
> 			  (arglist-cont-nonempty))
>  c-hanging-colons-alist nil
>  c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
>  c-backslash-column 48
>  c-backslash-max-column 72
>  c-special-indent-hook '(c-gnu-impose-minimum)
>  c-label-minimum-indentation 1
>  c-offsets-alist '((inexpr-class . +)
> 		   (inexpr-statement . +)
> 		   (lambda-intro-cont . +)
> 		   (inlambda . c-lineup-inexpr-block)
> 		   (template-args-cont c-lineup-template-args +)
> 		   (incomposition . +)
> 		   (inmodule . +)
> 		   (innamespace . +)
> 		   (inextern-lang . +)
> 		   (composition-close . 0)
> 		   (module-close . 0)
> 		   (namespace-close . 0)
> 		   (extern-lang-close . 0)
> 		   (composition-open . 0)
> 		   (module-open . 0)
> 		   (namespace-open . 0)
> 		   (extern-lang-open . 0)
> 		   (objc-method-call-cont
> 		    c-lineup-ObjC-method-call-colons
> 		    c-lineup-ObjC-method-call
> 		    +
> 		    )
> 		   (objc-method-args-cont . c-lineup-ObjC-method-args)
> 		   (objc-method-intro . [0])
> 		   (friend . 0)
> 		   (cpp-define-intro c-lineup-cpp-define +)
> 		   (cpp-macro-cont . +)
> 		   (cpp-macro . [0])
> 		   (inclass . +)
> 		   (stream-op . c-lineup-streamop)
> 		   (arglist-cont-nonempty
> 		    c-lineup-gcc-asm-reg
> 		    c-lineup-arglist
> 		    )
> 		   (arglist-cont c-lineup-gcc-asm-reg 0)
> 		   (comment-intro c-lineup-knr-region-comment c-lineup-comment)
> 		   (catch-clause . 0)
> 		   (else-clause . 0)
> 		   (do-while-closure . 0)
> 		   (access-label . -)
> 		   (case-label . 0)
> 		   (substatement . +)
> 		   (statement-case-intro . +)
> 		   (statement . 0)
> 		   (brace-entry-open . 0)
> 		   (brace-list-entry . c-lineup-under-anchor)
> 		   (brace-list-close . 0)
> 		   (block-close . 0)
> 		   (block-open . 0)
> 		   (inher-cont . c-lineup-multi-inher)
> 		   (inher-intro . +)
> 		   (member-init-cont . c-lineup-multi-inher)
> 		   (member-init-intro . +)
> 		   (annotation-var-cont . +)
> 		   (annotation-top-cont . 0)
> 		   (topmost-intro . 0)
> 		   (knr-argdecl . 0)
> 		   (func-decl-cont . +)
> 		   (inline-close . 0)
> 		   (class-close . 0)
> 		   (class-open . 0)
> 		   (defun-block-intro . +)
> 		   (defun-close . 0)
> 		   (defun-open . 0)
> 		   (c . c-lineup-C-comments)
> 		   (string . c-lineup-dont-change)
> 		   (topmost-intro-cont
> 		    first
> 		    c-lineup-topmost-intro-cont
> 		    c-lineup-gnu-DEFUN-intro-cont
> 		    )
> 		   (brace-list-intro . c-lineup-arglist-intro-after-paren)
> 		   (brace-list-open . +)
> 		   (inline-open . 0)
> 		   (arglist-close . c-lineup-arglist)
> 		   (arglist-intro . c-lineup-arglist-intro-after-paren)
> 		   (statement-cont . +)
> 		   (statement-case-open . +)
> 		   (label . 0)
> 		   (substatement-label . 0)
> 		   (substatement-open . +)
> 		   (knr-argdecl-intro . 5)
> 		   (statement-block-intro . +)
> 		   )
>  c-buffer-is-cc-mode 'c-mode
>  c-tab-always-indent t
>  c-syntactic-indentation t
>  c-syntactic-indentation-in-macros t
>  c-ignore-auto-fill '(string cpp code)
>  c-auto-align-backslashes t
>  c-backspace-function 'backward-delete-char-untabify
>  c-delete-function 'delete-char
>  c-electric-pound-behavior nil
>  c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu"))
>  c-enable-xemacs-performance-kludge-p nil
>  c-old-style-variable-behavior nil
>  defun-prompt-regexp nil
>  tab-width 8
>  comment-column 32
>  parse-sexp-ignore-comments t
>  parse-sexp-lookup-properties t
>  auto-fill-function nil
>  comment-multi-line t
>  comment-start-skip "\\(//+\\|/\\*+\\)\\s *"
>  fill-prefix nil
>  fill-column 70
>  paragraph-start "[ 	]*\\(//+\\|\\**\\)[ 	]*$\\|^\f"
>  adaptive-fill-mode t
>  adaptive-fill-regexp "[ 	]*\\(//+\\|\\**\\)[ 	]*\\([ 	]*\\([-–!|#%;>*·•‣⁃◦]+[ 	]*\\)*\\)"
>  )



> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot




Information forwarded to bug-cc-mode <at> gnu.org:
bug#28050; Package cc-mode. (Tue, 25 Sep 2018 19:38:02 GMT) Full text and rfc822 format available.

Message #11 received at 28050 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Mohammed Sadiq <sadiq <at> sadiqpk.org>
Cc: 28050 <at> debbugs.gnu.org
Subject: Re: bug#28050: CC Mode 5.33 (C/*l); indentation of array and enum in
 GNU style isn't right
Date: Tue, 25 Sep 2018 19:32:21 +0000
Hello, Mohammed.

On Sun, Sep 23, 2018 at 05:47:29 +0530, Mohammed Sadiq wrote:
> On 2018-09-23 01:00, Alan Mackenzie wrote:
> Hi,

> > It's been over a year since you reported the bug below.  I'm
> > top-posting this, so that you see exactly what you wrote, it being so
> > long ago.  Sorry about this delay.  Are you still interested in this
> > bug?

> > This has been a difficult bug to solve, not for the cases you gave,
> > e.g.:

> >     typedef enum {
> >                   GOOD,
> > 		  BETTER,
> > 		  BEST
> >     };

> I think I filed a bug for all of them to be miss-indented (Not just the 
> first item)

Sorry, I believe you did indeed.

> ie, this:
>      typedef enum {
>                    GOOD,
>                    BAD,
>                    NICE,
>      };

>      typedef enum {GOOD,
>                    BETTER,
>                    BEST
>      };

> [ ... ]

> > However, the changes to implement these rules have produced a patch a
> > little under 600 lines long.  :-(  These changes are not quite
> > finished: some doc strings need writing, and some new line-up
> > functions need to be documented in the CC Mode manual.  However,
> > other than that it is ready.

> > Are you still interested in this bug?  If so, would you be prepared to
> > apply this ~600 line patch, compile it, and test it?  If so, I would be

> Sure I'm interested. I have been using the following in my .dir-locals
> as a fix for this:

> ((nil . ((fill-column . 80)))
>   (c-mode . ((c-file-style . "GNU")
>              (c-file-offsets
>               (brace-list-intro . +)))))

> > grateful.  :-)  If so 2, would you please tell me in your reply which
> > CC Mode sources you are using (I'm a bit sloppy with version
> > numbers).

> I'm using the builtin cc-mode in GNU Emacs 27.x (from git master branch)

OK.  Here's (part of) the patch.  I haven't included the amendment to the
CC Mode manual for now, but I doubt that will bother you too much.

Would you please follow the following directions carefully: it's all too
easy to end up with a mixture of old and new (I've done that several
times):

1. Please apply the patch to the files in ..../emacs/lisp/progmodes, then
byte compile CC Mode in its entirety.  Something like

    $ emacs -Q -batch -f batch-byte-compile lisp/progmodes/cc-*.el

will do it.  Then please do either:

2a. Move the newly generated .elc files to where your Emacs finds its CC
Mode, e.g. ..../emacs/lisp/progmodes.  Then restart Emacs.

OR

2b. (Assuming your initialisation files don't load a particular other
version of CC Mode) restart your Emacs using -L, like this:

    $ emacs <other arguments> -L path/to/new/CC/Mode

.  This should ensure that the old CC Mode doesn't prevent the new one
loading fully.

Please then remove your workaround from .dir-locals, and test the new CC
Mode with your real source code.  Please let me know how well it works,
telling me about any problems you might still find.

Thanks!



diff -r e38b65ad9145 cc-align.el
--- a/cc-align.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-align.el	Tue Sep 25 19:01:56 2018 +0000
@@ -1086,6 +1086,130 @@
 	      (vector (+ (current-column) c-basic-offset))))
 	(vector 0)))))
 
+(defun c-lineup-2nd-brace-entry-in-arglist (langelem)
+  "Lineup the second entry of a brace block under the first, when the first
+line is also contained in an arglist or an enclosing brace ON THAT LINE.
+
+I.e. handle something like the following:
+
+    set_line (line_t {point_t{0.4, 0.2},
+                      point_t{0.2, 0.5},       <---- brace-list-intro
+                      .....});
+             ^ enclosing parenthesis.
+
+The middle line of that example will have a syntactic context
+with three syntactic symbols, arglist-cont-nonempty, brace-list-intro, and
+brace-list-entry.
+
+This function is intended for use in a list.  If the construct
+being analyzed isn't like the preceding, the function returns nil.
+Otherwise it returns the function `c-lineup-arglist-intro-after-paren', which
+the caller then uses to perform indentation.
+
+Works with brace-list-intro."
+  ;; brace-list-intro and brace-list-entry are both present for the second
+  ;; entry of the list when the first entry is on the same line as the opening
+  ;; brace.
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (or (assq 'arglist-cont-nonempty c-syntactic-context) ; "(" earlier on
+							     ; the line.
+	   (save-excursion		; "{" earlier on the line
+	     (goto-char (c-langelem-pos
+			 (assq 'brace-list-intro c-syntactic-context)))
+	     (and
+	      (eq (c-backward-token-2
+		   1 nil
+		   (c-point 'bol (c-langelem-pos
+				  (assq 'brace-list-entry
+					c-syntactic-context))))
+		  0)
+	      (eq (char-after) ?{))))
+       'c-lineup-arglist-intro-after-paren))
+
+(defun c-lineup-class-decl-init-+ (langelem)
+  "Line up the second entry of a class (etc.) initializer c-basic-offset
+characters in from the identifier when:
+\(i) The type is a class, struct, union, etc. (but not an enum);
+\(ii) There is a brace block in the type declaration, specifying it; and
+\(iii) The first element of the initializer is on the same line as its opening
+brace.
+
+I.e. we have a construct like this:
+
+    struct STR {
+        int i; float f;
+    } str_1 = {1, 1.7},
+        str_2 = {2,
+             3.1                   <---- brace-list-intro
+        };
+        <-->                       <---- c-basic-offset
+
+Note that the syntactic context of the brace-list-intro line also has a
+syntactic element with the symbol brace-list-entry.
+
+This function is intended for use in a list.  If the above structure isn't
+present, this function returns nil, allowing a different offset specification
+to indent the line.
+
+Works with: brace-list-intro."
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (let ((init-pos (c-point 'boi (c-langelem-pos
+				      (assq 'brace-list-entry
+					    c-syntactic-context))))
+	     )
+	 (save-excursion
+	   (goto-char (c-langelem-pos (assq 'brace-list-intro
+					    c-syntactic-context)))
+	   (and
+	    (c-forward-class-decl)
+	    (not (c-do-declarators init-pos t nil nil nil))
+	    (eq (point) init-pos)
+	    (vector (+ (current-column) c-basic-offset)))))))
+
+(defun c-lineup-class-decl-init-after-brace (langelem)
+  "Line up the second entry of a class (etc.) initializer after its opening
+brace when:
+\(i) The type is a class, struct, union, etc. (but not an enum);
+\(ii) There is a brace block in the type declaration, specifying it; and
+\(iii) The first element of the initializer is on the same line as its opening
+brace.
+
+I.e. we have a construct like this:
+
+    struct STR {
+        int i; float f;
+    } str_1 = {1, 1.7},
+        str_2 = {2,
+                 3.1                   <---- brace-list-intro
+        };
+
+Note that the syntactic context of the brace-list-intro line also has a
+syntactic element with the symbol brace-list-entry.  Also note that this
+function works by returning the symbol `c-lineup-arglist-intro-after-paren',
+which the caller then uses to perform the indentation.
+
+This function is intended for use in a list.  If the above structure isn't
+present, this function returns nil, allowing a different offset specification
+to indent the line.
+
+Works with: brace-list-intro."
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (let ((init-pos (c-point 'boi (c-langelem-pos
+				      (assq 'brace-list-entry
+					    c-syntactic-context))))
+	     )
+	 (save-excursion
+	   (goto-char (c-langelem-pos (assq 'brace-list-intro
+					    c-syntactic-context)))
+	   (and
+	    (c-forward-class-decl)
+	    (not (c-do-declarators init-pos t nil nil nil))
+	    (eq (point) init-pos)
+	    'c-lineup-arglist-intro-after-paren)))))
+
 (defun c-lineup-cpp-define (_langelem)
   "Line up macro continuation lines according to the indentation of
 the construct preceding the macro.  E.g.:
diff -r e38b65ad9145 cc-engine.el
--- a/cc-engine.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-engine.el	Tue Sep 25 19:01:56 2018 +0000
@@ -7936,49 +7936,28 @@
     (or res (goto-char here))
     res))
 
+(defun c-forward-class-decl ()
+  "From the beginning of a struct/union, etc. move forward to
+after the brace block which defines it, leaving point at the
+start of the next token and returning pointt.  On failure leave
+point unchanged and return nil."
+  (let ((here (point)))
+    (if
+	(and
+	 (looking-at c-class-key)
+	 (eq (c-forward-token-2) 0)
+	 (c-on-identifier)
+	 (eq (c-forward-token-2) 0)
+	 (eq (char-after) ?{)
+	 (c-go-list-forward))
+	(progn
+	  (c-forward-syntactic-ws)
+	  (point))
+      (goto-char here)
+      nil)))
 
 ;; Handling of large scale constructs like statements and declarations.
 
-;; Macro used inside `c-forward-decl-or-cast-1'.  It ought to be a
-;; defsubst or perhaps even a defun, but it contains lots of free
-;; variables that refer to things inside `c-forward-decl-or-cast-1'.
-(defmacro c-fdoc-shift-type-backward (&optional short)
-  ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
-  ;; of types when parsing a declaration, which means that it
-  ;; sometimes consumes the identifier in the declaration as a type.
-  ;; This is used to "backtrack" and make the last type be treated as
-  ;; an identifier instead.
-  `(progn
-     ,(unless short
-	;; These identifiers are bound only in the inner let.
-	'(setq identifier-type at-type
-	       identifier-start type-start
-	       got-parens nil
-	       got-identifier t
-	       got-suffix t
-	       got-suffix-after-parens id-start
-	       paren-depth 0))
-
-     (if (setq at-type (if (eq backup-at-type 'prefix)
-			   t
-			 backup-at-type))
-	 (setq type-start backup-type-start
-	       id-start backup-id-start)
-       (setq type-start start-pos
-	     id-start start-pos))
-
-     ;; When these flags already are set we've found specifiers that
-     ;; unconditionally signal these attributes - backtracking doesn't
-     ;; change that.  So keep them set in that case.
-     (or at-type-decl
-	 (setq at-type-decl backup-at-type-decl))
-     (or maybe-typeless
-	 (setq maybe-typeless backup-maybe-typeless))
-
-     ,(unless short
-	;; This identifier is bound only in the inner let.
-	'(setq start id-start))))
-
 (defun c-forward-declarator (&optional limit accept-anon)
   ;; Assuming point is at the start of a declarator, move forward over it,
   ;; leaving point at the next token after it (e.g. a ) or a ; or a ,).
@@ -8131,6 +8110,171 @@
       (goto-char here)
       nil)))
 
+(defun c-do-declarators (limit list not-top comma-prop cdd-function)
+  "Assuming point is at the start of a comma separated list of declarators,
+apply CDD-FUNCTION to each declarator (when LIST is non-nil) or just the
+first declarator (when LIST is nil).  When CDD-FUNCTION is nil, no
+function is applied.
+
+CDD-FUNCTION is supplied with 6 arguments:
+0. The start position of the declarator's identifier;
+1. The end position of this identifier;
+\[Note: if there is no identifier, as in int (*);, both of these are nil.]
+2. The position of the next token after the declarator (CLARIFY!!!).
+3. NOT-TOP;
+4. Non-nil if the identifier is of a function.
+5. When there is an initialization following the declarator (such as \"=
+....\" or \"( ....\".), the character which introduces this initialization,
+otherwise nil.
+
+Additionally, if COMMA-PROP is non-nil, mark the separating commas with
+this value of the c-type property, when LIST is non-nil.
+
+Stop at or before LIMIT (which may NOT be nil).
+
+If NOT-TOP is non-nil, we are not at the top-level (\"top-level\" includes
+being directly inside a class or namespace, etc.).
+
+Nil is always returned.  The function leaves point at the delimiter after
+the last declarator it processes.  FIXME!!! Check this (2018-09-21)
+
+This function might do hidden buffer changes."
+  (let
+      ((pos (point)) next-pos id-start id-end
+       decl-res got-func got-type got-init
+       c-last-identifier-range exhausted result)
+
+    ;; The following `while' fontifies a single declarator id each time round.
+    ;; It loops only when LIST is non-nil.
+    (while
+	(and (not exhausted)
+	     (setq decl-res (c-forward-declarator limit)))
+      (setq next-pos (point)
+	    id-start (car decl-res)
+	    id-end (cadr decl-res)
+	    got-func (and (eq (char-after) ?\()
+			  (or (not (c-major-mode-is 'c++-mode))
+			      (not not-top)
+			      (car (cddr (cddr decl-res))) ; Id is in
+					; parens, etc.
+			      (save-excursion
+				(forward-char)
+				(c-forward-syntactic-ws)
+				(looking-at "[*&]")))
+			  (not (car (cddr decl-res)))
+			  (or (not (c-major-mode-is 'c++-mode))
+			      (save-excursion
+				(let (c-last-identifier-range)
+				  (forward-char)
+				  (c-forward-syntactic-ws)
+				  (catch 'is-function
+				    (while
+					(progn
+					  (if (eq (char-after) ?\))
+					      (throw 'is-function t))
+					  (setq got-type (c-forward-type))
+					  (cond
+					   ((null got-type)
+					    (throw 'is-function nil))
+					   ((not (eq got-type 'maybe))
+					    (throw 'is-function t)))
+					  (c-forward-declarator nil t)
+					  (eq (char-after) ?,))
+				      (forward-char)
+				      (c-forward-syntactic-ws))
+				    t)))))
+	    got-init (and (cadr (cddr decl-res))
+			  (char-after)))
+
+      ;; Jump past any initializer or function prototype to see if
+      ;; there's a ',' to continue at.
+      (cond (got-func
+	     ;; Skip a parenthesized initializer (C++) or a function
+	     ;; prototype.
+	     (if (c-go-list-forward (point) limit) ; over the parameter list.
+		 (c-forward-syntactic-ws limit)
+	       (setq exhausted t)))	; unbalanced parens
+
+	    (got-init	; "=" sign OR opening "(", "[", or "{"
+	     ;; Skip an initializer expression.  If we're at a '='
+	     ;; then accept a brace list directly after it to cope
+	     ;; with array initializers.  Otherwise stop at braces
+	     ;; to avoid going past full function and class blocks.
+	     (if (and (if (and (eq got-init ?=)
+			       (= (c-forward-token-2 1 nil limit) 0)
+			       (looking-at "{"))
+			  (c-go-list-forward (point) limit)
+			t)
+		      ;; FIXME: Should look for c-decl-end markers here;
+		      ;; we might go far into the following declarations
+		      ;; in e.g. ObjC mode (see e.g. methods-4.m).
+		      (c-syntactic-re-search-forward "[;,{]" limit 'move t))
+		 (backward-char)
+	       (setq exhausted t)
+	       ))
+
+	    (t (c-forward-syntactic-ws limit)))
+
+      (if cdd-function
+	  (funcall cdd-function id-start id-end next-pos not-top got-func
+		   got-init))
+
+      ;; If a ',' is found we set pos to the next declarator and iterate.
+      (if (and list (< (point) limit) (looking-at ","))
+	  (progn
+	    (when comma-prop
+	      (c-put-char-property (point) 'c-type comma-prop))
+	    (when list
+	      (forward-char)
+	      (c-forward-syntactic-ws limit)
+	      (setq pos (point))))
+	(setq exhausted t)))
+
+    (if (> (point) pos)
+	t
+      (goto-char pos)
+      nil)))
+
+;; Macro used inside `c-forward-decl-or-cast-1'.  It ought to be a
+;; defsubst or perhaps even a defun, but it contains lots of free
+;; variables that refer to things inside `c-forward-decl-or-cast-1'.
+(defmacro c-fdoc-shift-type-backward (&optional short)
+  ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
+  ;; of types when parsing a declaration, which means that it
+  ;; sometimes consumes the identifier in the declaration as a type.
+  ;; This is used to "backtrack" and make the last type be treated as
+  ;; an identifier instead.
+  `(progn
+     ,(unless short
+	;; These identifiers are bound only in the inner let.
+	'(setq identifier-type at-type
+	       identifier-start type-start
+	       got-parens nil
+	       got-identifier t
+	       got-suffix t
+	       got-suffix-after-parens id-start
+	       paren-depth 0))
+
+     (if (setq at-type (if (eq backup-at-type 'prefix)
+			   t
+			 backup-at-type))
+	 (setq type-start backup-type-start
+	       id-start backup-id-start)
+       (setq type-start start-pos
+	     id-start start-pos))
+
+     ;; When these flags already are set we've found specifiers that
+     ;; unconditionally signal these attributes - backtracking doesn't
+     ;; change that.  So keep them set in that case.
+     (or at-type-decl
+	 (setq at-type-decl backup-at-type-decl))
+     (or maybe-typeless
+	 (setq maybe-typeless backup-maybe-typeless))
+
+     ,(unless short
+	;; This identifier is bound only in the inner let.
+	'(setq start id-start))))
+
 (defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end)
   ;; Move forward over a declaration or a cast if at the start of one.
   ;; The point is assumed to be at the start of some token.  Nil is
@@ -10608,12 +10752,17 @@
       )))
 
 (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren)
-  ;; return the buffer position of the beginning of the brace list
-  ;; statement if we're inside a brace list, otherwise return nil.
-  ;; CONTAINING-SEXP is the buffer pos of the innermost containing
-  ;; paren.  PAREN-STATE is the remainder of the state of enclosing
-  ;; braces.  ACCEPT-IN-PAREN is non-nil iff we will accept as a brace
-  ;; list a brace directly enclosed in a parenthesis.
+  ;; return the buffer position of the beginning of the brace list statement
+  ;; if CONTAINING-SEXP is inside a brace list, otherwise return nil.
+  ;;
+  ;; CONTAINING-SEXP is the buffer pos of the innermost containing paren.  NO
+  ;; IT ISN'T!!!  [This function is badly designed, and probably needs
+  ;; reformulating without its first argument, and the critical position being
+  ;; at point.]
+  ;;
+  ;; PAREN-STATE is the remainder of the state of enclosing braces.
+  ;; ACCEPT-IN-PAREN is non-nil iff we will accept as a brace list a brace
+  ;; directly enclosed in a parenthesis.
   ;;
   ;; The "brace list" here is recognized solely by its context, not by
   ;; its contents.
@@ -10733,7 +10882,8 @@
 (defun c-looking-at-statement-block ()
   ;; Point is at an opening brace.  If this is a statement block (i.e. the
   ;; elements in the block are terminated by semicolons, or the block is
-  ;; empty, or the block contains a keyword) return t.  Otherwise, return nil.
+  ;; empty, or the block contains a keyword) return non-nil.  Otherwise,
+  ;; return nil.
   (let ((here (point)))
     (prog1
 	(if (c-go-list-forward)
@@ -11237,7 +11387,7 @@
 
 	    (if (and (eq step-type 'same)
 		     (/= paren-pos (point)))
-		(let (inexpr)
+		(let (inexpr bspec)
 		  (cond
 		   ((save-excursion
 		      (goto-char paren-pos)
@@ -11259,6 +11409,13 @@
 			  (c-looking-at-statement-block))
 			(c-add-syntax 'defun-block-intro nil)
 		      (c-add-syntax 'brace-list-intro nil)))
+		   ((save-excursion
+		      (goto-char paren-pos)
+		      (setq bspec (c-looking-at-or-maybe-in-bracelist
+				   containing-sexp containing-sexp))
+		      (and (consp bspec)
+			   (eq (cdr bspec) 'in-paren)))
+		    (c-add-syntax 'brace-list-intro (car bspec)))
 		   (t (c-add-syntax 'defun-block-intro nil))))
 
 	      (c-add-syntax 'statement-block-intro nil)))
@@ -13082,7 +13239,7 @@
 Cannot combine relative offset %S with absolute %S in `%s' method"
 				       (car offset) symbol res val method)
 		     (setq res (vector (funcall method (aref res 0)
-						(aref val 0)))))))
+			   			(aref val 0)))))))
 		 (setq offset (cdr offset)))
 	       res))
 
@@ -13126,7 +13283,7 @@
 	   nil))))
 
     (if (or (null res) (integerp res)
-	    (and (vectorp res) (= (length res) 1) (integerp (aref res 0))))
+	    (and (vectorp res) (>= (length res) 1) (integerp (aref res 0))))
 	res
       (c-benign-error "Error evaluating offset %S for %s: Got invalid value %S"
 		      offset symbol res)
@@ -13149,12 +13306,11 @@
       (if c-strict-syntax-p
 	  (c-benign-error "No offset found for syntactic symbol %s" symbol))
       (setq offset 0))
-    (if (vectorp offset)
-	offset
-      (or (and (numberp offset) offset)
-	  (and (symbolp offset) (symbol-value offset))
-	  0))
-    ))
+    (cond
+     ((or (vectorp offset) (numberp offset))
+      offset)
+     ((and (symbolp offset) (symbol-value offset)))
+     (t 0))))
 
 (defun c-get-offset (langelem)
   ;; This is a compatibility wrapper for `c-calc-offset' in case
diff -r e38b65ad9145 cc-fonts.el
--- a/cc-fonts.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-fonts.el	Tue Sep 25 19:01:56 2018 +0000
@@ -1029,114 +1029,41 @@
 
   ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
   (c-fontify-types-and-refs
-      ((pos (point)) next-pos id-start
-       decl-res
-       id-face got-type got-init
-       c-last-identifier-range
-       (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
-
-    ;; The following `while' fontifies a single declarator id each time round.
-    ;; It loops only when LIST is non-nil.
-    (while
-	(and pos (setq decl-res (c-forward-declarator)))
-      (setq next-pos (point)
-	    id-start (car decl-res)
-	    id-face (if (and (eq (char-after) ?\()
-			     (or (not (c-major-mode-is 'c++-mode))
-				 (not not-top)
-				 (car (cddr (cddr decl-res))) ; Id is in
-							      ; parens, etc.
-				 (save-excursion
-				   (forward-char)
-				   (c-forward-syntactic-ws)
-				   (looking-at "[*&]")))
-			     (not (car (cddr decl-res)))
-			     (or (not (c-major-mode-is 'c++-mode))
-				 (save-excursion
-				   (let (c-last-identifier-range)
-				     (forward-char)
-				     (c-forward-syntactic-ws)
-				     (catch 'is-function
-				       (while
-					   (progn
-					     (if (eq (char-after) ?\))
-						 (throw 'is-function t))
-					     (setq got-type (c-forward-type))
-					     (cond
-					      ((null got-type)
-					       (throw 'is-function nil))
-					      ((not (eq got-type 'maybe))
-					       (throw 'is-function t)))
-					     (c-forward-declarator nil t)
-					     (eq (char-after) ?,))
-					 (forward-char)
-					 (c-forward-syntactic-ws))
-				       t)))))
-			'font-lock-function-name-face
-		      'font-lock-variable-name-face)
-	    got-init (and (cadr (cddr decl-res)) ; got-init
-			  (char-after)))
-
-      (if types
-	  ;; Register and fontify the identifier as a type.
-	  (let ((c-promote-possible-types t))
-	    (goto-char id-start)
-	    (c-forward-type))
-	;; Fontify the last symbol in the identifier if it isn't fontified
-	;; already.  The check is necessary only in certain cases where this
-	;; function is used "sloppily", e.g. in `c-simple-decl-matchers'.
-	(when (and c-last-identifier-range
-		   (not (get-text-property (car c-last-identifier-range)
-					   'face)))
-	  (c-put-font-lock-face (car c-last-identifier-range)
-				(cdr c-last-identifier-range)
-				id-face)))
-
-      (goto-char next-pos)
-      (setq pos nil)	      ; So as to terminate the enclosing `while' form.
-      (if (and template-class
-	       (eq got-init ?=) ; C++ "<class X = Y>"?
-	       (c-forward-token-2 1 nil limit) ; Over "="
-	       (let ((c-promote-possible-types t))
-		 (c-forward-type t)))	       ; Over "Y"
-	  (setq list nil)) ; Shouldn't be needed.  We can't have a list, here.
-
-      (when list
-	;; Jump past any initializer or function prototype to see if
-	;; there's a ',' to continue at.
-	(cond ((eq id-face 'font-lock-function-name-face)
-	       ;; Skip a parenthesized initializer (C++) or a function
-	       ;; prototype.
-	       (if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
-		   (c-forward-syntactic-ws limit)
-		 (goto-char limit)))	; unbalanced parens
-
-	      (got-init	; "=" sign OR opening "(", "[", or "{"
-	       ;; Skip an initializer expression.  If we're at a '='
-	       ;; then accept a brace list directly after it to cope
-	       ;; with array initializers.  Otherwise stop at braces
-	       ;; to avoid going past full function and class blocks.
-	       (and (if (and (eq got-init ?=)
-			     (= (c-forward-token-2 1 nil limit) 0)
-			     (looking-at "{"))
-			(c-safe (c-forward-sexp) t) ; over { .... }
-		      t)
-		    (< (point) limit)
-		    ;; FIXME: Should look for c-decl-end markers here;
-		    ;; we might go far into the following declarations
-		    ;; in e.g. ObjC mode (see e.g. methods-4.m).
-		    (c-syntactic-re-search-forward "[;,{]" limit 'move t)
-		    (backward-char)))
-
-	      (t (c-forward-syntactic-ws limit)))
-
-	;; If a ',' is found we set pos to the next declarator and iterate.
-	(when (and (< (point) limit) (looking-at ","))
-	  (c-put-char-property (point) 'c-type separator-prop)
-	  (forward-char)
-	  (c-forward-syntactic-ws limit)
-	  (setq pos (point))))))     ; acts to make the `while' form continue.
-  nil)
+      ()
+    (c-do-declarators
+     limit list not-top
+     (if types 'c-decl-type-start 'c-decl-id-start)
+     (lambda (id-start id-end end-pos not-top is-function init-char)
+       (if types
+	   ;; Register and fontify the identifier as a type.
+	   (let ((c-promote-possible-types t))
+	     (goto-char id-start)
+	     (c-forward-type))
+	 ;; The following doesn't work properly (yet, 2018-09-22).
+	 ;; (c-put-font-lock-face id-start id-end
+	 ;; 		       (if is-function
+	 ;; 			   'font-lock-function-name-face
+	 ;; 			 'font-lock-variable-name-face))
+	 (when (and c-last-identifier-range
+	 	    (not (get-text-property (car c-last-identifier-range)
+	 				    'face)))
+	   ;; We use `c-last-identifier-range' rather than `id-start' and
+	   ;; `id-end', since the latter two can be erroneous.  E.g. in
+	   ;; "~Foo", `id-start' is at the tilde.  This is a bug in
+	   ;; `c-forward-declarator'.
+	   (c-put-font-lock-face (car c-last-identifier-range)
+	 			 (cdr c-last-identifier-range)
+	 			 (if is-function
+	 			     'font-lock-function-name-face
+	 			   'font-lock-variable-name-face))))
+       (and template-class
+	    (eq init-char ?=)		; C++ "<class X = Y>"?
+	    (progn
+	      (goto-char end-pos)
+	      (c-forward-token-2 1 nil limit) ; Over "="
+	      (let ((c-promote-possible-types t))
+		(c-forward-type t))))))
+    nil))
 
 (defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
   ;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS.
diff -r e38b65ad9145 cc-langs.el
--- a/cc-langs.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-langs.el	Tue Sep 25 19:01:56 2018 +0000
@@ -3221,7 +3221,8 @@
 	       "\\|"
 	       "\\.\\.\\."
 	       "\\|"
-	       "[*(&]"
+;	       "[*(&]"
+	       "[*(&~]"
 	       "\\|"
 	       (c-lang-const c-type-decl-prefix-key)
 	       "\\|"
diff -r e38b65ad9145 cc-mode.el
--- a/cc-mode.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-mode.el	Tue Sep 25 19:01:56 2018 +0000
@@ -1781,7 +1781,20 @@
     (while
 	;; Go to a less nested declaration each time round this loop.
 	(and
-	 (c-syntactic-skip-backward "^;{}" bod-lim t)
+;;;; OLD STOUGH, 2018-09-22
+	 ;(c-syntactic-skip-backward "^;{}" bod-lim t)
+;;;; NEW STOUGH, 2018-09-22
+	 (let (pseudo)
+	   (while
+	       (progn
+		 (c-syntactic-skip-backward "^;{}" bod-lim t)
+		 (and (eq (char-before) ?})
+		      (save-excursion
+			(backward-char)
+			(setq pseudo (c-cheap-inside-bracelist-p (c-parse-state))))))
+	     (goto-char pseudo))
+	   t)
+;;;; END OF NEW STOUGH
 	 (> (point) bod-lim)
 	 (progn (c-forward-syntactic-ws)
 		(setq bo-decl (point))
diff -r e38b65ad9145 cc-styles.el
--- a/cc-styles.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-styles.el	Tue Sep 25 19:01:56 2018 +0000
@@ -73,7 +73,9 @@
 			 (arglist-close . c-lineup-arglist)
 			 (inline-open . 0)
 			 (brace-list-open . +)
-			 (brace-list-intro . c-lineup-arglist-intro-after-paren)
+			 (brace-list-intro . (first
+					      c-lineup-2nd-brace-entry-in-arglist
+					      c-lineup-class-decl-init-+ +))
 			 (topmost-intro-cont
 			  . (first c-lineup-topmost-intro-cont
 				   c-lineup-gnu-DEFUN-intro-cont))))
@@ -100,6 +102,9 @@
 			 (label . 0)
 			 (statement-cont . +)
 			 (inline-open . 0)
+			 (brace-list-intro . (first
+					      c-lineup-2nd-brace-entry-in-arglist
+					      c-lineup-class-decl-init-+ +))
 			 (inexpr-class . 0))))
 
     ("stroustrup"
@@ -109,6 +114,9 @@
 			 (substatement-open . 0)
 			 (substatement-label . 0)
 			 (label . 0)
+			 (brace-list-intro . (first
+					      c-lineup-2nd-brace-entry-in-arglist
+					      c-lineup-class-decl-init-+ +))
 			 (statement-cont . +))))
 
     ("whitesmith"
@@ -199,6 +207,9 @@
      (c-offsets-alist  . ((substatement-open . 0)
 			  (inextern-lang . 0)
 			  (arglist-intro . +)
+			  (brace-list-intro . (first
+					       c-lineup-2nd-brace-entry-in-arglist
+					       c-lineup-class-decl-init-+ +))
 			  (knr-argdecl-intro . +)))
      (c-hanging-braces-alist . ((brace-list-open)
 				(brace-list-intro)
@@ -224,6 +235,9 @@
 			 (statement-cont        . +)
 			 (arglist-intro  . c-lineup-arglist-intro-after-paren)
 			 (arglist-close  . c-lineup-arglist)
+			 (brace-list-intro . (first
+					      c-lineup-2nd-brace-entry-in-arglist
+					      c-lineup-class-decl-init-+ +))
 			 (access-label   . 0)
 			 (inher-cont     . c-lineup-java-inher)
 			 (func-decl-cont . c-lineup-java-throws))))
diff -r e38b65ad9145 cc-vars.el
--- a/cc-vars.el	Mon Aug 27 20:23:23 2018 +0000
+++ b/cc-vars.el	Tue Sep 25 19:01:56 2018 +0000
@@ -1117,7 +1117,7 @@
        ;; Anchor pos: At the brace list decl start(*).
        (brace-list-intro      . +)
        ;; Anchor pos: At the brace list decl start(*).
-       (brace-list-entry      . c-lineup-under-anchor)
+       (brace-list-entry      . 0)
        ;; Anchor pos: At the first non-ws char after the open paren if
        ;; the first token is on the same line, otherwise boi at that
        ;; token.

> [ ... ]

> Thanks

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-cc-mode <at> gnu.org:
bug#28050; Package cc-mode. (Thu, 27 Sep 2018 11:10:01 GMT) Full text and rfc822 format available.

Message #14 received at 28050 <at> debbugs.gnu.org (full text, mbox):

From: Mohammed Sadiq <sadiq <at> sadiqpk.org>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 28050 <at> debbugs.gnu.org
Subject: Re: bug#28050: CC Mode 5.33 (C/*l); indentation of array and enum in
 GNU style isn't right
Date: Thu, 27 Sep 2018 16:39:43 +0530
> On Sun, Sep 23, 2018 at 05:47:29 +0530, Mohammed Sadiq wrote:
>> On 2018-09-23 01:00, Alan Mackenzie wrote:

> diff -r e38b65ad9145 cc-align.el
> --- a/cc-align.el	Mon Aug 27 20:23:23 2018 +0000
> +++ b/cc-align.el	Tue Sep 25 19:01:56 2018 +0000

[ ... ]

Sorry the patch isn't applying the emacs master branch.
And I'm now busy with some work to manually merge each change.
It would be nice if you can rebase the patch over emacs master.
Or is the patch against cc-mode from sourceforge?

If you are busy too, please wait. I shall try again as I have
time. I wish this to be fixed in 27.x.

Thanks




Information forwarded to bug-cc-mode <at> gnu.org:
bug#28050; Package cc-mode. (Thu, 27 Sep 2018 20:25:01 GMT) Full text and rfc822 format available.

Message #17 received at 28050 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Mohammed Sadiq <sadiq <at> sadiqpk.org>
Cc: 28050 <at> debbugs.gnu.org
Subject: Re: bug#28050: CC Mode 5.33 (C/*l); indentation of array and enum in
 GNU style isn't right
Date: Thu, 27 Sep 2018 20:19:09 +0000
[Message part 1 (text/plain, inline)]
Hello, Mohammed

On Thu, Sep 27, 2018 at 16:39:43 +0530, Mohammed Sadiq wrote:
> > On Sun, Sep 23, 2018 at 05:47:29 +0530, Mohammed Sadiq wrote:
> >> On 2018-09-23 01:00, Alan Mackenzie wrote:

> > diff -r e38b65ad9145 cc-align.el
> > --- a/cc-align.el	Mon Aug 27 20:23:23 2018 +0000
> > +++ b/cc-align.el	Tue Sep 25 19:01:56 2018 +0000

> [ ... ]

> Sorry the patch isn't applying the emacs master branch.

I'm sorry, too.  Maybe including the patch inline wasn't such a
brilliant idea.

> And I'm now busy with some work to manually merge each change.
> It would be nice if you can rebase the patch over emacs master.
> Or is the patch against cc-mode from sourceforge?

Could you try instead the attached patch file?  Although the line
numbers don't quite correspond with the Emacs master, it applies cleanly
to Emacs master for me.

Yes, I made the patch basically for the standalone CC Mode, but amended
it to apply to the CC Mode in Emacs.

> If you are busy too, please wait. I shall try again as I have
> time. I wish this to be fixed in 27.x.

This WILL be fixed for Emacs 27.  :-)

> Thanks

Thank you for all the trouble you are taking.

-- 
Alan Mackenzie (Nuremberg, Germany).

[diff.20180927.diff (text/plain, attachment)]

Reply sent to Alan Mackenzie <acm <at> muc.de>:
You have taken responsibility. (Tue, 12 Mar 2019 19:18:01 GMT) Full text and rfc822 format available.

Notification sent to Mohammed Sadiq <sadiq <at> sadiqpk.org>:
bug acknowledged by developer. (Tue, 12 Mar 2019 19:18:01 GMT) Full text and rfc822 format available.

Message #22 received at 28050-done <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Mohammed Sadiq <sadiq <at> sadiqpk.org>
Cc: 28050-done <at> debbugs.gnu.org
Subject: Re: bug#28050: CC Mode 5.33 (C/*l); indentation of array and enum in
 GNU style isn't right
Date: Tue, 12 Mar 2019 19:16:54 +0000
Hello, Mohammed and Emacs.

I've just committed a fix to this bug to master.

On Fri, Aug 11, 2017 at 22:50:02 +0530, Mohammed Sadiq wrote:


> For the following code, the indentation of the code isn't right for GNU
> style (C-x h TAB after writing the code):

> /* Output after default (auto)indentation in GNU Emacs (TAB is used sometimes) */
> char *words[] = {
> 		 "good",
> 		 "better",
> 		 "best"
> };

> The GNU style is (as done by the program GNU indent):

> /* They should be indented with 2 spaces (and not TABs)
> char *words[] = {
>   "good",
>   "better",
>   "best"
> };

> Tabs are also add for indentation when defining enums:

> typedef enum {
> 	      GOOD,
> 	      BETTER,
> 	      BEST
> } test;


> The following might be better (2 spaces, and no TABs):

> typedef enum {
>   GOOD,
>   BETTER,
>   BEST
> } test;

> Emacs  : GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
>  of 2017-08-11
> Package: CC Mode 5.33 (C/*l)
> Buffer Style: gnu
> c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)

-- 
Alan Mackenzie (Nuremberg, Germany).




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 10 Apr 2019 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 14 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.