@@ -2526,6 +2526,25 @@ comment at the start of cc-engine.el for more info."
25262526;; reduced by buffer changes, and increased by invocations of
25272527;; `c-state-literal-at'.
25282528
2529+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2530+ ;; We also maintain a less simple cache of positions which aren't in a
2531+ ;; literal, disregarding macros.
2532+ ;;
2533+ ;; This cache is in two parts: the "near" cache, which is an association list
2534+ ;; of a small number (currently six) of positions and the parser states there;
2535+ ;; the "far" cache (also known as "the cache"), a list of compressed parser
2536+ ;; states going back to the beginning of the buffer, one entry every 3000
2537+ ;; characters.
2538+ ;;
2539+ ;; When searching this cache, `c-state-semi-pp-to-literal' first seeks an
2540+ ;; exact match, then a "close" match from the near cache. If neither of these
2541+ ;; succeed, the nearest entry in the far cache is used.
2542+ ;;
2543+ ;; Because either sub-cache can raise `c-state-semi-nonlit-pos-cache-limit',
2544+ ;; both of them are "trimmed" together after a buffer change to ensure
2545+ ;; consistency.
2546+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2547+
25292548(defvar c-state-semi-nonlit-pos-cache nil)
25302549(make-variable-buffer-local 'c-state-semi-nonlit-pos-cache)
25312550;; A list of elements which are either buffer positions (when such positions
@@ -2539,12 +2558,62 @@ comment at the start of cc-engine.el for more info."
25392558;; is reduced by buffer changes, and increased by invocations of
25402559;; `c-parse-ps-state-below'.
25412560
2561+ (defvar c-state-semi-nonlit-near-cache nil)
2562+ (make-variable-buffer-local 'c-state-semi-nonlit-near-cache)
2563+ ;; A list of up to six recent results from `c-state-semi-pp-to-literal'. Each
2564+ ;; element is a cons of the buffer position and the `parse-partial-sexp' state
2565+ ;; at that position.
2566+
25422567(defsubst c-truncate-semi-nonlit-pos-cache (pos)
25432568 ;; Truncate the upper bound of the cache `c-state-semi-nonlit-pos-cache' to
25442569 ;; POS, if it is higher than that position.
25452570 (setq c-state-semi-nonlit-pos-cache-limit
25462571 (min c-state-semi-nonlit-pos-cache-limit pos)))
25472572
2573+ (defun c-state-semi-trim-near-cache ()
2574+ ;; Remove stale entries in `c-state-semi-nonlit-near-cache', i.e. those
2575+ ;; whose positions are above `c-state-semi-nonlit-pos-cache-limit'.
2576+ (let ((nc-list c-state-semi-nonlit-near-cache))
2577+ (while nc-list
2578+ (if (> (caar nc-list) c-state-semi-nonlit-pos-cache-limit)
2579+ (setq c-state-semi-nonlit-near-cache
2580+ (delq (car nc-list) c-state-semi-nonlit-near-cache)
2581+ nc-list c-state-semi-nonlit-near-cache) ; start again in case
2582+ ; of list breakage.
2583+ (setq nc-list (cdr nc-list))))))
2584+
2585+ (defun c-state-semi-get-near-cache-entry (here)
2586+ ;; Return the near cache entry at the highest postion before HERE, if any,
2587+ ;; or nil. The near cache entry is of the form (POSITION . STATE), where
2588+ ;; STATE has the form of a result of `parse-partial-sexp'.
2589+ (let ((nc-pos-state
2590+ (or (assq here c-state-semi-nonlit-near-cache)
2591+ (let ((nc-list c-state-semi-nonlit-near-cache)
2592+ pos (nc-pos 0) cand-pos-state)
2593+ (while nc-list
2594+ (setq pos (caar nc-list))
2595+ (when (and (<= pos here)
2596+ (> pos nc-pos))
2597+ (setq nc-pos pos
2598+ cand-pos-state (car nc-list)))
2599+ (setq nc-list (cdr nc-list)))
2600+ cand-pos-state))))
2601+ (when (and nc-pos-state
2602+ (not (eq nc-pos-state (car c-state-semi-nonlit-near-cache))))
2603+ ;; Move the found cache entry to the front of the list.
2604+ (setq c-state-semi-nonlit-near-cache
2605+ (delq nc-pos-state c-state-semi-nonlit-near-cache))
2606+ (push nc-pos-state c-state-semi-nonlit-near-cache))
2607+ nc-pos-state))
2608+
2609+ (defun c-state-semi-put-near-cache-entry (here state)
2610+ ;; Put a new near cache entry into the near cache.
2611+ (while (>= (length c-state-semi-nonlit-near-cache) 6)
2612+ (setq c-state-semi-nonlit-near-cache
2613+ (delq (car (last c-state-semi-nonlit-near-cache))
2614+ c-state-semi-nonlit-near-cache)))
2615+ (push (cons here state) c-state-semi-nonlit-near-cache))
2616+
25482617(defun c-state-semi-pp-to-literal (here &optional not-in-delimiter)
25492618 ;; Do a parse-partial-sexp from a position in the buffer before HERE which
25502619 ;; isn't in a literal, and return information about HERE, either:
@@ -2564,12 +2633,28 @@ comment at the start of cc-engine.el for more info."
25642633 (save-excursion
25652634 (save-restriction
25662635 (widen)
2636+ (c-state-semi-trim-cache)
2637+ (c-state-semi-trim-near-cache)
2638+ (setq c-state-semi-nonlit-pos-cache-limit here)
25672639 (save-match-data
2568- (let* ((base-and-state (c-parse-ps-state-below here))
2640+ (let* ((base-and-state (c-state-semi-get-near-cache-entry here))
25692641 (base (car base-and-state))
2642+ (near-base base)
25702643 (s (cdr base-and-state))
2571- (s (parse-partial-sexp base here nil nil s))
2572- ty)
2644+ far-base-and-state far-base far-s ty)
2645+ (if (or (not base)
2646+ (< base (- here 100)))
2647+ (progn
2648+ (setq far-base-and-state (c-parse-ps-state-below here)
2649+ far-base (car far-base-and-state)
2650+ far-s (cdr far-base-and-state))
2651+ (when (or (not base) (> far-base base))
2652+ (setq base far-base
2653+ s far-s))))
2654+ (when (> here base)
2655+ (setq s (parse-partial-sexp base here nil nil s)))
2656+ (when (not (eq near-base here))
2657+ (c-state-semi-put-near-cache-entry here s))
25732658 (cond
25742659 ((or (nth 3 s)
25752660 (and (nth 4 s)
@@ -2612,12 +2697,28 @@ comment at the start of cc-engine.el for more info."
26122697 (save-excursion
26132698 (save-restriction
26142699 (widen)
2700+ (c-state-semi-trim-cache)
2701+ (c-state-semi-trim-near-cache)
2702+ (setq c-state-semi-nonlit-pos-cache-limit here)
26152703 (save-match-data
2616- (let* ((base-and-state (c-parse-ps-state-below here))
2704+ (let* ((base-and-state (c-state-semi-get-near-cache-entry here))
26172705 (base (car base-and-state))
2706+ (near-base base)
26182707 (s (cdr base-and-state))
2619- (s (parse-partial-sexp base here nil nil s))
2620- ty start)
2708+ far-base-and-state far-base far-s ty start)
2709+ (if (or (not base)
2710+ (< base (- here 100)))
2711+ (progn
2712+ (setq far-base-and-state (c-parse-ps-state-below here)
2713+ far-base (car far-base-and-state)
2714+ far-s (cdr far-base-and-state))
2715+ (when (or (not base) (> far-base base))
2716+ (setq base far-base
2717+ s far-s))))
2718+ (when (> here base)
2719+ (setq s (parse-partial-sexp base here nil nil s)))
2720+ (when (not (eq near-base here))
2721+ (c-state-semi-put-near-cache-entry here s))
26212722 (cond
26222723 ((or (nth 3 s)
26232724 (and (nth 4 s)
@@ -2812,6 +2913,14 @@ comment at the start of cc-engine.el for more info."
28122913 elt
28132914 (car elt)))
28142915
2916+ (defun c-state-semi-trim-cache ()
2917+ ;; Trim the `c-state-semi-nonlit-pos-cache' to take account of buffer
2918+ ;; changes, indicated by `c-state-semi-nonlit-pos-cache-limit'.
2919+ (while (and c-state-semi-nonlit-pos-cache
2920+ (> (c-ps-state-cache-pos (car c-state-semi-nonlit-pos-cache))
2921+ c-state-semi-nonlit-pos-cache-limit))
2922+ (setq c-state-semi-nonlit-pos-cache (cdr c-state-semi-nonlit-pos-cache))))
2923+
28152924(defun c-parse-ps-state-below (here)
28162925 ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where
28172926 ;; CACHE-POS is a position not very far before HERE for which the
@@ -2822,14 +2931,9 @@ comment at the start of cc-engine.el for more info."
28222931 (save-excursion
28232932 (save-restriction
28242933 (widen)
2934+ (c-state-semi-trim-cache)
28252935 (let ((c c-state-semi-nonlit-pos-cache)
28262936 elt state npos high-elt)
2827- ;; Trim the cache to take account of buffer changes.
2828- (while (and c (> (c-ps-state-cache-pos (car c))
2829- c-state-semi-nonlit-pos-cache-limit))
2830- (setq c (cdr c)))
2831- (setq c-state-semi-nonlit-pos-cache c)
2832-
28332937 (while (and c (> (c-ps-state-cache-pos (car c)) here))
28342938 (setq high-elt (car c))
28352939 (setq c (cdr c)))
@@ -5617,7 +5721,7 @@ comment at the start of cc-engine.el for more info."
56175721 (when (not high-elt)
56185722 (setq stack (cdr elt))
56195723 (while
5620- ;; Add an element to `c-state-semi-nonlit-pos -cache' each iteration.
5724+ ;; Add an element to `c-bs -cache' each iteration.
56215725 (<= (setq npos (+ pos c-bs-interval)) here)
56225726 (setq elt (c-update-brace-stack stack pos npos))
56235727 (setq npos (car elt))
@@ -6469,44 +6573,52 @@ comment at the start of cc-engine.el for more info."
64696573 ;;
64706574 ;; FIXME!!! This routine ignores the possibility of macros entirely.
64716575 ;; 2010-01-29.
6472- (save-excursion
6473- (c-save-buffer-state
6474- ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
6475- (end-lit-limits (progn (goto-char end) (c-literal-limits)))
6476- new-beg new-end beg-limit end-limit)
6477- ;; Locate the earliest < after the barrier before the changed region,
6478- ;; which isn't already marked as a paren.
6479- (goto-char (or beg-lit-start beg))
6480- (setq beg-limit (c-determine-limit 512))
6481-
6482- ;; Remove the syntax-table/category properties from each pertinent <...>
6483- ;; pair. Firstly, the ones with the < before beg and > after beg....
6484- (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit)
6485- (eq (char-before) ?<))
6486- (c-backward-token-2)
6487- (when (eq (char-after) ?<)
6488- (c-clear-<-pair-props-if-match-after beg)
6489- (setq new-beg (point))))
6490- (c-forward-syntactic-ws)
6576+ (when (and (> end beg)
6577+ (or
6578+ (progn
6579+ (goto-char beg)
6580+ (search-backward "<" (max (- (point) 1024) (point-min)) t))
6581+ (progn
6582+ (goto-char end)
6583+ (search-forward ">" (min (+ (point) 1024) (point-max)) t))))
6584+ (save-excursion
6585+ (c-save-buffer-state
6586+ ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
6587+ (end-lit-limits (progn (goto-char end) (c-literal-limits)))
6588+ new-beg new-end beg-limit end-limit)
6589+ ;; Locate the earliest < after the barrier before the changed region,
6590+ ;; which isn't already marked as a paren.
6591+ (goto-char (or beg-lit-start beg))
6592+ (setq beg-limit (c-determine-limit 512))
6593+
6594+ ;; Remove the syntax-table/category properties from each pertinent <...>
6595+ ;; pair. Firstly, the ones with the < before beg and > after beg....
6596+ (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit)
6597+ (eq (char-before) ?<))
6598+ (c-backward-token-2)
6599+ (when (eq (char-after) ?<)
6600+ (c-clear-<-pair-props-if-match-after beg)
6601+ (setq new-beg (point))))
6602+ (c-forward-syntactic-ws)
64916603
6492- ;; ...Then the ones with < before end and > after end.
6493- (goto-char (if end-lit-limits (cdr end-lit-limits) end))
6494- (setq end-limit (c-determine-+ve-limit 512))
6495- (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end)
6496- (eq (char-before) ?>))
6497- (c-end-of-current-token)
6498- (when (eq (char-before) ?>)
6499- (c-clear->-pair-props-if-match-before end (1- (point)))
6500- (setq new-end (point))))
6501- (c-backward-syntactic-ws)
6502-
6503- ;; Extend the fontification region, if needed.
6504- (and new-beg
6505- (< new-beg c-new-BEG)
6506- (setq c-new-BEG new-beg))
6507- (and new-end
6508- (> new-end c-new-END)
6509- (setq c-new-END new-end)))))
6604+ ;; ...Then the ones with < before end and > after end.
6605+ (goto-char (if end-lit-limits (cdr end-lit-limits) end))
6606+ (setq end-limit (c-determine-+ve-limit 512))
6607+ (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end)
6608+ (eq (char-before) ?>))
6609+ (c-end-of-current-token)
6610+ (when (eq (char-before) ?>)
6611+ (c-clear->-pair-props-if-match-before end (1- (point)))
6612+ (setq new-end (point))))
6613+ (c-backward-syntactic-ws)
6614+
6615+ ;; Extend the fontification region, if needed.
6616+ (and new-beg
6617+ (< new-beg c-new-BEG)
6618+ (setq c-new-BEG new-beg))
6619+ (and new-end
6620+ (> new-end c-new-END)
6621+ (setq c-new-END new-end) )))))
65106622
65116623(defun c-after-change-check-<>-operators (beg end)
65126624 ;; This is called from `after-change-functions' when
@@ -7123,7 +7235,8 @@ comment at the start of cc-engine.el for more info."
71237235 t)
71247236 ((save-excursion
71257237 (and
7126- (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\=" nil t)
7238+ (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\="
7239+ (c-point 'bol) t)
71277240 (setq id (match-string-no-properties 1))
71287241 (let* ((quoted-id (regexp-quote id))
71297242 (quoted-id-depth (regexp-opt-depth quoted-id)))
0 commit comments