aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2009-12-03 16:02:10 +0000
committerAlan Mackenzie2009-12-03 16:02:10 +0000
commit0ec1d2c5bb42c578aa555d77e379c8c256114306 (patch)
treea7050ce31c3132a0649bde014a4d62f202cb7e78
parent4267d8591048007bb584bdba9924056d660e0c53 (diff)
downloademacs-0ec1d2c5bb42c578aa555d77e379c8c256114306.tar.gz
emacs-0ec1d2c5bb42c578aa555d77e379c8c256114306.zip
Enhance `c-parse-state' to run efficiently in "brace desserts".
* progmodes/cc-mode.el (c-basic-common-init): Call c-state-cache-init. (c-neutralize-syntax-in-and-mark-CPP): Renamed from c-extend-and-neutralize-syntax-in-CPP. Mark each CPP construct by placing `category' properties value 'c-cpp-delimiter at its boundaries. * progmodes/cc-langs.el (c-before-font-lock-function): c-extend-and-neutralize-syntax-in-CPP has been renamed c-neutralize-syntax-in-and-mark-CPP. * progmodes/cc-fonts.el (c-cpp-matchers): Mark template brackets with `category' properties now, not `syntax-table' ones. * progmodes/cc-engine.el (c-syntactic-end-of-macro): A new enhanced (but slower) version of c-end-of-macro that won't land inside a literal or on another awkward character. (c-state-cache-too-far, c-state-cache-start) (c-state-nonlit-pos-interval, c-state-nonlit-pos-cache) (c-state-nonlit-pos-cache-limit, c-state-point-min) (c-state-point-min-lit-type, c-state-point-min-lit-start) (c-state-min-scan-pos, c-state-brace-pair-desert) (c-state-old-cpp-beg, c-state-old-cpp-end): New constants and buffer local variables. (c-state-literal-at, c-state-lit-beg) (c-state-cache-non-literal-place, c-state-get-min-scan-pos) (c-state-mark-point-min-literal, c-state-cache-top-lparen) (c-state-cache-top-paren, c-state-cache-after-top-paren) (c-get-cache-scan-pos, c-get-fallback-scan-pos) (c-state-balance-parens-backwards, c-parse-state-get-strategy) (c-renarrow-state-cache) (c-append-lower-brace-pair-to-state-cache) (c-state-push-any-brace-pair, c-append-to-state-cache) (c-remove-stale-state-cache) (c-remove-stale-state-cache-backwards, c-state-cache-init) (c-invalidate-state-cache-1, c-parse-state-1) (c-invalidate-state-cache): New defuns/defmacros/defsubsts. (c-parse-state): Enhanced and refactored. (c-debug-parse-state): Amended to deal with all the new variables. * progmodes/cc-defs.el (c-<-as-paren-syntax, c-mark-<-as-paren) (c->-as-paren-syntax, c-mark->-as-paren, c-unmark-<->-as-paren): modify to use category text properties rather than syntax-table ones. (c-suppress-<->-as-parens, c-restore-<->-as-parens): new defsubsts to switch off/on the syntactic paren property of C++ template delimiters using the category property. (c-with-<->-as-parens-suppressed): Macro to invoke code with template delims suppressed. (c-cpp-delimiter, c-set-cpp-delimiters, c-clear-cpp-delimiters): New constant/macros which apply category properties to the start and end of preprocessor constructs. (c-comment-out-cpps, c-uncomment-out-cpps): defsubsts which "comment out" the syntactic value of characters in preprocessor constructs. (c-with-cpps-commented-out) (c-with-all-but-one-cpps-commented-out): Macros to invoke code with characters in all or all but one preprocessor constructs "commented out".
-rw-r--r--lisp/progmodes/cc-defs.el106
-rw-r--r--lisp/progmodes/cc-engine.el1348
-rw-r--r--lisp/progmodes/cc-fonts.el3
-rw-r--r--lisp/progmodes/cc-langs.el2
-rw-r--r--lisp/progmodes/cc-mode.el54
5 files changed, 1195 insertions, 318 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 60838dc9ca7..8f41b172912 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1145,23 +1145,115 @@ been put there by c-put-char-property. POINT remains unchanged."
1145 (goto-char (point-max))))) 1145 (goto-char (point-max)))))
1146 1146
1147(defconst c-<-as-paren-syntax '(4 . ?>)) 1147(defconst c-<-as-paren-syntax '(4 . ?>))
1148(put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
1148 1149
1149(defsubst c-mark-<-as-paren (pos) 1150(defsubst c-mark-<-as-paren (pos)
1150 ;; Mark the "<" character at POS as an sexp list opener using the 1151 ;; Mark the "<" character at POS as a template opener using the
1151 ;; syntax-table property. 1152 ;; `syntax-table' property via the `category' property.
1152 ;; 1153 ;;
1153 ;; This function does a hidden buffer change. 1154 ;; This function does a hidden buffer change. Note that we use
1154 (c-put-char-property pos 'syntax-table c-<-as-paren-syntax)) 1155 ;; indirection through the `category' text property. This allows us to
1156 ;; toggle the property in all template brackets simultaneously and
1157 ;; cheaply. We use this, for instance, in `c-parse-state'.
1158 (c-put-char-property pos 'category 'c-<-as-paren-syntax))
1155 1159
1156(defconst c->-as-paren-syntax '(5 . ?<)) 1160(defconst c->-as-paren-syntax '(5 . ?<))
1161(put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax)
1157 1162
1158(defsubst c-mark->-as-paren (pos) 1163(defsubst c-mark->-as-paren (pos)
1159 ;; Mark the ">" character at POS as an sexp list closer using the 1164 ;; Mark the ">" character at POS as an sexp list closer using the
1160 ;; syntax-table property. 1165 ;; syntax-table property.
1161 ;; 1166 ;;
1162 ;; This function does a hidden buffer change. 1167 ;; This function does a hidden buffer change. Note that we use
1163 (c-put-char-property pos 'syntax-table c->-as-paren-syntax)) 1168 ;; indirection through the `category' text property. This allows us to
1164 1169 ;; toggle the property in all template brackets simultaneously and
1170 ;; cheaply. We use this, for instance, in `c-parse-state'.
1171 (c-put-char-property pos 'category 'c->-as-paren-syntax))
1172
1173(defsubst c-unmark-<->-as-paren (pos)
1174 ;; Unmark the "<" or "<" character at POS as an sexp list opener using
1175 ;; the syntax-table property indirectly through the `category' text
1176 ;; property.
1177 ;;
1178 ;; This function does a hidden buffer change. Note that we use
1179 ;; indirection through the `category' text property. This allows us to
1180 ;; toggle the property in all template brackets simultaneously and
1181 ;; cheaply. We use this, for instance, in `c-parse-state'.
1182 (c-clear-char-property pos 'category))
1183
1184(defsubst c-suppress-<->-as-parens ()
1185 ;; Suppress the syntactic effect of all marked < and > as parens. Note
1186 ;; that this effect is NOT buffer local. You should probably not use
1187 ;; this directly, but only through the macro
1188 ;; `c-with-<->-as-parens-suppressed'
1189 (put 'c-<-as-paren-syntax 'syntax-table nil)
1190 (put 'c->-as-paren-syntax 'syntax-table nil))
1191
1192(defsubst c-restore-<->-as-parens ()
1193 ;; Restore the syntactic effect of all marked <s and >s as parens. This
1194 ;; has no effect on unmarked <s and >s
1195 (put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
1196 (put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax))
1197
1198(defmacro c-with-<->-as-parens-suppressed (&rest forms)
1199 ;; Like progn, except that the paren property is suppressed on all
1200 ;; template brackets whilst they are running. This macro does a hidden
1201 ;; buffer change.
1202 `(unwind-protect
1203 (progn
1204 (c-suppress-<->-as-parens)
1205 ,@forms)
1206 (c-restore-<->-as-parens)))
1207
1208;;;;;;;;;;;;;;;
1209
1210(defconst c-cpp-delimiter '(14)) ; generic comment syntax
1211;; This is the value of the `category' text property placed on every #
1212;; which introduces a CPP construct and every EOL (or EOB, or character
1213;; preceding //, etc.) which terminates it. We can instantly "comment
1214;; out" all CPP constructs by giving `c-cpp-delimiter' a syntax-table
1215;; propery '(14) (generic comment delimiter).
1216(defmacro c-set-cpp-delimiters (beg end)
1217 ;; This macro does a hidden buffer change.
1218 `(progn
1219 (c-put-char-property ,beg 'category 'c-cpp-delimiter)
1220 (c-put-char-property ,end 'category 'c-cpp-delimiter)))
1221(defmacro c-clear-cpp-delimiters (beg end)
1222 ;; This macro does a hidden buffer change.
1223 `(progn
1224 (c-clear-char-property ,beg 'category)
1225 (c-clear-char-property ,end 'category)))
1226
1227(defsubst c-comment-out-cpps ()
1228 ;; Render all preprocessor constructs syntactically commented out.
1229 (put 'c-cpp-delimiter 'syntax-table c-cpp-delimiter))
1230(defsubst c-uncomment-out-cpps ()
1231 ;; Restore the syntactic visibility of preprocessor constructs.
1232 (put 'c-cpp-delimiter 'syntax-table nil))
1233
1234(defmacro c-with-cpps-commented-out (&rest forms)
1235 ;; Execute FORMS... whilst the syntactic effect of all characters in
1236 ;; all CPP regions is suppressed. In particular, this is to suppress
1237 ;; the syntactic significance of parens/braces/brackets to functions
1238 ;; such as `scan-lists' and `parse-partial-sexp'.
1239 `(unwind-protect
1240 (c-save-buffer-state ()
1241 (c-comment-out-cpps)
1242 ,@forms)
1243 (c-save-buffer-state ()
1244 (c-uncomment-out-cpps))))
1245
1246(defmacro c-with-all-but-one-cpps-commented-out (beg end &rest forms)
1247 ;; Execute FORMS... whilst the syntactic effect of all characters in
1248 ;; every CPP region APART FROM THE ONE BETWEEN BEG and END is
1249 ;; suppressed.
1250 `(unwind-protect
1251 (c-save-buffer-state ()
1252 (c-clear-cpp-delimiters ,beg ,end)
1253 ,`(c-with-cpps-commented-out ,@forms))
1254 (c-save-buffer-state ()
1255 (c-set-cpp-delimiters ,beg ,end))))
1256
1165(defsubst c-intersect-lists (list alist) 1257(defsubst c-intersect-lists (list alist)
1166 ;; return the element of ALIST that matches the first element found 1258 ;; return the element of ALIST that matches the first element found
1167 ;; in LIST. Uses assq. 1259 ;; in LIST. Uses assq.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 2c71b360748..664ce0cb376 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -79,6 +79,10 @@
79;; Note: This doc is for internal use only. Other packages should not 79;; Note: This doc is for internal use only. Other packages should not
80;; assume that these text properties are used as described here. 80;; assume that these text properties are used as described here.
81;; 81;;
82;; 'category
83;; Used for "indirection". With its help, some other property can
84;; be cheaply and easily switched on or off everywhere it occurs.
85;;
82;; 'syntax-table 86;; 'syntax-table
83;; Used to modify the syntax of some characters. It is used to 87;; Used to modify the syntax of some characters. It is used to
84;; mark the "<" and ">" of angle bracket parens with paren syntax, and 88;; mark the "<" and ">" of angle bracket parens with paren syntax, and
@@ -256,6 +260,27 @@ comment at the start of cc-engine.el for more info."
256 (forward-char) 260 (forward-char)
257 t)))) 261 t))))
258 262
263(defun c-syntactic-end-of-macro ()
264 ;; Go to the end of a CPP directive, or a "safe" pos just before.
265 ;;
266 ;; This is normally the end of the next non-escaped line. A "safe"
267 ;; position is one not within a string or comment. (The EOL on a line
268 ;; comment is NOT "safe").
269 ;;
270 ;; This function must only be called from the beginning of a CPP construct.
271 ;;
272 ;; Note that this function might do hidden buffer changes. See the comment
273 ;; at the start of cc-engine.el for more info.
274 (let* ((here (point))
275 (there (progn (c-end-of-macro) (point)))
276 (s (parse-partial-sexp here there)))
277 (while (and (or (nth 3 s) ; in a string
278 (nth 4 s)) ; in a comment (maybe at end of line comment)
279 (> there here)) ; No infinite loops, please.
280 (setq there (1- (nth 8 s)))
281 (setq s (parse-partial-sexp here there)))
282 (point)))
283
259(defun c-forward-over-cpp-define-id () 284(defun c-forward-over-cpp-define-id ()
260 ;; Assuming point is at the "#" that introduces a preprocessor 285 ;; Assuming point is at the "#" that introduces a preprocessor
261 ;; directive, it's moved forward to the end of the identifier which is 286 ;; directive, it's moved forward to the end of the identifier which is
@@ -1947,10 +1972,18 @@ comment at the start of cc-engine.el for more info."
1947 1972
1948;; A system for finding noteworthy parens before the point. 1973;; A system for finding noteworthy parens before the point.
1949 1974
1975(defconst c-state-cache-too-far 5000)
1976;; A maximum comfortable scanning distance, e.g. between
1977;; `c-state-cache-good-pos' and "HERE" (where we call c-parse-state). When
1978;; this distance is exceeded, we take "emergency meausures", e.g. by clearing
1979;; the cache and starting again from point-min or a beginning of defun. This
1980;; value can be tuned for efficiency or set to a lower value for testing.
1981
1950(defvar c-state-cache nil) 1982(defvar c-state-cache nil)
1951(make-variable-buffer-local 'c-state-cache) 1983(make-variable-buffer-local 'c-state-cache)
1952;; The state cache used by `c-parse-state' to cut down the amount of 1984;; The state cache used by `c-parse-state' to cut down the amount of
1953;; searching. It's the result from some earlier `c-parse-state' call. 1985;; searching. It's the result from some earlier `c-parse-state' call. See
1986;; `c-parse-state''s doc string for details of its structure.
1954;; 1987;;
1955;; The use of the cached info is more effective if the next 1988;; The use of the cached info is more effective if the next
1956;; `c-parse-state' call is on a line close by the one the cached state 1989;; `c-parse-state' call is on a line close by the one the cached state
@@ -1959,18 +1992,12 @@ comment at the start of cc-engine.el for more info."
1959;; most effective if `c-parse-state' is used on each line while moving 1992;; most effective if `c-parse-state' is used on each line while moving
1960;; forward. 1993;; forward.
1961 1994
1962(defvar c-state-cache-start 1)
1963(make-variable-buffer-local 'c-state-cache-start)
1964;; This is (point-min) when `c-state-cache' was calculated, since a
1965;; change of narrowing is likely to affect the parens that are visible
1966;; before the point.
1967
1968(defvar c-state-cache-good-pos 1) 1995(defvar c-state-cache-good-pos 1)
1969(make-variable-buffer-local 'c-state-cache-good-pos) 1996(make-variable-buffer-local 'c-state-cache-good-pos)
1970;; This is a position where `c-state-cache' is known to be correct. 1997;; This is a position where `c-state-cache' is known to be correct, or
1971;; It's a position inside one of the recorded unclosed parens or the 1998;; nil (see below). It's a position inside one of the recorded unclosed
1972;; top level, but not further nested inside any literal or subparen 1999;; parens or the top level, but not further nested inside any literal or
1973;; that is closed before the last recorded position. 2000;; subparen that is closed before the last recorded position.
1974;; 2001;;
1975;; The exact position is chosen to try to be close to yet earlier than 2002;; The exact position is chosen to try to be close to yet earlier than
1976;; the position where `c-state-cache' will be called next. Right now 2003;; the position where `c-state-cache' will be called next. Right now
@@ -1978,313 +2005,1052 @@ comment at the start of cc-engine.el for more info."
1978;; closing paren (of any type) before the line on which 2005;; closing paren (of any type) before the line on which
1979;; `c-parse-state' was called. That is chosen primarily to work well 2006;; `c-parse-state' was called. That is chosen primarily to work well
1980;; with refontification of the current line. 2007;; with refontification of the current line.
2008;;
2009;; 2009-07-28: When `c-state-point-min' and the last position where
2010;; `c-parse-state' or for which `c-invalidate-state-cache' was called, are
2011;; both in the same literal, there is no such "good position", and
2012;; c-state-cache-good-pos is then nil. This is the ONLY circumstance in which
2013;; it can be nil. In this case, `c-state-point-min-literal' will be non-nil.
2014;;
2015;; 2009-06-12: In a brace desert, c-state-cache-good-pos may also be in
2016;; the middle of the desert, as long as it is not within a brace pair
2017;; recorded in `c-state-cache' or a paren/bracket pair.
2018
2019
2020;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2021;; We maintain a simple cache of positions which aren't in a literal, so as to
2022;; speed up testing for non-literality.
2023(defconst c-state-nonlit-pos-interval 10000)
2024;; The approximate interval between entries in `c-state-nonlit-pos-cache'.
2025
2026(defvar c-state-nonlit-pos-cache nil)
2027(make-variable-buffer-local 'c-state-nonlit-pos-cache)
2028;; A list of buffer positions which are known not to be in a literal. This is
2029;; ordered with higher positions at the front of the list. Only those which
2030;; are less than `c-state-nonlit-pos-cache-limit' are valid.
2031
2032(defvar c-state-nonlit-pos-cache-limit 1)
2033(make-variable-buffer-local 'c-state-nonlit-pos-cache-limit)
2034;; An upper limit on valid entries in `c-state-nonlit-pos-cache'. This is
2035;; reduced by buffer changes, and increased by invocations of
2036;; `c-state-literal-at'.
2037
2038(defsubst c-state-pp-to-literal (from to)
2039 ;; Do a parse-partial-sexp from FROM to TO, returning the bounds of any
2040 ;; literal at TO as a cons, otherwise NIL.
2041 ;; FROM must not be in a literal, and the buffer should already be wide
2042 ;; enough.
2043 (save-excursion
2044 (let ((s (parse-partial-sexp from to)))
2045 (when (or (nth 3 s) (nth 4 s)) ; in a string or comment
2046 (parse-partial-sexp (point) (point-max)
2047 nil ; TARGETDEPTH
2048 nil ; STOPBEFORE
2049 s ; OLDSTATE
2050 'syntax-table) ; stop at end of literal
2051 (cons (nth 8 s) (point))))))
2052
2053(defun c-state-literal-at (here)
2054 ;; If position HERE is inside a literal, return (START . END), the
2055 ;; boundaries of the literal (which may be outside the accessible bit of the
2056 ;; buffer). Otherwise, return nil.
2057 ;;
2058 ;; This function is almost the same as `c-literal-limits'. It differs in
2059 ;; that it is a lower level function, and that it rigourously follows the
2060 ;; syntax from BOB, whereas `c-literal-limits' uses a "local" safe position.
2061 (save-restriction
2062 (widen)
2063 (save-excursion
2064 (let ((c c-state-nonlit-pos-cache)
2065 pos npos lit)
2066 ;; Trim the cache to take account of buffer changes.
2067 (while (and c (> (car c) c-state-nonlit-pos-cache-limit))
2068 (setq c (cdr c)))
2069 (setq c-state-nonlit-pos-cache c)
2070
2071 (while (and c (> (car c) here))
2072 (setq c (cdr c)))
2073 (setq pos (or (car c) (point-min)))
2074
2075 (while (<= (setq npos (+ pos c-state-nonlit-pos-interval))
2076 here)
2077 (setq lit (c-state-pp-to-literal pos npos))
2078 (setq pos (or (cdr lit) npos)) ; end of literal containing npos.
2079 (setq c-state-nonlit-pos-cache (cons pos c-state-nonlit-pos-cache)))
2080
2081 (if (> pos c-state-nonlit-pos-cache-limit)
2082 (setq c-state-nonlit-pos-cache-limit pos))
2083 (if (< pos here)
2084 (setq lit (c-state-pp-to-literal pos here)))
2085 lit))))
2086
2087(defsubst c-state-lit-beg (pos)
2088 ;; Return the start of the literal containing POS, or POS itself.
2089 (or (car (c-state-literal-at pos))
2090 pos))
2091
2092(defsubst c-state-cache-non-literal-place (pos state)
2093 ;; Return a position outside of a string/comment at or before POS.
2094 ;; STATE is the parse-partial-sexp state at POS.
2095 (if (or (nth 3 state) ; in a string?
2096 (nth 4 state)) ; in a comment?
2097 (nth 8 state)
2098 pos))
1981 2099
1982(defsubst c-invalidate-state-cache (pos) 2100
1983 ;; Invalidate all info on `c-state-cache' that applies to the buffer 2101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1984 ;; at POS or higher. This is much like `c-whack-state-after', but 2102;; Stuff to do with point-min, and coping with any literal there.
1985 ;; it never changes a paren pair element into an open paren element. 2103(defvar c-state-point-min 1)
1986 ;; Doing that would mean that the new open paren wouldn't have the 2104(make-variable-buffer-local 'c-state-point-min)
1987 ;; required preceding paren pair element. 2105;; This is (point-min) when `c-state-cache' was last calculated. A change of
1988 (while (and (or c-state-cache 2106;; narrowing is likely to affect the parens that are visible before the point.
1989 (when (< pos c-state-cache-good-pos) 2107
1990 (setq c-state-cache-good-pos 1) 2108(defvar c-state-point-min-lit-type nil)
1991 nil)) 2109(make-variable-buffer-local 'c-state-point-min-lit-type)
1992 (let ((elem (car c-state-cache))) 2110(defvar c-state-point-min-lit-start nil)
1993 (if (consp elem) 2111(make-variable-buffer-local 'c-state-point-min-lit-start)
1994 (or (< pos (cdr elem)) 2112;; These two variables define the literal, if any, containing point-min.
1995 (when (< pos c-state-cache-good-pos) 2113;; Their values are, respectively, 'string, c, or c++, and the start of the
1996 (setq c-state-cache-good-pos (cdr elem)) 2114;; literal. If there's no literal there, they're both nil.
1997 nil)) 2115
1998 (or (<= pos elem) 2116(defvar c-state-min-scan-pos 1)
1999 (when (< pos c-state-cache-good-pos) 2117(make-variable-buffer-local 'c-state-min-scan-pos)
2000 (setq c-state-cache-good-pos (1+ elem)) 2118;; This is the earliest buffer-pos from which scanning can be done. It is
2001 nil))))) 2119;; either the end of the literal containing point-min, or point-min itself.
2002 (setq c-state-cache (cdr c-state-cache)))) 2120;; It becomes nil if the buffer is changed earlier than this point.
2003 2121(defun c-state-get-min-scan-pos ()
2004(defun c-get-fallback-start-pos (here) 2122 ;; Return the lowest valid scanning pos. This will be the end of the
2005 ;; Return the start position for building `c-state-cache' from 2123 ;; literal enclosing point-min, or point-min itself.
2006 ;; scratch. 2124 (or c-state-min-scan-pos
2125 (save-restriction
2126 (save-excursion
2127 (widen)
2128 (goto-char c-state-point-min-lit-start)
2129 (if (eq c-state-point-min-lit-type 'string)
2130 (forward-sexp)
2131 (forward-comment 1))
2132 (setq c-state-min-scan-pos (point))))))
2133
2134(defun c-state-mark-point-min-literal ()
2135 ;; Determine the properties of any literal containing POINT-MIN, setting the
2136 ;; variables `c-state-point-min-lit-type', `c-state-point-min-lit-start',
2137 ;; and `c-state-min-scan-pos' accordingly. The return value is meaningless.
2138 (let ((p-min (point-min))
2139 lit)
2140 (save-restriction
2141 (widen)
2142 (setq lit (c-state-literal-at p-min))
2143 (if lit
2144 (setq c-state-point-min-lit-type
2145 (save-excursion
2146 (goto-char (car lit))
2147 (cond
2148 ((looking-at c-block-comment-start-regexp) 'c)
2149 ((looking-at c-line-comment-starter) 'c++)
2150 (t 'string)))
2151 c-state-point-min-lit-start (car lit)
2152 c-state-min-scan-pos (cdr lit))
2153 (setq c-state-point-min-lit-type nil
2154 c-state-point-min-lit-start nil
2155 c-state-min-scan-pos p-min)))))
2156
2157
2158;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2159;; A variable which signals a brace dessert - helpful for reducing the number
2160;; of fruitless backward scans.
2161(defvar c-state-brace-pair-desert nil)
2162(make-variable-buffer-local 'c-state-brace-pair-desert)
2163;; Used only in `c-append-lower-brace-pair-to-state-cache'. It is set when an
2164;; that defun has searched backwards for a brace pair and not found one. Its
2165;; value is either nil or a cons (PA . FROM), where PA is the position of the
2166;; enclosing opening paren/brace/bracket which bounds the backwards search (or
2167;; nil when at top level) and FROM is where the backward search started. It
2168;; is reset to nil in `c-invalidate-state-cache'.
2169
2170
2171;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2172;; Lowish level functions/macros which work directly on `c-state-cache', or a
2173;; list of like structure.
2174(defmacro c-state-cache-top-lparen (&optional cache)
2175 ;; Return the address of the top left brace/bracket/paren recorded in CACHE
2176 ;; (default `c-state-cache') (or nil).
2177 (let ((cash (or cache 'c-state-cache)))
2178 `(if (consp (car ,cash))
2179 (caar ,cash)
2180 (car ,cash))))
2181
2182(defmacro c-state-cache-top-paren (&optional cache)
2183 ;; Return the address of the latest brace/bracket/paren (whether left or
2184 ;; right) recorded in CACHE (default `c-state-cache') or nil.
2185 (let ((cash (or cache 'c-state-cache)))
2186 `(if (consp (car ,cash))
2187 (cdar ,cash)
2188 (car ,cash))))
2189
2190(defmacro c-state-cache-after-top-paren (&optional cache)
2191 ;; Return the position just after the latest brace/bracket/paren (whether
2192 ;; left or right) recorded in CACHE (default `c-state-cache') or nil.
2193 (let ((cash (or cache 'c-state-cache)))
2194 `(if (consp (car ,cash))
2195 (cdar ,cash)
2196 (and (car ,cash)
2197 (1+ (car ,cash))))))
2198
2199(defun c-get-cache-scan-pos (here)
2200 ;; From the state-cache, determine the buffer position from which we might
2201 ;; scan forward to HERE to update this cache. This position will be just
2202 ;; after a paren/brace/bracket recorded in the cache, if possible, otherwise
2203 ;; return the earliest position in the accessible region which isn't within
2204 ;; a literal. If the visible portion of the buffer is entirely within a
2205 ;; literal, return NIL.
2206 (let ((c c-state-cache) elt)
2207 ;(while (>= (or (c-state-cache-top-lparen c) 1) here)
2208 (while (and c
2209 (>= (c-state-cache-top-lparen c) here))
2210 (setq c (cdr c)))
2211
2212 (setq elt (car c))
2213 (cond
2214 ((consp elt)
2215 (if (> (cdr elt) here)
2216 (1+ (car elt))
2217 (cdr elt)))
2218 (elt (1+ elt))
2219 ((<= (c-state-get-min-scan-pos) here)
2220 (c-state-get-min-scan-pos))
2221 (t nil))))
2222
2223;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2224;; Variables which keep track of preprocessor constructs.
2225(defvar c-state-old-cpp-beg nil)
2226(make-variable-buffer-local 'c-state-old-cpp-beg)
2227(defvar c-state-old-cpp-end nil)
2228(make-variable-buffer-local 'c-state-old-cpp-end)
2229;; These are the limits of the macro containing point at the previous call of
2230;; `c-parse-state', or nil.
2231
2232;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2233;; Defuns which analyse the buffer, yet don't change `c-state-cache'.
2234(defun c-get-fallback-scan-pos (here)
2235 ;; Return a start position for building `c-state-cache' from
2236 ;; scratch. This will be at the top level, 2 defuns back.
2007 (save-excursion 2237 (save-excursion
2008 ;; Go back 2 bods, but ignore any bogus positions returned by 2238 ;; Go back 2 bods, but ignore any bogus positions returned by
2009 ;; beginning-of-defun (i.e. open paren in column zero). 2239 ;; beginning-of-defun (i.e. open paren in column zero).
2010 (goto-char here) 2240 (goto-char here)
2011 (let ((cnt 2)) 2241 (let ((cnt 2))
2012 (while (not (or (bobp) (zerop cnt))) 2242 (while (not (or (bobp) (zerop cnt)))
2013 (c-beginning-of-defun-1) 2243 (c-beginning-of-defun-1) ; Pure elisp BOD.
2014 (if (eq (char-after) ?\{) 2244 (if (eq (char-after) ?\{)
2015 (setq cnt (1- cnt))))) 2245 (setq cnt (1- cnt)))))
2016 (point))) 2246 (point)))
2017 2247
2018(defun c-parse-state () 2248(defun c-state-balance-parens-backwards (here top)
2019 ;; Find and record all noteworthy parens between some good point 2249 ;; Return the position of the opening paren/brace/bracket before HERE which
2020 ;; earlier in the file and point. That good point is at least the 2250 ;; matches the outermost close p/b/b between HERE and TOP, like this:
2021 ;; beginning of the top-level construct we are in, or the beginning 2251 ;;
2022 ;; of the preceding top-level construct if we aren't in one. 2252 ;; ......................................
2023 ;; 2253 ;; | |
2024 ;; The returned value is a list of the noteworthy parens with the 2254 ;; ( [ ( ........... ) ( ) ] )
2025 ;; last one first. If an element in the list is an integer, it's 2255 ;; ^ ^ ^
2026 ;; the position of an open paren which has not been closed before 2256 ;; | | |
2027 ;; the point. If an element is a cons, it gives the position of a 2257 ;; return HERE TOP
2028 ;; closed brace paren pair; the car is the start paren position and 2258 ;;
2029 ;; the cdr is the position following the closing paren. Only the 2259 ;; If there aren't enough opening paren/brace/brackets, return the position
2030 ;; last closed brace paren pair before each open paren and before 2260 ;; of the outermost one found, or HERE it there are none. If there are no
2031 ;; the point is recorded, and thus the state never contains two cons 2261 ;; closeing p/b/bs between HERE and TOP, return HERE. HERE and TOP must not
2032 ;; elements in succession. 2262 ;; be inside literals. Only the accessible portion of the buffer will be
2263 ;; scanned.
2264
2265 ;; PART 1: scan from `here' up to `top', accumulating ")"s which enclose
2266 ;; `here'. Go round the next loop each time we pass over such a ")". These
2267 ;; probably match "("s before `here'.
2268 (let (pos pa ren+1 lonely-rens)
2269 (save-excursion
2270 (save-restriction
2271 (narrow-to-region (point-min) top) ; This can move point, sometimes.
2272 (setq pos here)
2273 (c-safe
2274 (while
2275 (setq ren+1 (scan-lists pos 1 1)) ; might signal
2276 (setq lonely-rens (cons ren+1 lonely-rens)
2277 pos ren+1)))))
2278
2279 ;; PART 2: Scan back before `here' searching for the "("s
2280 ;; matching/mismatching the ")"s found above. We only need to direct the
2281 ;; caller to scan when we've encountered unmatched right parens.
2282 (when lonely-rens
2283 (setq pos here)
2284 (c-safe
2285 (while
2286 (and lonely-rens ; actual values aren't used.
2287 (setq pa (scan-lists pos -1 1)))
2288 (setq pos pa)
2289 (setq lonely-rens (cdr lonely-rens)))) ;)
2290 )
2291 pos))
2292
2293(defun c-parse-state-get-strategy (here good-pos)
2294 ;; Determine the scanning strategy for adjusting `c-parse-state', attempting
2295 ;; to minimise the amount of scanning. HERE is the pertinent position in
2296 ;; the buffer, GOOD-POS is a position where `c-state-cache' (possibly with
2297 ;; its head trimmed) is known to be good, or nil if there is no such
2298 ;; position.
2299 ;;
2300 ;; The return value is a list, one of the following:
2301 ;;
2302 ;; o - ('forward CACHE-POS START-POINT) - scan forward from START-POINT,
2303 ;; which is not less than CACHE-POS.
2304 ;; o - ('backward CACHE-POS nil) - scan backwards (from HERE).
2305 ;; o - ('BOD nil START-POINT) - scan forwards from START-POINT, which is at the
2306 ;; top level.
2307 ;; o - ('IN-LIT nil nil) - point is inside the literal containing point-min.
2308 ;; , where CACHE-POS is the highest position recorded in `c-state-cache' at
2309 ;; or below HERE.
2310 (let ((cache-pos (c-get-cache-scan-pos here)) ; highest position below HERE in cache (or 1)
2311 BOD-pos ; position of 2nd BOD before HERE.
2312 strategy ; 'forward, 'backward, 'BOD, or 'IN-LIT.
2313 start-point
2314 how-far) ; putative scanning distance.
2315 (setq good-pos (or good-pos (c-state-get-min-scan-pos)))
2316 (cond
2317 ((< here (c-state-get-min-scan-pos))
2318 (setq strategy 'IN-LIT
2319 start-point nil
2320 cache-pos nil
2321 how-far 0))
2322 ((<= good-pos here)
2323 (setq strategy 'forward
2324 start-point (max good-pos cache-pos)
2325 how-far (- here start-point)))
2326 ((< (- good-pos here) (- here cache-pos)) ; FIXME!!! ; apply some sort of weighting.
2327 (setq strategy 'backward
2328 how-far (- good-pos here)))
2329 (t
2330 (setq strategy 'forward
2331 how-far (- here cache-pos)
2332 start-point cache-pos)))
2333
2334 ;; Might we be better off starting from the top level, two defuns back,
2335 ;; instead?
2336 (when (> how-far c-state-cache-too-far)
2337 (setq BOD-pos (c-get-fallback-scan-pos here)) ; somewhat EXPENSIVE!!!
2338 (if (< (- here BOD-pos) how-far)
2339 (setq strategy 'BOD
2340 start-point BOD-pos)))
2341
2342 (list
2343 strategy
2344 (and (memq strategy '(forward backward)) cache-pos)
2345 (and (memq strategy '(forward BOD)) start-point))))
2346
2347
2348;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2349;; Routines which change `c-state-cache' and associated values.
2350(defun c-renarrow-state-cache ()
2351 ;; The region (more precisely, point-min) has changed since we
2352 ;; calculated `c-state-cache'. Amend `c-state-cache' accordingly.
2353 (if (< (point-min) c-state-point-min)
2354 ;; If point-min has MOVED BACKWARDS then we drop the state completely.
2355 ;; It would be possible to do a better job here and recalculate the top
2356 ;; only.
2357 (progn
2358 (c-state-mark-point-min-literal)
2359 (setq c-state-cache nil
2360 c-state-cache-good-pos c-state-min-scan-pos
2361 c-state-brace-pair-desert nil))
2362
2363 ;; point-min has MOVED FORWARD.
2364
2365 ;; Is the new point-min inside a (different) literal?
2366 (unless (and c-state-point-min-lit-start ; at prev. point-min
2367 (< (point-min) (c-state-get-min-scan-pos)))
2368 (c-state-mark-point-min-literal))
2369
2370 ;; Cut off a bit of the tail from `c-state-cache'.
2371 (let ((ptr (cons nil c-state-cache))
2372 pa)
2373 (while (and (setq pa (c-state-cache-top-lparen (cdr ptr)))
2374 (>= pa (point-min)))
2375 (setq ptr (cdr ptr)))
2376
2377 (when (consp ptr)
2378 (if (eq (cdr ptr) c-state-cache)
2379 (setq c-state-cache nil
2380 c-state-cache-good-pos c-state-min-scan-pos)
2381 (setcdr ptr nil)
2382 (setq c-state-cache-good-pos (1+ (c-state-cache-top-lparen))))
2383 )))
2384
2385 (setq c-state-point-min (point-min)))
2386
2387(defun c-append-lower-brace-pair-to-state-cache (from &optional upper-lim)
2388 ;; If there is a brace pair preceding FROM in the buffer (not necessarily
2389 ;; immediately preceding), push a cons onto `c-state-cache' to represent it.
2390 ;; FROM must not be inside a literal. If UPPER-LIM is non-nil, we append
2391 ;; the highest brace pair whose "}" is below UPPER-LIM.
2392 ;;
2393 ;; Return non-nil when this has been done.
2394 ;;
2395 ;; This routine should be fast. Since it can get called a LOT, we maintain
2396 ;; `c-state-brace-pair-desert', a small cache of "failures", such that we
2397 ;; reduce the time wasted in repeated fruitless searches in brace deserts.
2398 (save-excursion
2399 (save-restriction
2400 (let ((bra from) ce ; Positions of "{" and "}".
2401 new-cons
2402 (cache-pos (c-state-cache-top-lparen)) ; might be nil.
2403 (macro-start-or-from
2404 (progn (goto-char from)
2405 (c-beginning-of-macro)
2406 (point))))
2407 (or upper-lim (setq upper-lim from))
2408
2409 ;; If we're essentially repeating a fruitless search, just give up.
2410 (unless (and c-state-brace-pair-desert
2411 (eq cache-pos (car c-state-brace-pair-desert))
2412 (<= from (cdr c-state-brace-pair-desert)))
2413 ;; Only search what we absolutely need to:
2414 (if (and c-state-brace-pair-desert
2415 (> from (cdr c-state-brace-pair-desert)))
2416 (narrow-to-region (cdr c-state-brace-pair-desert) (point-max)))
2417
2418 ;; In the next pair of nested loops, the inner one moves back past a
2419 ;; pair of (mis-)matching parens or brackets; the outer one moves
2420 ;; back over a sequence of unmatched close brace/paren/bracket each
2421 ;; time round.
2422 (while
2423 (progn
2424 (c-safe
2425 (while
2426 (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; might signal
2427 (setq bra (scan-lists ce -1 1)) ; back past (/[/{; might signal
2428 (or (> ce upper-lim)
2429 (not (eq (char-after bra) ?\{))
2430 (and (goto-char bra)
2431 (c-beginning-of-macro)
2432 (< (point) macro-start-or-from))))))
2433 (and ce (< ce bra)))
2434 (setq bra ce)) ; If we just backed over an unbalanced closing
2435 ; brace, ignore it.
2436
2437 (if (and ce (< bra ce) (eq (char-after bra) ?\{))
2438 ;; We've found the desired brace-pair.
2439 (progn
2440 (setq new-cons (cons bra (1+ ce)))
2441 (cond
2442 ((consp (car c-state-cache))
2443 (setcar c-state-cache new-cons))
2444 ((and (numberp (car c-state-cache)) ; probably never happens
2445 (< ce (car c-state-cache)))
2446 (setcdr c-state-cache
2447 (cons new-cons (cdr c-state-cache))))
2448 (t (setq c-state-cache (cons new-cons c-state-cache)))))
2449
2450 ;; We haven't found a brace pair. Record this.
2451 (setq c-state-brace-pair-desert (cons cache-pos from))))))))
2452
2453(defsubst c-state-push-any-brace-pair (bra+1 macro-start-or-here)
2454 ;; If BRA+1 is nil, do nothing. Otherwise, BRA+1 is the buffer position
2455 ;; following a {, and that brace has a (mis-)matching } (or ]), and we
2456 ;; "push" "a" brace pair onto `c-state-cache'.
2457 ;;
2458 ;; Here "push" means overwrite the top element if it's itself a brace-pair,
2459 ;; otherwise push it normally.
2460 ;;
2461 ;; The brace pair we push is normally the one surrounding BRA+1, but if the
2462 ;; latter is inside a macro, not being a macro containing
2463 ;; MACRO-START-OR-HERE, we scan backwards through the buffer for a non-macro
2464 ;; base pair. This latter case is assumed to be rare.
2465 ;;
2466 ;; Note: POINT is not preserved in this routine.
2467 (if bra+1
2468 (if (or (> bra+1 macro-start-or-here)
2469 (progn (goto-char bra+1)
2470 (not (c-beginning-of-macro))))
2471 (setq c-state-cache
2472 (cons (cons (1- bra+1)
2473 (scan-lists bra+1 1 1))
2474 (if (consp (car c-state-cache))
2475 (cdr c-state-cache)
2476 c-state-cache)))
2477 ;; N.B. This defsubst codes one method for the simple, normal case,
2478 ;; and a more sophisticated, slower way for the general case. Don't
2479 ;; eliminate this defsubst - it's a speed optimisation.
2480 (c-append-lower-brace-pair-to-state-cache (1- bra+1)))))
2481
2482(defun c-append-to-state-cache (from)
2483 ;; Scan the buffer from FROM to (point-max), adding elements into
2484 ;; `c-state-cache' for braces etc. Return a candidate for
2485 ;; `c-state-cache-good-pos'.
2486 ;;
2487 ;; FROM must be after the latest brace/paren/bracket in `c-state-cache', if
2488 ;; any. Typically, it is immediately after it. It must not be inside a
2489 ;; literal.
2490 (let ((here-bol (c-point 'bol (point-max)))
2491 (macro-start-or-here
2492 (save-excursion (goto-char (point-max))
2493 (if (c-beginning-of-macro)
2494 (point)
2495 (point-max))))
2496 pa+1 ; pos just after an opening PAren (or brace).
2497 (ren+1 from) ; usually a pos just after an closing paREN etc.
2498 ; Is actually the pos. to scan for a (/{/[ from,
2499 ; which sometimes is after a silly )/}/].
2500 paren+1 ; Pos after some opening or closing paren.
2501 paren+1s ; A list of `paren+1's; used to determine a
2502 ; good-pos.
2503 bra+1 ce+1 ; just after L/R bra-ces.
2504 bra+1s ; list of OLD values of bra+1.
2505 mstart) ; start of a macro.
2506
2507 (save-excursion
2508 ;; Each time round the following loop, we enter a succesively deeper
2509 ;; level of brace/paren nesting. (Except sometimes we "continue at
2510 ;; the existing level".) `pa+1' is a pos inside an opening
2511 ;; brace/paren/bracket, usually just after it.
2512 (while
2513 (progn
2514 ;; Each time round the next loop moves forward over an opening then
2515 ;; a closing brace/bracket/paren. This loop is white hot, so it
2516 ;; plays ugly tricks to go fast. DON'T PUT ANYTHING INTO THIS
2517 ;; LOOP WHICH ISN'T ABSOLUTELY NECESSARY!!! It terminates when a
2518 ;; call of `scan-lists' signals an error, which happens when there
2519 ;; are no more b/b/p's to scan.
2520 (c-safe
2521 (while t
2522 (setq pa+1 (scan-lists ren+1 1 -1) ; Into (/{/[; might signal
2523 paren+1s (cons pa+1 paren+1s))
2524 (setq ren+1 (scan-lists pa+1 1 1)) ; Out of )/}/]; might signal
2525 (if (and (eq (char-before pa+1) ?{)) ; Check for a macro later.
2526 (setq bra+1 pa+1))
2527 (setcar paren+1s ren+1)))
2528
2529 (if (and pa+1 (> pa+1 ren+1))
2530 ;; We've just entered a deeper nesting level.
2531 (progn
2532 ;; Insert the brace pair (if present) and the single open
2533 ;; paren/brace/bracket into `c-state-cache' It cannot be
2534 ;; inside a macro, except one around point, because of what
2535 ;; `c-neutralize-syntax-in-CPP' has done.
2536 (c-state-push-any-brace-pair bra+1 macro-start-or-here)
2537 ;; Insert the opening brace/bracket/paren position.
2538 (setq c-state-cache (cons (1- pa+1) c-state-cache))
2539 ;; Clear admin stuff for the next more nested part of the scan.
2540 (setq ren+1 pa+1 pa+1 nil bra+1 nil bra+1s nil)
2541 t) ; Carry on the loop
2542
2543 ;; All open p/b/b's at this nesting level, if any, have probably
2544 ;; been closed by matching/mismatching ones. We're probably
2545 ;; finished - we just need to check for having found an
2546 ;; unmatched )/}/], which we ignore. Such a )/}/] can't be in a
2547 ;; macro, due the action of `c-neutralize-syntax-in-CPP'.
2548 (c-safe (setq ren+1 (scan-lists ren+1 1 1)))))) ; acts as loop control.
2549
2550 ;; Record the final, innermost, brace-pair if there is one.
2551 (c-state-push-any-brace-pair bra+1 macro-start-or-here)
2552
2553 ;; Determine a good pos
2554 (while (and (setq paren+1 (car paren+1s))
2555 (> (if (> paren+1 macro-start-or-here)
2556 paren+1
2557 (goto-char paren+1)
2558 (setq mstart (and (c-beginning-of-macro)
2559 (point)))
2560 (or mstart paren+1))
2561 here-bol))
2562 (setq paren+1s (cdr paren+1s)))
2563 (cond
2564 ((and paren+1 mstart)
2565 (min paren+1 mstart))
2566 (paren+1)
2567 (t from)))))
2568
2569(defun c-remove-stale-state-cache (good-pos pps-point)
2570 ;; Remove stale entries from the `c-cache-state', i.e. those which will
2571 ;; not be in it when it is amended for position (point-max).
2572 ;; Additionally, the "outermost" open-brace entry before (point-max)
2573 ;; will be converted to a cons if the matching close-brace is scanned.
2574 ;;
2575 ;; GOOD-POS is a "maximal" "safe position" - there must be no open
2576 ;; parens/braces/brackets between GOOD-POS and (point-max).
2577 ;;
2578 ;; As a second thing, calculate the result of parse-partial-sexp at
2579 ;; PPS-POINT, w.r.t. GOOD-POS. The motivation here is that
2580 ;; `c-state-cache-good-pos' may become PPS-POINT, but the caller may need to
2581 ;; adjust it to get outside a string/comment. (Sorry about this! The code
2582 ;; needs to be FAST).
2583 ;;
2584 ;; Return a list (GOOD-POS SCAN-BACK-POS PPS-STATE), where
2585 ;; o - GOOD-POS is a position where the new value `c-state-cache' is known
2586 ;; to be good (we aim for this to be as high as possible);
2587 ;; o - SCAN-BACK-POS, if not nil, indicates there may be a brace pair
2588 ;; preceding POS which needs to be recorded in `c-state-cache'. It is a
2589 ;; position to scan backwards from.
2590 ;; o - PPS-STATE is the parse-partial-sexp state at PPS-POINT.
2591 (save-restriction
2592 (narrow-to-region 1 (point-max))
2593 (save-excursion
2594 (let* ((in-macro-start ; point-max or beginning of macro containing it
2595 (save-excursion
2596 (goto-char (point-max))
2597 (and (c-beginning-of-macro)
2598 (point))))
2599 (good-pos-actual-macro-start ; Start of macro containing good-pos
2600 ; or nil
2601 (and (< good-pos (point-max))
2602 (save-excursion
2603 (goto-char good-pos)
2604 (and (c-beginning-of-macro)
2605 (point)))))
2606 (good-pos-actual-macro-end ; End of this macro, (maybe
2607 ; (point-max)), or nil.
2608 (and good-pos-actual-macro-start
2609 (save-excursion
2610 (goto-char good-pos-actual-macro-start)
2611 (c-end-of-macro)
2612 (point))))
2613 pps-state ; Will be 9 or 10 elements long.
2614 pos
2615 upper-lim ; ,beyond which `c-state-cache' entries are removed
2616 scan-back-pos
2617 pair-beg pps-point-state target-depth)
2618
2619 ;; Remove entries beyond (point-max). Also remove any entries inside
2620 ;; a macro, unless (point-max) is in the same macro.
2621 (setq upper-lim
2622 (if (or (null c-state-old-cpp-beg)
2623 (and (> (point-max) c-state-old-cpp-beg)
2624 (< (point-max) c-state-old-cpp-end)))
2625 (point-max)
2626 (min (point-max) c-state-old-cpp-beg)))
2627 (while (and c-state-cache (> (c-state-cache-top-lparen) upper-lim))
2628 (setq c-state-cache (cdr c-state-cache)))
2629 ;; If `upper-lim' is inside the last recorded brace pair, remove its
2630 ;; RBrace and indicate we'll need to search backwards for a previous
2631 ;; brace pair.
2632 (when (and c-state-cache
2633 (consp (car c-state-cache))
2634 (> (cdar c-state-cache) upper-lim))
2635 (setcar c-state-cache (caar c-state-cache))
2636 (setq scan-back-pos (car c-state-cache)))
2637
2638 ;; The next loop jumps forward out of a nested level of parens each
2639 ;; time round; the corresponding elements in `c-state-cache' are
2640 ;; removed. `pos' is just after the brace-pair or the open paren at
2641 ;; (car c-state-cache). There can be no open parens/braces/brackets
2642 ;; between `good-pos'/`good-pos-actual-macro-start' and (point-max),
2643 ;; due to the interface spec to this function.
2644 (setq pos (if good-pos-actual-macro-end
2645 (1+ good-pos-actual-macro-end) ; get outside the macro as
2646 ; marked by a `category' text property.
2647 good-pos))
2648 (goto-char pos)
2649 (while (and c-state-cache
2650 (< (point) (point-max)))
2651 (cond
2652 ((null pps-state) ; first time through
2653 (setq target-depth -1))
2654 ((eq (car pps-state) target-depth) ; found closing ),},]
2655 (setq target-depth (1- (car pps-state))))
2656 ;; Do nothing when we've merely reached pps-point.
2657 )
2658
2659 ;; Scan!
2660 (setq pps-state
2661 (parse-partial-sexp
2662 (point) (if (< (point) pps-point) pps-point (point-max))
2663 target-depth
2664 nil pps-state))
2665
2666 (if (= (point) pps-point)
2667 (setq pps-point-state pps-state))
2668
2669 (when (eq (car pps-state) target-depth)
2670 (setq pos (point)) ; POS is now just after an R-paren/brace.
2671 (cond
2672 ((and (consp (car c-state-cache))
2673 (eq (point) (cdar c-state-cache)))
2674 ;; We've just moved out of the paren pair containing the brace-pair
2675 ;; at (car c-state-cache). `pair-beg' is where the open paren is,
2676 ;; and is potentially where the open brace of a cons in
2677 ;; c-state-cache will be.
2678 (setq pair-beg (car-safe (cdr c-state-cache))
2679 c-state-cache (cdr-safe (cdr c-state-cache)))) ; remove {}pair + containing Lparen.
2680 ((numberp (car c-state-cache))
2681 (setq pair-beg (car c-state-cache)
2682 c-state-cache (cdr c-state-cache))) ; remove this
2683 ; containing Lparen
2684 ((numberp (cadr c-state-cache))
2685 (setq pair-beg (cadr c-state-cache)
2686 c-state-cache (cddr c-state-cache))) ; Remove a paren pair
2687 ; together with enclosed brace pair.
2688 ;; (t nil) ; Ignore an unmated Rparen.
2689 )))
2690
2691 (if (< (point) pps-point)
2692 (setq pps-state (parse-partial-sexp (point) pps-point
2693 nil nil ; TARGETDEPTH, STOPBEFORE
2694 pps-state)))
2695
2696 ;; If the last paren pair we moved out of was actually a brace pair,
2697 ;; insert it into `c-state-cache'.
2698 (when (and pair-beg (eq (char-after pair-beg) ?{))
2699 (if (consp (car-safe c-state-cache))
2700 (setq c-state-cache (cdr c-state-cache)))
2701 (setq c-state-cache (cons (cons pair-beg pos)
2702 c-state-cache)))
2703
2704 (list pos scan-back-pos pps-state)))))
2705
2706(defun c-remove-stale-state-cache-backwards (here cache-pos)
2707 ;; Strip stale elements of `c-state-cache' by moving backwards through the
2708 ;; buffer, and inform the caller of the scenario detected.
2709 ;;
2710 ;; HERE is the position we're setting `c-state-cache' for.
2711 ;; CACHE-POS is just after the latest recorded position in `c-state-cache'
2712 ;; before HERE, or a position at or near point-min which isn't in a
2713 ;; literal.
2714 ;;
2715 ;; This function must only be called only when (> `c-state-cache-good-pos'
2716 ;; HERE). Usually the gap between CACHE-POS and HERE is large. It is thus
2717 ;; optimised to eliminate (or minimise) scanning between these two
2718 ;; positions.
2719 ;;
2720 ;; Return a three element list (GOOD-POS SCAN-BACK-POS FWD-FLAG), where:
2721 ;; o - GOOD-POS is a "good position", where `c-state-cache' is valid, or
2722 ;; could become so after missing elements are inserted into
2723 ;; `c-state-cache'. This is JUST AFTER an opening or closing
2724 ;; brace/paren/bracket which is already in `c-state-cache' or just before
2725 ;; one otherwise. exceptionally (when there's no such b/p/b handy) the BOL
2726 ;; before `here''s line, or the start of the literal containing it.
2727 ;; o - SCAN-BACK-POS, if non-nil, indicates there may be a brace pair
2728 ;; preceding POS which isn't recorded in `c-state-cache'. It is a position
2729 ;; to scan backwards from.
2730 ;; o - FWD-FLAG, if non-nil, indicates there may be parens/braces between
2731 ;; POS and HERE which aren't recorded in `c-state-cache'.
2732 ;;
2733 ;; The comments in this defun use "paren" to mean parenthesis or square
2734 ;; bracket (as contrasted with a brace), and "(" and ")" likewise.
2735 ;;
2736 ;; . {..} (..) (..) ( .. { } ) (...) ( .... . ..)
2737 ;; | | | | | |
2738 ;; CP E here D C good
2739 (let ((pos c-state-cache-good-pos)
2740 pa ren ; positions of "(" and ")"
2741 dropped-cons ; whether the last element dropped from `c-state-cache'
2742 ; was a cons (representing a brace-pair)
2743 good-pos ; see above.
2744 lit ; (START . END) of a literal containing some point.
2745 here-lit-start here-lit-end ; bounds of literal containing `here'
2746 ; or `here' itself.
2747 (here-bol (c-point 'bol here))
2748 (too-far-back (max (- here c-state-cache-too-far) 1)))
2749
2750 ;; Remove completely irrelevant entries from `c-state-cache'.
2751 (while (and c-state-cache
2752 (>= (setq pa (c-state-cache-top-lparen)) here))
2753 (setq dropped-cons (consp (car c-state-cache)))
2754 (setq c-state-cache (cdr c-state-cache))
2755 (setq pos pa))
2756 ;; At this stage, (> pos here);
2757 ;; (< (c-state-cache-top-lparen) here) (or is nil).
2758
2759 ;; CASE 1: The top of the cache is a brace pair which now encloses `here'.
2760 ;; As good-pos, return the address. of the "{".
2761 (if (and (consp (car c-state-cache))
2762 (> (cdar c-state-cache) here))
2763 ;; Since we've no knowledge of what's inside these braces, we have no
2764 ;; alternative but to direct the caller to scan the buffer from the
2765 ;; opening brace.
2766 (progn
2767 (setq pos (caar c-state-cache))
2768 (setcar c-state-cache pos)
2769 (list (1+ pos) pos t)) ; return value. We've just converted a brace
2770 ; pair entry into a { entry, so the caller
2771 ; needs to search for a brace pair before the
2772 ; {.
2773
2774 ;; ;; `here' might be inside a literal. Check for this.
2775 (setq lit (c-state-literal-at here)
2776 here-lit-start (or (car lit) here)
2777 here-lit-end (or (cdr lit) here))
2778
2779 ;; `here' might be nested inside any depth of parens (or brackets but
2780 ;; not braces). Scan backwards to find the outermost such opening
2781 ;; paren, if there is one. This will be the scan position to return.
2782 (save-restriction
2783 (narrow-to-region cache-pos (point-max))
2784 (setq pos (c-state-balance-parens-backwards here-lit-end pos)))
2785
2786 (if (< pos here-lit-start)
2787 ;; CASE 2: Address of outermost ( or [ which now encloses `here',
2788 ;; but didn't enclose the (previous) `c-state-cache-good-pos'. If
2789 ;; there is a brace pair preceding this, it will already be in
2790 ;; `c-state-cache', unless there was a brace pair after it,
2791 ;; i.e. there'll only be one to scan for if we've just deleted one.
2792 (list pos (and dropped-cons pos) t) ; Return value.
2793
2794 ;; `here' isn't enclosed in a (previously unrecorded) bracket/paren.
2795 ;; Further forward scanning isn't needed, but we still need to find a
2796 ;; GOOD-POS. Step out of all enclosing "("s on HERE's line.
2797 (save-restriction
2798 (narrow-to-region here-bol (point-max))
2799 (setq pos here-lit-start)
2800 (c-safe (while (setq pa (scan-lists pos -1 1))
2801 (setq pos pa)))) ; might signal
2802 (if (setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
2803 ;; CASE 3: After a }/)/] before `here''s BOL.
2804 (list (1+ ren) (and dropped-cons pos) nil) ; Return value
2805
2806 ;; CASE 4; Best of a bad job: BOL before `here-bol', or beginning of
2807 ;; literal containing it.
2808 (setq good-pos (c-state-lit-beg (c-point 'bopl here-bol)))
2809 (list good-pos (and dropped-cons good-pos) nil))))))
2810
2811
2812;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2813;; Externally visible routines.
2814
2815(defun c-state-cache-init ()
2816 (setq c-state-cache nil
2817 c-state-cache-good-pos 1
2818 c-state-nonlit-pos-cache nil
2819 c-state-nonlit-pos-cache-limit 1
2820 c-state-brace-pair-desert nil
2821 c-state-point-min 1
2822 c-state-point-min-lit-type nil
2823 c-state-point-min-lit-start nil
2824 c-state-min-scan-pos 1
2825 c-state-old-cpp-beg nil
2826 c-state-old-cpp-end nil)
2827 (c-state-mark-point-min-literal))
2828
2829(defun c-invalidate-state-cache-1 (here)
2830 ;; Invalidate all info on `c-state-cache' that applies to the buffer at HERE
2831 ;; or higher and set `c-state-cache-good-pos' accordingly. The cache is
2832 ;; left in a consistent state.
2833 ;;
2834 ;; This is much like `c-whack-state-after', but it never changes a paren
2835 ;; pair element into an open paren element. Doing that would mean that the
2836 ;; new open paren wouldn't have the required preceding paren pair element.
2837 ;;
2838 ;; This function is called from c-after-change.
2839
2840 ;; The cache of non-literals:
2841 (if (< here c-state-nonlit-pos-cache-limit)
2842 (setq c-state-nonlit-pos-cache-limit here))
2843
2844 ;; `c-state-cache':
2845 ;; Case 1: if `here' is in a literal containing point-min, everything
2846 ;; becomes (or is already) nil.
2847 (if (or (null c-state-cache-good-pos)
2848 (< here (c-state-get-min-scan-pos)))
2849 (setq c-state-cache nil
2850 c-state-cache-good-pos nil
2851 c-state-min-scan-pos nil)
2852
2853;;; Truncate `c-state-cache' and set `c-state-cache-good-pos' to a value below
2854;;; `here'. To maintain its consistency, we may need to insert a new brace
2855;;; pair.
2856 (let ((here-bol (c-point 'bol here))
2857 too-high-pa ; recorded {/(/[ next above here, or nil.
2858 dropped-cons ; was the last removed element a brace pair?
2859 pa)
2860 ;; The easy bit - knock over-the-top bits off `c-state-cache'.
2861 (while (and c-state-cache
2862 (>= (setq pa (c-state-cache-top-paren)) here))
2863 (setq dropped-cons (consp (car c-state-cache))
2864 too-high-pa (c-state-cache-top-lparen)
2865 c-state-cache (cdr c-state-cache)))
2866
2867 ;; Do we need to add in an earlier brace pair, having lopped one off?
2868 (if (and dropped-cons
2869 (< too-high-pa (+ here c-state-cache-too-far)))
2870 (c-append-lower-brace-pair-to-state-cache too-high-pa here-bol))
2871 (setq c-state-cache-good-pos (or (c-state-cache-after-top-paren)
2872 (c-state-get-min-scan-pos)))))
2873
2874 ;; The brace-pair desert marker:
2875 (when (car c-state-brace-pair-desert)
2876 (if (< here (car c-state-brace-pair-desert))
2877 (setq c-state-brace-pair-desert nil)
2878 (if (< here (cdr c-state-brace-pair-desert))
2879 (setcdr c-state-brace-pair-desert here)))))
2880
2881(defun c-parse-state-1 ()
2882 ;; Find and record all noteworthy parens between some good point earlier in
2883 ;; the file and point. That good point is at least the beginning of the
2884 ;; top-level construct we are in, or the beginning of the preceding
2885 ;; top-level construct if we aren't in one.
2886 ;;
2887 ;; The returned value is a list of the noteworthy parens with the last one
2888 ;; first. If an element in the list is an integer, it's the position of an
2889 ;; open paren (of any type) which has not been closed before the point. If
2890 ;; an element is a cons, it gives the position of a closed BRACE paren
2891 ;; pair[*]; the car is the start brace position and the cdr is the position
2892 ;; following the closing brace. Only the last closed brace paren pair
2893 ;; before each open paren and before the point is recorded, and thus the
2894 ;; state never contains two cons elements in succession. When a close brace
2895 ;; has no matching open brace (e.g., the matching brace is outside the
2896 ;; visible region), it is not represented in the returned value.
2897 ;;
2898 ;; [*] N.B. The close "brace" might be a mismatching close bracket or paren.
2899 ;; This defun explicitly treats mismatching parens/braces/brackets as
2900 ;; matching. It is the open brace which makes it a "brace" pair.
2901 ;;
2902 ;; If POINT is within a macro, open parens and brace pairs within
2903 ;; THIS macro MIGHT be recorded. This depends on whether their
2904 ;; syntactic properties have been suppressed by
2905 ;; `c-neutralize-syntax-in-CPP'. This might need fixing (2008-12-11).
2033 ;; 2906 ;;
2034 ;; Currently no characters which are given paren syntax with the 2907 ;; Currently no characters which are given paren syntax with the
2035 ;; syntax-table property are recorded, i.e. angle bracket arglist 2908 ;; syntax-table property are recorded, i.e. angle bracket arglist
2036 ;; parens are never present here. Note that this might change. 2909 ;; parens are never present here. Note that this might change.
2037 ;; 2910 ;;
2038 ;; BUG: This function doesn't cope entirely well with unbalanced 2911 ;; BUG: This function doesn't cope entirely well with unbalanced
2039 ;; parens in macros. E.g. in the following case the brace before 2912 ;; parens in macros. (2008-12-11: this has probably been resolved
2040 ;; the macro isn't balanced with the one after it: 2913 ;; by the function `c-neutralize-syntax-in-CPP'.) E.g. in the
2914 ;; following case the brace before the macro isn't balanced with the
2915 ;; one after it:
2041 ;; 2916 ;;
2042 ;; { 2917 ;; {
2043 ;; #define X { 2918 ;; #define X {
2044 ;; } 2919 ;; }
2045 ;; 2920 ;;
2921 ;; Note to maintainers: this function DOES get called with point
2922 ;; within comments and strings, so don't assume it doesn't!
2923 ;;
2046 ;; This function might do hidden buffer changes. 2924 ;; This function might do hidden buffer changes.
2047 2925 (let* ((here (point))
2048 (save-restriction 2926 (here-bopl (c-point 'bopl))
2049 (let* ((here (point)) 2927 strategy ; 'forward, 'backward etc..
2050 (here-bol (c-point 'bol)) 2928 ;; Candidate positions to start scanning from:
2051 (c-macro-start (c-query-macro-start)) 2929 cache-pos ; highest position below HERE already existing in
2052 (in-macro-start (or c-macro-start (point))) 2930 ; cache (or 1).
2053 old-state last-pos brace-pair-open brace-pair-close 2931 good-pos
2054 pos save-pos) 2932 start-point
2055 (c-invalidate-state-cache here) 2933 bopl-state
2056 2934 res
2057 ;; If the minimum position has changed due to narrowing then we 2935 scan-backward-pos scan-forward-p) ; used for 'backward.
2058 ;; have to fix the tail of `c-state-cache' accordingly. 2936 ;; If POINT-MIN has changed, adjust the cache
2059 (unless (= c-state-cache-start (point-min)) 2937 (unless (= (point-min) c-state-point-min)
2060 (if (> (point-min) c-state-cache-start) 2938 (c-renarrow-state-cache))
2061 ;; If point-min has moved forward then we just need to cut 2939
2062 ;; off a bit of the tail. 2940 ;; Strategy?
2063 (let ((ptr (cons nil c-state-cache)) elem) 2941 (setq res (c-parse-state-get-strategy here c-state-cache-good-pos)
2064 (while (and (setq elem (car-safe (cdr ptr))) 2942 strategy (car res)
2065 (>= (if (consp elem) (car elem) elem) 2943 cache-pos (cadr res)
2066 (point-min))) 2944 start-point (nth 2 res))
2067 (setq ptr (cdr ptr))) 2945
2068 (when (consp ptr) 2946 (when (eq strategy 'BOD)
2069 (if (eq (cdr ptr) c-state-cache) 2947 (setq c-state-cache nil
2070 (setq c-state-cache nil 2948 c-state-cache-good-pos start-point))
2071 c-state-cache-good-pos 1) 2949
2072 (setcdr ptr nil)))) 2950 ;; SCAN!
2073 ;; If point-min has moved backward then we drop the state 2951 (save-restriction
2074 ;; completely. It's possible to do a better job here and 2952 (cond
2075 ;; recalculate the top only. 2953 ((memq strategy '(forward BOD))
2076 (setq c-state-cache nil
2077 c-state-cache-good-pos 1))
2078 (setq c-state-cache-start (point-min)))
2079
2080 ;; Get the latest position we know are directly inside the
2081 ;; closest containing paren of the cached state.
2082 (setq last-pos (and c-state-cache
2083 (if (consp (car c-state-cache))
2084 (cdr (car c-state-cache))
2085 (1+ (car c-state-cache)))))
2086 (if (or (not last-pos)
2087 (< last-pos c-state-cache-good-pos))
2088 (setq last-pos c-state-cache-good-pos)
2089 ;; Take the opportunity to move the cached good position
2090 ;; further down.
2091 (if (< last-pos here-bol)
2092 (setq c-state-cache-good-pos last-pos)))
2093
2094 ;; Check if `last-pos' is in a macro. If it is, and we're not
2095 ;; in the same macro, we must discard everything on
2096 ;; `c-state-cache' that is inside the macro before using it.
2097 (save-excursion
2098 (goto-char last-pos)
2099 (when (and (c-beginning-of-macro)
2100 (/= (point) in-macro-start))
2101 (c-invalidate-state-cache (point))
2102 ;; Set `last-pos' again just like above except that there's
2103 ;; no use looking at `c-state-cache-good-pos' here.
2104 (setq last-pos (if c-state-cache
2105 (if (consp (car c-state-cache))
2106 (cdr (car c-state-cache))
2107 (1+ (car c-state-cache)))
2108 1))))
2109
2110 ;; If we've moved very far from the last cached position then
2111 ;; it's probably better to redo it from scratch, otherwise we
2112 ;; might spend a lot of time searching from `last-pos' down to
2113 ;; here.
2114 (when (< last-pos (- here 20000))
2115 ;; First get the fallback start position. If it turns out
2116 ;; that it's so far back that the cached state is closer then
2117 ;; we'll keep it afterall.
2118 (setq pos (c-get-fallback-start-pos here))
2119 (if (<= pos last-pos)
2120 (setq pos nil)
2121 (setq last-pos nil
2122 c-state-cache nil
2123 c-state-cache-good-pos 1)))
2124
2125 ;; Find the start position for the forward search. (Can't
2126 ;; search in the backward direction since the point might be in
2127 ;; some kind of literal.)
2128
2129 (unless pos
2130 (setq old-state c-state-cache)
2131
2132 ;; There's a cached state with a containing paren. Pop off
2133 ;; the stale containing sexps from it by going forward out of
2134 ;; parens as far as possible.
2135 (narrow-to-region (point-min) here) 2954 (narrow-to-region (point-min) here)
2136 (let (placeholder pair-beg) 2955 (setq res (c-remove-stale-state-cache start-point here-bopl))
2137 (while (and c-state-cache 2956 (setq cache-pos (car res)
2138 (setq placeholder 2957 scan-backward-pos (cadr res)
2139 (c-up-list-forward last-pos))) 2958 bopl-state (car (cddr res))) ; will be nil if (< here-bopl
2140 (setq last-pos placeholder) 2959 ; start-point)
2141 (if (consp (car c-state-cache)) 2960 (if scan-backward-pos
2142 (setq pair-beg (car-safe (cdr c-state-cache)) 2961 (c-append-lower-brace-pair-to-state-cache scan-backward-pos))
2143 c-state-cache (cdr-safe (cdr c-state-cache))) 2962 (setq good-pos
2144 (setq pair-beg (car c-state-cache) 2963 (c-append-to-state-cache cache-pos))
2145 c-state-cache (cdr c-state-cache)))) 2964 (setq c-state-cache-good-pos
2146 2965 (if (and bopl-state
2147 (when (and pair-beg (eq (char-after pair-beg) ?{)) 2966 (< good-pos (- here c-state-cache-too-far)))
2148 ;; The last paren pair we moved out from was a brace 2967 (c-state-cache-non-literal-place here-bopl bopl-state)
2149 ;; pair. Modify the state to record this as a closed 2968 good-pos)))
2150 ;; pair now. 2969
2151 (if (consp (car-safe c-state-cache)) 2970 ((eq strategy 'backward)
2152 (setq c-state-cache (cdr c-state-cache))) 2971 (setq res (c-remove-stale-state-cache-backwards here cache-pos)
2153 (setq c-state-cache (cons (cons pair-beg last-pos) 2972 good-pos (car res)
2154 c-state-cache)))) 2973 scan-backward-pos (cadr res)
2155 2974 scan-forward-p (car (cddr res)))
2156 ;; Check if the preceding balanced paren is within a 2975 (if scan-backward-pos
2157 ;; macro; it should be ignored if we're outside the 2976 (c-append-lower-brace-pair-to-state-cache
2158 ;; macro. There's no need to check any further upwards; 2977 scan-backward-pos))
2159 ;; if the macro contains an unbalanced opening paren then 2978 (setq c-state-cache-good-pos
2160 ;; we're smoked anyway. 2979 (if scan-forward-p
2161 (when (and (<= (point) in-macro-start) 2980 (progn (narrow-to-region (point-min) here)
2162 (consp (car c-state-cache))) 2981 (c-append-to-state-cache good-pos))
2163 (save-excursion 2982
2164 (goto-char (car (car c-state-cache))) 2983 (c-get-cache-scan-pos good-pos))))
2165 (when (c-beginning-of-macro) 2984
2166 (setq here (point) 2985 (t ; (eq strategy 'IN-LIT)
2167 c-state-cache (cdr c-state-cache))))) 2986 (setq c-state-cache nil
2168 2987 c-state-cache-good-pos nil)))))
2169 (unless (eq c-state-cache old-state) 2988
2170 ;; Have to adjust the cached good position if state has been 2989 c-state-cache)
2171 ;; popped off. 2990
2172 (setq c-state-cache-good-pos 2991(defun c-invalidate-state-cache (here)
2173 (if c-state-cache 2992 ;; This is a wrapper over `c-invalidate-state-cache-1'.
2174 (if (consp (car c-state-cache)) 2993 ;;
2175 (cdr (car c-state-cache)) 2994 ;; It suppresses the syntactic effect of the < and > (template) brackets and
2176 (1+ (car c-state-cache))) 2995 ;; of all parens in preprocessor constructs, except for any such construct
2177 1) 2996 ;; containing point. We can then call `c-invalidate-state-cache-1' without
2178 old-state c-state-cache)) 2997 ;; worrying further about macros and template delimiters.
2179 2998 (c-with-<->-as-parens-suppressed
2180 (when c-state-cache 2999 (if c-state-old-cpp-beg
2181 (setq pos last-pos))) 3000 (c-with-all-but-one-cpps-commented-out
2182 3001 c-state-old-cpp-beg c-state-old-cpp-end
2183 ;; Get the fallback start position. 3002 (c-invalidate-state-cache-1 here))
2184 (unless pos 3003 (c-with-cpps-commented-out
2185 (setq pos (c-get-fallback-start-pos here) 3004 (c-invalidate-state-cache-1 here)))))
2186 c-state-cache nil 3005
2187 c-state-cache-good-pos 1)) 3006(defun c-parse-state ()
2188 3007 ;; This is a wrapper over `c-parse-state-1'. See that function for a
2189 (narrow-to-region (point-min) here) 3008 ;; description of the functionality and return value.
2190 3009 ;;
2191 (while pos 3010 ;; It suppresses the syntactic effect of the < and > (template) brackets and
2192 (setq save-pos pos 3011 ;; of all parens in preprocessor constructs, except for any such construct
2193 brace-pair-open nil) 3012 ;; containing point. We can then call `c-parse-state-1' without worrying
2194 3013 ;; further about macros and template delimiters.
2195 ;; Find the balanced brace pairs. This loop is hot, so it 3014 (let (here-cpp-beg here-cpp-end)
2196 ;; does ugly tricks to go faster. 3015 (save-excursion
2197 (c-safe 3016 (when (c-beginning-of-macro)
2198 (let (set-good-pos set-brace-pair) 3017 (setq here-cpp-beg (point))
2199 (while t 3018 (unless
2200 (setq last-pos nil 3019 (> (setq here-cpp-end (c-syntactic-end-of-macro))
2201 last-pos (scan-lists pos 1 -1)) ; Might signal. 3020 here-cpp-beg)
2202 (setq pos (scan-lists last-pos 1 1) ; Might signal. 3021 (setq here-cpp-beg nil here-cpp-end nil))))
2203 set-good-pos (< pos here-bol) 3022 ;; FIXME!!! Put in a `condition-case' here to protect the integrity of the
2204 set-brace-pair (eq (char-before last-pos) ?{)) 3023 ;; subsystem.
2205 3024 (prog1
2206 ;; Update the cached good position and record the brace 3025 (c-with-<->-as-parens-suppressed
2207 ;; pair, whichever is applicable for the paren we've 3026 (if (and here-cpp-beg (> here-cpp-end here-cpp-beg))
2208 ;; just jumped over. But first check that it isn't 3027 (c-with-all-but-one-cpps-commented-out
2209 ;; inside a macro and the point isn't inside the same 3028 here-cpp-beg here-cpp-end
2210 ;; one. 3029 (c-parse-state-1))
2211 (when (and (or set-good-pos set-brace-pair) 3030 (c-with-cpps-commented-out
2212 (or (>= pos in-macro-start) 3031 (c-parse-state-1))))
2213 (save-excursion 3032 (setq c-state-old-cpp-beg here-cpp-beg
2214 (goto-char pos) 3033 c-state-old-cpp-end here-cpp-end))))
2215 (not (c-beginning-of-macro))))) 3034
2216 (if set-good-pos 3035;; Debug tool to catch cache inconsistencies. This is called from
2217 (setq c-state-cache-good-pos pos)) 3036;; 000tests.el.
2218 (if set-brace-pair
2219 (setq brace-pair-open last-pos
2220 brace-pair-close pos))))))
2221
2222 ;; Record the last brace pair.
2223 (when brace-pair-open
2224 (let ((head (car-safe c-state-cache)))
2225 (if (consp head)
2226 (progn
2227 (setcar head (1- brace-pair-open))
2228 (setcdr head brace-pair-close))
2229 (setq c-state-cache (cons (cons (1- brace-pair-open)
2230 brace-pair-close)
2231 c-state-cache)))))
2232
2233 (if last-pos
2234 ;; Prepare to loop, but record the open paren only if it's
2235 ;; outside a macro or within the same macro as point, and
2236 ;; if it is a legitimate open paren and not some character
2237 ;; that got an open paren syntax-table property.
2238 (progn
2239 (setq pos last-pos)
2240 (when (and (or (>= last-pos in-macro-start)
2241 (save-excursion
2242 (goto-char last-pos)
2243 (not (c-beginning-of-macro))))
2244 ;; Check for known types of parens that we
2245 ;; want to record. The syntax table is not to
2246 ;; be trusted here since the caller might be
2247 ;; using e.g. `c++-template-syntax-table'.
2248 (memq (char-before last-pos) '(?{ ?\( ?\[)))
2249 (if (< last-pos here-bol)
2250 (setq c-state-cache-good-pos last-pos))
2251 (setq c-state-cache (cons (1- last-pos) c-state-cache))))
2252
2253 (if (setq last-pos (c-up-list-forward pos))
2254 ;; Found a close paren without a corresponding opening
2255 ;; one. Maybe we didn't go back far enough, so try to
2256 ;; scan backward for the start paren and then start over.
2257 (progn
2258 (setq pos (c-up-list-backward pos)
2259 c-state-cache nil
2260 c-state-cache-good-pos c-state-cache-start)
2261 (when (or (not pos)
2262 ;; Emacs (up to at least 21.2) can get confused by
2263 ;; open parens in column zero inside comments: The
2264 ;; sexp functions can then misbehave and bring us
2265 ;; back to the same point again. Check this so that
2266 ;; we don't get an infinite loop.
2267 (>= pos save-pos))
2268 (setq pos last-pos
2269 c-parsing-error
2270 (format "Unbalanced close paren at line %d"
2271 (1+ (count-lines (point-min)
2272 (c-point 'bol last-pos)))))))
2273 (setq pos nil))))
2274
2275 ;;(message "c-parse-state: %S end: %S" c-state-cache c-state-cache-good-pos)
2276 c-state-cache)))
2277
2278;; Debug tool to catch cache inconsistencies.
2279(defvar c-debug-parse-state nil) 3037(defvar c-debug-parse-state nil)
2280(unless (fboundp 'c-real-parse-state) 3038(unless (fboundp 'c-real-parse-state)
2281 (fset 'c-real-parse-state (symbol-function 'c-parse-state))) 3039 (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
2282(cc-bytecomp-defun c-real-parse-state) 3040(cc-bytecomp-defun c-real-parse-state)
2283(defun c-debug-parse-state () 3041(defun c-debug-parse-state ()
2284 (let ((res1 (c-real-parse-state)) res2) 3042 (let ((here (point)) (res1 (c-real-parse-state)) res2)
2285 (let ((c-state-cache nil) 3043 (let ((c-state-cache nil)
2286 (c-state-cache-start 1) 3044 (c-state-cache-good-pos 1)
2287 (c-state-cache-good-pos 1)) 3045 (c-state-nonlit-pos-cache nil)
3046 (c-state-nonlit-pos-cache-limit 1)
3047 (c-state-brace-pair-desert nil)
3048 (c-state-point-min 1)
3049 (c-state-point-min-lit-type nil)
3050 (c-state-point-min-lit-start nil)
3051 (c-state-min-scan-pos 1)
3052 (c-state-old-cpp-beg nil)
3053 (c-state-old-cpp-end nil))
2288 (setq res2 (c-real-parse-state))) 3054 (setq res2 (c-real-parse-state)))
2289 (unless (equal res1 res2) 3055 (unless (equal res1 res2)
2290 ;; The cache can actually go further back due to the ad-hoc way 3056 ;; The cache can actually go further back due to the ad-hoc way
@@ -2296,10 +3062,11 @@ comment at the start of cc-engine.el for more info."
2296 (while (not (or (bobp) (eq (char-after) ?{))) 3062 (while (not (or (bobp) (eq (char-after) ?{)))
2297 (c-beginning-of-defun-1)) 3063 (c-beginning-of-defun-1))
2298 (unless (equal (c-whack-state-before (point) res1) res2) 3064 (unless (equal (c-whack-state-before (point) res1) res2)
2299 (message (concat "c-parse-state inconsistency: " 3065 (message (concat "c-parse-state inconsistency at %s: "
2300 "using cache: %s, from scratch: %s") 3066 "using cache: %s, from scratch: %s")
2301 res1 res2)))) 3067 here res1 res2))))
2302 res1)) 3068 res1))
3069
2303(defun c-toggle-parse-state-debug (&optional arg) 3070(defun c-toggle-parse-state-debug (&optional arg)
2304 (interactive "P") 3071 (interactive "P")
2305 (setq c-debug-parse-state (c-calculate-state arg c-debug-parse-state)) 3072 (setq c-debug-parse-state (c-calculate-state arg c-debug-parse-state))
@@ -2310,6 +3077,7 @@ comment at the start of cc-engine.el for more info."
2310(when c-debug-parse-state 3077(when c-debug-parse-state
2311 (c-toggle-parse-state-debug 1)) 3078 (c-toggle-parse-state-debug 1))
2312 3079
3080
2313(defun c-whack-state-before (bufpos paren-state) 3081(defun c-whack-state-before (bufpos paren-state)
2314 ;; Whack off any state information from PAREN-STATE which lies 3082 ;; Whack off any state information from PAREN-STATE which lies
2315 ;; before BUFPOS. Not destructive on PAREN-STATE. 3083 ;; before BUFPOS. Not destructive on PAREN-STATE.
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 58b2ad5c20e..e9af813eeb3 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -426,7 +426,8 @@ stuff. Used on level 1 and higher."
426 (progn 426 (progn
427 (c-mark-<-as-paren beg) 427 (c-mark-<-as-paren beg)
428 (c-mark->-as-paren end)) 428 (c-mark->-as-paren end))
429 (c-clear-char-property beg 'syntax-table))) 429 ;; (c-clear-char-property beg 'syntax-table)
430 (c-clear-char-property beg 'category)))
430 nil))))))) 431 nil)))))))
431 432
432 ;; #define. 433 ;; #define.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index e6fcd2f85e2..9fdeb11c106 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -461,7 +461,7 @@ The function is called even when font locking is disabled.
461When the mode is initialized, this function is called with 461When the mode is initialized, this function is called with
462parameters \(point-min), \(point-max) and <buffer size>." 462parameters \(point-min), \(point-max) and <buffer size>."
463 t nil 463 t nil
464 (c c++ objc) 'c-extend-and-neutralize-syntax-in-CPP 464 (c c++ objc) 'c-neutralize-syntax-in-and-mark-CPP
465 awk 'c-awk-extend-and-syntax-tablify-region) 465 awk 'c-awk-extend-and-syntax-tablify-region)
466(c-lang-defvar c-before-font-lock-function 466(c-lang-defvar c-before-font-lock-function
467 (c-lang-const c-before-font-lock-function)) 467 (c-lang-const c-before-font-lock-function))
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 2bf725f1bc3..634d0989355 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -410,7 +410,7 @@ preferably use the `c-mode-menu' language constant directly."
410;; temporary changes in some font lock support modes, causing extra 410;; temporary changes in some font lock support modes, causing extra
411;; unnecessary work and font lock glitches due to interactions between 411;; unnecessary work and font lock glitches due to interactions between
412;; various text properties. 412;; various text properties.
413;; 413;;
414;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any 414;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any
415;; more. 415;; more.
416 416
@@ -451,18 +451,18 @@ preferably use the `c-mode-menu' language constant directly."
451 end (point)))))))) 451 end (point))))))))
452 452
453;; c-maybe-stale-found-type records a place near the region being 453;; c-maybe-stale-found-type records a place near the region being
454;; changed where an element of `found-types' might become stale. It 454;; changed where an element of `found-types' might become stale. It
455;; is set in c-before-change and is either nil, or has the form: 455;; is set in c-before-change and is either nil, or has the form:
456;; 456;;
457;; (c-decl-id-start "foo" 97 107 " (* ooka) " "o"), where 457;; (c-decl-id-start "foo" 97 107 " (* ooka) " "o"), where
458;; 458;;
459;; o - `c-decl-id-start' is the c-type text property value at buffer 459;; o - `c-decl-id-start' is the c-type text property value at buffer
460;; pos 96. 460;; pos 96.
461;; 461;;
462;; o - 97 107 is the region potentially containing the stale type - 462;; o - 97 107 is the region potentially containing the stale type -
463;; this is delimited by a non-nil c-type text property at 96 and 463;; this is delimited by a non-nil c-type text property at 96 and
464;; either another one or a ";", "{", or "}" at 107. 464;; either another one or a ";", "{", or "}" at 107.
465;; 465;;
466;; o - " (* ooka) " is the (before change) buffer portion containing 466;; o - " (* ooka) " is the (before change) buffer portion containing
467;; the suspect type (here "ooka"). 467;; the suspect type (here "ooka").
468;; 468;;
@@ -517,6 +517,9 @@ that requires a literal mode spec at compile time."
517 (make-local-variable 'fill-paragraph-function) 517 (make-local-variable 'fill-paragraph-function)
518 (setq fill-paragraph-function 'c-fill-paragraph) 518 (setq fill-paragraph-function 'c-fill-paragraph)
519 519
520 ;; Initialise the cache of brace pairs, and opening braces/brackets/parens.
521 (c-state-cache-init)
522
520 (when (or c-recognize-<>-arglists 523 (when (or c-recognize-<>-arglists
521 (c-major-mode-is 'awk-mode) 524 (c-major-mode-is 'awk-mode)
522 (c-major-mode-is '(c-mode c++-mode objc-mode))) 525 (c-major-mode-is '(c-mode c++-mode objc-mode)))
@@ -847,7 +850,7 @@ Note that the style variables are always made local to the buffer."
847 t) 850 t)
848 (t nil))))))) 851 (t nil)))))))
849 852
850(defun c-extend-and-neutralize-syntax-in-CPP (begg endd old-len) 853(defun c-neutralize-syntax-in-and-mark-CPP (begg endd old-len)
851 ;; (i) Extend the font lock region to cover all changed preprocessor 854 ;; (i) Extend the font lock region to cover all changed preprocessor
852 ;; regions; it does this by setting the variables `c-new-BEG' and 855 ;; regions; it does this by setting the variables `c-new-BEG' and
853 ;; `c-new-END' to the new boundaries. 856 ;; `c-new-END' to the new boundaries.
@@ -856,10 +859,15 @@ Note that the style variables are always made local to the buffer."
856 ;; extended changed region. "Restore" lines which were CPP lines before the 859 ;; extended changed region. "Restore" lines which were CPP lines before the
857 ;; change and are no longer so; these can be located from the Buffer local 860 ;; change and are no longer so; these can be located from the Buffer local
858 ;; variables `c-old-BOM' and `c-old-EOM'. 861 ;; variables `c-old-BOM' and `c-old-EOM'.
859 ;; 862 ;;
863 ;; (iii) Mark every CPP construct by placing a `category' property value
864 ;; `c-cpp-delimiter' at its start and end. The marked characters are the
865 ;; opening # and usually the terminating EOL, but sometimes the character
866 ;; before a comment/string delimiter.
867 ;;
860 ;; That is, set syntax-table properties on characters that would otherwise 868 ;; That is, set syntax-table properties on characters that would otherwise
861 ;; interact syntactically with those outside the CPP line(s). 869 ;; interact syntactically with those outside the CPP line(s).
862 ;; 870 ;;
863 ;; This function is called from an after-change function, BEGG ENDD and 871 ;; This function is called from an after-change function, BEGG ENDD and
864 ;; OLD-LEN being the standard parameters. It prepares the buffer for font 872 ;; OLD-LEN being the standard parameters. It prepares the buffer for font
865 ;; locking, hence must get called before `font-lock-after-change-function'. 873 ;; locking, hence must get called before `font-lock-after-change-function'.
@@ -870,32 +878,34 @@ Note that the style variables are always made local to the buffer."
870 ;; This function is the C/C++/ObjC value of `c-before-font-lock-function'. 878 ;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
871 ;; 879 ;;
872 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!! 880 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
873 ;; 881 ;;
874 ;; This function might make hidden buffer changes. 882 ;; This function might make hidden buffer changes.
875 (c-save-buffer-state (limits mbeg+1) 883 (c-save-buffer-state (limits)
876 ;; First determine the region, (c-new-BEG c-new-END), which will get font 884 ;; First determine the region, (c-new-BEG c-new-END), which will get font
877 ;; locked. It might need "neutralizing". This region may not start 885 ;; locked. It might need "neutralizing". This region may not start
878 ;; inside a string, comment, or macro. 886 ;; inside a string, comment, or macro.
879 (goto-char c-old-BOM) ; already set to old start of macro or begg. 887 (goto-char c-old-BOM) ; already set to old start of macro or begg.
880 (setq c-new-BEG 888 (setq c-new-BEG
881 (if (setq limits (c-literal-limits)) 889 (if (setq limits (c-state-literal-at (point)))
882 (cdr limits) ; go forward out of any string or comment. 890 (cdr limits) ; go forward out of any string or comment.
883 (point))) 891 (point)))
884 892
885 (goto-char endd) 893 (goto-char endd)
886 (if (setq limits (c-literal-limits)) 894 (if (setq limits (c-state-literal-at (point)))
887 (goto-char (car limits))) ; go backward out of any string or comment. 895 (goto-char (car limits))) ; go backward out of any string or comment.
888 (if (c-beginning-of-macro) 896 (if (c-beginning-of-macro)
889 (c-end-of-macro)) 897 (c-end-of-macro))
890 (setq c-new-END (max (+ (- c-old-EOM old-len) (- endd begg)) 898 (setq c-new-END (max (+ (- c-old-EOM old-len) (- endd begg))
891 (point))) 899 (point)))
892 900
893 ;; Clear any existing punctuation properties. 901 ;; Clear all old relevant properties.
894 (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1)) 902 (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
903 (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter)
904 ;; FIXME!!! What about the "<" and ">" category properties? 2009-11-16
895 905
896 ;; Add needed properties to each CPP construct in the region. 906 ;; Add needed properties to each CPP construct in the region.
897 (goto-char c-new-BEG) 907 (goto-char c-new-BEG)
898 (let ((pps-position c-new-BEG) pps-state) 908 (let ((pps-position c-new-BEG) pps-state mbeg)
899 (while (and (< (point) c-new-END) 909 (while (and (< (point) c-new-END)
900 (search-forward-regexp c-anchored-cpp-prefix c-new-END t)) 910 (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
901 ;; If we've found a "#" inside a string/comment, ignore it. 911 ;; If we've found a "#" inside a string/comment, ignore it.
@@ -904,10 +914,16 @@ Note that the style variables are always made local to the buffer."
904 pps-position (point)) 914 pps-position (point))
905 (unless (or (nth 3 pps-state) ; in a string? 915 (unless (or (nth 3 pps-state) ; in a string?
906 (nth 4 pps-state)) ; in a comment? 916 (nth 4 pps-state)) ; in a comment?
907 (setq mbeg+1 (point)) 917 (goto-char (match-beginning 0))
908 (c-end-of-macro) ; Do we need to go forward 1 char here? No! 918 (setq mbeg (point))
909 (c-neutralize-CPP-line mbeg+1 (point)) 919 (if (> (c-syntactic-end-of-macro) mbeg)
910 (setq pps-position (point))))))) ; no need to update pps-state. 920 (progn
921 (c-neutralize-CPP-line mbeg (point))
922 (c-set-cpp-delimiters mbeg (point))
923 ;(setq pps-position (point))
924 )
925 (forward-line)) ; no infinite loop with, e.g., "#//"
926 )))))
911 927
912(defun c-before-change (beg end) 928(defun c-before-change (beg end)
913 ;; Function to be put on `before-change-function'. Primarily, this calls 929 ;; Function to be put on `before-change-function'. Primarily, this calls
@@ -915,7 +931,7 @@ Note that the style variables are always made local to the buffer."
915 ;; otherwise used only to remove stale entries from the `c-found-types' 931 ;; otherwise used only to remove stale entries from the `c-found-types'
916 ;; cache, and to record entries which a `c-after-change' function might 932 ;; cache, and to record entries which a `c-after-change' function might
917 ;; confirm as stale. 933 ;; confirm as stale.
918 ;; 934 ;;
919 ;; Note that this function must be FAST rather than accurate. Note 935 ;; Note that this function must be FAST rather than accurate. Note
920 ;; also that it only has any effect when font locking is enabled. 936 ;; also that it only has any effect when font locking is enabled.
921 ;; We exploit this by checking for font-lock-*-face instead of doing 937 ;; We exploit this by checking for font-lock-*-face instead of doing