all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Steve Revilak <steve@srevilak.net>, 5209@emacsbugs.donarmstrong.com
Cc: emacs-pretest-bug@gnu.org
Subject: 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	[thread overview]
Message-ID: <20091213203311.GB3389@muc.de> (raw)
In-Reply-To: <20091213162210.GC376@srevilak.net>

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).





  reply	other threads:[~2009-12-13 20:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20091231193902.GB24581@srevilak.net>
2009-12-13 16:22 ` bug#5209: 23.1.90; CC Mode version 5.31.8 does not indent properly when writing new C files Steve Revilak
2009-12-13 20:33   ` Alan Mackenzie [this message]
2009-12-14  1:17     ` Steve Revilak
2010-01-01  0:50   ` bug#5209: marked as done (23.1.90; CC Mode version 5.31.8 does not indent properly when writing new C files) Emacs bug Tracking System

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091213203311.GB3389@muc.de \
    --to=acm@muc.de \
    --cc=5209@emacsbugs.donarmstrong.com \
    --cc=emacs-pretest-bug@gnu.org \
    --cc=steve@srevilak.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.