Subject: bug#9560: An exact recipe

From: Alan Mackenzie <[email-masked]>
Date: Thu, 20 Oct 2011 11:42:29 +0000

Hi, Michael.

On Wed, Oct 19, 2011 at 09:45:45AM -0400, Michael Welsh Duggan wrote:
> Alan Mackenzie <[email-masked]> writes:

> Okay, I've done some experimenting, and unfortunately, I have been
> unable to recreate this problem using this recipe using emacs -Q -nw.
> I've only encountered it using an X window.

That still perplexes me.  I've got a fix, but the problem should have
appeared on a tty and a -nw too.

> In this environment, I was able to recreate the problem consistently.
> I was able to replace the initial "3*C-v 7*C-n" in the macro with
> "100*C-n C-l" and this allowed it to work with larger frame sizes.
> Don't ask me why the C-l is necessary, as I do not know.

> >> When you have solved this bug, please let me know if the solution has a
> >> reasonable chance of having solved the other problem that I have not
> >> been able to recreate reliably, which is getting "topmost-intro indent
> >> 0" instead of "statement indent 4" when in the middle of editing a
> >> function.  If these have little chance of being connected, I'll do my
> >> best to try to create that scenario again (no promises).

I think there's a good chance of that bug being fixed by the following
patch (no promises ;-).

The bug was a bit of carelessness on my part.  I'd done
  (unless (and T1 T2 T3) ...) 
, and in the body tested
  (and T1 (not T3))
, which is rubbish, since that says nothing about the state of T2.  T2
being the wrong way round was what caused the bug to show up.

Anyhow, here's the patch.  Only the first chunk is for the bug; the rest
of it is the superior instrumentation.  Let me know how this goes!

*** orig/cc-engine.el	2011-10-19 19:16:01.000000000 +0000
--- cc-engine.el	2011-10-20 11:22:15.000000000 +0000
***************
*** 2485,2491 ****
  		     (<= from (cdr c-state-brace-pair-desert)))
  	  ;; Only search what we absolutely need to:
  	  (if (and c-state-brace-pair-desert
! 		   (> from (cdr c-state-brace-pair-desert)))
  	      (narrow-to-region (cdr c-state-brace-pair-desert) (point-max)))
  
  	  ;; In the next pair of nested loops, the inner one moves back past a
--- 2485,2491 ----
  		     (<= from (cdr c-state-brace-pair-desert)))
  	  ;; Only search what we absolutely need to:
  	  (if (and c-state-brace-pair-desert
! 		   (eq cache-pos (car c-state-brace-pair-desert)))
  	      (narrow-to-region (cdr c-state-brace-pair-desert) (point-max)))
  
  	  ;; In the next pair of nested loops, the inner one moves back past a
***************
*** 3169,3174 ****
--- 3169,3204 ----
  (unless (fboundp 'c-real-parse-state)
    (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
  (cc-bytecomp-defun c-real-parse-state)
+ 
+ (defvar c-parse-state-state nil)
+ (defun c-record-parse-state-state ()
+   (setq c-parse-state-state
+ 	(mapcar
+ 	 (lambda (arg)
+ 	   (cons arg (symbol-value arg)))
+ 	 '(c-state-cache
+ 	   c-state-cache-good-pos
+ 	   c-state-nonlit-pos-cache
+ 	   c-state-nonlit-pos-cache-limit
+ 	   c-state-brace-pair-desert
+ 	   c-state-point-min
+ 	   c-state-point-min-lit-type
+ 	   c-state-point-min-lit-start
+ 	   c-state-min-scan-pos
+ 	   c-state-old-cpp-beg
+ 	   c-state-old-cpp-end))))
+ (defun c-replay-parse-state-state ()
+   (let ((outstring "(setq "))
+     (mapc
+      (lambda (arg)
+        (setq outstring
+ 	     (concat outstring
+ 		     (format "  %s %s%s"
+ 			     (car arg) (if (atom (cdr arg)) "" "'") (cdr arg)))))
+      c-parse-state-state)
+     (setq outstring (concat outstring ")"))
+     (message outstring)))
+ 
  (defun c-debug-parse-state ()
    (let ((here (point)) (res1 (c-real-parse-state)) res2)
      (let ((c-state-cache nil)
***************
*** 3187,3201 ****
        ;; The cache can actually go further back due to the ad-hoc way
        ;; the first paren is found, so try to whack off a bit of its
        ;; start before complaining.
!       (save-excursion
! 	(goto-char (or (c-least-enclosing-brace res2) (point)))
! 	(c-beginning-of-defun-1)
! 	(while (not (or (bobp) (eq (char-after) ?{)))
! 	  (c-beginning-of-defun-1))
! 	(unless (equal (c-whack-state-before (point) res1) res2)
! 	  (message (concat "c-parse-state inconsistency at %s: "
! 			   "using cache: %s, from scratch: %s")
! 		   here res1 res2))))
      res1))
  
  (defun c-toggle-parse-state-debug (&optional arg)
--- 3217,3237 ----
        ;; The cache can actually go further back due to the ad-hoc way
        ;; the first paren is found, so try to whack off a bit of its
        ;; start before complaining.
!       ;; (save-excursion
!       ;; 	(goto-char (or (c-least-enclosing-brace res2) (point)))
!       ;; 	(c-beginning-of-defun-1)
!       ;; 	(while (not (or (bobp) (eq (char-after) ?{)))
!       ;; 	  (c-beginning-of-defun-1))
!       ;; 	(unless (equal (c-whack-state-before (point) res1) res2)
!       ;; 	  (message (concat "c-parse-state inconsistency at %s: "
!       ;; 			   "using cache: %s, from scratch: %s")
!       ;; 		   here res1 res2)))
!       (message (concat "c-parse-state inconsistency at %s: "
! 		       "using cache: %s, from scratch: %s")
! 	       here res1 res2)
!       (message "Old state:")
!       (c-replay-parse-state-state))
!     (c-record-parse-state-state)
      res1))
  
  (defun c-toggle-parse-state-debug (&optional arg)

> -- 
> Michael Welsh Duggan
> ([email-masked])

-- 
Alan Mackenzie (Nuremberg, Germany).