From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#11749: Acknowledgement (24.1; C-mode indentation gives wrong-type-argument error.) Date: Wed, 23 Jan 2013 14:16:45 +0000 Message-ID: <20130123141644.GB3411@acm.acm> References: <20121014170650.GA3766@acm.acm> <20121028113610.GA3339@acm.acm> <20121104203912.GA3274@acm.acm> <20121121213340.GB4025@acm.acm> <87sj7elgtt.fsf@maru.md5i.com> <20130107120951.GB3384@acm.acm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1358951049 5610 80.91.229.3 (23 Jan 2013 14:24:09 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 23 Jan 2013 14:24:09 +0000 (UTC) Cc: "11749@debbugs.gnu.org" <11749@debbugs.gnu.org>, Kim Storm To: Michael Welsh Duggan Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jan 23 15:24:27 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Ty1FY-0004fg-ON for geb-bug-gnu-emacs@m.gmane.org; Wed, 23 Jan 2013 15:24:25 +0100 Original-Received: from localhost ([::1]:53533 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ty1FH-0007Xu-HZ for geb-bug-gnu-emacs@m.gmane.org; Wed, 23 Jan 2013 09:24:07 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:59965) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ty1F8-0007Xd-Af for bug-gnu-emacs@gnu.org; Wed, 23 Jan 2013 09:24:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ty1F1-0004Pn-FH for bug-gnu-emacs@gnu.org; Wed, 23 Jan 2013 09:23:58 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:40485) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ty1Ey-0004P7-26; Wed, 23 Jan 2013 09:23:48 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1Ty1GA-00052Y-GT; Wed, 23 Jan 2013 09:25:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Wed, 23 Jan 2013 14:25:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 11749 X-GNU-PR-Package: emacs,cc-mode X-GNU-PR-Keywords: Original-Received: via spool by 11749-submit@debbugs.gnu.org id=B11749.135895109319324 (code B ref 11749); Wed, 23 Jan 2013 14:25:02 +0000 Original-Received: (at 11749) by debbugs.gnu.org; 23 Jan 2013 14:24:53 +0000 Original-Received: from localhost ([127.0.0.1]:45949 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Ty1Fz-00051U-N7 for submit@debbugs.gnu.org; Wed, 23 Jan 2013 09:24:53 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:29700 helo=mail.muc.de) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Ty1Fu-000510-Rj for 11749@debbugs.gnu.org; Wed, 23 Jan 2013 09:24:49 -0500 Original-Received: (qmail 3952 invoked by uid 3782); 23 Jan 2013 14:23:30 -0000 Original-Received: from acm.muc.de (pD951AF90.dip.t-dialin.net [217.81.175.144]) by colin.muc.de (tmda-ofmipd) with ESMTP; Wed, 23 Jan 2013 15:23:27 +0100 Original-Received: (qmail 4237 invoked by uid 1000); 23 Jan 2013 14:16:45 -0000 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:70209 Archived-At: Hi, Michael. On Thu, Jan 17, 2013 at 11:27:04AM -0500, Michael Welsh Duggan wrote: > Alan Mackenzie writes: > [This] fixes this case, indeed. Unfortunately, here's another. > emacs -Q rwtransfer.c > M-x c-toggle-parse-state-debug > M-> > Then type M-v until the parse failure happens. For me it happens at > 32% point in the file. Please not that this particular problem only > happens when paging through the file in reverse order. > c-parse-state inconsistency at 15885: using cache: (15636 15181 (13849 . 15141)), from scratch: (15636 (15303 . 15493) 15181 (13849 . 15141)) > Old state: > (setq c-state-cache '(16334 16271 16248 (16059 . 16193) 15181 (13849 . 15141)) c-state-cache-good-pos 16335 c-state-nonlit-pos-cache '(48473 45473 42473 39473 36473 33473 30473 27378 24378 21260 18015 15015 12015 9015 6015 3015) c-state-nonlit-pos-cache-limit 48473 c-state-semi-nonlit-pos-cache '(48323 45323 42323 39323 36323 33260 30260 27260 24260 21260 18001 15001 12001 9001 6001 3001) c-state-semi-nonlit-pos-cache-limit 48323 c-state-brace-pair-desert '(15181 . 17388) c-state-point-min 1 c-state-point-min-lit-type nil c-state-point-min-lit-start nil c-state-min-scan-pos 1 c-state-old-cpp-beg nil c-state-old-cpp-end nil c-parse-state-point 16335) > c-parse-state inconsistency at 15885: using cache: (15636 15181 (13849 . 15141)), from scratch: (15636 (15303 . 15493) 15181 (13849 . 15141)) I think the following patch should fix that glitch. I've also taken the opportunity to simplify things a little (part of the global state was being passed needlessly as a parameter) and to rename some variables for more consistency. Would you try this out and confirm it works, as usual, please. However, this isn't the end of the story - (i) Start your test case in rwtransfer.c, and M-v until the top of the file. (This shouldn't display any inconsistency messages) (ii) M-x goto-char 20001 . This should go to EOL 671, just after a "}". (iii) Type }. (Two characters) (iv) C-v, possibly twice. This displays a message something like: c-parse-state inconsistency at 21070: using cache: ((20458 . 20935)), from scratch: ((20838 . 20877)) , together with a state dump. This bug isn't a new one, but I've just come across it. I'll be working on it in the meantime. Here's the patch, based on the savannah emacs-24 branch (which should be identical to the trunk): === modified file 'lisp/progmodes/cc-engine.el' *** lisp/progmodes/cc-engine.el 2013-01-09 21:33:00 +0000 --- lisp/progmodes/cc-engine.el 2013-01-23 13:36:33 +0000 *************** *** 2545,2558 **** ;; ;; The return value is a list, one of the following: ;; ! ;; o - ('forward CACHE-POS START-POINT) - scan forward from START-POINT, ! ;; which is not less than CACHE-POS. ! ;; o - ('backward CACHE-POS nil) - scan backwards (from HERE). ! ;; o - ('BOD nil START-POINT) - scan forwards from START-POINT, which is at the ;; top level. ! ;; o - ('IN-LIT nil nil) - point is inside the literal containing point-min. ! ;; , where CACHE-POS is the highest position recorded in `c-state-cache' at ! ;; or below HERE. (let ((cache-pos (c-get-cache-scan-pos here)) ; highest position below HERE in cache (or 1) BOD-pos ; position of 2nd BOD before HERE. strategy ; 'forward, 'backward, 'BOD, or 'IN-LIT. --- 2545,2556 ---- ;; ;; The return value is a list, one of the following: ;; ! ;; o - ('forward START-POINT) - scan forward from START-POINT, ! ;; which is not less than the highest position in `c-state-cache' below here. ! ;; o - ('backward nil) - scan backwards (from HERE). ! ;; o - ('BOD START-POINT) - scan forwards from START-POINT, which is at the ;; top level. ! ;; o - ('IN-LIT nil) - point is inside the literal containing point-min. (let ((cache-pos (c-get-cache-scan-pos here)) ; highest position below HERE in cache (or 1) BOD-pos ; position of 2nd BOD before HERE. strategy ; 'forward, 'backward, 'BOD, or 'IN-LIT. *************** *** 2590,2596 **** (list strategy - (and (memq strategy '(forward backward)) cache-pos) (and (memq strategy '(forward BOD)) start-point)))) --- 2588,2593 ---- *************** *** 2657,2663 **** ;; reduce the time wasted in repeated fruitless searches in brace deserts. (save-excursion (save-restriction ! (let* (new-cons (cache-pos (c-state-cache-top-lparen)) ; might be nil. (macro-start-or-from (progn (goto-char from) --- 2654,2661 ---- ;; reduce the time wasted in repeated fruitless searches in brace deserts. (save-excursion (save-restriction ! (let* ((here (point-max)) ! new-cons (cache-pos (c-state-cache-top-lparen)) ; might be nil. (macro-start-or-from (progn (goto-char from) *************** *** 2692,2697 **** --- 2690,2696 ---- ;; search bound, even though the algorithm below would skip ;; over the new paren pair. (cache-lim (and cache-pos (< cache-pos from) cache-pos))) + (widen) (narrow-to-region (cond ((and desert-lim cache-lim) *************** *** 2711,2726 **** (while (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; might signal (setq bra (scan-lists ce -1 1)) ; back past (/[/{; might signal ! (or (> ce upper-lim) ! (not (eq (char-after bra) ?\{)) ! (and (goto-char bra) ! (c-beginning-of-macro) ! (< (point) macro-start-or-from)))))) (and ce (< ce bra))) (setq bra ce)) ; If we just backed over an unbalanced closing ; brace, ignore it. ! (if (and ce (< bra ce) (eq (char-after bra) ?\{)) ;; We've found the desired brace-pair. (progn (setq new-cons (cons bra (1+ ce))) --- 2710,2727 ---- (while (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; might signal (setq bra (scan-lists ce -1 1)) ; back past (/[/{; might signal ! (or (> bra here) ;(> ce here) ! (and ! (< ce here) ! (or (not (eq (char-after bra) ?\{)) ! (and (goto-char bra) ! (c-beginning-of-macro) ! (< (point) macro-start-or-from)))))))) (and ce (< ce bra))) (setq bra ce)) ; If we just backed over an unbalanced closing ; brace, ignore it. ! (if (and ce (< ce here) (< bra ce) (eq (char-after bra) ?\{)) ;; We've found the desired brace-pair. (progn (setq new-cons (cons bra (1+ ce))) *************** *** 2734,2740 **** (t (setq c-state-cache (cons new-cons c-state-cache))))) ;; We haven't found a brace pair. Record this in the cache. ! (setq c-state-brace-pair-desert (cons cache-pos from)))))))) (defsubst c-state-push-any-brace-pair (bra+1 macro-start-or-here) ;; If BRA+1 is nil, do nothing. Otherwise, BRA+1 is the buffer position --- 2735,2745 ---- (t (setq c-state-cache (cons new-cons c-state-cache))))) ;; We haven't found a brace pair. Record this in the cache. ! (setq c-state-brace-pair-desert ! (cons (if (and ce (< bra ce) (> ce here)) ; {..} straddling HERE? ! bra ! (point-min)) ! (min here from))))))))) (defsubst c-state-push-any-brace-pair (bra+1 macro-start-or-here) ;; If BRA+1 is nil, do nothing. Otherwise, BRA+1 is the buffer position *************** *** 2852,2870 **** (paren+1) (t from))))) ! (defun c-remove-stale-state-cache (good-pos pps-point) ;; Remove stale entries from the `c-cache-state', i.e. those which will ;; not be in it when it is amended for position (point-max). ;; Additionally, the "outermost" open-brace entry before (point-max) ;; will be converted to a cons if the matching close-brace is scanned. ;; ! ;; GOOD-POS is a "maximal" "safe position" - there must be no open ! ;; parens/braces/brackets between GOOD-POS and (point-max). ;; ;; As a second thing, calculate the result of parse-partial-sexp at ! ;; PPS-POINT, w.r.t. GOOD-POS. The motivation here is that ;; `c-state-cache-good-pos' may become PPS-POINT, but the caller may need to ! ;; adjust it to get outside a string/comment. (Sorry about this! The code ;; needs to be FAST). ;; ;; Return a list (GOOD-POS SCAN-BACK-POS PPS-STATE), where --- 2857,2875 ---- (paren+1) (t from))))) ! (defun c-remove-stale-state-cache (start-point pps-point) ;; Remove stale entries from the `c-cache-state', i.e. those which will ;; not be in it when it is amended for position (point-max). ;; Additionally, the "outermost" open-brace entry before (point-max) ;; will be converted to a cons if the matching close-brace is scanned. ;; ! ;; START-POINT is a "maximal" "safe position" - there must be no open ! ;; parens/braces/brackets between START-POINT and (point-max). ;; ;; As a second thing, calculate the result of parse-partial-sexp at ! ;; PPS-POINT, w.r.t. START-POINT. The motivation here is that ;; `c-state-cache-good-pos' may become PPS-POINT, but the caller may need to ! ;; adjust it to get outside a string/comment. (Sorry about this! The code ;; needs to be FAST). ;; ;; Return a list (GOOD-POS SCAN-BACK-POS PPS-STATE), where *************** *** 2872,2878 **** ;; to be good (we aim for this to be as high as possible); ;; 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)) --- 2877,2885 ---- ;; to be good (we aim for this to be as high as possible); ;; 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. It is the position of the "{" of the ! ;; last element to be removed from `c-state-cache', when that elt is a ! ;; cons, otherwise nil. ;; o - PPS-STATE is the parse-partial-sexp state at PPS-POINT. (save-restriction (narrow-to-region 1 (point-max)) *************** *** 2882,2902 **** (goto-char (point-max)) (and (c-beginning-of-macro) (point)))) ! (good-pos-actual-macro-start ; Start of macro containing good-pos ! ; or nil ! (and (< good-pos (point-max)) (save-excursion ! (goto-char good-pos) (and (c-beginning-of-macro) (point))))) ! (good-pos-actual-macro-end ; End of this macro, (maybe ; (point-max)), or nil. ! (and good-pos-actual-macro-start (save-excursion ! (goto-char good-pos-actual-macro-start) (c-end-of-macro) (point)))) ! pps-state ; Will be 9 or 10 elements long. pos upper-lim ; ,beyond which `c-state-cache' entries are removed scan-back-pos --- 2889,2909 ---- (goto-char (point-max)) (and (c-beginning-of-macro) (point)))) ! (start-point-actual-macro-start ; Start of macro containing ! ; start-point or nil ! (and (< start-point (point-max)) (save-excursion ! (goto-char start-point) (and (c-beginning-of-macro) (point))))) ! (start-point-actual-macro-end ; End of this macro, (maybe ; (point-max)), or nil. ! (and start-point-actual-macro-start (save-excursion ! (goto-char start-point-actual-macro-start) (c-end-of-macro) (point)))) ! pps-state ; Will be 9 or 10 elements long. pos upper-lim ; ,beyond which `c-state-cache' entries are removed scan-back-pos *************** *** 2926,2940 **** ;; The next loop jumps forward out of a nested level of parens each ;; time round; the corresponding elements in `c-state-cache' are ;; removed. `pos' is just after the brace-pair or the open paren at ! ;; (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-end ! (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)) (goto-char pos) (while (and c-state-cache (< (point) (point-max))) --- 2933,2947 ---- ;; The next loop jumps forward out of a nested level of parens each ;; time round; the corresponding elements in `c-state-cache' are ;; removed. `pos' is just after the brace-pair or the open paren at ! ;; (car c-state-cache). There can be no open parens/braces/brackets ! ;; between `start-point'/`start-point-actual-macro-start' and (point-max), ;; due to the interface spec to this function. ! (setq pos (if (and start-point-actual-macro-end ! (not (eq start-point-actual-macro-start in-macro-start))) ! (1+ start-point-actual-macro-end) ; get outside the macro as ; marked by a `category' text property. ! start-point)) (goto-char pos) (while (and c-state-cache (< (point) (point-max))) *************** *** 2993,3006 **** (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 ;; buffer, and inform the caller of the scenario detected. ;; ;; HERE is the position we're setting `c-state-cache' for. ! ;; CACHE-POS is just after the latest recorded position in `c-state-cache' ! ;; before HERE, or a position at or near point-min which isn't in a ! ;; literal. ;; ;; This function must only be called only when (> `c-state-cache-good-pos' ;; HERE). Usually the gap between CACHE-POS and HERE is large. It is thus --- 3000,3013 ---- (list pos scan-back-pos pps-state))))) ! (defun c-remove-stale-state-cache-backwards (here) ;; Strip stale elements of `c-state-cache' by moving backwards through the ;; buffer, and inform the caller of the scenario detected. ;; ;; HERE is the position we're setting `c-state-cache' for. ! ;; CACHE-POS (a locally bound variable) is just after the latest recorded ! ;; position in `c-state-cache' before HERE, or a position at or near ! ;; point-min which isn't in a literal. ;; ;; This function must only be called only when (> `c-state-cache-good-pos' ;; HERE). Usually the gap between CACHE-POS and HERE is large. It is thus *************** *** 3023,3032 **** ;; The comments in this defun use "paren" to mean parenthesis or square ;; bracket (as contrasted with a brace), and "(" and ")" likewise. ;; ! ;; . {..} (..) (..) ( .. { } ) (...) ( .... . ..) ! ;; | | | | | | ! ;; CP E here D C good ! (let ((pos c-state-cache-good-pos) pa ren ; positions of "(" and ")" dropped-cons ; whether the last element dropped from `c-state-cache' ; was a cons (representing a brace-pair) --- 3030,3040 ---- ;; The comments in this defun use "paren" to mean parenthesis or square ;; bracket (as contrasted with a brace), and "(" and ")" likewise. ;; ! ;; . {..} (..) (..) ( .. { } ) (...) ( .... . ..) ! ;; | | | | | | ! ;; CP E here D C good ! (let ((cache-pos (c-get-cache-scan-pos here)) ; highest position below HERE in cache (or 1) ! (pos c-state-cache-good-pos) pa ren ; positions of "(" and ")" dropped-cons ; whether the last element dropped from `c-state-cache' ; was a cons (representing a brace-pair) *************** *** 3263,3269 **** cache-pos ; highest position below HERE already existing in ; cache (or 1). good-pos ! start-point bopl-state res scan-backward-pos scan-forward-p) ; used for 'backward. --- 3271,3278 ---- cache-pos ; highest position below HERE already existing in ; cache (or 1). good-pos ! start-point ; (when scanning forward) a place below HERE where there ! ; are no open parens/braces between it and HERE. bopl-state res scan-backward-pos scan-forward-p) ; used for 'backward. *************** *** 3274,3281 **** ;; Strategy? (setq res (c-parse-state-get-strategy here c-state-cache-good-pos) strategy (car res) ! cache-pos (cadr res) ! start-point (nth 2 res)) (when (eq strategy 'BOD) (setq c-state-cache nil --- 3283,3289 ---- ;; Strategy? (setq res (c-parse-state-get-strategy here c-state-cache-good-pos) strategy (car res) ! start-point (cadr res)) (when (eq strategy 'BOD) (setq c-state-cache nil *************** *** 3302,3308 **** good-pos))) ((eq strategy 'backward) ! (setq res (c-remove-stale-state-cache-backwards here cache-pos) good-pos (car res) scan-backward-pos (cadr res) scan-forward-p (car (cddr res))) --- 3310,3316 ---- good-pos))) ((eq strategy 'backward) ! (setq res (c-remove-stale-state-cache-backwards here) good-pos (car res) scan-backward-pos (cadr res) scan-forward-p (car (cddr res))) > -- > Michael Welsh Duggan > (mwd@cert.org) -- Alan Mackenzie (Nuremberg, Germany).