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)))))