summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-engine.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r--lisp/progmodes/cc-engine.el78
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)