GNU bug report logs - #5209
23.1.90; CC Mode version 5.31.8 does not indent properly when writing new C files

Previous Next

Packages: cc-mode, emacs;

Reported by: Steve Revilak <steve <at> srevilak.net>

Date: Sun, 13 Dec 2009 16:30:03 UTC

Severity: normal

Done: Steve Revilak <steve <at> srevilak.net>

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 5209 in the body.
You can then email your comments to 5209 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-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#5209; Package emacs. (Sun, 13 Dec 2009 16:30:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to Steve Revilak <steve <at> srevilak.net>:
New bug report received and forwarded. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Sun, 13 Dec 2009 16:30:04 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> emacsbugs.donarmstrong.com (full text, mbox):

From: Steve Revilak <steve <at> srevilak.net>
To: emacs-pretest-bug <at> gnu.org
Subject: 23.1.90; CC Mode version 5.31.8 does not indent properly when
	writing new C files
Date: Sun, 13 Dec 2009 11:22:10 -0500
[Message part 1 (text/plain, inline)]
Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the emacs-pretest-bug <at> gnu.org mailing list.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug.  If you can, give
a recipe starting from `emacs -Q':

                                * * *

STEPS TO REPRODUCE
------------------

(1) Start emacs with the command line "emacs -nw -Q foo.c".

    foo.c should be a new file, which does not exist prior to starting
    emacs.

(2) Type "#include <stdio.h>" and RETURN

(3) Type RETURN to leave a blank line

(4) type "static void add_one(int * x) {" and RETURN

(5) type "*x += 1;" and RETURN

(6) type "}" and RETURN (to close the function definition)

NOTE: the statement written in step (5) is left-aligned to column
zero.  The statement should be indented.

(7) Place point in column zero of the line "*x += 1;".  Press TAB.

    Before pressing TAB, "*x += 1;" is aligned to column zero.  After
    pressing TAB, "*x += 1;" is still aligned to column zero.  TAB did
    not indent the statement.

(8) Type "C-x h TAB" (i.e., to select and re-indent the entire
    buffer).

    The minibuffer displays "Indenting region... done".  However, the
    statement "*x += 1;" is still aligned to column zero.

After step 8, buffer "foo.c" looks like this:
---------------------------------
#include <stdio.h>

static void add_one(int * x) {
*x += 1;
}
---------------------------------
NOTE: the fourth line is not indented (but it should be).


NOTES:
-----

In buffer "foo.c",  "M-x describe-key RET TAB" produces:
---------------------------------
TAB runs the command c-indent-line-or-region, which is an interactive
compiled Lisp function in `cc-cmds.el'.

It is bound to TAB, <menu-bar> <C> <Indent Line or Region>.

(c-indent-line-or-region &optional ARG REGION)

Indent active region, current line, or block starting on this line.
In Transient Mark mode, when the region is active, reindent the region.
Otherwise, with a prefix argument, rigidly reindent the expression
starting on the current line.
Otherwise reindent just the current line.
---------------------------------

NOTE: In step (8), when the entire buffer was selected, with transient
mark mode enabled, TAB did not re-indent the region correctly.

Likewise, in step (7) TAB did not re-indent the current line
("Otherwise reindent just the current line"). 




In buffer "foo.c",  "M-x desribe-mode" produces:
---------------------------------
Enabled minor modes: Abbrev Auto-Composition Auto-Compression
Auto-Encryption File-Name-Shadow Font-Lock Global-Auto-Composition
Global-Font-Lock Line-Number Menu-Bar Mouse-Wheel Tool-Bar Tooltip
Transient-Mark

(Information about these minor modes follows the major mode info.)

C/l mode:
Major mode for editing K&R and ANSI C code.
To submit a problem report, enter `C-c C-b' from a
c-mode buffer.  This automatically sets up a mail buffer with version
information already added.  You just need to add a description of the
problem, including a reproducible test case, and send the message.

To see what version of CC Mode you are running, enter `M-x c-version'.

