diff options
| author | Alan Mackenzie | 2009-12-03 16:02:10 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2009-12-03 16:02:10 +0000 |
| commit | 0ec1d2c5bb42c578aa555d77e379c8c256114306 (patch) | |
| tree | a7050ce31c3132a0649bde014a4d62f202cb7e78 | |
| parent | 4267d8591048007bb584bdba9924056d660e0c53 (diff) | |
| download | emacs-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.el | 106 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 1348 | ||||
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 54 |
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. | |||
| 461 | When the mode is initialized, this function is called with | 461 | When the mode is initialized, this function is called with |
| 462 | parameters \(point-min), \(point-max) and <buffer size>." | 462 | parameters \(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 |