Subject: bug#64133: closed (Re: bug#64133: CC Mode 5.35.2 (C/*l); incorrect indentation for an arrays of structs.)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 27 Jun 2023 20:20:02 +0000

Your bug report

#64133: CC Mode 5.35.2 (C/*l); incorrect indentation for an arrays of structs.

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
64133: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64133
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#64133: CC Mode 5.35.2 (C/*l); incorrect indentation for an arrays of structs.
From: Alan Mackenzie <[email-masked]>
To: Jeff Norden <[email-masked]>
Cc: [email-masked], Eli Zaretskii <[email-masked]>, [email-masked]
Date: Tue, 27 Jun 2023 20:19:25 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello, Jeff.

On Wed, Jun 21, 2023 at 13:43:20 -0500, Jeff Norden wrote:
> On Wed, Jun 21, 2023 at 5:39 AM Alan Mackenzie <[email-masked]> wrote:
> > OK, here's the patch which I think fixes the bug completely.  Would you
> > please apply this patch  ...   Then, please confirm that the bug is fixed, or
> > tell me what's still not working.
> Hi Alan,

> Thanks for taking care of this so quickly.  The patch seems to work
> perfectly for me.  I've tried it with 29.0.91 (2nd emacs-29 pretest)
> and with my current git build of emacs from the master branch (which
> is from June 11).  Patch gives differing "offset" messages, but all of
> the "hunks" succeed in both cases.  I haven't built the 3rd emacs-29
> pretest yet, but I can't foresee that there will be a problem.  I will
> be using this some more over the next few days.  I'll post again if I
> notice any issues, but I don't expect to.

Thanks for such comprehensive testing!  I've now committed the patch to
the Emacs master branch (it is too intricate a patch to go to the
release branch at this late stage), and I'm closing the bug with this
post.

If any other problems become apparent in this area (or anywhere else),
feel free to raise another bug report.

> -Jeff

-- 
Alan Mackenzie (Nuremberg, Germany).

Subject: CC Mode 5.35.2 (C/*l); incorrect indentation for an arrays of structs.
From: Jeff Norden <[email-masked]>
To: [email-masked]
Date: Sat, 17 Jun 2023 10:03:24 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

I've verified the following behavior with c-version 5.35.2 (emacs-29,
and emacs-30 from git) and with 5.35.1 (emacs 28.2).

Place the following text into a file with a ".c" extension, and load
it with "emacs -Q".
==========================================
#include <stdio.h>
struct three_ints {
  int a, b, c;
};
int main () {
  struct three_ints numbers[]= {
    {0,1,2},
{3,4,5},
    {6,7,8}
  };
  for (int i=0; i<numbers[2].a; i++) {
    printf("ack ");
  }
  printf("\n");
}
==========================================
Move the cursor to the beginning of the line with {3,4,5} and press
<tab> to indent the line.  It will be incorrectly indented 2 spaces
more than the previous line.  Move to the next line, press <tab>,
and you'll see:

  struct three_ints numbers[]= {
    {0,1,2},
      {3,4,5},
        {6,7,8}
  };

Just using <tab> to re-indent the lines will not change anything.
But, if you add or delete white-space before {0,1,2} or {3,4,5} and
press <tab>, it *may* fix things.  It seems to depend on just what you
delete and where the cursor is.  The pattern isn't clear to me.
Once fixed, you get:

  struct three_ints numbers[]= {
    {0,1,2},
    {3,4,5},
    {6,7,8}
  };

At this point it is stable, and <tab> will work correctly.  If you
restart c-mode with "M-x c-mode", the problem re-occurs.

This bug only seems to occur when a loop or similar construct occurs
after the array declaration/initialization.  It doesn't need to
immediately follow, though.

When incorrectly indenting, "C-c C-s" shows 'defun-block-intro' syntax
for the {0,1,2} line, and 'substatement-open' for {3,4,5} and {4,5,6}.
Once it gets fixed, this changes to 'brace-list-intro' and
'brace-entry-open'.

==========================================
For a more "real world" example, start with the example program at the
end of the getopt_long(3) man page:

  https://linux.die.net/man/3/getopt_long

and move the declaration of long_options[] from inside the while loop
to before it.  (This makes long_options a global variable, instead of
local to the loop).

==========================================
I'm afraid I can't offer a patch or suggestion for a fix.  My own
attempts at "parsing" the lisp in cc-engine.el come to an abrupt halt
when my brain receives an urgent "Warning! Meltdown imminent!"
message from my subconscious -- just kidding :-).

However, I did stumble upon the following in the comments for the
`c-inside-bracelist-p' function:

 ;; 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, ...

Thanks,
-Jeff
----------------------------
  If believing that "function is more important than form" and that "people
  are more important than technology" makes me a Luddite, then so be it!