The hook `c-mode-common-hook' is run with no args at mode
initialization, then `c-mode-hook'.

  [rest of describe-mode output omitted]
---------------------------------




M-x c-version produces the following:
---------------------------------
Using CC Mode version 5.31.8
---------------------------------

Finally, the same behavior occurs when emacs is started as "emacs -Q"
(i.e., if the -nw option is ommitted from the command line).


                                * * *

If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
    `bt full' and `xbacktrace'.
For information about debugging Emacs, please read the file
/Applications/Emacs.app/Contents/Resources/etc/DEBUG.


In GNU Emacs 23.1.90.1 (i386-apple-darwin9.8.0, NS apple-appkit-949.54)
 of 2009-12-09 on oatmeal.ma.runwaynine.com
Windowing system distributor `Apple', version 10.3.949
configured using `configure  '--with-ns''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: C
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: nil
  value of $XMODIFIERS: nil
  locale-coding-system: nil
  default enable-multibyte-characters: t

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
ESC x r e p o r t - e m a c s - b u TAB RET

Recent messages:
("/Applications/Emacs.app/Contents/MacOS/Emacs")
For information about GNU Emacs and the GNU system, type C-h C-a.

Load-path shadows:
None found.

Features:
(shadow mail-extr message ecomplete rfc822 mml mml-sec password-cache
mm-decode mm-bodies mm-encode mailcap mail-parse rfc2231 rfc2047 rfc2045
qp ietf-drums mailabbrev nnheader gnus-util netrc time-date mm-util
mail-prsvr gmm-utils wid-edit mailheader canlock sha1 hex-util hashcash
mail-utils warnings emacsbug sendmail regexp-opt tooltip ediff-hook
vc-hooks lisp-float-type mwheel ns-win easymenu tool-bar dnd fontset
image fringe lisp-mode register page menu-bar rfn-eshadow timer select
scroll-bar mldrag mouse jit-lock font-lock syntax facemenu font-core
frame cham georgian utf-8-lang misc-lang vietnamese tibetan thai
tai-viet lao korean japanese hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese case-table epa-hook jka-cmpr-hook help
simple abbrev loaddefs button minibuffer faces cus-face text-properties
overlay md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process ns multi-tty
emacs)
[Message part 2 (application/pgp-signature, inline)]

Information forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#5209; Package emacs. (Sun, 13 Dec 2009 20:35:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to Alan Mackenzie <acm <at> muc.de>:
Extra info received and forwarded to list. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Sun, 13 Dec 2009 20:35:04 GMT) Full text and rfc822 format available.

Message #10 received at submit <at> emacsbugs.donarmstrong.com (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Steve Revilak <steve <at> srevilak.net>, 5209 <at> debbugs.gnu.org
Cc: emacs-pretest-bug <at> gnu.org
Subject: Re: bug#5209: 23.1.90;
	CC Mode version 5.31.8 does not indent properly when writing new C
	files
Date: Sun, 13 Dec 2009 20:33:11 +0000
Hi, Steve,

On Sun, Dec 13, 2009 at 11:22:10AM -0500, Steve Revilak wrote:

> STEPS TO REPRODUCE
> ------------------

> (1) Start emacs with the command line "emacs -nw -Q foo.c".

>     foo.c should be a new file, which does not exist prior to starting
>     emacs.

> (2) Type "#include <stdio.h>" and RETURN

> (3) Type RETURN to leave a blank line

> (4) type "static void add_one(int * x) {" and RETURN

> (5) type "*x += 1;" and RETURN

> (6) type "}" and RETURN (to close the function definition)

> NOTE: the statement written in step (5) is left-aligned to column
> zero.  The statement should be indented.

> (7) Place point in column zero of the line "*x += 1;".  Press TAB.

>     Before pressing TAB, "*x += 1;" is aligned to column zero.  After
>     pressing TAB, "*x += 1;" is still aligned to column zero.  TAB did
>     not indent the statement.

