bug-gnu-emacs
[Top][All Lists]
Advanced

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]