diff options
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 78 |
1 files changed, 64 insertions, 14 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 142ec4cdd66..f7248e2d2d3 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -1452,8 +1452,21 @@ comment at the start of cc-engine.el for more info." ;; return t when moving backwards at bob. (not (bobp)) - (if (let (open-paren-in-column-0-is-defun-start) - (forward-comment -1)) + (if (let (open-paren-in-column-0-is-defun-start moved-comment) + (while + (and (not (setq moved-comment (forward-comment -1))) + ;; Cope specifically with ^M^J here - + ;; forward-comment sometimes gets stuck after ^Ms, + ;; sometimes after ^M^J. + (or + (when (eq (char-before) ?\r) + (backward-char) + t) + (when (and (eq (char-before) ?\n) + (eq (char-before (1- (point))) ?\r)) + (backward-char 2) + t)))) + moved-comment) (if (looking-at "\\*/") ;; Emacs <= 20 and XEmacs move back over the ;; closer of a block comment that lacks an opener. @@ -2561,8 +2574,11 @@ comment at the start of cc-engine.el for more info." start-point cache-pos))) ;; Might we be better off starting from the top level, two defuns back, - ;; instead? - (when (> how-far c-state-cache-too-far) + ;; instead? This heuristic no longer works well in C++, where + ;; declarations inside namespace brace blocks are frequently placed at + ;; column zero. + (when (and (not (c-major-mode-is 'c++-mode)) + (> how-far c-state-cache-too-far)) (setq BOD-pos (c-get-fallback-scan-pos here)) ; somewhat EXPENSIVE!!! (if (< (- here BOD-pos) how-far) (setq strategy 'BOD @@ -2649,17 +2665,20 @@ comment at the start of cc-engine.el for more info." ;; If we're essentially repeating a fruitless search, just give up. (unless (and c-state-brace-pair-desert (eq cache-pos (car c-state-brace-pair-desert)) + (or (null (car c-state-brace-pair-desert)) + (> from (car c-state-brace-pair-desert))) (<= from (cdr c-state-brace-pair-desert))) - ;; DESERT-LIM. Only search what we absolutely need to, + ;; DESERT-LIM. Avoid repeated searching through the cached desert. (let ((desert-lim (and c-state-brace-pair-desert (eq cache-pos (car c-state-brace-pair-desert)) + (>= from (cdr c-state-brace-pair-desert)) (cdr c-state-brace-pair-desert))) ;; CACHE-LIM. This limit will be necessary when an opening ;; paren at `cache-pos' has just had its matching close paren - ;; inserted. `cache-pos' continues to be a search bound, even - ;; though the algorithm below would skip over the new paren - ;; pair. + ;; inserted into the buffer. `cache-pos' continues to be a + ;; search bound, even though the algorithm below would skip + ;; over the new paren pair. (cache-lim (and cache-pos (< cache-pos from) cache-pos))) (narrow-to-region (cond @@ -3091,6 +3110,8 @@ comment at the start of cc-engine.el for more info." c-state-cache-good-pos 1 c-state-nonlit-pos-cache nil c-state-nonlit-pos-cache-limit 1 + c-state-semi-nonlit-pos-cache nil + c-state-semi-nonlit-pos-cache-limit 1 c-state-brace-pair-desert nil c-state-point-min 1 c-state-point-min-lit-type nil @@ -3340,23 +3361,32 @@ comment at the start of cc-engine.el for more info." (fset 'c-real-parse-state (symbol-function 'c-parse-state))) (cc-bytecomp-defun c-real-parse-state) +(defvar c-parse-state-point nil) (defvar c-parse-state-state nil) (defun c-record-parse-state-state () + (setq c-parse-state-point (point)) (setq c-parse-state-state (mapcar (lambda (arg) - (cons arg (symbol-value arg))) + (let ((val (symbol-value arg))) + (cons arg + (if (consp val) + (copy-tree val) + val)))) '(c-state-cache c-state-cache-good-pos c-state-nonlit-pos-cache c-state-nonlit-pos-cache-limit + c-state-semi-nonlit-pos-cache + c-state-semi-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)))) + c-state-old-cpp-end + c-parse-state-point)))) (defun c-replay-parse-state-state () (message (concat "(setq " @@ -3366,6 +3396,16 @@ comment at the start of cc-engine.el for more info." c-parse-state-state " ") ")"))) +(defun c-debug-parse-state-double-cons (state) + (let (state-car conses-not-ok) + (while state + (setq state-car (car state) + state (cdr state)) + (if (and (consp state-car) + (consp (car state))) + (setq conses-not-ok t))) + conses-not-ok)) + (defun c-debug-parse-state () (let ((here (point)) (res1 (c-real-parse-state)) res2) (let ((c-state-cache nil) @@ -3398,8 +3438,16 @@ comment at the start of cc-engine.el for more info." here res1 res2) (message "Old state:") (c-replay-parse-state-state)) + + (when (c-debug-parse-state-double-cons res1) + (message "c-parse-state INVALIDITY at %s: %s" + here res1) + (message "Old state:") + (c-replay-parse-state-state)) + (c-record-parse-state-state) - res1)) + res2 ; res1 correct a cascading series of errors ASAP + )) (defun c-toggle-parse-state-debug (&optional arg) (interactive "P") @@ -3407,7 +3455,9 @@ comment at the start of cc-engine.el for more info." (fset 'c-parse-state (symbol-function (if c-debug-parse-state 'c-debug-parse-state 'c-real-parse-state))) - (c-keep-region-active)) + (c-keep-region-active) + (message "c-debug-parse-state %sabled" + (if c-debug-parse-state "en" "dis"))) (when c-debug-parse-state (c-toggle-parse-state-debug 1)) @@ -9579,12 +9629,12 @@ comment at the start of cc-engine.el for more info." (setq tmpsymbol nil) (while (and (> (point) placeholder) (zerop (c-backward-token-2 1 t)) - (/= (char-after) ?=)) + (not (looking-at "=\\([^=]\\|$\\)"))) (and c-opt-inexpr-brace-list-key (not tmpsymbol) (looking-at c-opt-inexpr-brace-list-key) (setq tmpsymbol 'topmost-intro-cont))) - (eq (char-after) ?=)) + (looking-at "=\\([^=]\\|$\\)")) (looking-at c-brace-list-key)) (save-excursion (while (and (< (point) indent-point) |