> (8) Type "C-x h TAB" (i.e., to select and re-indent the entire
>     buffer).

>     The minibuffer displays "Indenting region... done".  However, the
>     statement "*x += 1;" is still aligned to column zero.

> After step 8, buffer "foo.c" looks like this:
> ---------------------------------
> #include <stdio.h>

> static void add_one(int * x) {
> *x += 1;
> }
> ---------------------------------
> NOTE: the fourth line is not indented (but it should be).

First thing, thanks for such a simple and clear bug report.

There is a bug in `c-parse-state', one of the low-level functions in CC
mode, which generates and changes a cache of brace and paren positions.

Would you apply the following patch, and test it, please.  If anything is
still wrong, please let me know again.


*** cc-engine.orig.el	2009-12-13 19:43:27.268817800 +0000
--- cc-engine.el	2009-12-13 20:06:47.819901672 +0000
***************
*** 2231,2236 ****
--- 2231,2249 ----
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Defuns which analyse the buffer, yet don't change `c-state-cache'.
+ (defun c-p1-not-in-p0-macro (p0 p1)
+   ;; Is P0 in a CPP construct and p1 not in it?
+   (save-restriction
+     (widen)
+     (save-excursion
+       (let ((p0-macro-begin
+ 	     (progn (goto-char p0) (and (c-beginning-of-macro) (point)))))
+ 	(and p0-macro-begin
+ 	     (not
+ 	      (eq p0-macro-begin
+ 		  (progn (goto-char p1) (and (c-beginning-of-macro) (point)))))
+ 	     )))))
+ 
  (defun c-get-fallback-scan-pos (here)
    ;; Return a start position for building `c-state-cache' from
    ;; scratch.  This will be at the top level, 2 defuns back.
***************
*** 2587,2593 ****
    ;; o - SCAN-BACK-POS, if not nil, indicates there may be a brace pair
    ;;   preceding POS which needs to be recorded in `c-state-cache'.  It is a
    ;;   position to scan backwards from.
!   ;; o - PPS-STATE is the parse-partial-sexp state at PPS-POINT.
    (save-restriction
      (narrow-to-region 1 (point-max))
      (save-excursion
--- 2600,2607 ----
    ;; o - SCAN-BACK-POS, if not nil, indicates there may be a brace pair
    ;;   preceding POS which needs to be recorded in `c-state-cache'.  It is a
    ;;   position to scan backwards from.
!   ;; o - PPS-STATE is the parse-partial-sexp state at PPS-POINT or nil if we
!   ;;   don't scan past PPS-POINT.
    (save-restriction
      (narrow-to-region 1 (point-max))
      (save-excursion
***************
*** 2624,2630 ****
  			   (< (point-max) c-state-old-cpp-end)))
  		  (point-max)
  		(min (point-max) c-state-old-cpp-beg)))
! 	(while (and c-state-cache (> (c-state-cache-top-lparen) upper-lim))
  	  (setq c-state-cache (cdr c-state-cache)))
  	;; If `upper-lim' is inside the last recorded brace pair, remove its
  	;; RBrace and indicate we'll need to search backwards for a previous
--- 2638,2645 ----
  			   (< (point-max) c-state-old-cpp-end)))
  		  (point-max)
  		(min (point-max) c-state-old-cpp-beg)))
! 	(while (and c-state-cache
! 		    (>= (c-state-cache-top-lparen) upper-lim))
  	  (setq c-state-cache (cdr c-state-cache)))
  	;; If `upper-lim' is inside the last recorded brace pair, remove its
  	;; RBrace and indicate we'll need to search backwards for a previous
***************
*** 2641,2647 ****
  	;; (car c-state-cache).  There can be no open parens/braces/brackets
  	;; between `good-pos'/`good-pos-actual-macro-start' and (point-max),
  	;; due to the interface spec to this function.
