Function: c-remove-stale-state-cache-backwards
c-remove-stale-state-cache-backwards is a byte-compiled function
defined in cc-engine.el.gz.
Signature
(c-remove-stale-state-cache-backwards HERE)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(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
;; optimized to eliminate (or minimize) scanning between these two
;; positions.
;;
;; Return a three element list (GOOD-POS SCAN-BACK-POS FWD-FLAG), where:
;; o - GOOD-POS is a "good position", where `c-state-cache' is valid, or
;; could become so after missing elements are inserted into
;; `c-state-cache'. This is JUST AFTER an opening or closing
;; brace/paren/bracket which is already in `c-state-cache' or just before
;; one otherwise. exceptionally (when there's no such b/p/b handy) the BOL
;; before `here''s line, or the start of the literal containing it.
;; o - SCAN-BACK-POS, if non-nil, indicates there may be a brace pair
;; preceding POS which isn't recorded in `c-state-cache'. It is a position
;; to scan backwards from.
;; o - FWD-FLAG, if non-nil, indicates there may be parens/braces between
;; POS and HERE which aren't recorded in `c-state-cache'.
;;
;; 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)
good-pos ; see above.
lit ; (START . END) of a literal containing some point.
here-lit-start here-lit-end ; bounds of literal containing `here'
; or `here' itself.
here- here+ ; start/end of macro around HERE, or HERE
(here-bol (c-point 'bol here))
(too-far-back (max (- here c-state-cache-too-far) (point-min))))
;; Remove completely irrelevant entries from `c-state-cache'.
(while (and c-state-cache
(>= (setq pa (c-state-cache-top-lparen)) here))
(setq dropped-cons (consp (car c-state-cache)))
(setq c-state-cache (cdr c-state-cache))
(setq pos pa))
;; At this stage, (>= pos here);
;; (< (c-state-cache-top-lparen) here) (or is nil).
(cond
((and (consp (car c-state-cache))
(> (cdar c-state-cache) here))
;; CASE 1: The top of the cache is a brace pair which now encloses
;; `here'. As good-pos, return the address of the "{". Since we've no
;; knowledge of what's inside these braces, we have no alternative but
;; to direct the caller to scan the buffer from the opening brace.
(setq pos (caar c-state-cache))
(setq c-state-cache (cons pos (cdr c-state-cache)))
(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.
((progn
(setq lit (c-state-literal-at here)
here-lit-start (or (car lit) here)
here-lit-end (or (cdr lit) here))
;; Has `here' just "newly entered" a macro?
(save-excursion
(goto-char here-lit-start)
(if (and (c-beginning-of-macro)
(or (null c-state-old-cpp-beg)
(not (= (point) c-state-old-cpp-beg))))
(progn
(setq here- (point))
(c-end-of-macro)
(setq here+ (point)))
(setq here- here-lit-start
here+ here-lit-end)))
;; `here' might be nested inside any depth of parens (or brackets but
;; not braces). Scan backwards to find the outermost such opening
;; paren, if there is one. This will be the scan position to return.
(save-restriction
(narrow-to-region cache-pos (point-max))
(setq pos (c-state-balance-parens-backwards here- here+ pos)))
nil)) ; for the cond
((< pos here-lit-start)
;; CASE 2: Address of outermost ( or [ which now encloses `here', but
;; didn't enclose the (previous) `c-state-cache-good-pos'. If there is
;; a brace pair preceding this, it will already be in `c-state-cache',
;; unless there was a brace pair after it, i.e. there'll only be one to
;; scan for if we've just deleted one.
(list pos (and dropped-cons pos) t)) ; Return value.
;; `here' isn't enclosed in a (previously unrecorded) bracket/paren.
;; Further forward scanning isn't needed, but we still need to find a
;; GOOD-POS. Step out of all enclosing "("s on HERE's line.
((progn
(save-restriction
(narrow-to-region here-bol (point-max))
(setq pos here-lit-start)
(c-safe (while (setq pa (c-sc-scan-lists pos -1 1))
(setq pos pa)))) ; might signal
nil)) ; for the cond
((save-restriction
(narrow-to-region too-far-back (point-max))
(setq ren (c-safe (c-sc-scan-lists pos -1 -1))))
;; CASE 3: After a }/)/] before `here''s BOL.
(list (1+ ren) (and dropped-cons pos) nil)) ; Return value
((progn (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
(>= cache-pos good-pos))
;; CASE 3.5: Just after an existing entry in `c-state-cache' on `here''s
;; line or the previous line.
(list cache-pos nil nil))
(t
;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
;; literal containing it.
(list good-pos (and dropped-cons good-pos) nil)))))