[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#5209: 23.1.90; CC Mode version 5.31.8 does not indent properly when
From: |
Alan Mackenzie |
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 |
User-agent: |
Mutt/1.5.9i |
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).