GNU bug report logs - #4289
23.1; Incorrect indentation in C, following certain 'case' labels

Previous Next

Packages: emacs, cc-mode;

Reported by: Benjamin Moody <benjamin.moody <at> gmail.com>

Date: Sat, 29 Aug 2009 21:05:05 UTC

Severity: normal

Done: Juanma Barranquero <lekktu <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Alan Mackenzie <acm <at> muc.de>
To: Benjamin Moody <benjamin.moody <at> gmail.com>, 4289 <at> debbugs.gnu.org
Cc: bug-gnu-emacs <at> gnu.org
Subject: bug#4289: 23.1; Incorrect indentation in C, following certain 'case' labels
Date: Mon, 31 Aug 2009 20:05:38 +0000
Hi, Benjamin!

On Sat, Aug 29, 2009 at 04:59:54PM -0400, Benjamin Moody wrote:



> In Emacs 23.1, I've found an issue with the indentation rules for C
> mode.  In some circumstances, following a series of multiple labels,
> the second and subsequent statements are not indented properly.  For
> example, in the following code:

> void foo(int x)
> {
>   switch (x) {
>   case 1:
>   case 2:
>     printf("aaa");
>     break;

>   case '3':
>   case '4':
>     printf("bbb");
>   break;
>   }
> }

> the second 'break' statement should be indented by 4 spaces, to align
> with the 'printf'.

Indeed it should.

> This problem seems to appear when there are multiple labels (either
> normal named labels, 'case' labels, or 'default' labels) in a row,
> with no intervening statments, and either the first or the last such
> label is a 'case' label with a character constant as its value.

> This problem does NOT occur with Emacs 22.3.  It does occur in C++ and
> ObjC modes as well.  It affects indentation using either TAB or M-x
> indent-region.

> A workaround is to place the character constant(s) in parentheses.

Yuck!

> This is obviously not a serious problem, ...

I might disagree about that.

> ... but it is a somewhat annoying one which would be nice to see fixed.

OK.  Would you please test the patch below, which I think fixes it.  Once
you've applied the patch, please rebuild the CC Mode files as follows:

M-x byte-compile-file cc-langs.el
M-x byte-compile-file cc-engine.el
M-x byte-compile-file cc-mode.el

(This is needed because cc-{engine,mode}.el use macros contained in
cc-langs.el.)  Then restart Emacs if necessary, then test your file.

Thank you indeed for such a wonderfully clear, concise and helpful bug
report!


Index: cc-engine.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-engine.el,v
retrieving revision 1.76
diff -c -r1.76 cc-engine.el
*** cc-engine.el	29 Aug 2009 02:07:45 -0000	1.76
--- cc-engine.el	31 Aug 2009 19:55:19 -0000
***************
*** 1067,1074 ****
  		 (not (eq ret 'beginning))
  		 (looking-at c-case-kwds-regexp))
  	(if (< after-case:-pos start)
! 	    (setq pos after-case:-pos)
! 	  (setq ret 'label)))
  
        ;; Skip over the unary operators that can start the statement.
        (while (progn
--- 1067,1075 ----
  		 (not (eq ret 'beginning))
  		 (looking-at c-case-kwds-regexp))
  	(if (< after-case:-pos start)
! 	    (setq pos after-case:-pos))
! 	(if (eq ret 'same)
! 	    (setq ret 'label)))
  
        ;; Skip over the unary operators that can start the statement.
        (while (progn
Index: cc-langs.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-langs.el,v
retrieving revision 1.67
diff -c -r1.67 cc-langs.el
*** cc-langs.el	19 May 2009 22:35:07 -0000	1.67
--- cc-langs.el	31 Aug 2009 19:55:21 -0000
***************
*** 2885,2891 ****
  i.e. before \":\".  Only used if `c-recognize-colon-labels' is set."
    t (concat
       ;; Don't allow string literals.
!      "[\"']\\|"
       ;; All keywords except `c-label-kwds' and `c-protection-kwds'.
       (c-make-keywords-re t
         (set-difference (c-lang-const c-keywords)
--- 2885,2891 ----
  i.e. before \":\".  Only used if `c-recognize-colon-labels' is set."
    t (concat
       ;; Don't allow string literals.
!      "\"\\|"
       ;; All keywords except `c-label-kwds' and `c-protection-kwds'.
       (c-make-keywords-re t
         (set-difference (c-lang-const c-keywords)

> Benjamin Moody

-- 
Alan Mackenzie (Nuremberg, Germany)







This bug report was last modified 15 years and 218 days ago.

Previous Next


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