! 	(setq pos (if good-pos-actual-macro-end
  		      (1+ good-pos-actual-macro-end) ; get outside the macro as
  					; marked by a `category' text property.
  		    good-pos))
--- 2656,2663 ----
  	;; (car c-state-cache).  There can be no open parens/braces/brackets
  	;; between `good-pos'/`good-pos-actual-macro-start' and (point-max),
  	;; due to the interface spec to this function.
! 	(setq pos (if (and good-pos-actual-macro-start
! 			   (not (eq good-pos-actual-macro-start in-macro-start)))
  		      (1+ good-pos-actual-macro-end) ; get outside the macro as
  					; marked by a `category' text property.
  		    good-pos))
***************
*** 2701,2707 ****
  	  (setq c-state-cache (cons (cons pair-beg pos)
  				    c-state-cache)))
  
! 	(list pos scan-back-pos pps-state)))))
  
  (defun c-remove-stale-state-cache-backwards (here cache-pos)
    ;; Strip stale elements of `c-state-cache' by moving backwards through the
--- 2717,2723 ----
  	  (setq c-state-cache (cons (cons pair-beg pos)
  				    c-state-cache)))
  
! 	(list pos scan-back-pos pps-point-state)))))
  
  (defun c-remove-stale-state-cache-backwards (here cache-pos)
    ;; Strip stale elements of `c-state-cache' by moving backwards through the
***************
*** 2769,2777 ****
  	  (list (1+ pos) pos t)) ; return value.  We've just converted a brace
  			         ; pair entry into a { entry, so the caller
  			         ; needs to search for a brace pair before the
! 			         ; {.
  
!       ;; ;; `here' might be inside a literal.  Check for this.
        (setq lit (c-state-literal-at here)
  	    here-lit-start (or (car lit) here)
  	    here-lit-end (or (cdr lit) here))
--- 2785,2793 ----
  	  (list (1+ pos) pos t)) ; return value.  We've just converted a brace
  			         ; pair entry into a { entry, so the caller
  			         ; needs to search for a brace pair before the
! 			         ; {, hence the `pos' in second last place.
  
!       ;; `here' might be inside a literal.  Check for this.
        (setq lit (c-state-literal-at here)
  	    here-lit-start (or (car lit) here)
  	    here-lit-end (or (cdr lit) here))
***************
*** 2801,2812 ****
  		    (setq pos pa))))	; might signal
  	(if (setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
  	    ;; CASE 3: After a }/)/] before `here''s BOL.
! 	    (list (1+ ren) (and dropped-cons pos) nil) ; Return value
  
  	  ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
  	  ;; literal containing it.
  	  (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
! 	  (list good-pos (and dropped-cons good-pos) nil))))))
  
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--- 2817,2836 ----
  		    (setq pos pa))))	; might signal
  	(if (setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
  	    ;; CASE 3: After a }/)/] before `here''s BOL.
! 	    (list (1+ ren)
! 		  (or (and (c-p1-not-in-p0-macro here c-state-cache-good-pos)
! 			   here)
! 		      (and dropped-cons pos))
! 		  nil) ; Return value
  
  	  ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
  	  ;; literal containing it.
  	  (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
! 	  (list good-pos
! 		(or (and (c-p1-not-in-p0-macro here c-state-cache-good-pos)
! 			 here)
! 		    (and dropped-cons good-pos))
! 		nil))))))
  
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


-- 
Alan Mackenzie (Nuremberg, Germany).



Information forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#5209; Package emacs. (Sun, 13 Dec 2009 20:35:06 GMT) Full text and rfc822 format available.

Acknowledgement sent to Alan Mackenzie <acm <at> muc.de>:
Extra info received and forwarded to list. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Sun, 13 Dec 2009 20:35:06 GMT) Full text and rfc822 format available.

Information forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#5209; Package emacs. (Mon, 14 Dec 2009 01:25:30 GMT) Full text and rfc822 format available.

