Function: c-append-lower-brace-pair-to-state-cache

c-append-lower-brace-pair-to-state-cache is a byte-compiled function defined in cc-engine.el.gz.

Signature

(c-append-lower-brace-pair-to-state-cache FROM HERE &optional UPPER-LIM)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-append-lower-brace-pair-to-state-cache (from here &optional upper-lim)
  ;; If there is a brace pair preceding FROM in the buffer, at the same level
  ;; of nesting (not necessarily immediately preceding), push a cons onto
  ;; `c-state-cache' to represent it.  FROM must not be inside a literal.  If
  ;; UPPER-LIM is non-nil, we append the highest brace pair whose "}" is below
  ;; UPPER-LIM.
  ;;
  ;; Return non-nil when this has been done.
  ;;
  ;; The situation it copes with is this transformation:
  ;;
  ;; OLD:   {                       (.)    {...........}
  ;;                                       ^             ^
  ;;                                     FROM          HERE
  ;;
  ;; NEW:   {             {....}    (.)    {.........
  ;;                         ^           ^           ^
  ;;                LOWER BRACE PAIR   HERE   or   HERE
  ;;
  ;; This routine should be fast.  Since it can get called a LOT, we maintain
  ;; `c-state-brace-pair-desert', a small cache of "failures", such that we
  ;; 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)
		     (c-beginning-of-macro)
		     (point)))
	     (bra			; Position of "{".
	      ;; Don't start scanning in the middle of a CPP construct unless
	      ;; it contains HERE.
	      (if (and (not (eq macro-start-or-from from))
		       (< macro-start-or-from here) ; Might not be needed.
		       (progn (goto-char macro-start-or-from)
			      (c-end-of-macro)
			      (>= (point) here)))
		  from
		macro-start-or-from))
	     ce)			; Position of "}"
	(or upper-lim (setq upper-lim from))

	;; 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.  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 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
		 ((and desert-lim cache-lim)
		  (max desert-lim cache-lim))
		 (desert-lim)
		 (cache-lim)
		 ((point-min)))
		;; The top limit is EOB to ensure that `bra' is inside the
		;; accessible part of the buffer at the next scan operation.
		(1+ (buffer-size))))

	  ;; In the next pair of nested loops, the inner one moves back past a
	  ;; pair of (mis-)matching parens or brackets; the outer one moves
	  ;; back over a sequence of unmatched close brace/paren/bracket each
	  ;; time round.
	  (while
	      (progn
		(c-safe
		  (while
		      (and (setq ce (c-sc-scan-lists bra -1 -1)) ; back past )/]/}; might signal
			   (setq bra (c-sc-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)))
		(cond
		 ((consp (car c-state-cache))
		  (setq c-state-cache (cons new-cons (cdr c-state-cache))))
		 ((and (numberp (car c-state-cache)) ; probably never happens
		       (< ce (car c-state-cache)))
		  (setq c-state-cache
			(cons (car c-state-cache)
			      (cons new-cons (cdr c-state-cache)))))
		 (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)))))))))