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).
next prev parent 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.