Acknowledgement sent to Steve Revilak <steve <at> srevilak.net>:
Extra info received and forwarded to list. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Mon, 14 Dec 2009 01:25:31 GMT) Full text and rfc822 format available.

Message #20 received at submit <at> emacsbugs.donarmstrong.com (full text, mbox):

From: Steve Revilak <steve <at> srevilak.net>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 5209 <at> debbugs.gnu.org, emacs-pretest-bug <at> gnu.org
Subject: Re: bug#5209: 23.1.90; CC Mode version 5.31.8 does not indent
	properly when writing new C files
Date: Sun, 13 Dec 2009 20:17:58 -0500
[Message part 1 (text/plain, inline)]
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=5209>

>First thing, thanks for such a simple and clear bug report.
>
>There is a bug in `c-parse-state', one of the low-level functions in CC
>mode, which generates and changes a cache of brace and paren positions.
>
>Would you apply the following patch, and test it, please.  If anything is
>still wrong, please let me know again.

Alan,

Glad to help, and thank you for the patch.

I applied the patch to lisp/progmodes/cc-engine.el.

Afterwards, I rebuilt emacs with 

  make clean
  make bootstrap
  make install

(perhaps more rebuilding than necessary, but I wanted to make sure
that I was getting a consistent build to test with)

After rebuilding, I repeated my earlier "Steps to Reproduce", and saw
exactly the same behavior that I reported in bug 5209 -- the patch did
not correct the indentation issue.

Sorry for the bad news :(

Steve

[Message part 2 (application/pgp-signature, inline)]

Information forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#5209; Package emacs. (Mon, 14 Dec 2009 01:25:49 GMT) Full text and rfc822 format available.

Acknowledgement sent to Steve Revilak <steve <at> srevilak.net>:
Extra info received and forwarded to list. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Mon, 14 Dec 2009 01:25:50 GMT) Full text and rfc822 format available.

bug reassigned from package 'emacs' to 'emacs,cc-mode'. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> emacsbugs.donarmstrong.com. (Mon, 14 Dec 2009 17:20:08 GMT) Full text and rfc822 format available.

Reply sent to Steve Revilak <steve <at> srevilak.net>:
You have taken responsibility. (Fri, 01 Jan 2010 00:50:03 GMT) Full text and rfc822 format available.

Notification sent to Steve Revilak <steve <at> srevilak.net>:
bug acknowledged by developer. (Fri, 01 Jan 2010 00:50:03 GMT) Full text and rfc822 format available.

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

From: Steve Revilak <steve <at> srevilak.net>
To: 5209-done <at> debbugs.gnu.org
Subject: Re: CC Mode version 5.31.8 does not indent properly when writing
	new C files
Date: Thu, 31 Dec 2009 14:39:02 -0500
[Message part 1 (text/plain, inline)]
I've tried this test case with 

  GNU Emacs 23.1.91.1 (powerpc-apple-darwin8.11.0, NS apple-appkit-824.48) of 2009-12-31 on spud
  GNU Emacs 23.1.91.1 (x86_64-apple-darwin10.2.0, NS apple-appkit-1038.25) of 2009-12-31 on oatmeal
  GNU Emacs 23.1.91.1 (i686-pc-linux-gnu, GTK+ Version 2.18.1) of 2009-12-31 on srevilak

The indentation problem no longer occurs with Emacs 23.1.91.1.

Relative to the original "Steps to Reproduce", 

 * In step (5), typing the final semicolon causes the line "*x += 1;"
   to be indented properly

 * If I delete leading whitespace from "*x += 1;" and perform step (7),
   then pressing TAB correctly indents the line.

 * If I delete leading whitespace from "*x += 1;" and perform step
   (8), then I find C-x h ESC C-\ correctly re-indents the entire
   buffer.

Nice work!

Steve
[Message part 2 (application/pgp-signature, inline)]

bug archived. Request was from Debbugs Internal Request <bug-gnu-emacs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 29 Jan 2010 12:24:03 GMT) Full text and rfc822 format available.

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

Previous Next


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