Mercurial > emacs
comparison lisp/progmodes/cc-engine.el @ 51714:bc91cbf50c24
Updated CC Mode to version 5.30.
author | Martin Stjernholm <mast@lysator.liu.se> |
---|---|
date | Thu, 03 Jul 2003 12:30:59 +0000 |
parents | ea06392567c0 |
children | d508ffa43505 |
comparison
equal
deleted
inserted
replaced
51713:205602055b5f | 51714:bc91cbf50c24 |
---|---|
1 ;;; cc-engine.el --- core syntax guessing engine for CC mode | 1 ;;; cc-engine.el --- core syntax guessing engine for CC mode |
2 | 2 |
3 ;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1985,1987,1992-2003 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Authors: 2000- Martin Stjernholm | 5 ;; Authors: 1998- Martin Stjernholm |
6 ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm | 6 ;; 1992-1999 Barry A. Warsaw |
7 ;; 1992-1997 Barry A. Warsaw | |
8 ;; 1987 Dave Detlefs and Stewart Clamen | 7 ;; 1987 Dave Detlefs and Stewart Clamen |
9 ;; 1985 Richard M. Stallman | 8 ;; 1985 Richard M. Stallman |
10 ;; Maintainer: bug-cc-mode@gnu.org | 9 ;; Maintainer: bug-cc-mode@gnu.org |
11 ;; Created: 22-Apr-1997 (split from cc-mode.el) | 10 ;; Created: 22-Apr-1997 (split from cc-mode.el) |
12 ;; Version: See cc-mode.el | 11 ;; Version: See cc-mode.el |
39 ;; | 38 ;; |
40 ;; (This policy applies to CC Mode as a whole, not just this file. It | 39 ;; (This policy applies to CC Mode as a whole, not just this file. It |
41 ;; probably also applies to many other Emacs packages, but here it's | 40 ;; probably also applies to many other Emacs packages, but here it's |
42 ;; clearly spelled out.) | 41 ;; clearly spelled out.) |
43 | 42 |
43 ;; Hidden buffer changes | |
44 ;; | |
45 ;; Various functions in CC Mode use text properties for caching and | |
46 ;; syntactic markup purposes, and those of them that might modify such | |
47 ;; properties are said to do "hidden buffer changes". They should be | |
48 ;; used within `c-save-buffer-state' or a similar function that saves | |
49 ;; and restores buffer modifiedness etc. | |
50 ;; | |
51 ;; Interactive functions are assumed to not do hidden buffer changes | |
52 ;; (this isn't applicable in the specific parts of them that do real | |
53 ;; changes, though). | |
54 ;; | |
55 ;; All other functions are assumed to do hidden buffer changes and | |
56 ;; must thus be wrapped inside `c-save-buffer-state' if they're used | |
57 ;; from any function that does not do hidden buffer changes. | |
58 ;; | |
59 ;; Every function, except the interactive ones, that doesn't do hidden | |
60 ;; buffer changes have that explicitly stated in their docstring or | |
61 ;; comment. | |
62 | |
63 ;; Use of text properties | |
64 ;; | |
65 ;; CC Mode uses several text properties internally to mark up various | |
66 ;; positions, e.g. to improve speed and to eliminate glitches in | |
67 ;; interactive refontification. | |
68 ;; | |
69 ;; 'syntax-table | |
70 ;; Used to modify the syntax of some characters. Currently used to | |
71 ;; mark the "<" and ">" of angle bracket parens with paren syntax. | |
72 ;; | |
73 ;; This property is used on single characters and is therefore | |
74 ;; always treated as front and rear nonsticky (or start and end open | |
75 ;; in XEmacs vocabulary). It's therefore installed on | |
76 ;; `text-property-default-nonsticky' if that variable exists (Emacs | |
77 ;; >= 21). | |
78 ;; | |
79 ;; 'c-is-sws and 'c-in-sws | |
80 ;; Used by `c-forward-syntactic-ws' and `c-backward-syntactic-ws' to | |
81 ;; speed them up. See the comment blurb before `c-put-is-sws' | |
82 ;; below for further details. | |
83 ;; | |
84 ;; 'c-type | |
85 ;; This property is used on single characters to mark positions with | |
86 ;; special syntactic relevance of various sorts. It's primary use | |
87 ;; is to avoid glitches when multiline constructs are refontified | |
88 ;; interactively (on font lock decoration level 3). It's cleared in | |
89 ;; a region before it's fontified and is then put on relevant chars | |
90 ;; in that region as they are encountered during the fontification. | |
91 ;; The value specifies the kind of position: | |
92 ;; | |
93 ;; 'c-decl-arg-start | |
94 ;; Put on the last char of the token preceding each declaration | |
95 ;; inside a declaration style arglist (typically in a function | |
96 ;; prototype). | |
97 ;; | |
98 ;; 'c-decl-end | |
99 ;; Put on the last char of the token preceding a declaration. | |
100 ;; This is used in cases where declaration boundaries can't be | |
101 ;; recognized simply by looking for a token like ";" or "}". | |
102 ;; `c-type-decl-end-used' must be set if this is used (see also | |
103 ;; `c-find-decl-spots'). | |
104 ;; | |
105 ;; 'c-<>-arg-sep | |
106 ;; Put on the commas that separate arguments in angle bracket | |
107 ;; arglists like C++ template arglists. | |
108 ;; | |
109 ;; 'c-decl-id-start and 'c-decl-type-start | |
110 ;; Put on the last char of the token preceding each declarator | |
111 ;; in the declarator list of a declaration. They are also used | |
112 ;; between the identifiers cases like enum declarations. | |
113 ;; 'c-decl-type-start is used when the declarators are types, | |
114 ;; 'c-decl-id-start otherwise. | |
115 ;; | |
116 ;; 'c-awk-NL-prop | |
117 ;; Used in AWK mode to mark the various kinds of newlines. See | |
118 ;; cc-awk.el. | |
119 | |
44 ;;; Code: | 120 ;;; Code: |
45 | 121 |
46 (eval-when-compile | 122 (eval-when-compile |
47 (let ((load-path | 123 (let ((load-path |
48 (if (and (boundp 'byte-compile-dest-file) | 124 (if (and (boundp 'byte-compile-dest-file) |
49 (stringp byte-compile-dest-file)) | 125 (stringp byte-compile-dest-file)) |
50 (cons (file-name-directory byte-compile-dest-file) load-path) | 126 (cons (file-name-directory byte-compile-dest-file) load-path) |
51 load-path))) | 127 load-path))) |
52 (require 'cc-bytecomp))) | 128 (load "cc-bytecomp" nil t))) |
53 | 129 |
54 (cc-require 'cc-defs) | 130 (cc-require 'cc-defs) |
131 (cc-require-when-compile 'cc-langs) | |
55 (cc-require 'cc-vars) | 132 (cc-require 'cc-vars) |
56 (cc-require 'cc-langs) | 133 |
134 ;; Some functions/constants in cc-awk.el that are called/referenced here. | |
135 ;; (Can't use cc-require due to cyclicity.) | |
136 (cc-bytecomp-defun c-awk-unstick-NL-prop) | |
137 (cc-bytecomp-defun c-awk-clear-NL-props) | |
138 (cc-bytecomp-defvar awk-mode-syntax-table) | |
139 (cc-bytecomp-defun c-awk-backward-syntactic-ws) | |
140 (cc-bytecomp-defun c-awk-after-logical-semicolon) | |
141 (cc-bytecomp-defun c-awk-NL-prop-not-set) | |
142 (cc-bytecomp-defun c-awk-completed-stmt-ws-ends-line-p) | |
143 (cc-bytecomp-defun c-awk-completed-stmt-ws-ends-prev-line-p) | |
144 (cc-bytecomp-defun c-awk-prev-line-incomplete-p) | |
145 (cc-bytecomp-defun c-awk-after-change) | |
57 | 146 |
58 ;; Silence the compiler. | 147 ;; Silence the compiler. |
59 (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs | 148 (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs |
60 | 149 |
61 | 150 |
151 ;; Make declarations for all the `c-lang-defvar' variables in cc-langs. | |
152 | |
153 (defmacro c-declare-lang-variables () | |
154 `(progn | |
155 ,@(mapcan (lambda (init) | |
156 `(,(if (elt init 2) | |
157 `(defvar ,(car init) nil ,(elt init 2)) | |
158 `(defvar ,(car init) nil)) | |
159 (make-variable-buffer-local ',(car init)))) | |
160 (cdr c-lang-variable-inits)))) | |
161 (c-declare-lang-variables) | |
162 | |
163 | |
164 ;;; Internal state variables. | |
165 | |
166 ;; Internal state of hungry delete key feature | |
167 (defvar c-hungry-delete-key nil) | |
168 (make-variable-buffer-local 'c-hungry-delete-key) | |
169 | |
170 ;; Internal state of auto newline feature. | |
171 (defvar c-auto-newline nil) | |
172 (make-variable-buffer-local 'c-auto-newline) | |
173 | |
174 ;; Internal auto-newline/hungry-delete designation string for mode line. | |
175 (defvar c-auto-hungry-string nil) | |
176 (make-variable-buffer-local 'c-auto-hungry-string) | |
177 | |
62 (defun c-calculate-state (arg prevstate) | 178 (defun c-calculate-state (arg prevstate) |
63 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If | 179 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If |
64 ;; arg is nil or zero, toggle the state. If arg is negative, turn | 180 ;; arg is nil or zero, toggle the state. If arg is negative, turn |
65 ;; the state off, and if arg is positive, turn the state on | 181 ;; the state off, and if arg is positive, turn the state on |
66 (if (or (not arg) | 182 (if (or (not arg) |
67 (zerop (setq arg (prefix-numeric-value arg)))) | 183 (zerop (setq arg (prefix-numeric-value arg)))) |
68 (not prevstate) | 184 (not prevstate) |
69 (> arg 0))) | 185 (> arg 0))) |
70 | 186 |
187 ;; Dynamically bound cache for `c-in-literal'. | |
188 (defvar c-in-literal-cache t) | |
189 | |
190 ;; Must be set in buffers where the `c-type' text property might be used | |
191 ;; with the value `c-decl-end'. | |
192 (defvar c-type-decl-end-used nil) | |
193 (make-variable-buffer-local 'c-type-decl-end-used) | |
194 | |
71 | 195 |
72 (defvar c-in-literal-cache t) | 196 ;;; Basic utility functions. |
197 | |
198 (defun c-syntactic-content (from to) | |
199 ;; Return the given region as a string where all syntactic | |
200 ;; whitespace is removed or, where necessary, replaced with a single | |
201 ;; space. | |
202 (save-excursion | |
203 (goto-char from) | |
204 (let* ((parts (list nil)) (tail parts) pos) | |
205 (while (re-search-forward c-syntactic-ws-start to t) | |
206 (goto-char (setq pos (match-beginning 0))) | |
207 (c-forward-syntactic-ws to) | |
208 (if (= (point) pos) | |
209 (forward-char) | |
210 (if (and (> pos from) | |
211 (< (point) to) | |
212 (looking-at "\\w\\|\\s_") | |
213 (save-excursion | |
214 (goto-char (1- pos)) | |
215 (looking-at "\\w\\|\\s_"))) | |
216 (progn | |
217 (setcdr tail (list (buffer-substring-no-properties from pos) | |
218 " ")) | |
219 (setq tail (cddr tail))) | |
220 (setcdr tail (list (buffer-substring-no-properties from pos))) | |
221 (setq tail (cdr tail))) | |
222 (setq from (point)))) | |
223 (setcdr tail (list (buffer-substring-no-properties from to))) | |
224 (apply 'concat (cdr parts))))) | |
225 | |
226 (defsubst c-keyword-sym (keyword) | |
227 ;; Return non-nil if the string KEYWORD is a known keyword. More | |
228 ;; precisely, the value is the symbol for the keyword in | |
229 ;; `c-keywords-obarray'. | |
230 (intern-soft keyword c-keywords-obarray)) | |
231 | |
232 (defsubst c-keyword-member (keyword-sym lang-constant) | |
233 ;; Return non-nil if the symbol KEYWORD-SYM, as returned by | |
234 ;; `c-keyword-sym', is a member of LANG-CONSTANT, which is the name | |
235 ;; of a language constant that ends with "-kwds". If KEYWORD-SYM is | |
236 ;; nil then the result is nil. | |
237 (get keyword-sym lang-constant)) | |
238 | |
239 ;; String syntax chars, suitable for skip-syntax-(forward|backward). | |
240 (defconst c-string-syntax (if (memq 'gen-string-delim c-emacs-features) | |
241 "\"|" | |
242 "\"")) | |
243 | |
244 ;; Regexp matching string start syntax. | |
245 (defconst c-string-limit-regexp (if (memq 'gen-string-delim c-emacs-features) | |
246 "\\s\"\\|\\s|" | |
247 "\\s\"")) | |
248 | |
249 ;; Holds formatted error strings for the few cases where parse errors | |
250 ;; are reported. | |
73 (defvar c-parsing-error nil) | 251 (defvar c-parsing-error nil) |
252 (make-variable-buffer-local 'c-parsing-error) | |
253 | |
254 (defun c-echo-parsing-error (&optional quiet) | |
255 ;; This function does not do any hidden buffer changes. | |
256 (when (and c-report-syntactic-errors c-parsing-error (not quiet)) | |
257 (c-benign-error "%s" c-parsing-error)) | |
258 c-parsing-error) | |
259 | |
260 ;; Faces given to comments and string literals. This is used in some | |
261 ;; situations to speed up recognition; it isn't mandatory that font | |
262 ;; locking is in use. This variable is extended with the face in | |
263 ;; `c-doc-face-name' when fontification is activated in cc-fonts.el. | |
264 (defconst c-literal-faces | |
265 '(font-lock-comment-face font-lock-string-face)) | |
266 | |
267 | |
268 ;; Some debug tools to visualize various special positions. This | |
269 ;; debug code isn't as portable as the rest of CC Mode. | |
270 | |
271 (cc-bytecomp-defun overlays-in) | |
272 (cc-bytecomp-defun overlay-get) | |
273 (cc-bytecomp-defun overlay-start) | |
274 (cc-bytecomp-defun overlay-end) | |
275 (cc-bytecomp-defun delete-overlay) | |
276 (cc-bytecomp-defun overlay-put) | |
277 (cc-bytecomp-defun make-overlay) | |
278 | |
279 (defun c-debug-add-face (beg end face) | |
280 (c-save-buffer-state ((overlays (overlays-in beg end)) overlay) | |
281 (while overlays | |
282 (setq overlay (car overlays) | |
283 overlays (cdr overlays)) | |
284 (when (eq (overlay-get overlay 'face) face) | |
285 (setq beg (min beg (overlay-start overlay)) | |
286 end (max end (overlay-end overlay))) | |
287 (delete-overlay overlay))) | |
288 (overlay-put (make-overlay beg end) 'face face))) | |
289 | |
290 (defun c-debug-remove-face (beg end face) | |
291 (c-save-buffer-state ((overlays (overlays-in beg end)) overlay | |
292 (ol-beg beg) (ol-end end)) | |
293 (while overlays | |
294 (setq overlay (car overlays) | |
295 overlays (cdr overlays)) | |
296 (when (eq (overlay-get overlay 'face) face) | |
297 (setq ol-beg (min ol-beg (overlay-start overlay)) | |
298 ol-end (max ol-end (overlay-end overlay))) | |
299 (delete-overlay overlay))) | |
300 (when (< ol-beg beg) | |
301 (overlay-put (make-overlay ol-beg beg) 'face face)) | |
302 (when (> ol-end end) | |
303 (overlay-put (make-overlay end ol-end) 'face face)))) | |
304 | |
305 | |
306 ;; `c-beginning-of-statement-1' and accompanying stuff. | |
74 | 307 |
75 ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between | 308 ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between |
76 ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A | 309 ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A |
77 ;; better way should be implemented, but this will at least shut up | 310 ;; better way should be implemented, but this will at least shut up |
78 ;; the byte compiler. | 311 ;; the byte compiler. |
79 (defvar c-maybe-labelp nil) | 312 (defvar c-maybe-labelp nil) |
313 | |
314 ;; New awk-compatible version of c-beginning-of-statement-1, ACM 2002/6/22 | |
80 | 315 |
81 ;; Macros used internally in c-beginning-of-statement-1 for the | 316 ;; Macros used internally in c-beginning-of-statement-1 for the |
82 ;; automaton actions. | 317 ;; automaton actions. |
83 (defmacro c-bos-push-state () | 318 (defmacro c-bos-push-state () |
84 '(setq stack (cons (cons state saved-pos) | 319 '(setq stack (cons (cons state saved-pos) |
121 "Move to the start of the current statement or declaration, or to | 356 "Move to the start of the current statement or declaration, or to |
122 the previous one if already at the beginning of one. Only | 357 the previous one if already at the beginning of one. Only |
123 statements/declarations on the same level are considered, i.e. don't | 358 statements/declarations on the same level are considered, i.e. don't |
124 move into or out of sexps (not even normal expression parentheses). | 359 move into or out of sexps (not even normal expression parentheses). |
125 | 360 |
126 Stop at statement continuations like \"else\", \"catch\", \"finally\" | 361 Stop at statement continuation tokens like \"else\", \"catch\", |
127 and the \"while\" in \"do ... while\" if the start point is within | 362 \"finally\" and the \"while\" in \"do ... while\" if the start point |
128 them. If starting at such a continuation, move to the corresponding | 363 is within the continuation. If starting at such a token, move to the |
129 statement start. If at the beginning of a statement, move to the | 364 corresponding statement start. If at the beginning of a statement, |
130 closest containing statement if there is any. This might also stop at | 365 move to the closest containing statement if there is any. This might |
131 a continuation clause. | 366 also stop at a continuation clause. |
132 | 367 |
133 Labels are treated as separate statements if IGNORE-LABELS is non-nil. | 368 Labels are treated as separate statements if IGNORE-LABELS is non-nil. |
134 The function is not overly intelligent in telling labels from other | 369 The function is not overly intelligent in telling labels from other |
135 uses of colons; if used outside a statement context it might trip up | 370 uses of colons; if used outside a statement context it might trip up |
136 on e.g. inherit colons, so IGNORE-LABELS should be used then. There | 371 on e.g. inherit colons, so IGNORE-LABELS should be used then. There |
157 NOERROR turns off error logging to `c-parsing-error'. | 392 NOERROR turns off error logging to `c-parsing-error'. |
158 | 393 |
159 Normally only ';' is considered to delimit statements, but if | 394 Normally only ';' is considered to delimit statements, but if |
160 COMMA-DELIM is non-nil then ',' is treated likewise." | 395 COMMA-DELIM is non-nil then ',' is treated likewise." |
161 | 396 |
162 ;; The bulk of this function is a pushdown automaton that looks at | 397 ;; The bulk of this function is a pushdown automaton that looks at statement |
163 ;; statement boundaries and the tokens in c-opt-block-stmt-key. | 398 ;; boundaries and the tokens (such as "while") in c-opt-block-stmt-key. Its |
399 ;; purpose is to keep track of nested statements, ensuring that such | |
400 ;; statments are skipped over in their entirety (somewhat akin to what C-M-p | |
401 ;; does with nested braces/brackets/parentheses). | |
164 ;; | 402 ;; |
165 ;; Note: The position of a boundary is the following token. | 403 ;; Note: The position of a boundary is the following token. |
166 ;; | 404 ;; |
167 ;; Begin with current token, stop when stack is empty and the | 405 ;; Beginning with the current token (the one following point), move back one |
168 ;; position has been moved. | 406 ;; sexp at a time (where a sexp is, more or less, either a token or the |
407 ;; entire contents of a brace/bracket/paren pair). Each time a statement | |
408 ;; boundary is crossed or a "while"-like token is found, update the state of | |
409 ;; the PDA. Stop at the beginning of a statement when the stack (holding | |
410 ;; nested statement info) is empty and the position has been moved. | |
411 ;; | |
412 ;; The following variables constitute the PDA: | |
413 ;; | |
414 ;; sym: This is either the "while"-like token (e.g. 'for) we've just | |
415 ;; scanned back over, 'boundary if we've just gone back over a | |
416 ;; statement boundary, or nil otherwise. | |
417 ;; state: takes one of the values (nil else else-boundary while | |
418 ;; while-boundary catch catch-boundary). | |
419 ;; nil means "no "while"-like token yet scanned". | |
420 ;; 'else, for example, means "just gone back over an else". | |
421 ;; 'else-boundary means "just gone back over a statement boundary | |
422 ;; immediately after having gone back over an else". | |
423 ;; saved-pos: A vector of either saved positions (tok ptok pptok, etc.) or | |
424 ;; of error reporting information. | |
425 ;; stack: The stack onto which the PDA pushes its state. Each entry | |
426 ;; consists of a saved value of state and saved-pos. An entry is | |
427 ;; pushed when we move back over a "continuation" token (e.g. else) | |
428 ;; and popped when we encounter the corresponding opening token | |
429 ;; (e.g. if). | |
430 ;; | |
431 ;; | |
432 ;; The following diagram briefly outlines the PDA. | |
169 ;; | 433 ;; |
170 ;; Common state: | 434 ;; Common state: |
171 ;; "else": Push state, goto state `else': | 435 ;; "else": Push state, goto state `else'. |
172 ;; boundary: Goto state `else-boundary': | 436 ;; "while": Push state, goto state `while'. |
173 ;; "if": Pop state. | 437 ;; "catch" or "finally": Push state, goto state `catch'. |
174 ;; boundary: Error, pop state. | 438 ;; boundary: Pop state. |
175 ;; other: See common state. | |
176 ;; other: Error, pop state, retry token. | |
177 ;; "while": Push state, goto state `while': | |
178 ;; boundary: Save position, goto state `while-boundary': | |
179 ;; "do": Pop state. | |
180 ;; boundary: Restore position if it's not at start, pop state. | |
181 ;; other: See common state. | |
182 ;; other: Pop state, retry token. | |
183 ;; "catch" or "finally": Push state, goto state `catch': | |
184 ;; boundary: Goto state `catch-boundary': | |
185 ;; "try": Pop state. | |
186 ;; "catch": Goto state `catch'. | |
187 ;; boundary: Error, pop state. | |
188 ;; other: See common state. | |
189 ;; other: Error, pop state, retry token. | |
190 ;; other: Do nothing special. | 439 ;; other: Do nothing special. |
440 ;; | |
441 ;; State `else': | |
442 ;; boundary: Goto state `else-boundary'. | |
443 ;; other: Error, pop state, retry token. | |
444 ;; | |
445 ;; State `else-boundary': | |
446 ;; "if": Pop state. | |
447 ;; boundary: Error, pop state. | |
448 ;; other: See common state. | |
449 ;; | |
450 ;; State `while': | |
451 ;; boundary: Save position, goto state `while-boundary'. | |
452 ;; other: Pop state, retry token. | |
453 ;; | |
454 ;; State `while-boundary': | |
455 ;; "do": Pop state. | |
456 ;; boundary: Restore position if it's not at start, pop state. [*see below] | |
457 ;; other: See common state. | |
458 ;; | |
459 ;; State `catch': | |
460 ;; boundary: Goto state `catch-boundary'. | |
461 ;; other: Error, pop state, retry token. | |
462 ;; | |
463 ;; State `catch-boundary': | |
464 ;; "try": Pop state. | |
465 ;; "catch": Goto state `catch'. | |
466 ;; boundary: Error, pop state. | |
467 ;; other: See common state. | |
468 ;; | |
469 ;; [*] In the `while-boundary' state, we had pushed a 'while state, and were | |
470 ;; searching for a "do" which would have opened a do-while. If we didn't | |
471 ;; find it, we discard the analysis done since the "while", go back to this | |
472 ;; token in the buffer and restart the scanning there, this time WITHOUT | |
473 ;; pushing the 'while state onto the stack. | |
191 ;; | 474 ;; |
192 ;; In addition to the above there is some special handling of labels | 475 ;; In addition to the above there is some special handling of labels |
193 ;; and macros. | 476 ;; and macros. |
194 | 477 |
195 (let ((case-fold-search nil) | 478 (let ((case-fold-search nil) |
198 (delims (if comma-delim '(?\; ?,) '(?\;))) | 481 (delims (if comma-delim '(?\; ?,) '(?\;))) |
199 (c-stmt-delim-chars (if comma-delim | 482 (c-stmt-delim-chars (if comma-delim |
200 c-stmt-delim-chars-with-comma | 483 c-stmt-delim-chars-with-comma |
201 c-stmt-delim-chars)) | 484 c-stmt-delim-chars)) |
202 pos ; Current position. | 485 pos ; Current position. |
203 boundary-pos ; Position of last boundary. | 486 boundary-pos ; Position of last stmt boundary character (e.g. ;). |
204 after-labels-pos ; Value of tok after first found colon. | 487 after-labels-pos ; Value of tok after first found colon. |
205 last-label-pos ; Value of tok after last found colon. | 488 last-label-pos ; Value of tok after last found colon. |
206 sym ; Current symbol in the alphabet. | 489 sym ; Symbol just scanned back over (e.g. 'while or |
207 state ; Current state in the automaton. | 490 ; 'boundary). See above |
208 saved-pos ; Current saved positions. | 491 state ; Current state in the automaton. See above. |
492 saved-pos ; Current saved positions. See above | |
209 stack ; Stack of conses (state . saved-pos). | 493 stack ; Stack of conses (state . saved-pos). |
210 (cond-key (or c-opt-block-stmt-key | 494 (cond-key (or c-opt-block-stmt-key ; regexp which matches "for", "if", etc. |
211 "\\<\\>")) ; Matches nothing. | 495 "\\<\\>")) ; Matches nothing. |
212 (ret 'same) | 496 (ret 'same) ; Return value. |
213 tok ptok pptok ; Pos of last three sexps or bounds. | 497 tok ptok pptok ; Pos of last three sexps or bounds. |
214 c-in-literal-cache c-maybe-labelp saved) | 498 c-in-literal-cache c-maybe-labelp saved) |
215 | 499 |
216 (save-restriction | 500 (save-restriction |
217 (if lim (narrow-to-region lim (point-max))) | 501 (if lim (narrow-to-region lim (point-max))) |
219 (if (save-excursion | 503 (if (save-excursion |
220 (and (c-beginning-of-macro) | 504 (and (c-beginning-of-macro) |
221 (/= (point) start))) | 505 (/= (point) start))) |
222 (setq macro-start (point))) | 506 (setq macro-start (point))) |
223 | 507 |
224 ;; Try to skip over unary operator characters, to register | 508 ;; Try to skip back over unary operator characters, to register |
225 ;; that we've moved. | 509 ;; that we've moved. |
226 (while (progn | 510 (while (progn |
227 (setq pos (point)) | 511 (setq pos (point)) |
228 (c-backward-syntactic-ws) | 512 (c-backward-syntactic-ws) ; might go back an awk-mode virtual semicolon, here. |
229 (/= (skip-chars-backward "-+!*&~@`#") 0))) | 513 ; How about using c-awk-NL-prop for AWK Mode, here. |
230 | 514 ; Something like c-awk-backward-syntactic-ws. |
231 ;; First check for bare semicolon. Later on we ignore the | 515 ; 2002/6/22. Doesn't matter! Leave it as it is. |
232 ;; boundaries for statements that doesn't contain any sexp. | 516 (/= (skip-chars-backward "-+!*&~@`#") 0))) ; ACM, 2002/5/31; |
233 ;; The only thing that is affected is that the error checking | 517 ; Make a variable in |
234 ;; is a little less strict, and we really don't bother. | 518 ; cc-langs.el, maybe |
519 | |
520 ;; Skip back over any semicolon here. If it was a bare semicolon, we're | |
521 ;; done. Later on we ignore the boundaries for statements that doesn't | |
522 ;; contain any sexp. The only thing that is affected is that the error | |
523 ;; checking is a little less strict, and we really don't bother. | |
235 (if (and (memq (char-before) delims) | 524 (if (and (memq (char-before) delims) |
236 (progn (forward-char -1) | 525 (progn (forward-char -1) |
237 (setq saved (point)) | 526 (setq saved (point)) |
238 (c-backward-syntactic-ws) | 527 (if (c-mode-is-new-awk-p) |
528 (c-awk-backward-syntactic-ws) | |
529 (c-backward-syntactic-ws)) | |
239 (or (memq (char-before) delims) | 530 (or (memq (char-before) delims) |
240 (memq (char-before) '(?: nil)) | 531 (memq (char-before) '(?: nil)) |
241 (eq (char-syntax (char-before)) ?\()))) | 532 (eq (char-syntax (char-before)) ?\() |
533 (and (c-mode-is-new-awk-p) | |
534 (c-awk-after-logical-semicolon))))) ; ACM 2002/6/22 | |
535 ;; ACM, 2002/7/20: What about giving a limit to the above function? | |
536 ;; ACM, 2003/6/16: The above two lines (checking for | |
537 ;; awk-logical-semicolon) are probably redundant after rewriting | |
538 ;; c-awk-backward-syntactic-ws. | |
242 (setq ret 'previous | 539 (setq ret 'previous |
243 pos saved) | 540 pos saved) |
244 | 541 |
245 ;; Begin at start and not pos to detect macros if we stand | 542 ;; Begin at start and not pos to detect macros if we stand |
246 ;; directly after the #. | 543 ;; directly after the #. |
247 (goto-char start) | 544 (goto-char start) |
248 (if (looking-at "\\<\\|\\W") | 545 (if (looking-at "\\<\\|\\W") |
249 ;; Record this as the first token if not starting inside it. | 546 ;; Record this as the first token if not starting inside it. |
250 (setq tok start)) | 547 (setq tok start)) |
251 | 548 |
549 ;; The following while loop goes back one sexp (balanced parens, | |
550 ;; etc. with contents, or symbol or suchlike) each iteration. This | |
551 ;; movement is accomplished with a call to scan-sexps approx 130 lines | |
552 ;; below. | |
252 (while | 553 (while |
253 (catch 'loop ;; Throw nil to break, non-nil to continue. | 554 (catch 'loop ;; Throw nil to break, non-nil to continue. |
254 (cond | 555 (cond |
255 ;; Check for macro start. | 556 ;; Check for macro start. Take this out for AWK Mode (ACM, 2002/5/31) |
557 ;; NO!! just make sure macro-start is nil in AWK Mode (ACM, 2002/6/22) | |
558 ;; It always is (ACM, 2002/6/23) | |
256 ((save-excursion | 559 ((save-excursion |
257 (and macro-start | 560 (and macro-start |
258 (looking-at "[ \t]*[a-zA-Z0-9!]") | |
259 (progn (skip-chars-backward " \t") | 561 (progn (skip-chars-backward " \t") |
260 (eq (char-before) ?#)) | 562 (eq (char-before) ?#)) |
261 (progn (setq saved (1- (point))) | 563 (progn (setq saved (1- (point))) |
262 (beginning-of-line) | 564 (beginning-of-line) |
263 (not (eq (char-before (1- (point))) ?\\))) | 565 (not (eq (char-before (1- (point))) ?\\))) |
566 (looking-at c-opt-cpp-start) | |
264 (progn (skip-chars-forward " \t") | 567 (progn (skip-chars-forward " \t") |
265 (eq (point) saved)))) | 568 (eq (point) saved)))) |
266 (goto-char saved) | 569 (goto-char saved) |
267 (if (and (c-forward-to-cpp-define-body) | 570 (if (and (c-forward-to-cpp-define-body) |
268 (progn (c-forward-syntactic-ws start) | 571 (progn (c-forward-syntactic-ws start) |
273 (setq pos saved | 576 (setq pos saved |
274 ret 'macro | 577 ret 'macro |
275 ignore-labels t)) | 578 ignore-labels t)) |
276 (throw 'loop nil)) | 579 (throw 'loop nil)) |
277 | 580 |
278 ;; Do a round through the automaton if we found a | 581 ;; Do a round through the automaton if we've just passed a |
279 ;; boundary or if looking at a statement keyword. | 582 ;; statement boundary or passed a "while"-like token. |
280 ((or sym | 583 ((or sym |
281 (and (looking-at cond-key) | 584 (and (looking-at cond-key) |
282 (setq sym (intern (match-string 1))))) | 585 (setq sym (intern (match-string 1))))) |
283 | 586 |
284 (when (and (< pos start) (null stack)) | 587 (when (and (< pos start) (null stack)) |
285 (throw 'loop nil)) | 588 (throw 'loop nil)) |
286 | 589 |
287 ;; The state handling. Continue in the common state for | 590 ;; The PDA state handling. |
288 ;; unhandled cases. | 591 ;; |
592 ;; Refer to the description of the PDA in the openining | |
593 ;; comments. In the following OR form, the first leaf | |
594 ;; attempts to handles one of the specific actions detailed | |
595 ;; (e.g., finding token "if" whilst in state `else-boundary'). | |
596 ;; We drop through to the second leaf (which handles common | |
597 ;; state) if no specific handler is found in the first cond. | |
598 ;; If a parsing error is detected (e.g. an "else" with no | |
599 ;; preceding "if"), we throw to the enclosing catch. | |
600 ;; | |
601 ;; Note that the (eq state 'else) means | |
602 ;; "we've just passed an else", NOT "we're looking for an | |
603 ;; else". | |
289 (or (cond | 604 (or (cond |
290 ((eq state 'else) | 605 ((eq state 'else) |
291 (if (eq sym 'boundary) | 606 (if (eq sym 'boundary) |
292 (setq state 'else-boundary) | 607 (setq state 'else-boundary) |
293 (c-bos-report-error) | 608 (c-bos-report-error) |
307 ;; If there's a label in front of the while | 622 ;; If there's a label in front of the while |
308 ;; it can't be part of a do-while. | 623 ;; it can't be part of a do-while. |
309 (not after-labels-pos)) | 624 (not after-labels-pos)) |
310 (progn (c-bos-save-pos) | 625 (progn (c-bos-save-pos) |
311 (setq state 'while-boundary)) | 626 (setq state 'while-boundary)) |
312 (c-bos-pop-state-and-retry))) | 627 (c-bos-pop-state-and-retry))) ; Can't be a do-while |
313 | 628 |
314 ((eq state 'while-boundary) | 629 ((eq state 'while-boundary) |
315 (cond ((eq sym 'do) | 630 (cond ((eq sym 'do) |
316 (c-bos-pop-state (setq ret 'beginning))) | 631 (c-bos-pop-state (setq ret 'beginning))) |
317 ((eq sym 'boundary) | 632 ((eq sym 'boundary) ; isn't a do-while |
318 (c-bos-restore-pos) | 633 (c-bos-restore-pos) ; the position of the while |
319 (c-bos-pop-state)))) | 634 (c-bos-pop-state)))) ; no longer searching for do. |
320 | 635 |
321 ((eq state 'catch) | 636 ((eq state 'catch) |
322 (if (eq sym 'boundary) | 637 (if (eq sym 'boundary) |
323 (setq state 'catch-boundary) | 638 (setq state 'catch-boundary) |
324 (c-bos-report-error) | 639 (c-bos-report-error) |
332 (setq state 'catch)) | 647 (setq state 'catch)) |
333 ((eq sym 'boundary) | 648 ((eq sym 'boundary) |
334 (c-bos-report-error) | 649 (c-bos-report-error) |
335 (c-bos-pop-state))))) | 650 (c-bos-pop-state))))) |
336 | 651 |
337 ;; This is state common. | 652 ;; This is state common. We get here when the previous |
653 ;; cond statement found no particular state handler. | |
338 (cond ((eq sym 'boundary) | 654 (cond ((eq sym 'boundary) |
339 (if (< pos start) | 655 ;; If we have a boundary at the start |
340 (c-bos-pop-state) | 656 ;; position we push a frame to go to the |
341 (c-bos-push-state))) | 657 ;; previous statement. |
658 (if (>= pos start) | |
659 (c-bos-push-state) | |
660 (c-bos-pop-state))) | |
342 ((eq sym 'else) | 661 ((eq sym 'else) |
343 (c-bos-push-state) | 662 (c-bos-push-state) |
344 (c-bos-save-error-info 'if 'else) | 663 (c-bos-save-error-info 'if 'else) |
345 (setq state 'else)) | 664 (setq state 'else)) |
346 ((eq sym 'while) | 665 ((eq sym 'while) |
347 (when (or (not pptok) | 666 (when (or (not pptok) |
348 (memq (char-after pptok) delims)) | 667 (memq (char-after pptok) delims) |
668 (and (c-mode-is-new-awk-p) | |
669 (or | |
670 ;; might we be calling this from | |
671 ;; c-awk-after-if-do-for-while-condition-p? | |
672 ;; If so, avoid infinite recursion. | |
673 (and (eq (point) start) | |
674 (c-awk-NL-prop-not-set)) | |
675 ;; The following may recursively | |
676 ;; call this function. | |
677 (c-awk-completed-stmt-ws-ends-line-p pptok)))) | |
349 ;; Since this can cause backtracking we do a | 678 ;; Since this can cause backtracking we do a |
350 ;; little more careful analysis to avoid it: If | 679 ;; little more careful analysis to avoid it: If |
351 ;; the while isn't followed by a semicolon it | 680 ;; the while isn't followed by a semicolon it |
352 ;; can't be a do-while. | 681 ;; can't be a do-while. |
682 ;; ACM, 2002/5/31; IT CAN IN AWK Mode. ;-( | |
353 (c-bos-push-state) | 683 (c-bos-push-state) |
354 (setq state 'while))) | 684 (setq state 'while))) |
355 ((memq sym '(catch finally)) | 685 ((memq sym '(catch finally)) |
356 (c-bos-push-state) | 686 (c-bos-push-state) |
357 (c-bos-save-error-info 'try sym) | 687 (c-bos-save-error-info 'try sym) |
363 ;; for the previous one. | 693 ;; for the previous one. |
364 (setq after-labels-pos nil | 694 (setq after-labels-pos nil |
365 last-label-pos nil | 695 last-label-pos nil |
366 c-maybe-labelp nil)))) | 696 c-maybe-labelp nil)))) |
367 | 697 |
368 ;; Step to next sexp, but not if we crossed a boundary, since | 698 ;; Step to the previous sexp, but not if we crossed a |
369 ;; that doesn't consume a sexp. | 699 ;; boundary, since that doesn't consume an sexp. |
370 (if (eq sym 'boundary) | 700 (if (eq sym 'boundary) |
371 (setq ret 'previous) | 701 (setq ret 'previous) |
702 | |
703 ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE | |
704 ;; BACKWARDS THROUGH THE SOURCE. The following loop goes back | |
705 ;; one sexp and then only loops in special circumstances (line | |
706 ;; continuations and skipping past entire macros). | |
372 (while | 707 (while |
373 (progn | 708 (progn |
374 (or (c-safe (goto-char (scan-sexps (point) -1)) t) | 709 (or (c-safe (goto-char (scan-sexps (point) -1)) t) |
710 ;; Give up if we hit an unbalanced block. | |
711 ;; Since the stack won't be empty the code | |
712 ;; below will report a suitable error. | |
375 (throw 'loop nil)) | 713 (throw 'loop nil)) |
376 (cond ((looking-at "\\\\$") | 714 (cond ((looking-at "\\\\$") |
377 ;; Step again if we hit a line continuation. | 715 ;; Step again if we hit a line continuation. |
378 t) | 716 t) |
379 (macro-start | 717 (macro-start |
380 ;; If we started inside a macro then this | 718 ;; If we started inside a macro then this |
381 ;; sexp is always interesting. | 719 ;; sexp is always interesting. |
382 nil) | 720 nil) |
383 (t | 721 ((not (c-mode-is-new-awk-p)) ; Changed from t, ACM 2002/6/25 |
384 ;; Otherwise check that we didn't step | 722 ;; Otherwise check that we didn't step |
385 ;; into a macro from the end. | 723 ;; into a macro from the end. |
386 (let ((macro-start | 724 (let ((macro-start |
387 (save-excursion | 725 (save-excursion |
388 (and (c-beginning-of-macro) | 726 (and (c-beginning-of-macro) |
389 (point))))) | 727 (point))))) |
390 (when macro-start | 728 (when macro-start |
391 (goto-char macro-start) | 729 (goto-char macro-start) |
392 t)))))) | 730 t)))))) |
393 | 731 |
394 ;; Check for statement boundary. | 732 ;; Did the last movement by a sexp cross a statement boundary? |
395 (when (save-excursion | 733 (when (save-excursion |
396 (if (if (eq (char-after) ?{) | 734 (if (if (eq (char-after) ?{) |
397 (c-looking-at-inexpr-block lim nil) | 735 (c-looking-at-inexpr-block lim nil) |
398 (eq (char-syntax (char-after)) ?\()) | 736 (looking-at "\\s\(")) |
399 ;; Need to move over parens and | 737 |
400 ;; in-expression blocks to get a good start | 738 ;; Should not include the paren sexp we've |
401 ;; position for the boundary check. | 739 ;; passed over in the boundary check. |
402 (c-forward-sexp 1)) | 740 (if (> (point) (- pos 100)) |
741 (c-forward-sexp 1) | |
742 | |
743 ;; Find its end position this way instead of | |
744 ;; moving forward if the sexp is large. | |
745 (goto-char pos) | |
746 (while | |
747 (progn | |
748 (goto-char (1+ (c-down-list-backward))) | |
749 (unless macro-start | |
750 ;; Check that we didn't step into | |
751 ;; a macro from the end. | |
752 (let ((macro-start | |
753 (save-excursion | |
754 (and (c-beginning-of-macro) | |
755 (point))))) | |
756 (when macro-start | |
757 (goto-char macro-start) | |
758 t))))))) | |
759 | |
403 (setq boundary-pos (c-crosses-statement-barrier-p | 760 (setq boundary-pos (c-crosses-statement-barrier-p |
404 (point) pos))) | 761 (point) pos))) |
762 | |
405 (setq pptok ptok | 763 (setq pptok ptok |
406 ptok tok | 764 ptok tok |
407 tok boundary-pos | 765 tok boundary-pos |
408 sym 'boundary) | 766 sym 'boundary) |
409 (throw 'loop t))) | 767 (throw 'loop t))) ; like a C "continue". Analyze the next sexp. |
410 | 768 |
411 (when (and (numberp c-maybe-labelp) (not ignore-labels)) | 769 (when (and (numberp c-maybe-labelp) (not ignore-labels)) |
412 ;; c-crosses-statement-barrier-p has found a colon, so | 770 ;; c-crosses-statement-barrier-p has found a colon, so |
413 ;; we might be in a label now. | 771 ;; we might be in a label now. |
414 (if (not after-labels-pos) | 772 (if (not after-labels-pos) |
421 (setq saved (c-in-method-def-p))) | 779 (setq saved (c-in-method-def-p))) |
422 (setq pos saved | 780 (setq pos saved |
423 ignore-labels t) ; Avoid the label check on exit. | 781 ignore-labels t) ; Avoid the label check on exit. |
424 (throw 'loop nil)) | 782 (throw 'loop nil)) |
425 | 783 |
784 ;; We've moved back by a sexp, so update the token positions. | |
426 (setq sym nil | 785 (setq sym nil |
427 pptok ptok | 786 pptok ptok |
428 ptok tok | 787 ptok tok |
429 tok (point) | 788 tok (point) |
430 pos tok))) ; Not nil. | 789 pos tok))) ; Not nil (for the while loop). |
431 | 790 |
432 ;; If the stack isn't empty there might be errors to report. | 791 ;; If the stack isn't empty there might be errors to report. |
433 (while stack | 792 (while stack |
434 (if (and (vectorp saved-pos) (eq (length saved-pos) 3)) | 793 (if (and (vectorp saved-pos) (eq (length saved-pos) 3)) |
435 (c-bos-report-error)) | 794 (c-bos-report-error)) |
444 ptok | 803 ptok |
445 pptok)) | 804 pptok)) |
446 (cond ((> start saved) (setq pos saved)) | 805 (cond ((> start saved) (setq pos saved)) |
447 ((= start saved) (setq ret 'up))))) | 806 ((= start saved) (setq ret 'up))))) |
448 | 807 |
449 (when (and c-maybe-labelp (not ignore-labels) after-labels-pos) | 808 (when (and c-maybe-labelp |
809 (not ignore-labels) | |
810 (not (eq ret 'beginning)) | |
811 after-labels-pos) | |
450 ;; We're in a label. Maybe we should step to the statement | 812 ;; We're in a label. Maybe we should step to the statement |
451 ;; after it. | 813 ;; after it. |
452 (if (< after-labels-pos start) | 814 (if (< after-labels-pos start) |
453 (setq pos after-labels-pos) | 815 (setq pos after-labels-pos) |
454 (setq ret 'label) | 816 (setq ret 'label) |
457 | 819 |
458 ;; Skip over the unary operators that can start the statement. | 820 ;; Skip over the unary operators that can start the statement. |
459 (goto-char pos) | 821 (goto-char pos) |
460 (while (progn | 822 (while (progn |
461 (c-backward-syntactic-ws) | 823 (c-backward-syntactic-ws) |
462 (/= (skip-chars-backward "-+!*&~@`#") 0)) | 824 (/= (skip-chars-backward "-+!*&~@`#") 0)) ; Hopefully the # won't hurt awk. |
463 (setq pos (point))) | 825 (setq pos (point))) |
464 (goto-char pos) | 826 (goto-char pos) |
465 ret))) | 827 ret))) |
466 | 828 |
467 (defun c-crosses-statement-barrier-p (from to) | 829 (defun c-crosses-statement-barrier-p (from to) |
468 "Return non-nil if buffer positions FROM to TO cross one or more | 830 "Return non-nil if buffer positions FROM to TO cross one or more |
469 statement or declaration boundaries. The returned value is actually | 831 statement or declaration boundaries. The returned value is actually |
470 the position of the earliest boundary char. | 832 the position of the earliest boundary char. FROM must not be within |
833 a string or comment. | |
471 | 834 |
472 The variable `c-maybe-labelp' is set to the position of the first `:' that | 835 The variable `c-maybe-labelp' is set to the position of the first `:' that |
473 might start a label (i.e. not part of `::' and not preceded by `?'). If a | 836 might start a label (i.e. not part of `::' and not preceded by `?'). If a |
474 single `?' is found, then `c-maybe-labelp' is cleared." | 837 single `?' is found, then `c-maybe-labelp' is cleared." |
475 (let ((skip-chars c-stmt-delim-chars) | 838 (let ((skip-chars c-stmt-delim-chars) |
477 (save-excursion | 840 (save-excursion |
478 (catch 'done | 841 (catch 'done |
479 (goto-char from) | 842 (goto-char from) |
480 (while (progn (skip-chars-forward skip-chars to) | 843 (while (progn (skip-chars-forward skip-chars to) |
481 (< (point) to)) | 844 (< (point) to)) |
482 (if (setq lit-range (c-literal-limits from)) | 845 (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? |
483 (goto-char (setq from (cdr lit-range))) | 846 (progn (goto-char (setq from (cdr lit-range))) |
847 (if (and (c-mode-is-new-awk-p) (bolp)) ; ACM 2002/7/17. Make sure we | |
848 (backward-char))) ; don't skip over a virtual semi-colon after an awk comment. :-( | |
484 (cond ((eq (char-after) ?:) | 849 (cond ((eq (char-after) ?:) |
485 (forward-char) | 850 (forward-char) |
486 (if (and (eq (char-after) ?:) | 851 (if (and (eq (char-after) ?:) |
487 (< (point) to)) | 852 (< (point) to)) |
488 ;; Ignore scope operators. | 853 ;; Ignore scope operators. |
491 ((eq (char-after) ??) | 856 ((eq (char-after) ??) |
492 ;; A question mark. Can't be a label, so stop | 857 ;; A question mark. Can't be a label, so stop |
493 ;; looking for more : and ?. | 858 ;; looking for more : and ?. |
494 (setq c-maybe-labelp nil | 859 (setq c-maybe-labelp nil |
495 skip-chars (substring c-stmt-delim-chars 0 -2))) | 860 skip-chars (substring c-stmt-delim-chars 0 -2))) |
861 ((and (eolp) ; Can only happen in AWK Mode | |
862 (not (c-awk-completed-stmt-ws-ends-line-p))) | |
863 (forward-char)) | |
864 ((and (c-mode-is-new-awk-p) | |
865 (bolp) lit-range ; awk: comment/string ended prev line. | |
866 (not (c-awk-completed-stmt-ws-ends-prev-line-p)))) | |
496 (t (throw 'done (point)))))) | 867 (t (throw 'done (point)))))) |
497 nil)))) | 868 nil)))) |
498 | 869 |
499 | 870 |
871 ;; A set of functions that covers various idiosyncrasies in | |
872 ;; implementations of `forward-comment'. | |
873 | |
874 ;; Note: Some emacsen considers incorrectly that any line comment | |
875 ;; ending with a backslash continues to the next line. I can't think | |
876 ;; of any way to work around that in a reliable way without changing | |
877 ;; the buffer, though. Suggestions welcome. ;) (No, temporarily | |
878 ;; changing the syntax for backslash doesn't work since we must treat | |
879 ;; escapes in string literals correctly.) | |
880 | |
881 (defun c-forward-single-comment () | |
882 "Move forward past whitespace and the closest following comment, if any. | |
883 Return t if a comment was found, nil otherwise. In either case, the | |
884 point is moved past the following whitespace. Line continuations, | |
885 i.e. a backslashes followed by line breaks, are treated as whitespace. | |
886 The line breaks that end line comments are considered to be the | |
887 comment enders, so the point will be put on the beginning of the next | |
888 line if it moved past a line comment. | |
889 | |
890 This function does not do any hidden buffer changes." | |
891 | |
892 (let ((start (point))) | |
893 (when (looking-at "\\([ \t\n\r\f\v]\\|\\\\[\n\r]\\)+") | |
894 (goto-char (match-end 0))) | |
895 | |
896 (when (forward-comment 1) | |
897 (if (eobp) | |
898 ;; Some emacsen (e.g. XEmacs 21) return t when moving | |
899 ;; forwards at eob. | |
900 nil | |
901 | |
902 ;; Emacs includes the ending newline in a b-style (c++) | |
903 ;; comment, but XEmacs doesn't. We depend on the Emacs | |
904 ;; behavior (which also is symmetric). | |
905 (if (and (eolp) (elt (parse-partial-sexp start (point)) 7)) | |
906 (condition-case nil (forward-char 1))) | |
907 | |
908 t)))) | |
909 | |
910 (defsubst c-forward-comments () | |
911 "Move forward past all following whitespace and comments. | |
912 Line continuations, i.e. a backslashes followed by line breaks, are | |
913 treated as whitespace. | |
914 | |
915 This function does not do any hidden buffer changes." | |
916 | |
917 (while (or | |
918 ;; If forward-comment in at least XEmacs 21 is given a large | |
919 ;; positive value, it'll loop all the way through if it hits | |
920 ;; eob. | |
921 (and (forward-comment 5) | |
922 ;; Some emacsen (e.g. XEmacs 21) return t when moving | |
923 ;; forwards at eob. | |
924 (not (eobp))) | |
925 | |
926 (when (looking-at "\\\\[\n\r]") | |
927 (forward-char 2) | |
928 t)))) | |
929 | |
930 (defun c-backward-single-comment () | |
931 "Move backward past whitespace and the closest preceding comment, if any. | |
932 Return t if a comment was found, nil otherwise. In either case, the | |
933 point is moved past the preceding whitespace. Line continuations, | |
934 i.e. a backslashes followed by line breaks, are treated as whitespace. | |
935 The line breaks that end line comments are considered to be the | |
936 comment enders, so the point cannot be at the end of the same line to | |
937 move over a line comment. | |
938 | |
939 This function does not do any hidden buffer changes." | |
940 | |
941 (let ((start (point))) | |
942 ;; When we got newline terminated comments, forward-comment in all | |
943 ;; supported emacsen so far will stop at eol of each line not | |
944 ;; ending with a comment when moving backwards. This corrects for | |
945 ;; that, and at the same time handles line continuations. | |
946 (while (progn | |
947 (skip-chars-backward " \t\n\r\f\v") | |
948 (and (looking-at "[\n\r]") | |
949 (eq (char-before) ?\\) | |
950 (< (point) start))) | |
951 (backward-char)) | |
952 | |
953 (if (bobp) | |
954 ;; Some emacsen (e.g. Emacs 19.34) return t when moving | |
955 ;; backwards at bob. | |
956 nil | |
957 | |
958 ;; Leave point after the closest following newline if we've | |
959 ;; backed up over any above, since forward-comment won't move | |
960 ;; backward over a line comment if point is at the end of the | |
961 ;; same line. | |
962 (re-search-forward "\\=\\s *[\n\r]" start t) | |
963 | |
964 (if (if (forward-comment -1) | |
965 (if (eolp) | |
966 ;; If forward-comment above succeeded and we're at eol | |
967 ;; then the newline we moved over above didn't end a | |
968 ;; line comment, so we give it another go. | |
969 (forward-comment -1) | |
970 t)) | |
971 | |
972 ;; Emacs <= 20 and XEmacs move back over the closer of a | |
973 ;; block comment that lacks an opener. | |
974 (if (looking-at "\\*/") | |
975 (progn (forward-char 2) nil) | |
976 t))))) | |
977 | |
978 (defsubst c-backward-comments () | |
979 "Move backward past all preceding whitespace and comments. | |
980 Line continuations, i.e. a backslashes followed by line breaks, are | |
981 treated as whitespace. The line breaks that end line comments are | |
982 considered to be the comment enders, so the point cannot be at the end | |
983 of the same line to move over a line comment. | |
984 | |
985 This function does not do any hidden buffer changes." | |
986 | |
987 (let ((start (point))) | |
988 (while (and | |
989 ;; `forward-comment' in some emacsen (e.g. Emacs 19.34) | |
990 ;; return t when moving backwards at bob. | |
991 (not (bobp)) | |
992 | |
993 (if (forward-comment -1) | |
994 (if (looking-at "\\*/") | |
995 ;; Emacs <= 20 and XEmacs move back over the | |
996 ;; closer of a block comment that lacks an opener. | |
997 (progn (forward-char 2) nil) | |
998 t) | |
999 | |
1000 ;; XEmacs treats line continuations as whitespace but | |
1001 ;; only in the backward direction, which seems a bit | |
1002 ;; odd. Anyway, this is necessary for Emacs. | |
1003 (when (and (looking-at "[\n\r]") | |
1004 (eq (char-before) ?\\) | |
1005 (< (point) start)) | |
1006 (backward-char) | |
1007 t)))))) | |
1008 | |
1009 | |
1010 ;; Basic handling of preprocessor directives. | |
1011 | |
500 ;; This is a dynamically bound cache used together with | 1012 ;; This is a dynamically bound cache used together with |
501 ;; c-query-macro-start and c-query-and-set-macro-start. It only works | 1013 ;; `c-query-macro-start' and `c-query-and-set-macro-start'. It only |
502 ;; as long as point doesn't cross a macro boundary. | 1014 ;; works as long as point doesn't cross a macro boundary. |
503 (defvar c-macro-start 'unknown) | 1015 (defvar c-macro-start 'unknown) |
504 | 1016 |
505 (defsubst c-query-and-set-macro-start () | 1017 (defsubst c-query-and-set-macro-start () |
1018 ;; This function does not do any hidden buffer changes. | |
506 (if (symbolp c-macro-start) | 1019 (if (symbolp c-macro-start) |
507 (setq c-macro-start (save-excursion | 1020 (setq c-macro-start (save-excursion |
508 (and (c-beginning-of-macro) | 1021 (and (c-beginning-of-macro) |
509 (point)))) | 1022 (point)))) |
510 c-macro-start)) | 1023 c-macro-start)) |
511 | 1024 |
512 (defsubst c-query-macro-start () | 1025 (defsubst c-query-macro-start () |
1026 ;; This function does not do any hidden buffer changes. | |
513 (if (symbolp c-macro-start) | 1027 (if (symbolp c-macro-start) |
514 (save-excursion | 1028 (save-excursion |
515 (and (c-beginning-of-macro) | 1029 (and (c-beginning-of-macro) |
516 (point))) | 1030 (point))) |
517 c-macro-start)) | 1031 c-macro-start)) |
518 | 1032 |
519 (defun c-beginning-of-macro (&optional lim) | 1033 (defun c-beginning-of-macro (&optional lim) |
520 "Go to the beginning of a cpp macro definition. | 1034 "Go to the beginning of a preprocessor directive. |
521 Leave point at the beginning of the macro and return t if in a cpp | 1035 Leave point at the beginning of the directive and return t if in one, |
522 macro definition, otherwise return nil and leave point unchanged." | 1036 otherwise return nil and leave point unchanged. |
523 (let ((here (point))) | 1037 |
524 (save-restriction | 1038 This function does not do any hidden buffer changes." |
525 (if lim (narrow-to-region lim (point-max))) | 1039 (when c-opt-cpp-prefix |
526 (beginning-of-line) | 1040 (let ((here (point))) |
527 (while (eq (char-before (1- (point))) ?\\) | 1041 (save-restriction |
528 (forward-line -1)) | 1042 (if lim (narrow-to-region lim (point-max))) |
529 (back-to-indentation) | 1043 (beginning-of-line) |
530 (if (and (<= (point) here) | 1044 (while (eq (char-before (1- (point))) ?\\) |
531 (looking-at "#[ \t]*[a-zA-Z0-9!]")) | 1045 (forward-line -1)) |
532 t | 1046 (back-to-indentation) |
533 (goto-char here) | 1047 (if (and (<= (point) here) |
534 nil)))) | 1048 (looking-at c-opt-cpp-start)) |
1049 t | |
1050 (goto-char here) | |
1051 nil))))) | |
535 | 1052 |
536 (defun c-end-of-macro () | 1053 (defun c-end-of-macro () |
537 "Go to the end of a cpp macro definition. | 1054 "Go to the end of a preprocessor directive. |
538 More accurately, move point to the end of the closest following line | 1055 More accurately, move point to the end of the closest following line |
539 that doesn't end with a line continuation backslash." | 1056 that doesn't end with a line continuation backslash. |
1057 | |
1058 This function does not do any hidden buffer changes." | |
540 (while (progn | 1059 (while (progn |
541 (end-of-line) | 1060 (end-of-line) |
542 (when (and (eq (char-before) ?\\) | 1061 (when (and (eq (char-before) ?\\) |
543 (not (eobp))) | 1062 (not (eobp))) |
544 (forward-char) | 1063 (forward-char) |
545 t)))) | 1064 t)))) |
546 | 1065 |
547 (defun c-forward-comment (count) | 1066 (defun c-forward-to-cpp-define-body () |
548 ;; Insulation from various idiosyncrasies in implementations of | 1067 ;; Assuming point is at the "#" that introduces a preprocessor |
549 ;; `forward-comment'. | 1068 ;; directive, it's moved forward to the start of the definition body |
550 ;; | 1069 ;; if it's a "#define". Non-nil is returned in this case, in all |
551 ;; Note: Some emacsen considers incorrectly that any line comment | 1070 ;; other cases nil is returned and point isn't moved. |
552 ;; ending with a backslash continues to the next line. I can't | 1071 (when (and (looking-at |
553 ;; think of any way to work around that in a reliable way without | 1072 (concat "#[ \t]*" |
554 ;; changing the buffer, though. Suggestions welcome. ;) (No, | 1073 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?" |
555 ;; temporarily changing the syntax for backslash doesn't work since | 1074 "\\([ \t]\\|\\\\\n\\)*")) |
556 ;; we must treat escapes in string literals correctly.) | 1075 (not (= (match-end 0) (c-point 'eol)))) |
557 ;; | 1076 (goto-char (match-end 0)))) |
558 ;; Another note: When moving backwards over a block comment, there's | 1077 |
559 ;; a bug in forward-comment that can make it stop at "/*" inside a | 1078 |
560 ;; line comment. Haven't yet found a reasonably cheap way to kludge | 1079 ;; Tools for skipping over syntactic whitespace. |
561 ;; around that one either. :\ | 1080 |
562 (let ((here (point))) | 1081 ;; The following functions use text properties to cache searches over |
563 (if (>= count 0) | 1082 ;; large regions of syntactic whitespace. It works as follows: |
564 (when (forward-comment count) | 1083 ;; |
565 (if (eobp) | 1084 ;; o If a syntactic whitespace region contains anything but simple |
566 ;; Some emacsen (e.g. XEmacs 21) return t when moving | 1085 ;; whitespace (i.e. space, tab and line breaks), the text property |
567 ;; forwards at eob. | 1086 ;; `c-in-sws' is put over it. At places where we have stopped |
568 nil | 1087 ;; within that region there's also a `c-is-sws' text property. |
569 ;; Emacs includes the ending newline in a b-style (c++) | 1088 ;; That since there typically are nested whitespace inside that |
570 ;; comment, but XEmacs doesn't. We depend on the Emacs | 1089 ;; must be handled separately, e.g. whitespace inside a comment or |
571 ;; behavior (which also is symmetric). | 1090 ;; cpp directive. Thus, from one point with `c-is-sws' it's safe |
572 (if (and (eolp) (nth 7 (parse-partial-sexp here (point)))) | 1091 ;; to jump to another point with that property within the same |
573 (condition-case nil (forward-char 1))) | 1092 ;; `c-in-sws' region. It can be likened to a ladder where |
574 t)) | 1093 ;; `c-in-sws' marks the bars and `c-is-sws' the rungs. |
575 ;; When we got newline terminated comments, | 1094 ;; |
576 ;; forward-comment in all supported emacsen so far will | 1095 ;; o The `c-is-sws' property is put on the simple whitespace chars at |
577 ;; stop at eol of each line not ending with a comment when | 1096 ;; a "rung position" and also maybe on the first following char. |
578 ;; moving backwards. The following corrects for it when | 1097 ;; As many characters as can be conveniently found in this range |
579 ;; count is -1. The other common case, when count is | 1098 ;; are marked, but no assumption can be made that the whole range |
580 ;; large and negative, works regardless. It's too much | 1099 ;; is marked (it could be clobbered by later changes, for |
581 ;; work to correct for the rest of the cases. | 1100 ;; instance). |
582 (skip-chars-backward " \t\n\r\f") | 1101 ;; |
583 (if (bobp) | 1102 ;; Note that some part of the beginning of a sequence of simple |
584 ;; Some emacsen return t when moving backwards at bob. | 1103 ;; whitespace might be part of the end of a preceding line comment |
585 nil | 1104 ;; or cpp directive and must not be considered part of the "rung". |
586 (re-search-forward "[\n\r]" here t) | 1105 ;; Such whitespace is some amount of horizontal whitespace followed |
587 (let* ((res (if (forward-comment count) | 1106 ;; by a newline. In the case of cpp directives it could also be |
588 (if (eolp) (forward-comment -1) t))) | 1107 ;; two newlines with horizontal whitespace between them. |
589 (savepos (point))) | 1108 ;; |
590 ;; XEmacs treats line continuations as whitespace (but only | 1109 ;; The reason to include the first following char is to cope with |
591 ;; in the backward direction). | 1110 ;; "rung positions" that doesn't have any ordinary whitespace. If |
592 (while (and (progn (end-of-line) (< (point) here)) | 1111 ;; `c-is-sws' is put on a token character it does not have |
593 (eq (char-before) ?\\)) | 1112 ;; `c-in-sws' set simultaneously. That's the only case when that |
594 (setq res nil | 1113 ;; can occur, and the reason for not extending the `c-in-sws' |
595 savepos (point)) | 1114 ;; region to cover it is that the `c-in-sws' region could then be |
596 (forward-line)) | 1115 ;; accidentally merged with a following one if the token is only |
597 (goto-char savepos) | 1116 ;; one character long. |
598 res))))) | 1117 ;; |
599 | 1118 ;; o On buffer changes the `c-in-sws' and `c-is-sws' properties are |
600 (defun c-forward-comment-lc (count) | 1119 ;; removed in the changed region. If the change was inside |
601 ;; Like `c-forward-comment', but treat line continuations as | 1120 ;; syntactic whitespace that means that the "ladder" is broken, but |
602 ;; whitespace. | 1121 ;; a later call to `c-forward-sws' or `c-backward-sws' will use the |
603 (catch 'done | 1122 ;; parts on either side and use an ordinary search only to "repair" |
604 (if (> count 0) | 1123 ;; the gap. |
605 (while (if (c-forward-comment 1) | 1124 ;; |
606 (progn | 1125 ;; Special care needs to be taken if a region is removed: If there |
607 (setq count (1- count)) | 1126 ;; are `c-in-sws' on both sides of it which do not connect inside |
608 (> count 0)) | 1127 ;; the region then they can't be joined. If e.g. a marked macro is |
609 (if (looking-at "\\\\$") | 1128 ;; broken, syntactic whitespace inside the new text might be |
610 (progn | 1129 ;; marked. If those marks would become connected with the old |
611 (forward-char) | 1130 ;; `c-in-sws' range around the macro then we could get a ladder |
612 t) | 1131 ;; with one end outside the macro and the other at some whitespace |
613 (throw 'done nil)))) | 1132 ;; within it. |
614 (while (if (c-forward-comment -1) | 1133 ;; |
615 (progn | 1134 ;; The main motivation for this system is to increase the speed in |
616 (setq count (1+ count)) | 1135 ;; skipping over the large whitespace regions that can occur at the |
617 (< count 0)) | 1136 ;; top level in e.g. header files that contain a lot of comments and |
618 (if (and (eolp) (eq (char-before) ?\\)) | 1137 ;; cpp directives. For small comments inside code it's probably |
619 (progn | 1138 ;; slower than using `forward-comment' straightforwardly, but speed is |
620 (backward-char) | 1139 ;; not a significant factor there anyway. |
621 t) | 1140 |
622 (throw 'done nil))))) | 1141 ; (defface c-debug-is-sws-face |
623 t)) | 1142 ; '((t (:background "GreenYellow"))) |
624 | 1143 ; "Debug face to mark the `c-is-sws' property.") |
625 (defun c-forward-syntactic-ws (&optional lim) | 1144 ; (defface c-debug-in-sws-face |
626 "Forward skip of syntactic whitespace. | 1145 ; '((t (:underline t))) |
627 Syntactic whitespace is defined as whitespace characters, comments, | 1146 ; "Debug face to mark the `c-in-sws' property.") |
628 and preprocessor directives. However if point starts inside a comment | 1147 |
629 or preprocessor directive, the content of it is not treated as | 1148 ; (defun c-debug-put-sws-faces () |
630 whitespace. LIM sets an upper limit of the forward movement, if | 1149 ; ;; Put the sws debug faces on all the `c-is-sws' and `c-in-sws' |
631 specified." | 1150 ; ;; properties in the buffer. |
632 (let ((here (point-max))) | 1151 ; (interactive) |
633 (or lim (setq lim here)) | 1152 ; (save-excursion |
634 (while (/= here (point)) | 1153 ; (let (in-face) |
635 ;; If forward-comment in at least XEmacs 21 is given a large | 1154 ; (goto-char (point-min)) |
636 ;; positive value, it'll loop all the way through if it hits eob. | 1155 ; (setq in-face (if (get-text-property (point) 'c-is-sws) |
637 (while (c-forward-comment 5)) | 1156 ; (point))) |
638 (setq here (point)) | 1157 ; (while (progn |
639 (cond | 1158 ; (goto-char (next-single-property-change |
640 ;; Skip line continuations. | 1159 ; (point) 'c-is-sws nil (point-max))) |
641 ((looking-at "\\\\$") | 1160 ; (if in-face |
642 (forward-char)) | 1161 ; (progn |
643 ;; Skip preprocessor directives. | 1162 ; (c-debug-add-face in-face (point) 'c-debug-is-sws-face) |
644 ((and (looking-at "#[ \t]*[a-zA-Z0-9!]") | 1163 ; (setq in-face nil)) |
1164 ; (setq in-face (point))) | |
1165 ; (not (eobp)))) | |
1166 ; (goto-char (point-min)) | |
1167 ; (setq in-face (if (get-text-property (point) 'c-in-sws) | |
1168 ; (point))) | |
1169 ; (while (progn | |
1170 ; (goto-char (next-single-property-change | |
1171 ; (point) 'c-in-sws nil (point-max))) | |
1172 ; (if in-face | |
1173 ; (progn | |
1174 ; (c-debug-add-face in-face (point) 'c-debug-in-sws-face) | |
1175 ; (setq in-face nil)) | |
1176 ; (setq in-face (point))) | |
1177 ; (not (eobp))))))) | |
1178 | |
1179 (defmacro c-debug-sws-msg (&rest args) | |
1180 ;;`(message ,@args) | |
1181 ) | |
1182 | |
1183 (defmacro c-put-is-sws (beg end) | |
1184 `(let ((beg ,beg) (end ,end)) | |
1185 (put-text-property beg end 'c-is-sws t) | |
1186 ,@(when (facep 'c-debug-is-sws-face) | |
1187 `((c-debug-add-face beg end 'c-debug-is-sws-face))))) | |
1188 | |
1189 (defmacro c-put-in-sws (beg end) | |
1190 `(let ((beg ,beg) (end ,end)) | |
1191 (put-text-property beg end 'c-in-sws t) | |
1192 ,@(when (facep 'c-debug-is-sws-face) | |
1193 `((c-debug-add-face beg end 'c-debug-in-sws-face))))) | |
1194 | |
1195 (defmacro c-remove-is-sws (beg end) | |
1196 `(let ((beg ,beg) (end ,end)) | |
1197 (remove-text-properties beg end '(c-is-sws nil)) | |
1198 ,@(when (facep 'c-debug-is-sws-face) | |
1199 `((c-debug-remove-face beg end 'c-debug-is-sws-face))))) | |
1200 | |
1201 (defmacro c-remove-in-sws (beg end) | |
1202 `(let ((beg ,beg) (end ,end)) | |
1203 (remove-text-properties beg end '(c-in-sws nil)) | |
1204 ,@(when (facep 'c-debug-is-sws-face) | |
1205 `((c-debug-remove-face beg end 'c-debug-in-sws-face))))) | |
1206 | |
1207 (defmacro c-remove-is-and-in-sws (beg end) | |
1208 `(let ((beg ,beg) (end ,end)) | |
1209 (remove-text-properties beg end '(c-is-sws nil c-in-sws nil)) | |
1210 ,@(when (facep 'c-debug-is-sws-face) | |
1211 `((c-debug-remove-face beg end 'c-debug-is-sws-face) | |
1212 (c-debug-remove-face beg end 'c-debug-in-sws-face))))) | |
1213 | |
1214 (defsubst c-invalidate-sws-region-after (beg end) | |
1215 ;; Called from `after-change-functions'. Note that if | |
1216 ;; `c-forward-sws' or `c-backward-sws' are used outside | |
1217 ;; `c-save-buffer-state' or similar then this will remove the cache | |
1218 ;; properties right after they're added. | |
1219 | |
1220 (save-excursion | |
1221 ;; Adjust the end to remove the properties in any following simple | |
1222 ;; ws up to and including the next line break, if there is any | |
1223 ;; after the changed region. This is necessary e.g. when a rung | |
1224 ;; marked empty line is converted to a line comment by inserting | |
1225 ;; "//" before the line break. In that case the line break would | |
1226 ;; keep the rung mark which could make a later `c-backward-sws' | |
1227 ;; move into the line comment instead of over it. | |
1228 (goto-char end) | |
1229 (skip-chars-forward " \t\f\v") | |
1230 (when (and (eolp) (not (eobp))) | |
1231 (setq end (1+ (point))))) | |
1232 | |
1233 (when (and (= beg end) | |
1234 (get-text-property beg 'c-in-sws) | |
1235 (not (bobp)) | |
1236 (get-text-property (1- beg) 'c-in-sws)) | |
1237 ;; Ensure that an `c-in-sws' range gets broken. Note that it isn't | |
1238 ;; safe to keep a range that was continuous before the change. E.g: | |
1239 ;; | |
1240 ;; #define foo | |
1241 ;; \ | |
1242 ;; bar | |
1243 ;; | |
1244 ;; There can be a "ladder" between "#" and "b". Now, if the newline | |
1245 ;; after "foo" is removed then "bar" will become part of the cpp | |
1246 ;; directive instead of a syntactically relevant token. In that | |
1247 ;; case there's no longer syntactic ws from "#" to "b". | |
1248 (setq beg (1- beg))) | |
1249 | |
1250 (c-debug-sws-msg "c-invalidate-sws-region-after [%s..%s]" beg end) | |
1251 (c-remove-is-and-in-sws beg end)) | |
1252 | |
1253 (defun c-forward-sws () | |
1254 ;; Used by `c-forward-syntactic-ws' to implement the unbounded search. | |
1255 | |
1256 (let (;; `rung-pos' is set to a position as early as possible in the | |
1257 ;; unmarked part of the simple ws region. | |
1258 (rung-pos (point)) next-rung-pos rung-end-pos last-put-in-sws-pos | |
1259 rung-is-marked next-rung-is-marked simple-ws-end | |
1260 ;; `safe-start' is set when it's safe to cache the start position. | |
1261 ;; It's not set if we've initially skipped over comments and line | |
1262 ;; continuations since we might have gone out through the end of a | |
1263 ;; macro then. This provision makes `c-forward-sws' not populate the | |
1264 ;; cache in the majority of cases, but otoh is `c-backward-sws' by far | |
1265 ;; more common. | |
1266 safe-start) | |
1267 | |
1268 ;; Skip simple ws and do a quick check on the following character to see | |
1269 ;; if it's anything that can't start syntactic ws, so we can bail out | |
1270 ;; early in the majority of cases when there just are a few ws chars. | |
1271 (skip-chars-forward " \t\n\r\f\v") | |
1272 (when (looking-at c-syntactic-ws-start) | |
1273 | |
1274 (setq rung-end-pos (min (1+ (point)) (point-max))) | |
1275 (if (setq rung-is-marked (text-property-any rung-pos rung-end-pos | |
1276 'c-is-sws t)) | |
1277 ;; Find the last rung position to avoid setting properties in all | |
1278 ;; the cases when the marked rung is complete. | |
1279 ;; (`next-single-property-change' is certain to move at least one | |
1280 ;; step forward.) | |
1281 (setq rung-pos (1- (next-single-property-change | |
1282 rung-is-marked 'c-is-sws nil rung-end-pos))) | |
1283 ;; Got no marked rung here. Since the simple ws might have started | |
1284 ;; inside a line comment or cpp directive we must set `rung-pos' as | |
1285 ;; high as possible. | |
1286 (setq rung-pos (point))) | |
1287 | |
1288 (while | |
1289 (progn | |
1290 (while | |
1291 (when (and rung-is-marked | |
1292 (get-text-property (point) 'c-in-sws)) | |
1293 | |
1294 ;; The following search is the main reason that `c-in-sws' | |
1295 ;; and `c-is-sws' aren't combined to one property. | |
1296 (goto-char (next-single-property-change | |
1297 (point) 'c-in-sws nil (point-max))) | |
1298 (unless (get-text-property (point) 'c-is-sws) | |
1299 ;; If the `c-in-sws' region extended past the last | |
1300 ;; `c-is-sws' char we have to go back a bit. | |
1301 (or (get-text-property (1- (point)) 'c-is-sws) | |
1302 (goto-char (previous-single-property-change | |
1303 (point) 'c-is-sws))) | |
1304 (backward-char)) | |
1305 | |
1306 (c-debug-sws-msg | |
1307 "c-forward-sws cached move %s -> %s (max %s)" | |
1308 rung-pos (point) (point-max)) | |
1309 | |
1310 (setq rung-pos (point)) | |
1311 (and (> (skip-chars-forward " \t\n\r\f\v") 0) | |
1312 (not (eobp)))) | |
1313 | |
1314 ;; We'll loop here if there is simple ws after the last rung. | |
1315 ;; That means that there's been some change in it and it's | |
1316 ;; possible that we've stepped into another ladder, so extend | |
1317 ;; the previous one to join with it if there is one, and try to | |
1318 ;; use the cache again. | |
1319 (c-debug-sws-msg | |
1320 "c-forward-sws extending rung with [%s..%s] (max %s)" | |
1321 (1+ rung-pos) (1+ (point)) (point-max)) | |
1322 (unless (get-text-property (point) 'c-is-sws) | |
1323 ;; Remove any `c-in-sws' property from the last char of | |
1324 ;; the rung before we mark it with `c-is-sws', so that we | |
1325 ;; won't connect with the remains of a broken "ladder". | |
1326 (c-remove-in-sws (point) (1+ (point)))) | |
1327 (c-put-is-sws (1+ rung-pos) | |
1328 (1+ (point))) | |
1329 (c-put-in-sws rung-pos | |
1330 (setq rung-pos (point) | |
1331 last-put-in-sws-pos rung-pos))) | |
1332 | |
1333 (setq simple-ws-end (point)) | |
1334 (c-forward-comments) | |
1335 | |
1336 (cond | |
1337 ((/= (point) simple-ws-end) | |
1338 ;; Skipped over comments. Don't cache at eob in case the buffer | |
1339 ;; is narrowed. | |
1340 (not (eobp))) | |
1341 | |
1342 ((save-excursion | |
1343 (and c-opt-cpp-prefix | |
1344 (looking-at c-opt-cpp-start) | |
1345 (progn (skip-chars-backward " \t") | |
1346 (bolp)) | |
1347 (or (bobp) | |
1348 (progn (backward-char) | |
1349 (not (eq (char-before) ?\\)))))) | |
1350 ;; Skip a preprocessor directive. | |
1351 (end-of-line) | |
1352 (while (and (eq (char-before) ?\\) | |
1353 (= (forward-line 1) 0)) | |
1354 (end-of-line)) | |
1355 (forward-line 1) | |
1356 (setq safe-start t) | |
1357 ;; Don't cache at eob in case the buffer is narrowed. | |
1358 (not (eobp))))) | |
1359 | |
1360 ;; We've searched over a piece of non-white syntactic ws. See if this | |
1361 ;; can be cached. | |
1362 (setq next-rung-pos (point)) | |
1363 (skip-chars-forward " \t\n\r\f\v") | |
1364 (setq rung-end-pos (min (1+ (point)) (point-max))) | |
1365 | |
1366 (if (or | |
1367 ;; Cache if we haven't skipped comments only, and if we started | |
1368 ;; either from a marked rung or from a completely uncached | |
1369 ;; position. | |
1370 (and safe-start | |
1371 (or rung-is-marked | |
1372 (not (get-text-property simple-ws-end 'c-in-sws)))) | |
1373 | |
1374 ;; See if there's a marked rung in the encountered simple ws. If | |
1375 ;; so then we can cache, unless `safe-start' is nil. Even then | |
1376 ;; we need to do this to check if the cache can be used for the | |
1377 ;; next step. | |
1378 (and (setq next-rung-is-marked | |
1379 (text-property-any next-rung-pos rung-end-pos | |
1380 'c-is-sws t)) | |
1381 safe-start)) | |
1382 | |
1383 (progn | |
1384 (c-debug-sws-msg | |
1385 "c-forward-sws caching [%s..%s] - [%s..%s] (max %s)" | |
1386 rung-pos (1+ simple-ws-end) next-rung-pos rung-end-pos | |
1387 (point-max)) | |
1388 | |
1389 ;; Remove the properties for any nested ws that might be cached. | |
1390 ;; Only necessary for `c-is-sws' since `c-in-sws' will be set | |
1391 ;; anyway. | |
1392 (c-remove-is-sws (1+ simple-ws-end) next-rung-pos) | |
1393 (unless (and rung-is-marked (= rung-pos simple-ws-end)) | |
1394 (c-put-is-sws rung-pos | |
1395 (1+ simple-ws-end)) | |
1396 (setq rung-is-marked t)) | |
1397 (c-put-in-sws rung-pos | |
1398 (setq rung-pos (point) | |
1399 last-put-in-sws-pos rung-pos)) | |
1400 (unless (get-text-property (1- rung-end-pos) 'c-is-sws) | |
1401 ;; Remove any `c-in-sws' property from the last char of | |
1402 ;; the rung before we mark it with `c-is-sws', so that we | |
1403 ;; won't connect with the remains of a broken "ladder". | |
1404 (c-remove-in-sws (1- rung-end-pos) rung-end-pos)) | |
1405 (c-put-is-sws next-rung-pos | |
1406 rung-end-pos)) | |
1407 | |
1408 (c-debug-sws-msg | |
1409 "c-forward-sws not caching [%s..%s] - [%s..%s] (max %s)" | |
1410 rung-pos (1+ simple-ws-end) next-rung-pos rung-end-pos | |
1411 (point-max)) | |
1412 | |
1413 ;; Set `rung-pos' for the next rung. It's the same thing here as | |
1414 ;; initially, except that the rung position is set as early as | |
1415 ;; possible since we can't be in the ending ws of a line comment or | |
1416 ;; cpp directive now. | |
1417 (if (setq rung-is-marked next-rung-is-marked) | |
1418 (setq rung-pos (1- (next-single-property-change | |
1419 rung-is-marked 'c-is-sws nil rung-end-pos))) | |
1420 (setq rung-pos next-rung-pos)) | |
1421 (setq safe-start t))) | |
1422 | |
1423 ;; Make sure that the newly marked `c-in-sws' region doesn't connect to | |
1424 ;; another one after the point (which might occur when editing inside a | |
1425 ;; comment or macro). | |
1426 (when (eq last-put-in-sws-pos (point)) | |
1427 (cond ((< last-put-in-sws-pos (point-max)) | |
1428 (c-debug-sws-msg | |
1429 "c-forward-sws clearing at %s for cache separation" | |
1430 last-put-in-sws-pos) | |
1431 (c-remove-in-sws last-put-in-sws-pos | |
1432 (1+ last-put-in-sws-pos))) | |
1433 (t | |
1434 ;; If at eob we have to clear the last character before the end | |
1435 ;; instead since the buffer might be narrowed and there might | |
1436 ;; be a `c-in-sws' after (point-max). In this case it's | |
1437 ;; necessary to clear both properties. | |
1438 (c-debug-sws-msg | |
1439 "c-forward-sws clearing thoroughly at %s for cache separation" | |
1440 (1- last-put-in-sws-pos)) | |
1441 (c-remove-is-and-in-sws (1- last-put-in-sws-pos) | |
1442 last-put-in-sws-pos)))) | |
1443 ))) | |
1444 | |
1445 (defun c-backward-sws () | |
1446 ;; Used by `c-backward-syntactic-ws' to implement the unbounded search. | |
1447 | |
1448 (let (;; `rung-pos' is set to a position as late as possible in the unmarked | |
1449 ;; part of the simple ws region. | |
1450 (rung-pos (point)) next-rung-pos last-put-in-sws-pos | |
1451 rung-is-marked simple-ws-beg cmt-skip-pos) | |
1452 | |
1453 ;; Skip simple horizontal ws and do a quick check on the preceding | |
1454 ;; character to see if it's anying that can't end syntactic ws, so we can | |
1455 ;; bail out early in the majority of cases when there just are a few ws | |
1456 ;; chars. Newlines are complicated in the backward direction, so we can't | |
1457 ;; skip over them. | |
1458 (skip-chars-backward " \t\f") | |
1459 (when (and (not (bobp)) | |
1460 (save-excursion | |
1461 (backward-char) | |
1462 (looking-at c-syntactic-ws-end))) | |
1463 | |
1464 ;; Try to find a rung position in the simple ws preceding point, so that | |
1465 ;; we can get a cache hit even if the last bit of the simple ws has | |
1466 ;; changed recently. | |
1467 (setq simple-ws-beg (point)) | |
1468 (skip-chars-backward " \t\n\r\f\v") | |
1469 (if (setq rung-is-marked (text-property-any | |
1470 (point) (min (1+ rung-pos) (point-max)) | |
1471 'c-is-sws t)) | |
1472 ;; `rung-pos' will be the earliest marked position, which means that | |
1473 ;; there might be later unmarked parts in the simple ws region. | |
1474 ;; It's not worth the effort to fix that; the last part of the | |
1475 ;; simple ws is also typically edited often, so it could be wasted. | |
1476 (goto-char (setq rung-pos rung-is-marked)) | |
1477 (goto-char simple-ws-beg)) | |
1478 | |
1479 (while | |
1480 (progn | |
1481 (while | |
1482 (when (and rung-is-marked | |
1483 (not (bobp)) | |
1484 (get-text-property (1- (point)) 'c-in-sws)) | |
1485 | |
1486 ;; The following search is the main reason that `c-in-sws' | |
1487 ;; and `c-is-sws' aren't combined to one property. | |
1488 (goto-char (previous-single-property-change | |
1489 (point) 'c-in-sws nil (point-min))) | |
1490 (unless (get-text-property (point) 'c-is-sws) | |
1491 ;; If the `c-in-sws' region extended past the first | |
1492 ;; `c-is-sws' char we have to go forward a bit. | |
1493 (goto-char (next-single-property-change | |
1494 (point) 'c-is-sws))) | |
1495 | |
1496 (c-debug-sws-msg | |
1497 "c-backward-sws cached move %s <- %s (min %s)" | |
1498 (point) rung-pos (point-min)) | |
1499 | |
1500 (setq rung-pos (point)) | |
1501 (if (and (< (min (skip-chars-backward " \t\f\v") | |
1502 (progn | |
1503 (setq simple-ws-beg (point)) | |
1504 (skip-chars-backward " \t\n\r\f\v"))) | |
1505 0) | |
1506 (setq rung-is-marked | |
1507 (text-property-any (point) rung-pos | |
1508 'c-is-sws t))) | |
1509 t | |
1510 (goto-char simple-ws-beg) | |
1511 nil)) | |
1512 | |
1513 ;; We'll loop here if there is simple ws before the first rung. | |
1514 ;; That means that there's been some change in it and it's | |
1515 ;; possible that we've stepped into another ladder, so extend | |
1516 ;; the previous one to join with it if there is one, and try to | |
1517 ;; use the cache again. | |
1518 (c-debug-sws-msg | |
1519 "c-backward-sws extending rung with [%s..%s] (min %s)" | |
1520 rung-is-marked rung-pos (point-min)) | |
1521 (unless (get-text-property (1- rung-pos) 'c-is-sws) | |
1522 ;; Remove any `c-in-sws' property from the last char of | |
1523 ;; the rung before we mark it with `c-is-sws', so that we | |
1524 ;; won't connect with the remains of a broken "ladder". | |
1525 (c-remove-in-sws (1- rung-pos) rung-pos)) | |
1526 (c-put-is-sws rung-is-marked | |
1527 rung-pos) | |
1528 (c-put-in-sws rung-is-marked | |
1529 (1- rung-pos)) | |
1530 (setq rung-pos rung-is-marked | |
1531 last-put-in-sws-pos rung-pos)) | |
1532 | |
1533 (c-backward-comments) | |
1534 (setq cmt-skip-pos (point)) | |
1535 | |
1536 (cond | |
1537 ((and c-opt-cpp-prefix | |
1538 (/= cmt-skip-pos simple-ws-beg) | |
1539 (c-beginning-of-macro)) | |
1540 ;; Inside a cpp directive. See if it should be skipped over. | |
1541 (let ((cpp-beg (point))) | |
1542 | |
1543 ;; Move back over all line continuations in the region skipped | |
1544 ;; over by `c-backward-comments'. If we go past it then we | |
1545 ;; started inside the cpp directive. | |
1546 (goto-char simple-ws-beg) | |
1547 (beginning-of-line) | |
1548 (while (and (> (point) cmt-skip-pos) | |
1549 (progn (backward-char) | |
1550 (eq (char-before) ?\\))) | |
1551 (beginning-of-line)) | |
1552 | |
1553 (if (< (point) cmt-skip-pos) | |
1554 ;; Don't move past the cpp directive if we began inside | |
1555 ;; it. Note that the position at the end of the last line | |
1556 ;; of the macro is also considered to be within it. | |
1557 (progn (goto-char cmt-skip-pos) | |
1558 nil) | |
1559 | |
1560 ;; It's worthwhile to spend a little bit of effort on finding | |
1561 ;; the end of the macro, to get a good `simple-ws-beg' | |
1562 ;; position for the cache. Note that `c-backward-comments' | |
1563 ;; could have stepped over some comments before going into | |
1564 ;; the macro, and then `simple-ws-beg' must be kept on the | |
1565 ;; same side of those comments. | |
1566 (goto-char simple-ws-beg) | |
1567 (skip-chars-backward " \t\n\r\f\v") | |
1568 (if (eq (char-before) ?\\) | |
1569 (forward-char)) | |
1570 (forward-line 1) | |
1571 (if (< (point) simple-ws-beg) | |
1572 ;; Might happen if comments after the macro were skipped | |
1573 ;; over. | |
1574 (setq simple-ws-beg (point))) | |
1575 | |
1576 (goto-char cpp-beg) | |
1577 t))) | |
1578 | |
1579 ((/= (save-excursion | |
1580 (skip-chars-forward " \t\n\r\f\v" simple-ws-beg) | |
1581 (setq next-rung-pos (point))) | |
1582 simple-ws-beg) | |
1583 ;; Skipped over comments. Must put point at the end of | |
1584 ;; the simple ws at point since we might be after a line | |
1585 ;; comment or cpp directive that's been partially | |
1586 ;; narrowed out, and we can't risk marking the simple ws | |
1587 ;; at the end of it. | |
1588 (goto-char next-rung-pos) | |
1589 t))) | |
1590 | |
1591 ;; We've searched over a piece of non-white syntactic ws. See if this | |
1592 ;; can be cached. | |
1593 (setq next-rung-pos (point)) | |
1594 (skip-chars-backward " \t\f\v") | |
1595 | |
1596 (if (or | |
1597 ;; Cache if we started either from a marked rung or from a | |
1598 ;; completely uncached position. | |
1599 rung-is-marked | |
1600 (not (get-text-property (1- simple-ws-beg) 'c-in-sws)) | |
1601 | |
1602 ;; Cache if there's a marked rung in the encountered simple ws. | |
645 (save-excursion | 1603 (save-excursion |
646 (skip-chars-backward " \t") | 1604 (skip-chars-backward " \t\n\r\f\v") |
647 (bolp))) | 1605 (text-property-any (point) (min (1+ next-rung-pos) (point-max)) |
648 (end-of-line) | 1606 'c-is-sws t))) |
649 (while (and (<= (point) lim) | 1607 |
650 (eq (char-before) ?\\) | |
651 (= (forward-line 1) 0)) | |
652 (end-of-line)) | |
653 (when (> (point) lim) | |
654 ;; Don't move past the macro if that'd take us past the limit. | |
655 (goto-char here))) | |
656 ;; Skip in-comment line continuations (used for Pike refdoc). | |
657 ((and c-opt-in-comment-lc (looking-at c-opt-in-comment-lc)) | |
658 (goto-char (match-end 0))))) | |
659 (goto-char (min (point) lim)))) | |
660 | |
661 (defun c-backward-syntactic-ws (&optional lim) | |
662 "Backward skip of syntactic whitespace. | |
663 Syntactic whitespace is defined as whitespace characters, comments, | |
664 and preprocessor directives. However if point starts inside a comment | |
665 or preprocessor directive, the content of it is not treated as | |
666 whitespace. LIM sets a lower limit of the backward movement, if | |
667 specified." | |
668 (let ((start-line (c-point 'bol)) | |
669 (here (point-min)) | |
670 (line-cont 'maybe) | |
671 prev-pos) | |
672 (or lim (setq lim here)) | |
673 (while (/= here (point)) | |
674 (setq prev-pos (point)) | |
675 ;; If forward-comment in Emacs 19.34 is given a large negative | |
676 ;; value, it'll loop all the way through if it hits bob. | |
677 (while (c-forward-comment -5)) | |
678 (setq here (point)) | |
679 (cond | |
680 ((and (eolp) | |
681 (eq (char-before) ?\\) | |
682 (if (<= prev-pos (c-point 'eonl)) | |
683 t | |
684 ;; Passed a line continuation, but not from the line we | |
685 ;; started on. | |
686 (forward-char) | |
687 (setq line-cont nil))) | |
688 (backward-char) | |
689 (setq line-cont t)) | |
690 ((progn | |
691 (when (eq line-cont 'maybe) | |
692 (save-excursion | |
693 (end-of-line) | |
694 (setq line-cont (eq (char-before) ?\\)))) | |
695 (or line-cont | |
696 (and (< (point) start-line) | |
697 (c-beginning-of-macro)))) | |
698 (if (< (point) lim) | |
699 ;; Don't move past the macro if we began inside it or at | |
700 ;; the end of the same line, or if the move would take us | |
701 ;; past the limit. | |
702 (goto-char here)) | |
703 (setq line-cont nil)) | |
704 ;; Skip in-comment line continuations (used for Pike refdoc). | |
705 ((and c-opt-in-comment-lc | |
706 (save-excursion | |
707 (and (c-safe (beginning-of-line) | |
708 (backward-char 2) | |
709 t) | |
710 (looking-at c-opt-in-comment-lc) | |
711 (eq (match-end 0) here)))) | |
712 (goto-char (match-beginning 0))))) | |
713 (goto-char (max (point) lim)))) | |
714 | |
715 (defun c-forward-token-1 (&optional count balanced lim) | |
716 "Move forward by tokens. | |
717 A token is defined as all symbols and identifiers which aren't | |
718 syntactic whitespace \(note that e.g. \"->\" is considered to be two | |
719 tokens). Point is always either left at the beginning of a token or | |
720 not moved at all. COUNT specifies the number of tokens to move; a | |
721 negative COUNT moves in the opposite direction. A COUNT of 0 moves to | |
722 the next token beginning only if not already at one. If BALANCED is | |
723 true, move over balanced parens, otherwise move into them. Also, if | |
724 BALANCED is true, never move out of an enclosing paren. LIM sets the | |
725 limit for the movement and defaults to the point limit. | |
726 | |
727 Return the number of tokens left to move \(positive or negative). If | |
728 BALANCED is true, a move over a balanced paren counts as one. Note | |
729 that if COUNT is 0 and no appropriate token beginning is found, 1 will | |
730 be returned. Thus, a return value of 0 guarantees that point is at | |
731 the requested position and a return value less \(without signs) than | |
732 COUNT guarantees that point is at the beginning of some token." | |
733 (or count (setq count 1)) | |
734 (if (< count 0) | |
735 (- (c-backward-token-1 (- count) balanced lim)) | |
736 (let ((jump-syntax (if balanced | |
737 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?') | |
738 '(?w ?_ ?\" ?\\ ?/ ?'))) | |
739 (last (point)) | |
740 (prev (point))) | |
741 (save-restriction | |
742 (if lim (narrow-to-region (point-min) lim)) | |
743 (if (/= (point) | |
744 (progn (c-forward-syntactic-ws) (point))) | |
745 ;; Skip whitespace. Count this as a move if we did in fact | |
746 ;; move and aren't out of bounds. | |
747 (or (eobp) | |
748 (setq count (max (1- count) 0)))) | |
749 (if (and (= count 0) | |
750 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_)) | |
751 (memq (char-syntax (or (char-before) ? )) '(?w ?_))) | |
752 (eobp))) | |
753 ;; If count is zero we should jump if in the middle of a | |
754 ;; token or if there is whitespace between point and the | |
755 ;; following token beginning. | |
756 (setq count 1)) | |
757 (if (eobp) | |
758 (goto-char last) | |
759 ;; Avoid having the limit tests inside the loop. | |
760 (condition-case nil | |
761 (while (> count 0) | |
762 (setq prev last | |
763 last (point)) | |
764 (if (memq (char-syntax (char-after)) jump-syntax) | |
765 (goto-char (scan-sexps (point) 1)) | |
766 (forward-char)) | |
767 (c-forward-syntactic-ws) | |
768 (setq count (1- count))) | |
769 (error (goto-char last))) | |
770 (when (eobp) | |
771 (goto-char prev) | |
772 (setq count (1+ count))))) | |
773 count))) | |
774 | |
775 (defun c-backward-token-1 (&optional count balanced lim) | |
776 "Move backward by tokens. | |
777 See `c-forward-token-1' for details." | |
778 (or count (setq count 1)) | |
779 (if (< count 0) | |
780 (- (c-forward-token-1 (- count) balanced lim)) | |
781 (let ((jump-syntax (if balanced | |
782 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?') | |
783 '(?w ?_ ?\" ?\\ ?/ ?'))) | |
784 last) | |
785 (if (and (= count 0) | |
786 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_)) | |
787 (memq (char-syntax (or (char-before) ? )) '(?w ?_))) | |
788 (/= (point) | |
789 (save-excursion | |
790 (c-forward-syntactic-ws (1+ lim)) | |
791 (point))) | |
792 (eobp))) | |
793 ;; If count is zero we should jump if in the middle of a | |
794 ;; token or if there is whitespace between point and the | |
795 ;; following token beginning. | |
796 (setq count 1)) | |
797 (save-restriction | |
798 (if lim (narrow-to-region lim (point-max))) | |
799 (or (bobp) | |
800 (progn | 1608 (progn |
801 ;; Avoid having the limit tests inside the loop. | 1609 (c-debug-sws-msg |
802 (condition-case nil | 1610 "c-backward-sws caching [%s..%s] - [%s..%s] (min %s)" |
803 (while (progn | 1611 (point) (1+ next-rung-pos) |
804 (setq last (point)) | 1612 simple-ws-beg (min (1+ rung-pos) (point-max)) |
805 (> count 0)) | 1613 (point-min)) |
806 (c-backward-syntactic-ws) | 1614 |
807 (if (memq (char-syntax (char-before)) jump-syntax) | 1615 ;; Remove the properties for any nested ws that might be cached. |
808 (goto-char (scan-sexps (point) -1)) | 1616 ;; Only necessary for `c-is-sws' since `c-in-sws' will be set |
809 (backward-char)) | 1617 ;; anyway. |
810 (setq count (1- count))) | 1618 (c-remove-is-sws (1+ next-rung-pos) simple-ws-beg) |
811 (error (goto-char last))) | 1619 (unless (and rung-is-marked (= simple-ws-beg rung-pos)) |
812 (if (bobp) (goto-char last))))) | 1620 (let ((rung-end-pos (min (1+ rung-pos) (point-max)))) |
813 count))) | 1621 (unless (get-text-property (1- rung-end-pos) 'c-is-sws) |
814 | 1622 ;; Remove any `c-in-sws' property from the last char of |
815 (defun c-syntactic-re-search-forward (regexp &optional bound noerror count | 1623 ;; the rung before we mark it with `c-is-sws', so that we |
816 paren-level) | 1624 ;; won't connect with the remains of a broken "ladder". |
817 ;; Like `re-search-forward', but only report matches that are found | 1625 (c-remove-in-sws (1- rung-end-pos) rung-end-pos)) |
818 ;; in syntactically significant text. I.e. matches that begins in | 1626 (c-put-is-sws simple-ws-beg |
819 ;; comments, macros or string literals are ignored. The start point | 1627 rung-end-pos) |
820 ;; is assumed to be outside any comment, macro or string literal, or | 1628 (setq rung-is-marked t))) |
821 ;; else the content of that region is taken as syntactically | 1629 (c-put-in-sws (setq simple-ws-beg (point) |
822 ;; significant text. If PAREN-LEVEL is non-nil, an additional | 1630 last-put-in-sws-pos simple-ws-beg) |
823 ;; restriction is added to ignore matches in nested paren sexps, and | 1631 rung-pos) |
824 ;; the search will also not go outside the current paren sexp. | 1632 (c-put-is-sws (setq rung-pos simple-ws-beg) |
825 (or bound (setq bound (point-max))) | 1633 (1+ next-rung-pos))) |
826 (or count (setq count 1)) | 1634 |
827 (if paren-level (setq paren-level -1)) | 1635 (c-debug-sws-msg |
828 (let ((start (point)) | 1636 "c-backward-sws not caching [%s..%s] - [%s..%s] (min %s)" |
829 (pos (point)) | 1637 (point) (1+ next-rung-pos) |
830 match-pos state) | 1638 simple-ws-beg (min (1+ rung-pos) (point-max)) |
831 (condition-case err | 1639 (point-min)) |
832 (while (and (> count 0) | 1640 (setq rung-pos next-rung-pos |
833 (re-search-forward regexp bound noerror)) | 1641 simple-ws-beg (point)) |
834 (setq match-pos (point) | 1642 )) |
835 state (parse-partial-sexp pos (match-beginning 0) | 1643 |
836 paren-level nil state) | 1644 ;; Make sure that the newly marked `c-in-sws' region doesn't connect to |
837 pos (point)) | 1645 ;; another one before the point (which might occur when editing inside a |
838 (cond ((nth 3 state) | 1646 ;; comment or macro). |
839 ;; Match inside a string. Skip to the end of it | 1647 (when (eq last-put-in-sws-pos (point)) |
840 ;; before continuing. | 1648 (cond ((< (point-min) last-put-in-sws-pos) |
841 (let ((ender (make-string 1 (nth 3 state)))) | 1649 (c-debug-sws-msg |
842 (while (progn | 1650 "c-backward-sws clearing at %s for cache separation" |
843 (search-forward ender bound noerror) | 1651 (1- last-put-in-sws-pos)) |
844 (setq state (parse-partial-sexp pos (point) | 1652 (c-remove-in-sws (1- last-put-in-sws-pos) |
845 nil nil state) | 1653 last-put-in-sws-pos)) |
846 pos (point)) | 1654 ((> (point-min) 1) |
847 (nth 3 state))))) | 1655 ;; If at bob and the buffer is narrowed, we have to clear the |
848 ((nth 7 state) | 1656 ;; character we're standing on instead since there might be a |
849 ;; Match inside a line comment. Skip to eol. Use | 1657 ;; `c-in-sws' before (point-min). In this case it's necessary |
850 ;; re-search-forward for it to get the right bound | 1658 ;; to clear both properties. |
851 ;; behavior. | 1659 (c-debug-sws-msg |
852 (re-search-forward "[\n\r]" bound noerror)) | 1660 "c-backward-sws clearing thoroughly at %s for cache separation" |
853 ((nth 4 state) | 1661 last-put-in-sws-pos) |
854 ;; Match inside a block comment. Skip to the '*/'. | 1662 (c-remove-is-and-in-sws last-put-in-sws-pos |
855 (re-search-forward "\\*/" bound noerror)) | 1663 (1+ last-put-in-sws-pos))))) |
856 ((save-excursion (c-beginning-of-macro start)) | 1664 ))) |
857 ;; Match inside a macro. Skip to the end of it. | |
858 (c-end-of-macro)) | |
859 ((and paren-level (/= (car state) 0)) | |
860 (if (> (car state) 0) | |
861 ;; Match inside a nested paren sexp. Skip out of it. | |
862 (setq state (parse-partial-sexp pos bound 0 nil state) | |
863 pos (point)) | |
864 ;; Have exited the current paren sexp. The | |
865 ;; parse-partial-sexp above has left us just after | |
866 ;; the closing paren in this case. Just make | |
867 ;; re-search-forward above fail in the appropriate | |
868 ;; way; we'll adjust the leave off point below if | |
869 ;; necessary. | |
870 (setq bound (point)))) | |
871 (t | |
872 ;; A real match. | |
873 (setq count (1- count))))) | |
874 (error | |
875 (goto-char start) | |
876 (signal (car err) (cdr err)))) | |
877 (if (= count 0) | |
878 (progn | |
879 (goto-char match-pos) | |
880 match-pos) | |
881 ;; Search failed. Set point as appropriate. | |
882 (cond ((eq noerror t) | |
883 (goto-char start)) | |
884 (paren-level | |
885 (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1) | |
886 (backward-char))) | |
887 (t | |
888 (goto-char bound))) | |
889 nil))) | |
890 | 1665 |
891 | 1666 |
892 (defun c-in-literal (&optional lim detect-cpp) | 1667 ;; A system for handling noteworthy parens before the point. |
893 "Return the type of literal point is in, if any. | |
894 The return value is `c' if in a C-style comment, `c++' if in a C++ | |
895 style comment, `string' if in a string literal, `pound' if DETECT-CPP | |
896 is non-nil and on a preprocessor line, or nil if somewhere else. | |
897 Optional LIM is used as the backward limit of the search. If omitted, | |
898 or nil, `c-beginning-of-defun' is used. | |
899 | |
900 The last point calculated is cached if the cache is enabled, i.e. if | |
901 `c-in-literal-cache' is bound to a two element vector." | |
902 (if (and (vectorp c-in-literal-cache) | |
903 (= (point) (aref c-in-literal-cache 0))) | |
904 (aref c-in-literal-cache 1) | |
905 (let ((rtn (save-excursion | |
906 (let* ((lim (or lim (c-point 'bod))) | |
907 (state (parse-partial-sexp lim (point)))) | |
908 (cond | |
909 ((nth 3 state) 'string) | |
910 ((nth 4 state) (if (nth 7 state) 'c++ 'c)) | |
911 ((and detect-cpp (c-beginning-of-macro lim)) 'pound) | |
912 (t nil)))))) | |
913 ;; cache this result if the cache is enabled | |
914 (if (not c-in-literal-cache) | |
915 (setq c-in-literal-cache (vector (point) rtn))) | |
916 rtn))) | |
917 | |
918 ;; XEmacs has a built-in function that should make this much quicker. | |
919 ;; I don't think we even need the cache, which makes our lives more | |
920 ;; complicated anyway. In this case, lim is only used to detect | |
921 ;; cpp directives. | |
922 (defun c-fast-in-literal (&optional lim detect-cpp) | |
923 (let ((context (buffer-syntactic-context))) | |
924 (cond | |
925 ((eq context 'string) 'string) | |
926 ((eq context 'comment) 'c++) | |
927 ((eq context 'block-comment) 'c) | |
928 ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound)))) | |
929 | |
930 (if (fboundp 'buffer-syntactic-context) | |
931 (defalias 'c-in-literal 'c-fast-in-literal)) | |
932 | |
933 (defun c-literal-limits (&optional lim near not-in-delimiter) | |
934 "Return a cons of the beginning and end positions of the comment or | |
935 string surrounding point (including both delimiters), or nil if point | |
936 isn't in one. If LIM is non-nil, it's used as the \"safe\" position | |
937 to start parsing from. If NEAR is non-nil, then the limits of any | |
938 literal next to point is returned. \"Next to\" means there's only [ | |
939 \t] between point and the literal. The search for such a literal is | |
940 done first in forward direction. If NOT-IN-DELIMITER is non-nil, the | |
941 case when point is inside a starting delimiter won't be recognized. | |
942 This only has effect for comments, which have starting delimiters with | |
943 more than one character." | |
944 (save-excursion | |
945 (let* ((pos (point)) | |
946 (lim (or lim (c-point 'bod))) | |
947 (state (parse-partial-sexp lim (point)))) | |
948 (cond ((nth 3 state) | |
949 ;; String. Search backward for the start. | |
950 (while (nth 3 state) | |
951 (search-backward (make-string 1 (nth 3 state))) | |
952 (setq state (parse-partial-sexp lim (point)))) | |
953 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
954 (point-max)))) | |
955 ((nth 7 state) | |
956 ;; Line comment. Search from bol for the comment starter. | |
957 (beginning-of-line) | |
958 (setq state (parse-partial-sexp lim (point)) | |
959 lim (point)) | |
960 (while (not (nth 7 state)) | |
961 (search-forward "//") ; Should never fail. | |
962 (setq state (parse-partial-sexp | |
963 lim (point) nil nil state) | |
964 lim (point))) | |
965 (backward-char 2) | |
966 (cons (point) (progn (c-forward-comment 1) (point)))) | |
967 ((nth 4 state) | |
968 ;; Block comment. Search backward for the comment starter. | |
969 (while (nth 4 state) | |
970 (search-backward "/*") ; Should never fail. | |
971 (setq state (parse-partial-sexp lim (point)))) | |
972 (cons (point) (progn (c-forward-comment 1) (point)))) | |
973 ((and (not not-in-delimiter) | |
974 (not (nth 5 state)) | |
975 (eq (char-before) ?/) | |
976 (looking-at "[/*]")) | |
977 ;; We're standing in a comment starter. | |
978 (backward-char 1) | |
979 (cons (point) (progn (c-forward-comment 1) (point)))) | |
980 (near | |
981 (goto-char pos) | |
982 ;; Search forward for a literal. | |
983 (skip-chars-forward " \t") | |
984 (cond | |
985 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String. | |
986 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
987 (point-max)))) | |
988 ((looking-at "/[/*]") ; Line or block comment. | |
989 (cons (point) (progn (c-forward-comment 1) (point)))) | |
990 (t | |
991 ;; Search backward. | |
992 (skip-chars-backward " \t") | |
993 (let ((end (point)) beg) | |
994 (cond | |
995 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String. | |
996 (setq beg (c-safe (c-backward-sexp 1) (point)))) | |
997 ((and (c-safe (forward-char -2) t) | |
998 (looking-at "*/")) | |
999 ;; Block comment. Due to the nature of line | |
1000 ;; comments, they will always be covered by the | |
1001 ;; normal case above. | |
1002 (goto-char end) | |
1003 (c-forward-comment -1) | |
1004 ;; If LIM is bogus, beg will be bogus. | |
1005 (setq beg (point)))) | |
1006 (if beg (cons beg end)))))) | |
1007 )))) | |
1008 | |
1009 (defun c-literal-limits-fast (&optional lim near not-in-delimiter) | |
1010 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp' | |
1011 ;; returns the pos of the comment start. | |
1012 (save-excursion | |
1013 (let* ((pos (point)) | |
1014 (lim (or lim (c-point 'bod))) | |
1015 (state (parse-partial-sexp lim (point)))) | |
1016 (cond ((nth 3 state) ; String. | |
1017 (goto-char (nth 8 state)) | |
1018 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
1019 (point-max)))) | |
1020 ((nth 4 state) ; Comment. | |
1021 (goto-char (nth 8 state)) | |
1022 (cons (point) (progn (c-forward-comment 1) (point)))) | |
1023 ((and (not not-in-delimiter) | |
1024 (not (nth 5 state)) | |
1025 (eq (char-before) ?/) | |
1026 (looking-at "[/*]")) | |
1027 ;; We're standing in a comment starter. | |
1028 (backward-char 1) | |
1029 (cons (point) (progn (c-forward-comment 1) (point)))) | |
1030 (near | |
1031 (goto-char pos) | |
1032 ;; Search forward for a literal. | |
1033 (skip-chars-forward " \t") | |
1034 (cond | |
1035 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String. | |
1036 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
1037 (point-max)))) | |
1038 ((looking-at "/[/*]") ; Line or block comment. | |
1039 (cons (point) (progn (c-forward-comment 1) (point)))) | |
1040 (t | |
1041 ;; Search backward. | |
1042 (skip-chars-backward " \t") | |
1043 (let ((end (point)) beg) | |
1044 (cond | |
1045 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String. | |
1046 (setq beg (c-safe (c-backward-sexp 1) (point)))) | |
1047 ((and (c-safe (forward-char -2) t) | |
1048 (looking-at "*/")) | |
1049 ;; Block comment. Due to the nature of line | |
1050 ;; comments, they will always be covered by the | |
1051 ;; normal case above. | |
1052 (goto-char end) | |
1053 (c-forward-comment -1) | |
1054 ;; If LIM is bogus, beg will be bogus. | |
1055 (setq beg (point)))) | |
1056 (if beg (cons beg end)))))) | |
1057 )))) | |
1058 | |
1059 (if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8)) | |
1060 (defalias 'c-literal-limits 'c-literal-limits-fast)) | |
1061 | |
1062 (defun c-collect-line-comments (range) | |
1063 "If the argument is a cons of two buffer positions (such as returned by | |
1064 `c-literal-limits'), and that range contains a C++ style line comment, | |
1065 then an extended range is returned that contains all adjacent line | |
1066 comments (i.e. all comments that starts in the same column with no | |
1067 empty lines or non-whitespace characters between them). Otherwise the | |
1068 argument is returned." | |
1069 (save-excursion | |
1070 (condition-case nil | |
1071 (if (and (consp range) (progn | |
1072 (goto-char (car range)) | |
1073 (looking-at "//"))) | |
1074 (let ((col (current-column)) | |
1075 (beg (point)) | |
1076 (bopl (c-point 'bopl)) | |
1077 (end (cdr range))) | |
1078 ;; Got to take care in the backward direction to handle | |
1079 ;; comments which are preceded by code. | |
1080 (while (and (c-forward-comment -1) | |
1081 (>= (point) bopl) | |
1082 (looking-at "//") | |
1083 (= col (current-column))) | |
1084 (setq beg (point) | |
1085 bopl (c-point 'bopl))) | |
1086 (goto-char end) | |
1087 (while (and (progn (skip-chars-forward " \t") | |
1088 (looking-at "//")) | |
1089 (= col (current-column)) | |
1090 (prog1 (zerop (forward-line 1)) | |
1091 (setq end (point))))) | |
1092 (cons beg end)) | |
1093 range) | |
1094 (error range)))) | |
1095 | |
1096 (defun c-literal-type (range) | |
1097 "Convenience function that given the result of `c-literal-limits', | |
1098 returns nil or the type of literal that the range surrounds. It's | |
1099 much faster than using `c-in-literal' and is intended to be used when | |
1100 you need both the type of a literal and its limits." | |
1101 (if (consp range) | |
1102 (save-excursion | |
1103 (goto-char (car range)) | |
1104 (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string) | |
1105 ((looking-at "//") 'c++) | |
1106 (t 'c))) ; Assuming the range is valid. | |
1107 range)) | |
1108 | |
1109 | |
1110 | |
1111 ;; utilities for moving and querying around syntactic elements | |
1112 | 1668 |
1113 (defvar c-state-cache nil) | 1669 (defvar c-state-cache nil) |
1114 (make-variable-buffer-local 'c-state-cache) | 1670 (make-variable-buffer-local 'c-state-cache) |
1115 ;; The state cache used by `c-parse-state' to cut down the amount of | 1671 ;; The state cache used by `c-parse-state' to cut down the amount of |
1116 ;; searching. It's the result from some earlier `c-parse-state' call. | 1672 ;; searching. It's the result from some earlier `c-parse-state' call. |
1119 ;; was made at; the cache can actually slow down a little if the | 1675 ;; was made at; the cache can actually slow down a little if the |
1120 ;; cached state was made very far back in the buffer. The cache is | 1676 ;; cached state was made very far back in the buffer. The cache is |
1121 ;; most effective if `c-parse-state' is used on each line while moving | 1677 ;; most effective if `c-parse-state' is used on each line while moving |
1122 ;; forward. | 1678 ;; forward. |
1123 | 1679 |
1124 (defvar c-state-cache-start nil) | 1680 (defvar c-state-cache-start 1) |
1125 ;; This (point-min) when `c-state-cache' was calculated, to detect | 1681 (make-variable-buffer-local 'c-state-cache-start) |
1126 ;; that the start point hasn't changed due to narrowing. | 1682 ;; This is (point-min) when `c-state-cache' was calculated, since a |
1683 ;; change of narrowing is likely to affect the parens that are visible | |
1684 ;; before the point. | |
1685 | |
1686 (defsubst c-invalidate-state-cache (pos) | |
1687 ;; Invalidate all info on `c-state-cache' that applies to the buffer | |
1688 ;; at POS or higher. This is much like `c-whack-state-after', but | |
1689 ;; it never changes a paren pair element into an open paren element. | |
1690 ;; Doing that would mean that the new open paren wouldn't have the | |
1691 ;; required preceding paren pair element. | |
1692 ;; | |
1693 ;; This function does not do any hidden buffer changes. | |
1694 (while (and c-state-cache | |
1695 (let ((elem (car c-state-cache))) | |
1696 (if (consp elem) | |
1697 (or (<= pos (car elem)) | |
1698 (< pos (cdr elem))) | |
1699 (<= pos elem)))) | |
1700 (setq c-state-cache (cdr c-state-cache)))) | |
1127 | 1701 |
1128 (defun c-parse-state () | 1702 (defun c-parse-state () |
1129 ;; Finds and records all noteworthy parens between some good point | 1703 ;; Finds and records all noteworthy parens between some good point |
1130 ;; earlier in the file and point. That good point is at least the | 1704 ;; earlier in the file and point. That good point is at least the |
1131 ;; beginning of the top-level construct we are in, or the beginning | 1705 ;; beginning of the top-level construct we are in, or the beginning |
1132 ;; of the preceding top-level construct if we aren't in one. | 1706 ;; of the preceding top-level construct if we aren't in one. |
1133 ;; | 1707 ;; |
1134 ;; The returned value is a list of the noteworthy parens with the | 1708 ;; The returned value is a list of the noteworthy parens with the |
1135 ;; last one first. If an element in the list is an integer, it's | 1709 ;; last one first. If an element in the list is an integer, it's |
1136 ;; the position of an open paren which has not been closed before | 1710 ;; the position of an open paren which has not been closed before |
1137 ;; point. If an element is a cons, it gives the position of a | 1711 ;; the point. If an element is a cons, it gives the position of a |
1138 ;; closed brace paren pair; the car is the start paren position and | 1712 ;; closed brace paren pair; the car is the start paren position and |
1139 ;; the cdr is the position following the closing paren. Only the | 1713 ;; the cdr is the position following the closing paren. Only the |
1140 ;; last closed brace paren pair before each open paren is recorded, | 1714 ;; last closed brace paren pair before each open paren is recorded, |
1141 ;; and thus the state never contains two cons elements in | 1715 ;; and thus the state never contains two cons elements in |
1142 ;; succession. | 1716 ;; succession. |
1717 ;; | |
1718 ;; Currently no characters which are given paren syntax with the | |
1719 ;; syntax-table property are recorded, i.e. angle bracket arglist | |
1720 ;; parens are never present here. Note that this might change. | |
1721 ;; | |
1722 ;; This function does not do any hidden buffer changes. | |
1723 | |
1143 (save-restriction | 1724 (save-restriction |
1144 (let* ((here (point)) | 1725 (let* ((here (point)) |
1145 (c-macro-start (c-query-macro-start)) | 1726 (c-macro-start (c-query-macro-start)) |
1146 (in-macro-start (or c-macro-start (point))) | 1727 (in-macro-start (or c-macro-start (point))) |
1147 old-state last-pos pairs pos save-pos) | 1728 old-state last-pos pairs pos save-pos) |
1148 ;; Somewhat ugly use of c-check-state-cache to get rid of the | 1729 (c-invalidate-state-cache (point)) |
1149 ;; part of the state cache that is after point. Can't use | 1730 |
1150 ;; c-whack-state-after for the same reasons as in that function. | 1731 ;; If the minimum position has changed due to narrowing then we |
1151 (c-check-state-cache (point) nil nil) | 1732 ;; have to fix the tail of `c-state-cache' accordingly. |
1733 (unless (= c-state-cache-start (point-min)) | |
1734 (if (> (point-min) c-state-cache-start) | |
1735 ;; If point-min has moved forward then we just need to cut | |
1736 ;; off a bit of the tail. | |
1737 (let ((ptr (cons nil c-state-cache)) elem) | |
1738 (while (and (setq elem (cdr ptr)) | |
1739 (>= (if (consp elem) (car elem) elem) | |
1740 (point-min))) | |
1741 (setq ptr elem)) | |
1742 (when (consp ptr) | |
1743 (if (eq (cdr ptr) c-state-cache) | |
1744 (setq c-state-cache nil) | |
1745 (setcdr ptr nil)))) | |
1746 ;; If point-min has moved backward then we drop the state | |
1747 ;; completely. It's possible to do a better job here and | |
1748 ;; recalculate the top only. | |
1749 (setq c-state-cache nil)) | |
1750 (setq c-state-cache-start (point-min))) | |
1751 | |
1152 ;; Get the latest position we know are directly inside the | 1752 ;; Get the latest position we know are directly inside the |
1153 ;; closest containing paren of the cached state. | 1753 ;; closest containing paren of the cached state. |
1154 (setq last-pos (and c-state-cache | 1754 (setq last-pos (and c-state-cache |
1155 (if (consp (car c-state-cache)) | 1755 (if (consp (car c-state-cache)) |
1156 (cdr (car c-state-cache)) | 1756 (cdr (car c-state-cache)) |
1157 (1+ (car c-state-cache))))) | 1757 (1+ (car c-state-cache))))) |
1758 | |
1158 ;; Check if the found last-pos is in a macro. If it is, and | 1759 ;; Check if the found last-pos is in a macro. If it is, and |
1159 ;; we're not in the same macro, we must discard everything on | 1760 ;; we're not in the same macro, we must discard everything on |
1160 ;; c-state-cache that is inside the macro before using it. | 1761 ;; c-state-cache that is inside the macro before using it. |
1161 (when last-pos | 1762 (when last-pos |
1162 (save-excursion | 1763 (save-excursion |
1163 (goto-char last-pos) | 1764 (goto-char last-pos) |
1164 (when (and (c-beginning-of-macro) | 1765 (when (and (c-beginning-of-macro) |
1165 (/= (point) in-macro-start)) | 1766 (/= (point) in-macro-start)) |
1166 (c-check-state-cache (point) nil nil) | 1767 (c-invalidate-state-cache (point)) |
1167 ;; Set last-pos again, just like above. | 1768 ;; Set last-pos again, just like above. |
1168 (setq last-pos (and c-state-cache | 1769 (setq last-pos (and c-state-cache |
1169 (if (consp (car c-state-cache)) | 1770 (if (consp (car c-state-cache)) |
1170 (cdr (car c-state-cache)) | 1771 (cdr (car c-state-cache)) |
1171 (1+ (car c-state-cache)))))))) | 1772 (1+ (car c-state-cache)))))))) |
1773 | |
1172 (setq pos | 1774 (setq pos |
1173 ;; Find the start position for the forward search. (Can't | 1775 ;; Find the start position for the forward search. (Can't |
1174 ;; search in the backward direction since point might be | 1776 ;; search in the backward direction since point might be |
1175 ;; in some kind of literal.) | 1777 ;; in some kind of literal.) |
1176 (or (when last-pos | 1778 (or (when last-pos |
1779 | |
1177 ;; There's a cached state with a containing paren. Pop | 1780 ;; There's a cached state with a containing paren. Pop |
1178 ;; off the stale containing sexps from it by going | 1781 ;; off the stale containing sexps from it by going |
1179 ;; forward out of parens as far as possible. | 1782 ;; forward out of parens as far as possible. |
1180 (narrow-to-region (point-min) here) | 1783 (narrow-to-region (point-min) here) |
1181 (let (placeholder pair-beg) | 1784 (let (placeholder pair-beg) |
1186 (if (consp (car c-state-cache)) | 1789 (if (consp (car c-state-cache)) |
1187 (setq pair-beg (car-safe (cdr c-state-cache)) | 1790 (setq pair-beg (car-safe (cdr c-state-cache)) |
1188 c-state-cache (cdr-safe (cdr c-state-cache))) | 1791 c-state-cache (cdr-safe (cdr c-state-cache))) |
1189 (setq pair-beg (car c-state-cache) | 1792 (setq pair-beg (car c-state-cache) |
1190 c-state-cache (cdr c-state-cache)))) | 1793 c-state-cache (cdr c-state-cache)))) |
1794 | |
1191 (when (and pair-beg (eq (char-after pair-beg) ?{)) | 1795 (when (and pair-beg (eq (char-after pair-beg) ?{)) |
1192 ;; The last paren pair we moved out from was a brace | 1796 ;; The last paren pair we moved out from was a brace |
1193 ;; pair. Modify the state to record this as a closed | 1797 ;; pair. Modify the state to record this as a closed |
1194 ;; pair now. | 1798 ;; pair now. |
1195 (if (consp (car-safe c-state-cache)) | 1799 (if (consp (car-safe c-state-cache)) |
1196 (setq c-state-cache (cdr c-state-cache))) | 1800 (setq c-state-cache (cdr c-state-cache))) |
1197 (setq c-state-cache (cons (cons pair-beg last-pos) | 1801 (setq c-state-cache (cons (cons pair-beg last-pos) |
1198 c-state-cache)))) | 1802 c-state-cache)))) |
1803 | |
1199 ;; Check if the preceding balanced paren is within a | 1804 ;; Check if the preceding balanced paren is within a |
1200 ;; macro; it should be ignored if we're outside the | 1805 ;; macro; it should be ignored if we're outside the |
1201 ;; macro. There's no need to check any further upwards; | 1806 ;; macro. There's no need to check any further upwards; |
1202 ;; if the macro contains an unbalanced opening paren then | 1807 ;; if the macro contains an unbalanced opening paren then |
1203 ;; we're smoked anyway. | 1808 ;; we're smoked anyway. |
1206 (save-excursion | 1811 (save-excursion |
1207 (goto-char (car (car c-state-cache))) | 1812 (goto-char (car (car c-state-cache))) |
1208 (when (c-beginning-of-macro) | 1813 (when (c-beginning-of-macro) |
1209 (setq here (point) | 1814 (setq here (point) |
1210 c-state-cache (cdr c-state-cache))))) | 1815 c-state-cache (cdr c-state-cache))))) |
1816 | |
1211 (when c-state-cache | 1817 (when c-state-cache |
1212 (setq old-state c-state-cache) | 1818 (setq old-state c-state-cache) |
1213 last-pos)) | 1819 last-pos)) |
1820 | |
1214 (save-excursion | 1821 (save-excursion |
1215 ;; go back 2 bods, but ignore any bogus positions | 1822 ;; go back 2 bods, but ignore any bogus positions |
1216 ;; returned by beginning-of-defun (i.e. open paren in | 1823 ;; returned by beginning-of-defun (i.e. open paren in |
1217 ;; column zero) | 1824 ;; column zero) |
1218 (goto-char here) | 1825 (goto-char here) |
1220 (while (not (or (bobp) (zerop cnt))) | 1827 (while (not (or (bobp) (zerop cnt))) |
1221 (c-beginning-of-defun-1) | 1828 (c-beginning-of-defun-1) |
1222 (if (eq (char-after) ?\{) | 1829 (if (eq (char-after) ?\{) |
1223 (setq cnt (1- cnt))))) | 1830 (setq cnt (1- cnt))))) |
1224 (point)))) | 1831 (point)))) |
1832 | |
1225 (narrow-to-region (point-min) here) | 1833 (narrow-to-region (point-min) here) |
1834 | |
1226 (while pos | 1835 (while pos |
1227 ;; Find the balanced brace pairs. | 1836 ;; Find the balanced brace pairs. |
1228 (setq save-pos pos | 1837 (setq save-pos pos |
1229 pairs nil) | 1838 pairs nil) |
1230 (while (and (setq last-pos (c-down-list-forward pos)) | 1839 (while (and (setq last-pos (c-down-list-forward pos)) |
1231 (setq pos (c-up-list-forward last-pos))) | 1840 (setq pos (c-up-list-forward last-pos))) |
1232 (if (eq (char-before last-pos) ?{) | 1841 (if (eq (char-before last-pos) ?{) |
1233 (setq pairs (cons (cons last-pos pos) pairs)))) | 1842 (setq pairs (cons (cons last-pos pos) pairs)))) |
1843 | |
1234 ;; Should ignore any pairs that are in a macro, providing | 1844 ;; Should ignore any pairs that are in a macro, providing |
1235 ;; we're not in the same one. | 1845 ;; we're not in the same one. |
1236 (when (and pairs (< (car (car pairs)) in-macro-start)) | 1846 (when (and pairs (< (car (car pairs)) in-macro-start)) |
1237 (while (and (save-excursion | 1847 (while (and (save-excursion |
1238 (goto-char (car (car pairs))) | 1848 (goto-char (car (car pairs))) |
1239 (c-beginning-of-macro)) | 1849 (c-beginning-of-macro)) |
1240 (setq pairs (cdr pairs))))) | 1850 (setq pairs (cdr pairs))))) |
1851 | |
1241 ;; Record the last brace pair. | 1852 ;; Record the last brace pair. |
1242 (when pairs | 1853 (when pairs |
1243 (if (and (eq c-state-cache old-state) | 1854 (if (and (eq c-state-cache old-state) |
1244 (consp (car-safe c-state-cache))) | 1855 (consp (car-safe c-state-cache))) |
1245 ;; There's a closed pair on the cached state but we've | 1856 ;; There's a closed pair on the cached state but we've |
1247 (setq c-state-cache (cdr c-state-cache))) | 1858 (setq c-state-cache (cdr c-state-cache))) |
1248 (setq pairs (car pairs)) | 1859 (setq pairs (car pairs)) |
1249 (setcar pairs (1- (car pairs))) | 1860 (setcar pairs (1- (car pairs))) |
1250 (when (consp (car-safe c-state-cache)) | 1861 (when (consp (car-safe c-state-cache)) |
1251 ;; There could already be a cons first in `c-state-cache' | 1862 ;; There could already be a cons first in `c-state-cache' |
1252 ;; if we've jumped over an unbalanced open paren in a | 1863 ;; if we've e.g. jumped over an unbalanced open paren in a |
1253 ;; macro below. | 1864 ;; macro below. |
1254 (setq c-state-cache (cdr c-state-cache))) | 1865 (setq c-state-cache (cdr c-state-cache))) |
1255 (setq c-state-cache (cons pairs c-state-cache))) | 1866 (setq c-state-cache (cons pairs c-state-cache))) |
1867 | |
1256 (if last-pos | 1868 (if last-pos |
1257 ;; Prepare to loop, but record the open paren only if it's | 1869 ;; Prepare to loop, but record the open paren only if it's |
1258 ;; outside a macro or within the same macro as point. | 1870 ;; outside a macro or within the same macro as point, and |
1871 ;; if it is a "real" open paren and not some character | |
1872 ;; that got an open paren syntax-table property. | |
1259 (progn | 1873 (progn |
1260 (setq pos last-pos) | 1874 (setq pos last-pos) |
1261 (if (or (>= last-pos in-macro-start) | 1875 (if (and (or (>= last-pos in-macro-start) |
1262 (save-excursion | 1876 (save-excursion |
1263 (goto-char last-pos) | 1877 (goto-char last-pos) |
1264 (not (c-beginning-of-macro)))) | 1878 (not (c-beginning-of-macro)))) |
1265 (setq c-state-cache (cons (1- pos) c-state-cache)))) | 1879 (= (char-syntax (char-before last-pos)) ?\()) |
1880 (setq c-state-cache (cons (1- last-pos) c-state-cache)))) | |
1881 | |
1266 (if (setq last-pos (c-up-list-forward pos)) | 1882 (if (setq last-pos (c-up-list-forward pos)) |
1267 ;; Found a close paren without a corresponding opening | 1883 ;; Found a close paren without a corresponding opening |
1268 ;; one. Maybe we didn't go back far enough, so try to | 1884 ;; one. Maybe we didn't go back far enough, so try to |
1269 ;; scan backward for the start paren and then start over. | 1885 ;; scan backward for the start paren and then start over. |
1270 (progn | 1886 (progn |
1281 c-parsing-error | 1897 c-parsing-error |
1282 (format "Unbalanced close paren at line %d" | 1898 (format "Unbalanced close paren at line %d" |
1283 (1+ (count-lines (point-min) | 1899 (1+ (count-lines (point-min) |
1284 (c-point 'bol last-pos))))))) | 1900 (c-point 'bol last-pos))))))) |
1285 (setq pos nil)))) | 1901 (setq pos nil)))) |
1902 | |
1286 c-state-cache))) | 1903 c-state-cache))) |
1287 | 1904 |
1288 ;; Debug tool to catch cache inconsistencies. | 1905 ;; Debug tool to catch cache inconsistencies. |
1289 (defvar c-debug-parse-state nil) | 1906 (defvar c-debug-parse-state nil) |
1290 (unless (fboundp 'c-real-parse-state) | 1907 (unless (fboundp 'c-real-parse-state) |
1304 (fset 'c-parse-state (symbol-function (if c-debug-parse-state | 1921 (fset 'c-parse-state (symbol-function (if c-debug-parse-state |
1305 'c-debug-parse-state | 1922 'c-debug-parse-state |
1306 'c-real-parse-state))) | 1923 'c-real-parse-state))) |
1307 (c-keep-region-active)) | 1924 (c-keep-region-active)) |
1308 | 1925 |
1309 (defun c-check-state-cache (beg end old-length) | |
1310 ;; Used on `after-change-functions' to adjust `c-state-cache'. | |
1311 ;; Prefer speed to finesse here, since there will be many more calls | |
1312 ;; to this function than times `c-state-cache' is used. | |
1313 ;; | |
1314 ;; This is much like `c-whack-state-after', but it never changes a | |
1315 ;; paren pair element into an open paren element. Doing that would | |
1316 ;; mean that the new open paren wouldn't have the required preceding | |
1317 ;; paren pair element. | |
1318 (if (not (eq c-state-cache-start (point-min))) | |
1319 (setq c-state-cache-start (point-min) | |
1320 c-state-cache nil) | |
1321 (while (and c-state-cache | |
1322 (let ((elem (car c-state-cache))) | |
1323 (if (consp elem) | |
1324 (or (<= beg (car elem)) | |
1325 (< beg (cdr elem))) | |
1326 (<= beg elem)))) | |
1327 (setq c-state-cache (cdr c-state-cache))))) | |
1328 | |
1329 (defun c-whack-state-before (bufpos paren-state) | 1926 (defun c-whack-state-before (bufpos paren-state) |
1330 ;; Whack off any state information from PAREN-STATE which lies | 1927 ;; Whack off any state information from PAREN-STATE which lies |
1331 ;; before BUFPOS. Not destructive on PAREN-STATE. | 1928 ;; before BUFPOS. Not destructive on PAREN-STATE. |
1929 ;; | |
1930 ;; This function does not do any hidden buffer changes. | |
1332 (let* ((newstate (list nil)) | 1931 (let* ((newstate (list nil)) |
1333 (ptr newstate) | 1932 (ptr newstate) |
1334 car) | 1933 car) |
1335 (while paren-state | 1934 (while paren-state |
1336 (setq car (car paren-state) | 1935 (setq car (car paren-state) |
1342 (cdr newstate))) | 1941 (cdr newstate))) |
1343 | 1942 |
1344 (defun c-whack-state-after (bufpos paren-state) | 1943 (defun c-whack-state-after (bufpos paren-state) |
1345 ;; Whack off any state information from PAREN-STATE which lies at or | 1944 ;; Whack off any state information from PAREN-STATE which lies at or |
1346 ;; after BUFPOS. Not destructive on PAREN-STATE. | 1945 ;; after BUFPOS. Not destructive on PAREN-STATE. |
1946 ;; | |
1947 ;; This function does not do any hidden buffer changes. | |
1347 (catch 'done | 1948 (catch 'done |
1348 (while paren-state | 1949 (while paren-state |
1349 (let ((car (car paren-state))) | 1950 (let ((car (car paren-state))) |
1350 (if (consp car) | 1951 (if (consp car) |
1351 ;; just check the car, because in a balanced brace | 1952 ;; just check the car, because in a balanced brace |
1370 ;; it's before bufpos, so everything else should too. | 1971 ;; it's before bufpos, so everything else should too. |
1371 (throw 'done paren-state))) | 1972 (throw 'done paren-state))) |
1372 (setq paren-state (cdr paren-state))) | 1973 (setq paren-state (cdr paren-state))) |
1373 nil))) | 1974 nil))) |
1374 | 1975 |
1976 (defun c-most-enclosing-brace (paren-state &optional bufpos) | |
1977 ;; Return the bufpos of the innermost enclosing open paren before | |
1978 ;; bufpos that hasn't been narrowed out, or nil if none was found. | |
1979 ;; | |
1980 ;; This function does not do any hidden buffer changes. | |
1981 (let (enclosingp) | |
1982 (or bufpos (setq bufpos 134217727)) | |
1983 (while paren-state | |
1984 (setq enclosingp (car paren-state) | |
1985 paren-state (cdr paren-state)) | |
1986 (if (or (consp enclosingp) | |
1987 (>= enclosingp bufpos)) | |
1988 (setq enclosingp nil) | |
1989 (if (< enclosingp (point-min)) | |
1990 (setq enclosingp nil)) | |
1991 (setq paren-state nil))) | |
1992 enclosingp)) | |
1993 | |
1994 (defun c-least-enclosing-brace (paren-state &optional bufpos) | |
1995 ;; Return the bufpos of the outermost enclosing open paren before | |
1996 ;; bufpos that hasn't been narrowed out, or nil if none was found. | |
1997 ;; | |
1998 ;; This function does not do any hidden buffer changes. | |
1999 (let (pos elem) | |
2000 (or bufpos (setq bufpos 134217727)) | |
2001 (while paren-state | |
2002 (setq elem (car paren-state) | |
2003 paren-state (cdr paren-state)) | |
2004 (unless (or (consp elem) | |
2005 (>= elem bufpos)) | |
2006 (if (>= elem (point-min)) | |
2007 (setq pos elem)))) | |
2008 pos)) | |
2009 | |
2010 (defun c-safe-position (bufpos paren-state) | |
2011 ;; Return the closest known safe position higher up than BUFPOS, or | |
2012 ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is | |
2013 ;; nil, which is useful to find the closest limit before a given | |
2014 ;; limit that might be nil. | |
2015 ;; | |
2016 ;; This function does not do any hidden buffer changes. | |
2017 (when bufpos | |
2018 (let (elem) | |
2019 (catch 'done | |
2020 (while paren-state | |
2021 (setq elem (car paren-state)) | |
2022 (if (consp elem) | |
2023 (cond ((< (cdr elem) bufpos) | |
2024 (throw 'done (cdr elem))) | |
2025 ((< (car elem) bufpos) | |
2026 ;; See below. | |
2027 (throw 'done (min (1+ (car elem)) bufpos)))) | |
2028 (if (< elem bufpos) | |
2029 ;; elem is the position at and not after the opening paren, so | |
2030 ;; we can go forward one more step unless it's equal to | |
2031 ;; bufpos. This is useful in some cases avoid an extra paren | |
2032 ;; level between the safe position and bufpos. | |
2033 (throw 'done (min (1+ elem) bufpos)))) | |
2034 (setq paren-state (cdr paren-state))))))) | |
2035 | |
2036 (defun c-beginning-of-syntax () | |
2037 ;; This is used for `font-lock-beginning-of-syntax-function'. It | |
2038 ;; goes to the closest previous point that is known to be outside | |
2039 ;; any string literal or comment. `c-state-cache' is used if it has | |
2040 ;; a position in the vicinity. | |
2041 (let* ((paren-state c-state-cache) | |
2042 elem | |
2043 | |
2044 (pos (catch 'done | |
2045 ;; Note: Similar code in `c-safe-position'. The | |
2046 ;; difference is that we accept a safe position at | |
2047 ;; the point and don't bother to go forward past open | |
2048 ;; parens. | |
2049 (while paren-state | |
2050 (setq elem (car paren-state)) | |
2051 (if (consp elem) | |
2052 (cond ((<= (cdr elem) (point)) | |
2053 (throw 'done (cdr elem))) | |
2054 ((<= (car elem) (point)) | |
2055 (throw 'done (car elem)))) | |
2056 (if (<= elem (point)) | |
2057 (throw 'done elem))) | |
2058 (setq paren-state (cdr paren-state))) | |
2059 (point-min)))) | |
2060 | |
2061 (if (> pos (- (point) 4000)) | |
2062 (goto-char pos) | |
2063 ;; The position is far back. Try `c-beginning-of-defun-1' | |
2064 ;; (although we can't be entirely sure it will go to a position | |
2065 ;; outside a comment or string in current emacsen). FIXME: | |
2066 ;; Consult `syntax-ppss' here. | |
2067 (c-beginning-of-defun-1) | |
2068 (if (< (point) pos) | |
2069 (goto-char pos))))) | |
2070 | |
1375 | 2071 |
2072 ;; Tools for scanning identifiers and other tokens. | |
2073 | |
2074 (defun c-on-identifier () | |
2075 "Return non-nil if the point is on or directly after an identifier. | |
2076 Keywords are recognized and not considered identifiers. If an | |
2077 identifier is detected, the returned value is its starting position. | |
2078 If an identifier both starts and stops at the point \(can only happen | |
2079 in Pike) then the point for the preceding one is returned. | |
2080 | |
2081 This function does not do any hidden buffer changes." | |
2082 | |
2083 (save-excursion | |
2084 (if (zerop (skip-syntax-backward "w_")) | |
2085 | |
2086 (when (c-major-mode-is 'pike-mode) | |
2087 ;; Handle the `<operator> syntax in Pike. | |
2088 (let ((pos (point))) | |
2089 (skip-chars-backward "!%&*+\\-/<=>^|~[]()") | |
2090 (and (if (< (skip-chars-backward "`") 0) | |
2091 t | |
2092 (goto-char pos) | |
2093 (eq (char-after) ?\`)) | |
2094 (looking-at c-symbol-key) | |
2095 (>= (match-end 0) pos) | |
2096 (point)))) | |
2097 | |
2098 (and (not (looking-at c-keywords-regexp)) | |
2099 (point))))) | |
2100 | |
2101 (defsubst c-simple-skip-symbol-backward () | |
2102 ;; If the point is at the end of a symbol then skip backward to the | |
2103 ;; beginning of it. Don't move otherwise. Return non-nil if point | |
2104 ;; moved. | |
2105 (or (< (skip-syntax-backward "w_") 0) | |
2106 (and (c-major-mode-is 'pike-mode) | |
2107 ;; Handle the `<operator> syntax in Pike. | |
2108 (let ((pos (point))) | |
2109 (if (and (< (skip-chars-backward "!%&*+\\-/<=>^|~[]()") 0) | |
2110 (< (skip-chars-backward "`") 0) | |
2111 (looking-at c-symbol-key) | |
2112 (>= (match-end 0) pos)) | |
2113 t | |
2114 (goto-char pos) | |
2115 nil))))) | |
2116 | |
2117 (defsubst c-beginning-of-current-token (&optional back-limit) | |
2118 ;; Move to the beginning of the current token. Do not move if not | |
2119 ;; in the middle of one. BACK-LIMIT may be used to bound the | |
2120 ;; backward search; if given it's assumed to be at the boundary | |
2121 ;; between two tokens. | |
2122 (if (looking-at "\\w\\|\\s_") | |
2123 (skip-syntax-backward "w_" back-limit) | |
2124 (let ((start (point))) | |
2125 (when (< (skip-syntax-backward ".()" back-limit) 0) | |
2126 (while (let ((pos (or (and (looking-at c-nonsymbol-token-regexp) | |
2127 (match-end 0)) | |
2128 ;; `c-nonsymbol-token-regexp' should always match | |
2129 ;; since we've skipped backward over punctuator | |
2130 ;; or paren syntax, but consume one char in case | |
2131 ;; it doesn't so that we don't leave point before | |
2132 ;; some earlier incorrect token. | |
2133 (1+ (point))))) | |
2134 (if (<= pos start) | |
2135 (goto-char pos)) | |
2136 (< pos start))))))) | |
2137 | |
2138 (defsubst c-end-of-current-token (&optional back-limit) | |
2139 ;; Move to the end of the current token. Do not move if not in the | |
2140 ;; middle of one. BACK-LIMIT may be used to bound the backward | |
2141 ;; search; if given it's assumed to be at the boundary between two | |
2142 ;; tokens. | |
2143 (let ((start (point))) | |
2144 (cond ((< (skip-syntax-backward "w_" (1- start)) 0) | |
2145 (skip-syntax-forward "w_")) | |
2146 ((< (skip-syntax-backward ".()" back-limit) 0) | |
2147 (while (progn | |
2148 (if (looking-at c-nonsymbol-token-regexp) | |
2149 (goto-char (match-end 0)) | |
2150 ;; `c-nonsymbol-token-regexp' should always match since | |
2151 ;; we've skipped backward over punctuator or paren | |
2152 ;; syntax, but move forward in case it doesn't so that | |
2153 ;; we don't leave point earlier than we started with. | |
2154 (forward-char)) | |
2155 (< (point) start))))))) | |
2156 | |
2157 (defconst c-jump-syntax-balanced | |
2158 (if (memq 'gen-string-delim c-emacs-features) | |
2159 "\\w\\|\\s_\\|\\s\(\\|\\s\)\\|\\s\"\\|\\s|" | |
2160 "\\w\\|\\s_\\|\\s\(\\|\\s\)\\|\\s\"")) | |
2161 | |
2162 (defconst c-jump-syntax-unbalanced | |
2163 (if (memq 'gen-string-delim c-emacs-features) | |
2164 "\\w\\|\\s_\\|\\s\"\\|\\s|" | |
2165 "\\w\\|\\s_\\|\\s\"")) | |
2166 | |
2167 (defun c-forward-token-2 (&optional count balanced limit) | |
2168 "Move forward by tokens. | |
2169 A token is defined as all symbols and identifiers which aren't | |
2170 syntactic whitespace \(note that multicharacter tokens like \"==\" are | |
2171 treated properly). Point is always either left at the beginning of a | |
2172 token or not moved at all. COUNT specifies the number of tokens to | |
2173 move; a negative COUNT moves in the opposite direction. A COUNT of 0 | |
2174 moves to the next token beginning only if not already at one. If | |
2175 BALANCED is true, move over balanced parens, otherwise move into them. | |
2176 Also, if BALANCED is true, never move out of an enclosing paren. | |
2177 | |
2178 LIMIT sets the limit for the movement and defaults to the point limit. | |
2179 The case when LIMIT is set in the middle of a token, comment or macro | |
2180 is handled correctly, i.e. the point won't be left there. | |
2181 | |
2182 Return the number of tokens left to move \(positive or negative). If | |
2183 BALANCED is true, a move over a balanced paren counts as one. Note | |
2184 that if COUNT is 0 and no appropriate token beginning is found, 1 will | |
2185 be returned. Thus, a return value of 0 guarantees that point is at | |
2186 the requested position and a return value less \(without signs) than | |
2187 COUNT guarantees that point is at the beginning of some token." | |
2188 | |
2189 (or count (setq count 1)) | |
2190 (if (< count 0) | |
2191 (- (c-backward-token-2 (- count) balanced limit)) | |
2192 | |
2193 (let ((jump-syntax (if balanced | |
2194 c-jump-syntax-balanced | |
2195 c-jump-syntax-unbalanced)) | |
2196 (last (point)) | |
2197 (prev (point))) | |
2198 | |
2199 (if (zerop count) | |
2200 ;; If count is zero we should jump if in the middle of a token. | |
2201 (c-end-of-current-token)) | |
2202 | |
2203 (save-restriction | |
2204 (if limit (narrow-to-region (point-min) limit)) | |
2205 (if (/= (point) | |
2206 (progn (c-forward-syntactic-ws) (point))) | |
2207 ;; Skip whitespace. Count this as a move if we did in | |
2208 ;; fact move. | |
2209 (setq count (max (1- count) 0))) | |
2210 | |
2211 (if (eobp) | |
2212 ;; Moved out of bounds. Make sure the returned count isn't zero. | |
2213 (progn | |
2214 (if (zerop count) (setq count 1)) | |
2215 (goto-char last)) | |
2216 | |
2217 ;; Use `condition-case' to avoid having the limit tests | |
2218 ;; inside the loop. | |
2219 (condition-case nil | |
2220 (while (and | |
2221 (> count 0) | |
2222 (progn | |
2223 (setq last (point)) | |
2224 (cond ((looking-at jump-syntax) | |
2225 (goto-char (scan-sexps (point) 1)) | |
2226 t) | |
2227 ((looking-at c-nonsymbol-token-regexp) | |
2228 (goto-char (match-end 0)) | |
2229 t) | |
2230 ;; `c-nonsymbol-token-regexp' above should always | |
2231 ;; match if there are correct tokens. Try to | |
2232 ;; widen to see if the limit was set in the | |
2233 ;; middle of one, else fall back to treating | |
2234 ;; the offending thing as a one character token. | |
2235 ((and limit | |
2236 (save-restriction | |
2237 (widen) | |
2238 (looking-at c-nonsymbol-token-regexp))) | |
2239 nil) | |
2240 (t | |
2241 (forward-char) | |
2242 t)))) | |
2243 (c-forward-syntactic-ws) | |
2244 (setq prev last | |
2245 count (1- count))) | |
2246 (error (goto-char last))) | |
2247 | |
2248 (when (eobp) | |
2249 (goto-char prev) | |
2250 (setq count (1+ count))))) | |
2251 | |
2252 count))) | |
2253 | |
2254 (defun c-backward-token-2 (&optional count balanced limit) | |
2255 "Move backward by tokens. | |
2256 See `c-forward-token-2' for details." | |
2257 | |
2258 (or count (setq count 1)) | |
2259 (if (< count 0) | |
2260 (- (c-forward-token-2 (- count) balanced limit)) | |
2261 | |
2262 (or limit (setq limit (point-min))) | |
2263 (let ((jump-syntax (if balanced | |
2264 c-jump-syntax-balanced | |
2265 c-jump-syntax-unbalanced)) | |
2266 (last (point))) | |
2267 | |
2268 (if (zerop count) | |
2269 ;; The count is zero so try to skip to the beginning of the | |
2270 ;; current token. | |
2271 (if (> (point) | |
2272 (progn (c-beginning-of-current-token) (point))) | |
2273 (if (< (point) limit) | |
2274 ;; The limit is inside the same token, so return 1. | |
2275 (setq count 1)) | |
2276 | |
2277 ;; We're not in the middle of a token. If there's | |
2278 ;; whitespace after the point then we must move backward, | |
2279 ;; so set count to 1 in that case. | |
2280 (and (looking-at c-syntactic-ws-start) | |
2281 ;; If we're looking at a '#' that might start a cpp | |
2282 ;; directive then we have to do a more elaborate check. | |
2283 (or (/= (char-after) ?#) | |
2284 (not c-opt-cpp-prefix) | |
2285 (save-excursion | |
2286 (and (= (point) | |
2287 (progn (beginning-of-line) | |
2288 (looking-at "[ \t]*") | |
2289 (match-end 0))) | |
2290 (or (bobp) | |
2291 (progn (backward-char) | |
2292 (not (eq (char-before) ?\\))))))) | |
2293 (setq count 1)))) | |
2294 | |
2295 ;; Use `condition-case' to avoid having to check for buffer | |
2296 ;; limits in `backward-char', `scan-sexps' and `goto-char' below. | |
2297 (condition-case nil | |
2298 (while (and | |
2299 (> count 0) | |
2300 (progn | |
2301 (c-backward-syntactic-ws) | |
2302 (backward-char) | |
2303 (if (looking-at jump-syntax) | |
2304 (goto-char (scan-sexps (1+ (point)) -1)) | |
2305 ;; This can be very inefficient if there's a long | |
2306 ;; sequence of operator tokens without any separation. | |
2307 ;; That doesn't happen in practice, anyway. | |
2308 (c-beginning-of-current-token)) | |
2309 (>= (point) limit))) | |
2310 (setq last (point) | |
2311 count (1- count))) | |
2312 (error (goto-char last))) | |
2313 | |
2314 (if (< (point) limit) | |
2315 (goto-char last)) | |
2316 | |
2317 count))) | |
2318 | |
2319 (defun c-forward-token-1 (&optional count balanced limit) | |
2320 "Like `c-forward-token-2' but doesn't treat multicharacter operator | |
2321 tokens like \"==\" as single tokens, i.e. all sequences of symbol | |
2322 characters are jumped over character by character. This function is | |
2323 for compatibility only; it's only a wrapper over `c-forward-token-2'." | |
2324 (let ((c-nonsymbol-token-regexp "\\s.\\|\\s\(\\|\\s\)")) | |
2325 (c-forward-token-2 count balanced limit))) | |
2326 | |
2327 (defun c-backward-token-1 (&optional count balanced limit) | |
2328 "Like `c-backward-token-2' but doesn't treat multicharacter operator | |
2329 tokens like \"==\" as single tokens, i.e. all sequences of symbol | |
2330 characters are jumped over character by character. This function is | |
2331 for compatibility only; it's only a wrapper over `c-backward-token-2'." | |
2332 (let ((c-nonsymbol-token-regexp "\\s.\\|\\s\(\\|\\s\)")) | |
2333 (c-backward-token-2 count balanced limit))) | |
2334 | |
2335 | |
2336 ;; Tools for doing searches restricted to syntactically relevant text. | |
2337 | |
2338 (defun c-syntactic-re-search-forward (regexp &optional bound noerror | |
2339 paren-level not-inside-token | |
2340 lookbehind-submatch) | |
2341 "Like `re-search-forward', but only report matches that are found | |
2342 in syntactically significant text. I.e. matches in comments, macros | |
2343 or string literals are ignored. The start point is assumed to be | |
2344 outside any comment, macro or string literal, or else the content of | |
2345 that region is taken as syntactically significant text. | |
2346 | |
2347 If PAREN-LEVEL is non-nil, an additional restriction is added to | |
2348 ignore matches in nested paren sexps, and the search will also not go | |
2349 outside the current paren sexp. | |
2350 | |
2351 If NOT-INSIDE-TOKEN is non-nil, matches in the middle of tokens are | |
2352 ignored. Things like multicharacter operators and special symbols | |
2353 \(e.g. \"`()\" in Pike) are handled but currently not floating point | |
2354 constants. | |
2355 | |
2356 If LOOKBEHIND-SUBMATCH is non-nil, it's taken as a number of a | |
2357 subexpression in REGEXP. The end of that submatch is used as the | |
2358 position to check for syntactic significance. If LOOKBEHIND-SUBMATCH | |
2359 isn't used or if that subexpression didn't match then the start | |
2360 position of the whole match is used instead. The \"look behind\" | |
2361 subexpression is never tested before the starting position, so it | |
2362 might be a good idea to include \\=\\= as a match alternative in it. | |
2363 | |
2364 Optimization note: Matches might be missed if the \"look behind\" | |
2365 subexpression should match the end of nonwhite syntactic whitespace, | |
2366 i.e. the end of comments or cpp directives. This since the function | |
2367 skips over such things before resuming the search. It's also not safe | |
2368 to assume that the \"look behind\" subexpression never can match | |
2369 syntactic whitespace." | |
2370 | |
2371 (or bound (setq bound (point-max))) | |
2372 (if paren-level (setq paren-level -1)) | |
2373 | |
2374 ;;(message "c-syntactic-re-search-forward %s %s %S" (point) bound regexp) | |
2375 | |
2376 (let ((start (point)) | |
2377 (pos (point)) | |
2378 (last-token-end-pos (point-min)) | |
2379 match-pos found state check-pos check-state tmp) | |
2380 | |
2381 (condition-case err | |
2382 (while | |
2383 (and | |
2384 (re-search-forward regexp bound noerror) | |
2385 | |
2386 (progn | |
2387 (setq match-pos (point) | |
2388 state (parse-partial-sexp | |
2389 pos (match-beginning 0) paren-level nil state) | |
2390 pos (point)) | |
2391 (if (setq check-pos (and lookbehind-submatch | |
2392 (match-end lookbehind-submatch))) | |
2393 (setq check-state (parse-partial-sexp | |
2394 pos check-pos paren-level nil state)) | |
2395 (setq check-pos pos | |
2396 check-state state)) | |
2397 | |
2398 ;; If we got a look behind subexpression and get an | |
2399 ;; insignificant match in something that isn't | |
2400 ;; syntactic whitespace (i.e. strings or in nested | |
2401 ;; parentheses), then we can never skip more than a | |
2402 ;; single character from the match position before | |
2403 ;; continuing the search. That since the look behind | |
2404 ;; subexpression might match the end of the | |
2405 ;; insignificant region. | |
2406 | |
2407 (cond | |
2408 ((setq tmp (elt check-state 3)) | |
2409 ;; Match inside a string. | |
2410 (if (or lookbehind-submatch | |
2411 (not (integerp tmp))) | |
2412 (goto-char (min (1+ pos) bound)) | |
2413 ;; Skip to the end of the string before continuing. | |
2414 (let ((ender (make-string 1 tmp)) (continue t)) | |
2415 (while (if (search-forward ender bound noerror) | |
2416 (progn | |
2417 (setq state (parse-partial-sexp | |
2418 pos (point) nil nil state) | |
2419 pos (point)) | |
2420 (elt state 3)) | |
2421 (setq continue nil))) | |
2422 continue))) | |
2423 | |
2424 ((elt check-state 7) | |
2425 ;; Match inside a line comment. Skip to eol. Use | |
2426 ;; `re-search-forward' instead of `skip-chars-forward' to get | |
2427 ;; the right bound behavior. | |
2428 (re-search-forward "[\n\r]" bound noerror)) | |
2429 | |
2430 ((elt check-state 4) | |
2431 ;; Match inside a block comment. Skip to the '*/'. | |
2432 (search-forward "*/" bound noerror)) | |
2433 | |
2434 ((and (not (elt check-state 5)) | |
2435 (eq (char-before check-pos) ?/) | |
2436 (memq (char-after check-pos) '(?/ ?*))) | |
2437 ;; Match in the middle of the opener of a block or line | |
2438 ;; comment. | |
2439 (if (= (char-after check-pos) ?/) | |
2440 (re-search-forward "[\n\r]" bound noerror) | |
2441 (search-forward "*/" bound noerror))) | |
2442 | |
2443 ((and not-inside-token | |
2444 (or (< check-pos last-token-end-pos) | |
2445 (< check-pos | |
2446 (save-excursion | |
2447 (goto-char check-pos) | |
2448 (c-end-of-current-token last-token-end-pos) | |
2449 (setq last-token-end-pos (point)))))) | |
2450 ;; Match inside a token. | |
2451 (cond ((<= (point) bound) | |
2452 (goto-char (min (1+ pos) bound)) | |
2453 t) | |
2454 (noerror nil) | |
2455 (t (signal 'search-failed "end of token")))) | |
2456 | |
2457 ((save-excursion | |
2458 (save-match-data | |
2459 (c-beginning-of-macro start))) | |
2460 ;; Match inside a macro. Skip to the end of it. | |
2461 (c-end-of-macro) | |
2462 (cond ((<= (point) bound) t) | |
2463 (noerror nil) | |
2464 (t (signal 'search-failed "end of macro")))) | |
2465 | |
2466 ((and paren-level | |
2467 (/= (setq tmp (car check-state)) 0)) | |
2468 (if (> tmp 0) | |
2469 ;; Match inside a nested paren sexp. | |
2470 (if lookbehind-submatch | |
2471 (goto-char (min (1+ pos) bound)) | |
2472 ;; Skip out of the paren quickly. | |
2473 (setq state (parse-partial-sexp pos bound 0 nil state) | |
2474 pos (point))) | |
2475 ;; Have exited the current paren sexp. The | |
2476 ;; `parse-partial-sexp' above has left us just after the | |
2477 ;; closing paren in this case. Just make | |
2478 ;; `re-search-forward' above fail in the appropriate way; | |
2479 ;; we'll adjust the leave off point below if necessary. | |
2480 (setq bound (point)))) | |
2481 | |
2482 (t | |
2483 ;; A real match. | |
2484 (setq found t) | |
2485 nil))))) | |
2486 | |
2487 (error | |
2488 (goto-char start) | |
2489 (signal (car err) (cdr err)))) | |
2490 | |
2491 ;;(message "c-syntactic-re-search-forward done %s" (or match-pos (point))) | |
2492 | |
2493 (if found | |
2494 (progn | |
2495 (goto-char match-pos) | |
2496 match-pos) | |
2497 | |
2498 ;; Search failed. Set point as appropriate. | |
2499 (cond ((eq noerror t) | |
2500 (goto-char start)) | |
2501 (paren-level | |
2502 (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1) | |
2503 (backward-char))) | |
2504 (t | |
2505 (goto-char bound))) | |
2506 nil))) | |
2507 | |
2508 (defun c-syntactic-skip-backward (skip-chars &optional limit) | |
2509 "Like `skip-chars-backward' but only look at syntactically relevant chars, | |
2510 i.e. don't stop at positions inside syntactic whitespace or string | |
2511 literals. Preprocessor directives are also ignored, with the exception | |
2512 of the one that the point starts within, if any. If LIMIT is given, | |
2513 it's assumed to be at a syntactically relevant position. | |
2514 | |
2515 This function does not do any hidden buffer changes." | |
2516 | |
2517 (let ((start (point)) | |
2518 ;; A list of syntactically relevant positions in descending | |
2519 ;; order. It's used to avoid scanning repeatedly over | |
2520 ;; potentially large regions with `parse-partial-sexp' to verify | |
2521 ;; each position. | |
2522 safe-pos-list | |
2523 ;; The result from `c-beginning-of-macro' at the start position or the | |
2524 ;; start position itself if it isn't within a macro. Evaluated on | |
2525 ;; demand. | |
2526 start-macro-beg) | |
2527 | |
2528 (while (progn | |
2529 (while (and | |
2530 (< (skip-chars-backward skip-chars limit) 0) | |
2531 | |
2532 ;; Use `parse-partial-sexp' from a safe position down to | |
2533 ;; the point to check if it's outside comments and | |
2534 ;; strings. | |
2535 (let ((pos (point)) safe-pos state) | |
2536 ;; Pick a safe position as close to the point as | |
2537 ;; possible. | |
2538 ;; | |
2539 ;; FIXME: Consult `syntax-ppss' here if our | |
2540 ;; cache doesn't give a good position. | |
2541 (while (and safe-pos-list | |
2542 (> (car safe-pos-list) (point))) | |
2543 (setq safe-pos-list (cdr safe-pos-list))) | |
2544 (unless (setq safe-pos (car-safe safe-pos-list)) | |
2545 (setq safe-pos (max (or (c-safe-position | |
2546 (point) (or c-state-cache | |
2547 (c-parse-state))) | |
2548 0) | |
2549 (point-min)) | |
2550 safe-pos-list (list safe-pos))) | |
2551 | |
2552 (while (progn | |
2553 (setq state (parse-partial-sexp | |
2554 safe-pos pos 0)) | |
2555 (< (point) pos)) | |
2556 ;; Cache positions along the way to use if we have to | |
2557 ;; back up more. Every closing paren on the same | |
2558 ;; level seems like fairly well spaced positions. | |
2559 (setq safe-pos (point) | |
2560 safe-pos-list (cons safe-pos safe-pos-list))) | |
2561 | |
2562 (cond | |
2563 ((or (elt state 3) (elt state 4)) | |
2564 ;; Inside string or comment. Continue search at the | |
2565 ;; beginning of it. | |
2566 (if (setq pos (nth 8 state)) | |
2567 ;; It's an emacs where `parse-partial-sexp' | |
2568 ;; supplies the starting position. | |
2569 (goto-char pos) | |
2570 (goto-char (car (c-literal-limits safe-pos)))) | |
2571 t) | |
2572 | |
2573 ((c-beginning-of-macro limit) | |
2574 ;; Inside a macro. | |
2575 (if (< (point) | |
2576 (or start-macro-beg | |
2577 (setq start-macro-beg | |
2578 (save-excursion | |
2579 (goto-char start) | |
2580 (c-beginning-of-macro limit) | |
2581 (point))))) | |
2582 t | |
2583 ;; It's inside the same macro we started in so it's | |
2584 ;; a relevant match. | |
2585 (goto-char pos) | |
2586 nil)))))) | |
2587 | |
2588 (> (point) | |
2589 (progn | |
2590 ;; Skip syntactic ws afterwards so that we don't stop at the | |
2591 ;; end of a comment if `skip-chars' is something like "^/". | |
2592 (c-backward-syntactic-ws) | |
2593 (point))))) | |
2594 | |
2595 (- (point) start))) | |
2596 | |
2597 | |
2598 ;; Tools for handling comments and string literals. | |
2599 | |
2600 (defun c-slow-in-literal (&optional lim detect-cpp) | |
2601 "Return the type of literal point is in, if any. | |
2602 The return value is `c' if in a C-style comment, `c++' if in a C++ | |
2603 style comment, `string' if in a string literal, `pound' if DETECT-CPP | |
2604 is non-nil and in a preprocessor line, or nil if somewhere else. | |
2605 Optional LIM is used as the backward limit of the search. If omitted, | |
2606 or nil, `c-beginning-of-defun' is used. | |
2607 | |
2608 The last point calculated is cached if the cache is enabled, i.e. if | |
2609 `c-in-literal-cache' is bound to a two element vector. | |
2610 | |
2611 This function does not do any hidden buffer changes." | |
2612 (if (and (vectorp c-in-literal-cache) | |
2613 (= (point) (aref c-in-literal-cache 0))) | |
2614 (aref c-in-literal-cache 1) | |
2615 (let ((rtn (save-excursion | |
2616 (let* ((pos (point)) | |
2617 (lim (or lim (progn | |
2618 (c-beginning-of-syntax) | |
2619 (point)))) | |
2620 (state (parse-partial-sexp lim pos))) | |
2621 (cond | |
2622 ((elt state 3) 'string) | |
2623 ((elt state 4) (if (elt state 7) 'c++ 'c)) | |
2624 ((and detect-cpp (c-beginning-of-macro lim)) 'pound) | |
2625 (t nil)))))) | |
2626 ;; cache this result if the cache is enabled | |
2627 (if (not c-in-literal-cache) | |
2628 (setq c-in-literal-cache (vector (point) rtn))) | |
2629 rtn))) | |
2630 | |
2631 ;; XEmacs has a built-in function that should make this much quicker. | |
2632 ;; I don't think we even need the cache, which makes our lives more | |
2633 ;; complicated anyway. In this case, lim is only used to detect | |
2634 ;; cpp directives. | |
2635 ;; | |
2636 ;; Note that there is a bug in Xemacs's buffer-syntactic-context when used in | |
2637 ;; conjunction with syntax-table-properties. The bug is present in, e.g., | |
2638 ;; Xemacs 21.4.4. It manifested itself thus: | |
2639 ;; | |
2640 ;; Starting with an empty AWK Mode buffer, type | |
2641 ;; /regexp/ {<C-j> | |
2642 ;; Point gets wrongly left at column 0, rather than being indented to tab-width. | |
2643 ;; | |
2644 ;; AWK Mode is designed such that when the first / is typed, it gets the | |
2645 ;; syntax-table property "string fence". When the second / is typed, BOTH /s | |
2646 ;; are given the s-t property "string". However, buffer-syntactic-context | |
2647 ;; fails to take account of the change of the s-t property on the opening / to | |
2648 ;; "string", and reports that the { is within a string started by the second /. | |
2649 ;; | |
2650 ;; The workaround for this is for the AWK Mode initialisation to switch the | |
2651 ;; defalias for c-in-literal to c-slow-in-literal. This will slow down other | |
2652 ;; cc-modes in Xemacs whenever an awk-buffer has been initialised. | |
2653 ;; | |
2654 ;; (Alan Mackenzie, 2003/4/30). | |
2655 | |
2656 (defun c-fast-in-literal (&optional lim detect-cpp) | |
2657 (let ((context (buffer-syntactic-context))) | |
2658 (cond | |
2659 ((eq context 'string) 'string) | |
2660 ((eq context 'comment) 'c++) | |
2661 ((eq context 'block-comment) 'c) | |
2662 ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound)))) | |
2663 | |
2664 (defalias 'c-in-literal | |
2665 (if (fboundp 'buffer-syntactic-context) | |
2666 'c-fast-in-literal ; Xemacs | |
2667 'c-slow-in-literal)) ; GNU Emacs | |
2668 | |
2669 ;; The defalias above isn't enough to shut up the byte compiler. | |
2670 (cc-bytecomp-defun c-in-literal) | |
2671 | |
2672 (defun c-literal-limits (&optional lim near not-in-delimiter) | |
2673 "Return a cons of the beginning and end positions of the comment or | |
2674 string surrounding point (including both delimiters), or nil if point | |
2675 isn't in one. If LIM is non-nil, it's used as the \"safe\" position | |
2676 to start parsing from. If NEAR is non-nil, then the limits of any | |
2677 literal next to point is returned. \"Next to\" means there's only | |
2678 spaces and tabs between point and the literal. The search for such a | |
2679 literal is done first in forward direction. If NOT-IN-DELIMITER is | |
2680 non-nil, the case when point is inside a starting delimiter won't be | |
2681 recognized. This only has effect for comments, which have starting | |
2682 delimiters with more than one character. | |
2683 | |
2684 This function does not do any hidden buffer changes." | |
2685 | |
2686 (save-excursion | |
2687 (let* ((pos (point)) | |
2688 (lim (or lim (progn | |
2689 (c-beginning-of-syntax) | |
2690 (point)))) | |
2691 (state (parse-partial-sexp lim pos))) | |
2692 | |
2693 (cond ((elt state 3) | |
2694 ;; String. Search backward for the start. | |
2695 (while (elt state 3) | |
2696 (search-backward (make-string 1 (elt state 3))) | |
2697 (setq state (parse-partial-sexp lim (point)))) | |
2698 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
2699 (point-max)))) | |
2700 | |
2701 ((elt state 7) | |
2702 ;; Line comment. Search from bol for the comment starter. | |
2703 (beginning-of-line) | |
2704 (setq state (parse-partial-sexp lim (point)) | |
2705 lim (point)) | |
2706 (while (not (elt state 7)) | |
2707 (search-forward "//") ; Should never fail. | |
2708 (setq state (parse-partial-sexp | |
2709 lim (point) nil nil state) | |
2710 lim (point))) | |
2711 (backward-char 2) | |
2712 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2713 | |
2714 ((elt state 4) | |
2715 ;; Block comment. Search backward for the comment starter. | |
2716 (while (elt state 4) | |
2717 (search-backward "/*") ; Should never fail. | |
2718 (setq state (parse-partial-sexp lim (point)))) | |
2719 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2720 | |
2721 ((and (not not-in-delimiter) | |
2722 (not (elt state 5)) | |
2723 (eq (char-before) ?/) | |
2724 (looking-at "[/*]")) | |
2725 ;; We're standing in a comment starter. | |
2726 (backward-char 1) | |
2727 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2728 | |
2729 (near | |
2730 (goto-char pos) | |
2731 | |
2732 ;; Search forward for a literal. | |
2733 (skip-chars-forward " \t") | |
2734 | |
2735 (cond | |
2736 ((looking-at c-string-limit-regexp) ; String. | |
2737 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
2738 (point-max)))) | |
2739 | |
2740 ((looking-at c-comment-start-regexp) ; Line or block comment. | |
2741 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2742 | |
2743 (t | |
2744 ;; Search backward. | |
2745 (skip-chars-backward " \t") | |
2746 | |
2747 (let ((end (point)) beg) | |
2748 (cond | |
2749 ((save-excursion | |
2750 (< (skip-syntax-backward c-string-syntax) 0)) ; String. | |
2751 (setq beg (c-safe (c-backward-sexp 1) (point)))) | |
2752 | |
2753 ((and (c-safe (forward-char -2) t) | |
2754 (looking-at "*/")) | |
2755 ;; Block comment. Due to the nature of line | |
2756 ;; comments, they will always be covered by the | |
2757 ;; normal case above. | |
2758 (goto-char end) | |
2759 (c-backward-single-comment) | |
2760 ;; If LIM is bogus, beg will be bogus. | |
2761 (setq beg (point)))) | |
2762 | |
2763 (if beg (cons beg end)))))) | |
2764 )))) | |
2765 | |
2766 (defun c-literal-limits-fast (&optional lim near not-in-delimiter) | |
2767 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp' | |
2768 ;; returns the pos of the comment start. | |
2769 | |
2770 "Return a cons of the beginning and end positions of the comment or | |
2771 string surrounding point (including both delimiters), or nil if point | |
2772 isn't in one. If LIM is non-nil, it's used as the \"safe\" position | |
2773 to start parsing from. If NEAR is non-nil, then the limits of any | |
2774 literal next to point is returned. \"Next to\" means there's only | |
2775 spaces and tabs between point and the literal. The search for such a | |
2776 literal is done first in forward direction. If NOT-IN-DELIMITER is | |
2777 non-nil, the case when point is inside a starting delimiter won't be | |
2778 recognized. This only has effect for comments, which have starting | |
2779 delimiters with more than one character. | |
2780 | |
2781 This function does not do any hidden buffer changes." | |
2782 | |
2783 (save-excursion | |
2784 (let* ((pos (point)) | |
2785 (lim (or lim (progn | |
2786 (c-beginning-of-syntax) | |
2787 (point)))) | |
2788 (state (parse-partial-sexp lim pos))) | |
2789 | |
2790 (cond ((elt state 3) ; String. | |
2791 (goto-char (elt state 8)) | |
2792 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
2793 (point-max)))) | |
2794 | |
2795 ((elt state 4) ; Comment. | |
2796 (goto-char (elt state 8)) | |
2797 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2798 | |
2799 ((and (not not-in-delimiter) | |
2800 (not (elt state 5)) | |
2801 (eq (char-before) ?/) | |
2802 (looking-at "[/*]")) | |
2803 ;; We're standing in a comment starter. | |
2804 (backward-char 1) | |
2805 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2806 | |
2807 (near | |
2808 (goto-char pos) | |
2809 | |
2810 ;; Search forward for a literal. | |
2811 (skip-chars-forward " \t") | |
2812 | |
2813 (cond | |
2814 ((looking-at c-string-limit-regexp) ; String. | |
2815 (cons (point) (or (c-safe (c-forward-sexp 1) (point)) | |
2816 (point-max)))) | |
2817 | |
2818 ((looking-at c-comment-start-regexp) ; Line or block comment. | |
2819 (cons (point) (progn (c-forward-single-comment) (point)))) | |
2820 | |
2821 (t | |
2822 ;; Search backward. | |
2823 (skip-chars-backward " \t") | |
2824 | |
2825 (let ((end (point)) beg) | |
2826 (cond | |
2827 ((save-excursion | |
2828 (< (skip-syntax-backward c-string-syntax) 0)) ; String. | |
2829 (setq beg (c-safe (c-backward-sexp 1) (point)))) | |
2830 | |
2831 ((and (c-safe (forward-char -2) t) | |
2832 (looking-at "*/")) | |
2833 ;; Block comment. Due to the nature of line | |
2834 ;; comments, they will always be covered by the | |
2835 ;; normal case above. | |
2836 (goto-char end) | |
2837 (c-backward-single-comment) | |
2838 ;; If LIM is bogus, beg will be bogus. | |
2839 (setq beg (point)))) | |
2840 | |
2841 (if beg (cons beg end)))))) | |
2842 )))) | |
2843 | |
2844 (if (memq 'pps-extended-state c-emacs-features) | |
2845 (defalias 'c-literal-limits 'c-literal-limits-fast)) | |
2846 | |
2847 (defun c-collect-line-comments (range) | |
2848 "If the argument is a cons of two buffer positions (such as returned by | |
2849 `c-literal-limits'), and that range contains a C++ style line comment, | |
2850 then an extended range is returned that contains all adjacent line | |
2851 comments (i.e. all comments that starts in the same column with no | |
2852 empty lines or non-whitespace characters between them). Otherwise the | |
2853 argument is returned. | |
2854 | |
2855 This function does not do any hidden buffer changes." | |
2856 (save-excursion | |
2857 (condition-case nil | |
2858 (if (and (consp range) (progn | |
2859 (goto-char (car range)) | |
2860 (looking-at "//"))) | |
2861 (let ((col (current-column)) | |
2862 (beg (point)) | |
2863 (bopl (c-point 'bopl)) | |
2864 (end (cdr range))) | |
2865 ;; Got to take care in the backward direction to handle | |
2866 ;; comments which are preceded by code. | |
2867 (while (and (c-backward-single-comment) | |
2868 (>= (point) bopl) | |
2869 (looking-at "//") | |
2870 (= col (current-column))) | |
2871 (setq beg (point) | |
2872 bopl (c-point 'bopl))) | |
2873 (goto-char end) | |
2874 (while (and (progn (skip-chars-forward " \t") | |
2875 (looking-at "//")) | |
2876 (= col (current-column)) | |
2877 (prog1 (zerop (forward-line 1)) | |
2878 (setq end (point))))) | |
2879 (cons beg end)) | |
2880 range) | |
2881 (error range)))) | |
2882 | |
2883 (defun c-literal-type (range) | |
2884 "Convenience function that given the result of `c-literal-limits', | |
2885 returns nil or the type of literal that the range surrounds. It's | |
2886 much faster than using `c-in-literal' and is intended to be used when | |
2887 you need both the type of a literal and its limits. | |
2888 | |
2889 This function does not do any hidden buffer changes." | |
2890 (if (consp range) | |
2891 (save-excursion | |
2892 (goto-char (car range)) | |
2893 (cond ((looking-at c-string-limit-regexp) 'string) | |
2894 ((or (looking-at "//") ; c++ line comment | |
2895 (and (looking-at "\\s<") ; comment starter | |
2896 (looking-at "#"))) ; awk comment. | |
2897 'c++) | |
2898 (t 'c))) ; Assuming the range is valid. | |
2899 range)) | |
2900 | |
2901 | |
2902 ;; `c-find-decl-spots' and accompanying stuff. | |
2903 | |
2904 ;; Variables used in `c-find-decl-spots' to cache the search done for | |
2905 ;; the first declaration in the last call. When that function starts, | |
2906 ;; it needs to back up over syntactic whitespace to look at the last | |
2907 ;; token before the region being searched. That can sometimes cause | |
2908 ;; moves back and forth over a quite large region of comments and | |
2909 ;; macros, which would be repeated for each changed character when | |
2910 ;; we're called during fontification, since font-lock refontifies the | |
2911 ;; current line for each change. Thus it's worthwhile to cache the | |
2912 ;; first match. | |
2913 ;; | |
2914 ;; `c-find-decl-syntactic-pos' is a syntactically relevant position in | |
2915 ;; the syntactic whitespace less or equal to some start position. | |
2916 ;; There's no cached value if it's nil. | |
2917 ;; | |
2918 ;; `c-find-decl-match-pos' is the match position if | |
2919 ;; `c-find-decl-prefix-search' matched before the syntactic whitespace | |
2920 ;; at `c-find-decl-syntactic-pos', or nil if there's no such match. | |
2921 (defvar c-find-decl-syntactic-pos nil) | |
2922 (make-variable-buffer-local 'c-find-decl-syntactic-pos) | |
2923 (defvar c-find-decl-match-pos nil) | |
2924 (make-variable-buffer-local 'c-find-decl-match-pos) | |
2925 | |
2926 (defsubst c-invalidate-find-decl-cache (change-min-pos) | |
2927 (and c-find-decl-syntactic-pos | |
2928 (< change-min-pos c-find-decl-syntactic-pos) | |
2929 (setq c-find-decl-syntactic-pos nil))) | |
2930 | |
2931 ; (defface c-debug-decl-spot-face | |
2932 ; '((t (:background "Turquoise"))) | |
2933 ; "Debug face to mark the spots where `c-find-decl-spots' stopped.") | |
2934 ; (defface c-debug-decl-sws-face | |
2935 ; '((t (:background "Khaki"))) | |
2936 ; "Debug face to mark the syntactic whitespace between the declaration | |
2937 ; spots and the preceding token end.") | |
2938 | |
2939 (defmacro c-debug-put-decl-spot-faces (match-pos decl-pos) | |
2940 (when (facep 'c-debug-decl-spot-face) | |
2941 `(let ((match-pos ,match-pos) (decl-pos ,decl-pos)) | |
2942 (c-debug-add-face (max match-pos (point-min)) decl-pos | |
2943 'c-debug-decl-sws-face) | |
2944 (c-debug-add-face decl-pos (min (1+ decl-pos) (point-max)) | |
2945 'c-debug-decl-spot-face)))) | |
2946 (defmacro c-debug-remove-decl-spot-faces (beg end) | |
2947 (when (facep 'c-debug-decl-spot-face) | |
2948 `(progn | |
2949 (c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face) | |
2950 (c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face)))) | |
2951 | |
2952 (defmacro c-find-decl-prefix-search () | |
2953 ;; Macro used inside `c-find-decl-spots'. It ought to be a defun, | |
2954 ;; but it contains lots of free variables that refer to things | |
2955 ;; inside `c-find-decl-spots'. The point is left at `cfd-match-pos' | |
2956 ;; if there is a match, otherwise at `cfd-limit'. | |
2957 | |
2958 '(progn | |
2959 ;; Find the next property match position if we haven't got one already. | |
2960 (unless cfd-prop-match | |
2961 (save-excursion | |
2962 (while (progn | |
2963 (goto-char (next-single-property-change | |
2964 (point) 'c-type nil cfd-limit)) | |
2965 (and (< (point) cfd-limit) | |
2966 (not (eq (c-get-char-property (1- (point)) 'c-type) | |
2967 'c-decl-end))))) | |
2968 (setq cfd-prop-match (point)))) | |
2969 | |
2970 ;; Find the next `c-decl-prefix-re' match if we haven't got one already. | |
2971 (unless cfd-re-match | |
2972 (while (and (setq cfd-re-match | |
2973 (re-search-forward c-decl-prefix-re cfd-limit 'move)) | |
2974 (c-got-face-at (1- (setq cfd-re-match (match-end 1))) | |
2975 c-literal-faces)) | |
2976 ;; Search again if the match is within a comment or a string literal. | |
2977 (while (progn | |
2978 (goto-char (next-single-property-change | |
2979 cfd-re-match 'face nil cfd-limit)) | |
2980 (and (< (point) cfd-limit) | |
2981 (c-got-face-at (point) c-literal-faces))) | |
2982 (setq cfd-re-match (point)))) | |
2983 (unless cfd-re-match | |
2984 (setq cfd-re-match cfd-limit))) | |
2985 | |
2986 ;; Choose whichever match is closer to the start. | |
2987 (if (< cfd-re-match cfd-prop-match) | |
2988 (setq cfd-match-pos cfd-re-match | |
2989 cfd-re-match nil) | |
2990 (setq cfd-match-pos cfd-prop-match | |
2991 cfd-prop-match nil)) | |
2992 | |
2993 (goto-char cfd-match-pos) | |
2994 | |
2995 (when (< cfd-match-pos cfd-limit) | |
2996 ;; Skip forward past comments only so we don't skip macros. | |
2997 (c-forward-comments) | |
2998 ;; Set the position to continue at. We can avoid going over | |
2999 ;; the comments skipped above a second time, but it's possible | |
3000 ;; that the comment skipping has taken us past `cfd-prop-match' | |
3001 ;; since the property might be used inside comments. | |
3002 (setq cfd-continue-pos (if cfd-prop-match | |
3003 (min cfd-prop-match (point)) | |
3004 (point)))))) | |
3005 | |
3006 (defun c-find-decl-spots (cfd-limit cfd-decl-re cfd-face-checklist cfd-fun) | |
3007 ;; Call CFD-FUN for each possible spot for a declaration from the | |
3008 ;; point to CFD-LIMIT. A spot for a declaration is the first token | |
3009 ;; in the buffer and each token after the ones matched by | |
3010 ;; `c-decl-prefix-re' and after the occurrences of the `c-type' | |
3011 ;; property with the value `c-decl-end' (if `c-type-decl-end-used' | |
3012 ;; is set). Only a spot that match CFD-DECL-RE and whose face is in | |
3013 ;; the CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The | |
3014 ;; face check is disabled if CFD-FACE-CHECKLIST is nil. | |
3015 ;; | |
3016 ;; If the match is inside a macro then the buffer is narrowed to the | |
3017 ;; end of it, so that CFD-FUN can investigate the following tokens | |
3018 ;; without matching something that begins inside a macro and ends | |
3019 ;; outside it. It's to avoid this work that the CFD-DECL-RE and | |
3020 ;; CFD-FACE-CHECKLIST checks exist. | |
3021 ;; | |
3022 ;; CFD-FUN is called with point at the start of the spot. It's | |
3023 ;; passed two arguments: The first is the end position of the token | |
3024 ;; that `c-decl-prefix-re' matched, or 0 for the implicit match at | |
3025 ;; bob. The second is a flag that is t when the match is inside a | |
3026 ;; macro. | |
3027 ;; | |
3028 ;; It's assumed that comment and strings are fontified in the | |
3029 ;; searched range. | |
3030 ;; | |
3031 ;; This is mainly used in fontification, and so has an elaborate | |
3032 ;; cache to handle repeated calls from the same start position; see | |
3033 ;; the variables above. | |
3034 ;; | |
3035 ;; All variables in this function begin with `cfd-' to avoid name | |
3036 ;; collision with the (dynamically bound) variables used in CFD-FUN. | |
3037 | |
3038 (let ((cfd-buffer-end (point-max)) | |
3039 ;; The last regexp match found by `c-find-decl-prefix-search'. | |
3040 cfd-re-match | |
3041 ;; The last `c-decl-end' found by `c-find-decl-prefix-search'. | |
3042 ;; If searching for the property isn't needed then we disable | |
3043 ;; it by faking a first match at the limit. | |
3044 (cfd-prop-match (unless c-type-decl-end-used cfd-limit)) | |
3045 ;; The position of the last match found by | |
3046 ;; `c-find-decl-prefix-search'. For regexp matches it's the | |
3047 ;; end of the matched token, for property matches it's the end | |
3048 ;; of the property. 0 for the implicit match at bob. | |
3049 ;; `cfd-limit' if there's no match. | |
3050 (cfd-match-pos cfd-limit) | |
3051 ;; The position to continue searching at. | |
3052 cfd-continue-pos | |
3053 ;; The position of the last "real" token we've stopped at. | |
3054 ;; This can be greater than `cfd-continue-pos' when we get | |
3055 ;; hits inside macros or at `c-decl-end' positions inside | |
3056 ;; comments. | |
3057 (cfd-token-pos 0) | |
3058 ;; The end position of the last entered macro. | |
3059 (cfd-macro-end 0)) | |
3060 | |
3061 ;; Initialize by finding a syntactically relevant start position | |
3062 ;; before the point, and do the first `c-decl-prefix-re' search | |
3063 ;; unless we're at bob. | |
3064 | |
3065 (let ((start-pos (point)) syntactic-pos) | |
3066 ;; Must back up a bit since we look for the end of the previous | |
3067 ;; statement or declaration, which is earlier than the first | |
3068 ;; returned match. | |
3069 | |
3070 (when (c-got-face-at (point) c-literal-faces) | |
3071 ;; But first we need to move to a syntactically relevant | |
3072 ;; position. Use the faces to back up to the start of the | |
3073 ;; comment or string literal. | |
3074 (when (and (not (bobp)) | |
3075 (c-got-face-at (1- (point)) c-literal-faces)) | |
3076 (while (progn | |
3077 (goto-char (previous-single-property-change | |
3078 (point) 'face nil (point-min))) | |
3079 (and (> (point) (point-min)) | |
3080 (c-got-face-at (point) c-literal-faces))))) | |
3081 | |
3082 ;; XEmacs doesn't fontify the quotes surrounding string | |
3083 ;; literals. | |
3084 (and (featurep 'xemacs) | |
3085 (eq (get-text-property (point) 'face) | |
3086 'font-lock-string-face) | |
3087 (not (bobp)) | |
3088 (progn (backward-char) | |
3089 (not (looking-at c-string-limit-regexp))) | |
3090 (forward-char)) | |
3091 | |
3092 ;; The font lock package might not have fontified the start of | |
3093 ;; the literal at all so check that we have arrived at | |
3094 ;; something that looks like a start or else resort to | |
3095 ;; `c-literal-limits'. | |
3096 (unless (looking-at c-literal-start-regexp) | |
3097 (let ((range (c-literal-limits))) | |
3098 (if range (goto-char (car range)))))) | |
3099 | |
3100 ;; Must back out of any macro so that we don't miss any | |
3101 ;; declaration that could follow after it, unless the limit is | |
3102 ;; inside the macro. We only check that for the current line to | |
3103 ;; save some time; it's enough for the by far most common case | |
3104 ;; when font-lock refontifies the current line only. | |
3105 (when (save-excursion | |
3106 (and (= (forward-line 1) 0) | |
3107 (or (< (c-point 'eol) cfd-limit) | |
3108 (progn (backward-char) | |
3109 (not (eq (char-before) ?\\)))))) | |
3110 (c-beginning-of-macro)) | |
3111 | |
3112 ;; Clear the cache if it applied further down. | |
3113 (c-invalidate-find-decl-cache start-pos) | |
3114 | |
3115 (setq syntactic-pos (point)) | |
3116 (c-backward-syntactic-ws c-find-decl-syntactic-pos) | |
3117 | |
3118 ;; If we hit `c-find-decl-syntactic-pos' and | |
3119 ;; `c-find-decl-match-pos' is set then we install the cached | |
3120 ;; values. If we hit `c-find-decl-syntactic-pos' and | |
3121 ;; `c-find-decl-match-pos' is nil then we know there's no decl | |
3122 ;; prefix in the whitespace before `c-find-decl-syntactic-pos' | |
3123 ;; and so we can continue the search from this point. If we | |
3124 ;; didn't hit `c-find-decl-syntactic-pos' then we're now in the | |
3125 ;; right spot to begin searching anyway. | |
3126 (if (and (eq (point) c-find-decl-syntactic-pos) | |
3127 c-find-decl-match-pos) | |
3128 | |
3129 (progn | |
3130 ;; The match is always outside macros and comments so we | |
3131 ;; start at the next token. The loop below will later go | |
3132 ;; back using `cfd-continue-pos' to fix declarations inside | |
3133 ;; the syntactic ws. | |
3134 (goto-char syntactic-pos) | |
3135 (c-forward-syntactic-ws) | |
3136 (setq cfd-match-pos c-find-decl-match-pos | |
3137 cfd-continue-pos syntactic-pos) | |
3138 (if (< cfd-continue-pos (point)) | |
3139 (setq cfd-token-pos (point)))) | |
3140 | |
3141 (setq c-find-decl-syntactic-pos syntactic-pos) | |
3142 | |
3143 (when (if (bobp) | |
3144 ;; Always consider bob a match to get the first declaration | |
3145 ;; in the file. Do this separately instead of letting | |
3146 ;; `c-decl-prefix-re' match bob, so that it always can | |
3147 ;; consume at least one character to ensure that we won't | |
3148 ;; get stuck in an infinite loop. | |
3149 (setq cfd-re-match 0) | |
3150 (backward-char) | |
3151 (c-beginning-of-current-token) | |
3152 (< (point) cfd-limit)) | |
3153 ;; Do an initial search now. In the bob case above it's only done | |
3154 ;; to search for the `c-type' property. | |
3155 (c-find-decl-prefix-search)) | |
3156 | |
3157 ;; Advance `cfd-continue-pos' if we got a hit before the start | |
3158 ;; position. The earliest position that could affect after | |
3159 ;; the start position is the char before the preceding | |
3160 ;; comments. | |
3161 (when (and cfd-continue-pos (< cfd-continue-pos start-pos)) | |
3162 (goto-char syntactic-pos) | |
3163 (c-backward-comments) | |
3164 (unless (bobp) | |
3165 (backward-char) | |
3166 (c-beginning-of-current-token)) | |
3167 (setq cfd-continue-pos (max cfd-continue-pos (point)))) | |
3168 | |
3169 ;; If we got a match it's always outside macros and comments so | |
3170 ;; advance to the next token and set `cfd-token-pos'. The loop | |
3171 ;; below will later go back using `cfd-continue-pos' to fix | |
3172 ;; declarations inside the syntactic ws. | |
3173 (when (and (< cfd-match-pos cfd-limit) (< (point) syntactic-pos)) | |
3174 (goto-char syntactic-pos) | |
3175 (c-forward-syntactic-ws) | |
3176 (and cfd-continue-pos | |
3177 (< cfd-continue-pos (point)) | |
3178 (setq cfd-token-pos (point)))) | |
3179 | |
3180 (setq c-find-decl-match-pos (and (< cfd-match-pos start-pos) | |
3181 cfd-match-pos)))) | |
3182 | |
3183 ;; Now loop. We already got the first match. | |
3184 | |
3185 (while (progn | |
3186 (while (and | |
3187 (< cfd-match-pos cfd-limit) | |
3188 | |
3189 (or | |
3190 ;; Kludge to filter out matches on the "<" that | |
3191 ;; aren't open parens, for the sake of languages | |
3192 ;; that got `c-recognize-<>-arglists' set. | |
3193 (and (eq (char-before cfd-match-pos) ?<) | |
3194 (not (c-get-char-property (1- cfd-match-pos) | |
3195 'syntax-table))) | |
3196 | |
3197 ;; If `cfd-continue-pos' is less or equal to | |
3198 ;; `cfd-token-pos', we've got a hit inside a macro | |
3199 ;; that's in the syntactic whitespace before the last | |
3200 ;; "real" declaration we've checked. If they're equal | |
3201 ;; we've arrived at the declaration a second time, so | |
3202 ;; there's nothing to do. | |
3203 (= cfd-continue-pos cfd-token-pos) | |
3204 | |
3205 (progn | |
3206 ;; If `cfd-continue-pos' is less than `cfd-token-pos' | |
3207 ;; we're still searching for declarations embedded in | |
3208 ;; the syntactic whitespace. In that case we need | |
3209 ;; only to skip comments and not macros, since they | |
3210 ;; can't be nested, and that's already been done in | |
3211 ;; `c-find-decl-prefix-search'. | |
3212 (when (> cfd-continue-pos cfd-token-pos) | |
3213 (c-forward-syntactic-ws) | |
3214 (setq cfd-token-pos (point))) | |
3215 | |
3216 ;; Continue if the following token fails the | |
3217 ;; CFD-DECL-RE and CFD-FACE-CHECKLIST checks. | |
3218 (when (or (>= (point) cfd-limit) | |
3219 (not (looking-at cfd-decl-re)) | |
3220 (and cfd-face-checklist | |
3221 (not (c-got-face-at | |
3222 (point) cfd-face-checklist)))) | |
3223 (goto-char cfd-continue-pos) | |
3224 t))) | |
3225 | |
3226 (< (point) cfd-limit)) | |
3227 (c-find-decl-prefix-search)) | |
3228 | |
3229 (< (point) cfd-limit)) | |
3230 | |
3231 (when (progn | |
3232 ;; Narrow to the end of the macro if we got a hit inside | |
3233 ;; one, to avoid recognizing things that start inside | |
3234 ;; the macro and end outside it. | |
3235 (when (> cfd-match-pos cfd-macro-end) | |
3236 ;; Not in the same macro as in the previous round. | |
3237 (save-excursion | |
3238 (goto-char cfd-match-pos) | |
3239 (setq cfd-macro-end | |
3240 (if (save-excursion (and (c-beginning-of-macro) | |
3241 (< (point) cfd-match-pos))) | |
3242 (progn (c-end-of-macro) | |
3243 (point)) | |
3244 0)))) | |
3245 | |
3246 (if (zerop cfd-macro-end) | |
3247 t | |
3248 (if (> cfd-macro-end (point)) | |
3249 (progn (narrow-to-region (point-min) cfd-macro-end) | |
3250 t) | |
3251 ;; The matched token was the last thing in the | |
3252 ;; macro, so the whole match is bogus. | |
3253 (setq cfd-macro-end 0) | |
3254 nil))) | |
3255 | |
3256 (c-debug-put-decl-spot-faces cfd-match-pos (point)) | |
3257 (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0)) | |
3258 | |
3259 (when (/= cfd-macro-end 0) | |
3260 ;; Restore limits if we did macro narrowment above. | |
3261 (narrow-to-region (point-min) cfd-buffer-end))) | |
3262 | |
3263 (goto-char cfd-continue-pos) | |
3264 (if (= cfd-continue-pos cfd-limit) | |
3265 (setq cfd-match-pos cfd-limit) | |
3266 (c-find-decl-prefix-search))))) | |
3267 | |
3268 | |
3269 ;; A cache for found types. | |
3270 | |
3271 ;; Buffer local variable that contains an obarray with the types we've | |
3272 ;; found. If a declaration is recognized somewhere we record the | |
3273 ;; fully qualified identifier in it to recognize it as a type | |
3274 ;; elsewhere in the file too. This is not accurate since we do not | |
3275 ;; bother with the scoping rules of the languages, but in practice the | |
3276 ;; same name is seldom used as both a type and something else in a | |
3277 ;; file, and we only use this as a last resort in ambiguous cases (see | |
3278 ;; `c-font-lock-declarations'). | |
3279 (defvar c-found-types nil) | |
3280 (make-variable-buffer-local 'c-found-types) | |
3281 | |
3282 (defsubst c-clear-found-types () | |
3283 ;; Clears `c-found-types'. | |
3284 ;; | |
3285 ;; This function does not do any hidden buffer changes. | |
3286 (setq c-found-types (make-vector 53 0))) | |
3287 | |
3288 (defun c-add-type (from to) | |
3289 ;; Add the given region as a type in `c-found-types'. If the region | |
3290 ;; doesn't match an existing type but there is a type which is equal | |
3291 ;; to the given one except that the last character is missing, then | |
3292 ;; the shorter type is removed. That's done to avoid adding all | |
3293 ;; prefixes of a type as it's being entered and font locked. This | |
3294 ;; doesn't cover cases like when characters are removed from a type | |
3295 ;; or added in the middle. We'd need the position of point when the | |
3296 ;; font locking is invoked to solve this well. | |
3297 (unless (and c-recognize-<>-arglists | |
3298 (save-excursion | |
3299 (goto-char from) | |
3300 (c-syntactic-re-search-forward "<" to t))) | |
3301 ;; To avoid storing very long strings, do not add a type that | |
3302 ;; contains '<' in languages with angle bracket arglists, since | |
3303 ;; the type then probably contains a C++ template spec and those | |
3304 ;; can be fairly sized programs in themselves. | |
3305 (let ((type (c-syntactic-content from to))) | |
3306 (unless (intern-soft type c-found-types) | |
3307 (unintern (substring type 0 -1) c-found-types) | |
3308 (intern type c-found-types))))) | |
3309 | |
3310 (defsubst c-check-type (from to) | |
3311 ;; Return non-nil if the given region contains a type in | |
3312 ;; `c-found-types'. | |
3313 (intern-soft (c-syntactic-content from to) c-found-types)) | |
3314 | |
3315 (defun c-list-found-types () | |
3316 ;; Return all the types in `c-found-types' as a sorted list of | |
3317 ;; strings. | |
3318 (let (type-list) | |
3319 (mapatoms (lambda (type) | |
3320 (setq type-list (cons (symbol-name type) | |
3321 type-list))) | |
3322 c-found-types) | |
3323 (sort type-list 'string-lessp))) | |
3324 | |
3325 | |
3326 ;; Handling of small scale constructs like types and names. | |
3327 | |
3328 (defun c-remove-<>-arglist-properties (from to) | |
3329 ;; Remove all the properties put by `c-forward-<>-arglist' in the | |
3330 ;; specified region. Point is clobbered. | |
3331 (goto-char from) | |
3332 (while (progn (skip-chars-forward "^<>," to) | |
3333 (< (point) to)) | |
3334 (if (eq (char-after) ?,) | |
3335 (when (eq (c-get-char-property (point) 'c-type) 'c-<>-arg-sep) | |
3336 (c-clear-char-property (point) 'c-type)) | |
3337 (c-clear-char-property (point) 'syntax-table)) | |
3338 (forward-char))) | |
3339 | |
3340 ;; Dynamically bound variable that instructs `c-forward-type' to also | |
3341 ;; treat possible types (i.e. those that it normally returns 'maybe or | |
3342 ;; 'found for) as actual types (and always return 'found for them). | |
3343 ;; This means that it records them in `c-record-type-identifiers' if | |
3344 ;; that is set, and that it adds them to `c-found-types'. | |
3345 (defvar c-promote-possible-types nil) | |
3346 | |
3347 ;; Dynamically bound variable that instructs `c-forward-<>-arglist' to | |
3348 ;; not accept arglists that contain more than one argument. It's used | |
3349 ;; to handle ambiguous cases like "foo (a < b, c > d)" better. | |
3350 (defvar c-disallow-comma-in-<>-arglists nil) | |
3351 | |
3352 ;; Dynamically bound variables that instructs `c-forward-name', | |
3353 ;; `c-forward-type' and `c-forward-<>-arglist' to record the ranges of | |
3354 ;; all the type and reference identifiers they encounter. They will | |
3355 ;; build lists on these variables where each element is a cons of the | |
3356 ;; buffer positions surrounding each identifier. This recording is | |
3357 ;; only activated when `c-record-type-identifiers' is non-nil. | |
3358 ;; | |
3359 ;; All known types that can't be identifiers are recorded, and also | |
3360 ;; other possible types if `c-promote-possible-types' is set. | |
3361 ;; Recording is however disabled inside angle bracket arglists that | |
3362 ;; are encountered inside names and other angle bracket arglists. | |
3363 ;; Such occurences are taken care of by `c-font-lock-<>-arglists' | |
3364 ;; instead. | |
3365 ;; | |
3366 ;; Only the names in C++ template style references (e.g. "tmpl" in | |
3367 ;; "tmpl<a,b>::foo") are recorded as references, other references | |
3368 ;; aren't handled here. | |
3369 (defvar c-record-type-identifiers nil) | |
3370 (defvar c-record-ref-identifiers nil) | |
3371 | |
3372 ;; If `c-record-type-identifiers' is set, this will receive a cons | |
3373 ;; cell of the range of the last single identifier symbol stepped over | |
3374 ;; by `c-forward-name' if it's successful. This is the range that | |
3375 ;; should be put on one of the record lists by the caller. It's | |
3376 ;; assigned nil if there's no such symbol in the name. | |
3377 (defvar c-last-identifier-range nil) | |
3378 | |
3379 (defmacro c-record-type-id (range) | |
3380 (if (eq (car-safe range) 'cons) | |
3381 ;; Always true. | |
3382 `(setq c-record-type-identifiers | |
3383 (cons ,range c-record-type-identifiers)) | |
3384 `(let ((range ,range)) | |
3385 (if range | |
3386 (setq c-record-type-identifiers | |
3387 (cons range c-record-type-identifiers)))))) | |
3388 | |
3389 (defmacro c-record-ref-id (range) | |
3390 (if (eq (car-safe range) 'cons) | |
3391 ;; Always true. | |
3392 `(setq c-record-ref-identifiers | |
3393 (cons ,range c-record-ref-identifiers)) | |
3394 `(let ((range ,range)) | |
3395 (if range | |
3396 (setq c-record-ref-identifiers | |
3397 (cons range c-record-ref-identifiers)))))) | |
3398 | |
3399 ;; Dynamically bound variable that instructs `c-forward-type' to | |
3400 ;; record the ranges of types that only are found. Behaves otherwise | |
3401 ;; like `c-record-type-identifiers'. | |
3402 (defvar c-record-found-types nil) | |
3403 | |
3404 (defmacro c-forward-keyword-prefixed-id (type) | |
3405 ;; Used internally in `c-forward-keyword-clause' to move forward | |
3406 ;; over a type (if TYPE is 'type) or a name (otherwise) which | |
3407 ;; possibly is prefixed by keywords and their associated clauses. | |
3408 ;; Try with a type/name first to not trip up on those that begin | |
3409 ;; with a keyword. Return t if a known or found type is moved | |
3410 ;; over. The point is clobbered if nil is returned. If range | |
3411 ;; recording is enabled, the identifier is recorded on as a type | |
3412 ;; if TYPE is 'type or as a reference if TYPE is 'ref. | |
3413 `(let (res) | |
3414 (while (if (setq res ,(if (eq type 'type) | |
3415 `(c-forward-type) | |
3416 `(c-forward-name))) | |
3417 nil | |
3418 (and (looking-at c-keywords-regexp) | |
3419 (c-forward-keyword-clause)))) | |
3420 (when (memq res '(t known found prefix)) | |
3421 ,(when (eq type 'ref) | |
3422 `(when c-record-type-identifiers | |
3423 (c-record-ref-id c-last-identifier-range))) | |
3424 t))) | |
3425 | |
3426 (defmacro c-forward-id-comma-list (type) | |
3427 ;; Used internally in `c-forward-keyword-clause' to move forward | |
3428 ;; over a comma separated list of types or names using | |
3429 ;; `c-forward-keyword-prefixed-id'. | |
3430 `(while (and (progn | |
3431 (setq safe-pos (point)) | |
3432 (eq (char-after) ?,)) | |
3433 (progn | |
3434 (forward-char) | |
3435 (c-forward-syntactic-ws) | |
3436 (c-forward-keyword-prefixed-id ,type))))) | |
3437 | |
3438 (defun c-forward-keyword-clause () | |
3439 ;; The first submatch in the current match data is assumed to | |
3440 ;; surround a token. If it's a keyword, move over it and any | |
3441 ;; following clauses associated with it, stopping at the next | |
3442 ;; following token. t is returned in that case, otherwise the point | |
3443 ;; stays and nil is returned. The kind of clauses that are | |
3444 ;; recognized are those specified by `c-type-list-kwds', | |
3445 ;; `c-ref-list-kwds', `c-colon-type-list-kwds', | |
3446 ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', | |
3447 ;; and `c-<>-arglist-kwds'. | |
3448 | |
3449 (let ((kwd-sym (c-keyword-sym (match-string 1))) safe-pos pos) | |
3450 (when kwd-sym | |
3451 (goto-char (match-end 1)) | |
3452 (c-forward-syntactic-ws) | |
3453 (setq safe-pos (point)) | |
3454 | |
3455 (cond | |
3456 ((and (c-keyword-member kwd-sym 'c-type-list-kwds) | |
3457 (c-forward-keyword-prefixed-id type)) | |
3458 ;; There's a type directly after a keyword in `c-type-list-kwds'. | |
3459 (c-forward-id-comma-list type)) | |
3460 | |
3461 ((and (c-keyword-member kwd-sym 'c-ref-list-kwds) | |
3462 (c-forward-keyword-prefixed-id ref)) | |
3463 ;; There's a name directly after a keyword in `c-ref-list-kwds'. | |
3464 (c-forward-id-comma-list ref)) | |
3465 | |
3466 ((and (c-keyword-member kwd-sym 'c-paren-any-kwds) | |
3467 (eq (char-after) ?\()) | |
3468 ;; There's an open paren after a keyword in `c-paren-any-kwds'. | |
3469 | |
3470 (forward-char) | |
3471 (when (and (setq pos (c-up-list-forward)) | |
3472 (eq (char-before pos) ?\))) | |
3473 (when (and c-record-type-identifiers | |
3474 (c-keyword-member kwd-sym 'c-paren-type-kwds)) | |
3475 ;; Use `c-forward-type' on every identifier we can find | |
3476 ;; inside the paren, to record the types. | |
3477 (while (c-syntactic-re-search-forward c-symbol-start pos t) | |
3478 (goto-char (match-beginning 0)) | |
3479 (unless (c-forward-type) | |
3480 (looking-at c-symbol-key) ; Always matches. | |
3481 (goto-char (match-end 0))))) | |
3482 | |
3483 (goto-char pos) | |
3484 (c-forward-syntactic-ws) | |
3485 (setq safe-pos (point)))) | |
3486 | |
3487 ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds) | |
3488 (eq (char-after) ?<) | |
3489 (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds) | |
3490 (or c-record-type-identifiers | |
3491 c-disallow-comma-in-<>-arglists))) | |
3492 (c-forward-syntactic-ws) | |
3493 (setq safe-pos (point))) | |
3494 | |
3495 ((and (c-keyword-member kwd-sym 'c-nonsymbol-sexp-kwds) | |
3496 (not (looking-at c-symbol-start))) | |
3497 (c-forward-sexp) | |
3498 (c-forward-syntactic-ws) | |
3499 (setq safe-pos (point)))) | |
3500 | |
3501 (when (and (c-keyword-member kwd-sym 'c-colon-type-list-kwds) | |
3502 (progn | |
3503 ;; If a keyword matched both one of the types above and | |
3504 ;; this one, we match `c-colon-type-list-re' after the | |
3505 ;; clause matched above. | |
3506 (goto-char safe-pos) | |
3507 (looking-at c-colon-type-list-re)) | |
3508 (progn | |
3509 (goto-char (match-end 0)) | |
3510 (c-forward-syntactic-ws) | |
3511 (c-forward-keyword-prefixed-id type))) | |
3512 ;; There's a type after the `c-colon-type-list-re' | |
3513 ;; match after a keyword in `c-colon-type-list-kwds'. | |
3514 (c-forward-id-comma-list type)) | |
3515 | |
3516 (goto-char safe-pos) | |
3517 t))) | |
3518 | |
3519 (defun c-forward-<>-arglist (all-types reparse) | |
3520 ;; The point is assumed to be at a '<'. Try to treat it as the open | |
3521 ;; paren of an angle bracket arglist and move forward to the the | |
3522 ;; corresponding '>'. If successful, the point is left after the | |
3523 ;; '>' and t is returned, otherwise the point isn't moved and nil is | |
3524 ;; returned. If ALL-TYPES is t then all encountered arguments in | |
3525 ;; the arglist that might be types are treated as found types. | |
3526 ;; | |
3527 ;; The surrounding '<' and '>' are given syntax-table properties to | |
3528 ;; make them behave like parentheses. Each argument separating ',' | |
3529 ;; is also set to `c-<>-arg-sep' in the `c-type' property. These | |
3530 ;; properties are also cleared in a relevant region forward from the | |
3531 ;; point if they seems to be set and it turns out to not be an | |
3532 ;; arglist. | |
3533 ;; | |
3534 ;; If the arglist has been successfully parsed before then paren | |
3535 ;; syntax properties will be exploited to quickly jump to the end, | |
3536 ;; but that can be disabled by setting REPARSE to t. That is | |
3537 ;; necessary if the various side effects, e.g. recording of type | |
3538 ;; ranges, are important. Setting REPARSE to t only applies | |
3539 ;; recursively to nested angle bracket arglists if | |
3540 ;; `c-disallow-comma-in-<>-arglists' is set. | |
3541 ;; | |
3542 ;; This is primarily used in C++ to mark up template arglists. C++ | |
3543 ;; disambiguates them by checking whether the preceding name is a | |
3544 ;; template or not. We can't do that, so we assume it is a template | |
3545 ;; if it can be parsed as one. This usually works well since | |
3546 ;; comparison expressions on the forms "a < b > c" or "a < b, c > d" | |
3547 ;; in almost all cases would be pointless. Cases like function | |
3548 ;; calls on the form "foo (a < b, c > d)" needs to be handled | |
3549 ;; specially through the `c-disallow-comma-in-<>-arglists' variable. | |
3550 | |
3551 (let ((start (point)) | |
3552 ;; If `c-record-type-identifiers' is set then activate | |
3553 ;; recording of any found types that constitute an argument in | |
3554 ;; the arglist. | |
3555 (c-record-found-types (if c-record-type-identifiers t))) | |
3556 (if (catch 'angle-bracket-arglist-escape | |
3557 (setq c-record-found-types | |
3558 (c-forward-<>-arglist-recur all-types reparse))) | |
3559 (progn | |
3560 (when (consp c-record-found-types) | |
3561 (setq c-record-type-identifiers | |
3562 ;; `nconc' doesn't mind that the tail of | |
3563 ;; `c-record-found-types' is t. | |
3564 (nconc c-record-found-types c-record-type-identifiers))) | |
3565 t) | |
3566 | |
3567 (goto-char start) | |
3568 nil))) | |
3569 | |
3570 (defun c-forward-<>-arglist-recur (all-types reparse) | |
3571 ;; Recursive part of `c-forward-<>-arglist'. | |
3572 | |
3573 (let ((start (point)) res pos tmp | |
3574 ;; Cover this so that any recorded found type ranges are | |
3575 ;; automatically lost if it turns out to not be an angle | |
3576 ;; bracket arglist. It's propagated through the return value | |
3577 ;; on successful completion. | |
3578 (c-record-found-types c-record-found-types) | |
3579 ;; List that collects the positions after the argument | |
3580 ;; separating ',' in the arglist. | |
3581 arg-start-pos) | |
3582 | |
3583 ;; If the '<' has paren open syntax then we've marked it as an | |
3584 ;; angle bracket arglist before, so try to skip to the end and see | |
3585 ;; that the close paren matches. | |
3586 (if (and (c-get-char-property (point) 'syntax-table) | |
3587 (progn | |
3588 (forward-char) | |
3589 (if (and (not (looking-at c-<-op-cont-regexp)) | |
3590 (if (c-parse-sexp-lookup-properties) | |
3591 (c-go-up-list-forward) | |
3592 (catch 'at-end | |
3593 (let ((depth 1)) | |
3594 (while (c-syntactic-re-search-forward | |
3595 "[<>]" nil t t) | |
3596 (when (c-get-char-property (1- (point)) | |
3597 'syntax-table) | |
3598 (if (eq (char-before) ?<) | |
3599 (setq depth (1+ depth)) | |
3600 (setq depth (1- depth)) | |
3601 (when (= depth 0) (throw 'at-end t))))) | |
3602 nil))) | |
3603 (not (looking-at c->-op-cont-regexp)) | |
3604 (save-excursion | |
3605 (backward-char) | |
3606 (= (point) | |
3607 (progn (c-beginning-of-current-token) | |
3608 (point))))) | |
3609 | |
3610 ;; Got an arglist that appears to be valid. | |
3611 (if reparse | |
3612 ;; Reparsing is requested, so zap the properties in the | |
3613 ;; region and go on to redo it. It's done here to | |
3614 ;; avoid leaving it behind if we exit through | |
3615 ;; `angle-bracket-arglist-escape' below. | |
3616 (progn | |
3617 (c-remove-<>-arglist-properties start (point)) | |
3618 (goto-char start) | |
3619 nil) | |
3620 t) | |
3621 | |
3622 ;; Got unmatched paren brackets or either paren was | |
3623 ;; actually some other token. Recover by clearing the | |
3624 ;; syntax properties on all the '<' and '>' in the | |
3625 ;; range where we'll search for the arglist below. | |
3626 (goto-char start) | |
3627 (while (progn (skip-chars-forward "^<>,;{}") | |
3628 (looking-at "[<>,]")) | |
3629 (if (eq (char-after) ?,) | |
3630 (when (eq (c-get-char-property (point) 'c-type) | |
3631 'c-<>-arg-sep) | |
3632 (c-clear-char-property (point) 'c-type)) | |
3633 (c-clear-char-property (point) 'syntax-table)) | |
3634 (forward-char)) | |
3635 (goto-char start) | |
3636 nil))) | |
3637 t | |
3638 | |
3639 (forward-char) | |
3640 (unless (looking-at c-<-op-cont-regexp) | |
3641 (while (and | |
3642 (progn | |
3643 | |
3644 (when c-record-type-identifiers | |
3645 (if all-types | |
3646 | |
3647 ;; All encountered identifiers are types, so set the | |
3648 ;; promote flag and parse the type. | |
3649 (progn | |
3650 (c-forward-syntactic-ws) | |
3651 (when (looking-at c-identifier-start) | |
3652 (let ((c-promote-possible-types t)) | |
3653 (c-forward-type)))) | |
3654 | |
3655 ;; Check if this arglist argument is a sole type. If | |
3656 ;; it's known then it's recorded in | |
3657 ;; `c-record-type-identifiers'. If it only is found | |
3658 ;; then it's recorded in `c-record-found-types' which we | |
3659 ;; might roll back if it turns out that this isn't an | |
3660 ;; angle bracket arglist afterall. | |
3661 (when (memq (char-before) '(?, ?<)) | |
3662 (let ((orig-record-found-types c-record-found-types)) | |
3663 (c-forward-syntactic-ws) | |
3664 (and (memq (c-forward-type) '(known found)) | |
3665 (not (looking-at "[,>]")) | |
3666 ;; A found type was recorded but it's not the | |
3667 ;; only thing in the arglist argument, so reset | |
3668 ;; `c-record-found-types'. | |
3669 (setq c-record-found-types | |
3670 orig-record-found-types)))))) | |
3671 | |
3672 (setq pos (point)) | |
3673 (or (when (eq (char-after) ?>) | |
3674 ;; Must check for '>' at the very start separately, | |
3675 ;; since the regexp below has to avoid ">>" without | |
3676 ;; using \\=. | |
3677 (forward-char) | |
3678 t) | |
3679 | |
3680 ;; Note: This regexp exploits the match order in | |
3681 ;; \| so that "<>" is matched by "<" rather than | |
3682 ;; "[^>:-]>". | |
3683 (c-syntactic-re-search-forward | |
3684 "[<;{},]\\|\\([^>:-]>\\)" nil 'move t t 1) | |
3685 | |
3686 ;; If the arglist starter has lost its open paren | |
3687 ;; syntax but not the closer, we won't find the | |
3688 ;; closer above since we only search in the | |
3689 ;; balanced sexp. In that case we stop just short | |
3690 ;; of it so check if the following char is the closer. | |
3691 (when (eq (char-after) ?>) | |
3692 ;; Remove its syntax so that we don't enter the | |
3693 ;; recovery code below. That's not necessary | |
3694 ;; since there's no real reason to suspect that | |
3695 ;; things inside the arglist are unbalanced. | |
3696 (c-clear-char-property (point) 'syntax-table) | |
3697 (forward-char) | |
3698 t))) | |
3699 | |
3700 (cond | |
3701 ((eq (char-before) ?>) | |
3702 ;; Either an operator starting with '>' or the end of | |
3703 ;; the angle bracket arglist. | |
3704 | |
3705 (if (and (/= (1- (point)) pos) | |
3706 (c-get-char-property (1- (point)) 'syntax-table) | |
3707 (progn | |
3708 (c-clear-char-property (1- (point)) 'syntax-table) | |
3709 (c-parse-sexp-lookup-properties))) | |
3710 | |
3711 ;; We've skipped past a list that ended with '>'. It | |
3712 ;; must be unbalanced since nested arglists are handled | |
3713 ;; in the case below. Recover by removing all paren | |
3714 ;; properties on '<' and '>' in the searched region and | |
3715 ;; redo the search. | |
3716 (progn | |
3717 (c-remove-<>-arglist-properties pos (point)) | |
3718 (goto-char pos) | |
3719 t) | |
3720 | |
3721 (if (looking-at c->-op-cont-regexp) | |
3722 (progn | |
3723 (when (text-property-not-all | |
3724 (1- (point)) (match-end 0) 'syntax-table nil) | |
3725 (c-remove-<>-arglist-properties (1- (point)) | |
3726 (match-end 0))) | |
3727 (goto-char (match-end 0)) | |
3728 t) | |
3729 | |
3730 ;; The angle bracket arglist is finished. | |
3731 (while arg-start-pos | |
3732 (c-put-char-property (1- (car arg-start-pos)) | |
3733 'c-type 'c-<>-arg-sep) | |
3734 (setq arg-start-pos (cdr arg-start-pos))) | |
3735 (c-mark-<-as-paren start) | |
3736 (c-mark->-as-paren (1- (point))) | |
3737 (setq res t) | |
3738 nil))) | |
3739 | |
3740 ((eq (char-before) ?<) | |
3741 ;; Either an operator starting with '<' or a nested arglist. | |
3742 | |
3743 (setq pos (point)) | |
3744 (let (id-start id-end subres keyword-match) | |
3745 (if (if (looking-at c-<-op-cont-regexp) | |
3746 (setq tmp (match-end 0)) | |
3747 (setq tmp pos) | |
3748 (backward-char) | |
3749 (not | |
3750 (and | |
3751 | |
3752 (save-excursion | |
3753 ;; There's always an identifier before a angle | |
3754 ;; bracket arglist, or a keyword in | |
3755 ;; `c-<>-type-kwds' or `c-<>-arglist-kwds'. | |
3756 (c-backward-syntactic-ws) | |
3757 (setq id-end (point)) | |
3758 (c-simple-skip-symbol-backward) | |
3759 (when (or (setq keyword-match | |
3760 (looking-at c-opt-<>-sexp-key)) | |
3761 (not (looking-at c-keywords-regexp))) | |
3762 (setq id-start (point)))) | |
3763 | |
3764 (setq subres | |
3765 (let ((c-record-type-identifiers nil) | |
3766 (c-record-found-types nil)) | |
3767 (c-forward-<>-arglist-recur | |
3768 (and keyword-match | |
3769 (c-keyword-member | |
3770 (c-keyword-sym (match-string 1)) | |
3771 'c-<>-type-kwds)) | |
3772 (and reparse | |
3773 c-disallow-comma-in-<>-arglists)))) | |
3774 ))) | |
3775 | |
3776 ;; It was not an angle bracket arglist. | |
3777 (progn | |
3778 (when (text-property-not-all | |
3779 (1- pos) tmp 'syntax-table nil) | |
3780 (if (c-parse-sexp-lookup-properties) | |
3781 ;; Got an invalid open paren syntax on this | |
3782 ;; '<'. We'll probably get an unbalanced '>' | |
3783 ;; further ahead if we just remove the syntax | |
3784 ;; here, so recover by removing all paren | |
3785 ;; properties up to and including the | |
3786 ;; balancing close paren. | |
3787 (parse-partial-sexp pos (point-max) -1) | |
3788 (goto-char tmp)) | |
3789 (c-remove-<>-arglist-properties pos (point))) | |
3790 (goto-char tmp)) | |
3791 | |
3792 ;; It was an angle bracket arglist. | |
3793 (setq c-record-found-types subres) | |
3794 | |
3795 ;; Record the identifier before the template as a type | |
3796 ;; or reference depending on whether the arglist is last | |
3797 ;; in a qualified identifier. | |
3798 (when (and c-record-type-identifiers | |
3799 (not keyword-match)) | |
3800 (if (and c-opt-identifier-concat-key | |
3801 (progn | |
3802 (c-forward-syntactic-ws) | |
3803 (looking-at c-opt-identifier-concat-key))) | |
3804 (c-record-ref-id (cons id-start id-end)) | |
3805 (c-record-type-id (cons id-start id-end)))))) | |
3806 t) | |
3807 | |
3808 ((and (eq (char-before) ?,) | |
3809 (not c-disallow-comma-in-<>-arglists)) | |
3810 ;; Just another argument. Record the position. The | |
3811 ;; type check stuff that made us stop at it is at | |
3812 ;; the top of the loop. | |
3813 (setq arg-start-pos (cons (point) arg-start-pos))) | |
3814 | |
3815 (t | |
3816 ;; Got a character that can't be in an angle bracket | |
3817 ;; arglist argument. Abort using `throw', since | |
3818 ;; it's useless to try to find a surrounding arglist | |
3819 ;; if we're nested. | |
3820 (throw 'angle-bracket-arglist-escape nil)))))) | |
3821 | |
3822 (if res | |
3823 (or c-record-found-types t))))) | |
3824 | |
3825 (defun c-forward-name () | |
3826 ;; Move forward over a complete name if at the beginning of one, | |
3827 ;; stopping at the next following token. If the point is not at | |
3828 ;; something that are recognized as name then it stays put. A name | |
3829 ;; could be something as simple as "foo" in C or something as | |
3830 ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> :: | |
3831 ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short | |
3832 ;; int>::*volatile const" in C++ (this function is actually little | |
3833 ;; more than a `looking-at' call in all modes except those that, | |
3834 ;; like C++, have `c-recognize-<>-arglists' set). Return nil if no | |
3835 ;; name is found, 'template if it's an identifier ending with an | |
3836 ;; angle bracket arglist, 'operator of it's an operator identifier, | |
3837 ;; or t if it's some other kind of name. | |
3838 | |
3839 (let ((pos (point)) res id-start id-end | |
3840 ;; Turn off `c-promote-possible-types' here since we might | |
3841 ;; call `c-forward-<>-arglist' and we don't want it to promote | |
3842 ;; every suspect thing in the arglist to a type. We're | |
3843 ;; typically called from `c-forward-type' in this case, and | |
3844 ;; the caller only wants the top level type that it finds to | |
3845 ;; be promoted. | |
3846 c-promote-possible-types) | |
3847 (while | |
3848 (and | |
3849 (looking-at c-identifier-key) | |
3850 | |
3851 (progn | |
3852 ;; Check for keyword. We go to the last symbol in | |
3853 ;; `c-identifier-key' first. | |
3854 (if (eq c-identifier-key c-symbol-key) | |
3855 (setq id-start (point) | |
3856 id-end (match-end 0)) | |
3857 (goto-char (setq id-end (match-end 0))) | |
3858 (c-simple-skip-symbol-backward) | |
3859 (setq id-start (point))) | |
3860 | |
3861 (if (looking-at c-keywords-regexp) | |
3862 (when (and (c-major-mode-is 'c++-mode) | |
3863 (looking-at | |
3864 (cc-eval-when-compile | |
3865 (concat "\\(operator\\|\\(template\\)\\)" | |
3866 "\\(" (c-lang-const c-nonsymbol-key c++) | |
3867 "\\|$\\)"))) | |
3868 (if (match-beginning 2) | |
3869 ;; "template" is only valid inside an | |
3870 ;; identifier if preceded by "::". | |
3871 (save-excursion | |
3872 (c-backward-syntactic-ws) | |
3873 (and (c-safe (backward-char 2) t) | |
3874 (looking-at "::"))) | |
3875 t)) | |
3876 | |
3877 ;; Handle a C++ operator or template identifier. | |
3878 (goto-char id-end) | |
3879 (c-forward-syntactic-ws) | |
3880 (cond ((eq (char-before id-end) ?e) | |
3881 ;; Got "... ::template". | |
3882 (let ((subres (c-forward-name))) | |
3883 (when subres | |
3884 (setq pos (point) | |
3885 res subres)))) | |
3886 | |
3887 ((looking-at c-identifier-start) | |
3888 ;; Got a cast operator. | |
3889 (when (c-forward-type) | |
3890 (setq pos (point) | |
3891 res 'operator) | |
3892 ;; Now we should match a sequence of either | |
3893 ;; '*', '&' or a name followed by ":: *", | |
3894 ;; where each can be followed by a sequence | |
3895 ;; of `c-opt-type-modifier-key'. | |
3896 (while (cond ((looking-at "[*&]") | |
3897 (goto-char (match-end 0)) | |
3898 t) | |
3899 ((looking-at c-identifier-start) | |
3900 (and (c-forward-name) | |
3901 (looking-at "::") | |
3902 (progn | |
3903 (goto-char (match-end 0)) | |
3904 (c-forward-syntactic-ws) | |
3905 (eq (char-after) ?*)) | |
3906 (progn | |
3907 (forward-char) | |
3908 t)))) | |
3909 (while (progn | |
3910 (c-forward-syntactic-ws) | |
3911 (setq pos (point)) | |
3912 (looking-at c-opt-type-modifier-key)) | |
3913 (goto-char (match-end 1)))))) | |
3914 | |
3915 ((looking-at c-overloadable-operators-regexp) | |
3916 ;; Got some other operator. | |
3917 (when c-record-type-identifiers | |
3918 (setq c-last-identifier-range | |
3919 (cons (point) (match-end 0)))) | |
3920 (goto-char (match-end 0)) | |
3921 (c-forward-syntactic-ws) | |
3922 (setq pos (point) | |
3923 res 'operator))) | |
3924 | |
3925 nil) | |
3926 | |
3927 (when c-record-type-identifiers | |
3928 (setq c-last-identifier-range | |
3929 (cons id-start id-end))) | |
3930 (goto-char id-end) | |
3931 (c-forward-syntactic-ws) | |
3932 (setq pos (point) | |
3933 res t))) | |
3934 | |
3935 (progn | |
3936 (goto-char pos) | |
3937 (when (or c-opt-identifier-concat-key | |
3938 c-recognize-<>-arglists) | |
3939 | |
3940 (cond | |
3941 ((and c-opt-identifier-concat-key | |
3942 (looking-at c-opt-identifier-concat-key)) | |
3943 ;; Got a concatenated identifier. This handles the | |
3944 ;; cases with tricky syntactic whitespace that aren't | |
3945 ;; covered in `c-identifier-key'. | |
3946 (goto-char (match-end 0)) | |
3947 (c-forward-syntactic-ws) | |
3948 t) | |
3949 | |
3950 ((and c-recognize-<>-arglists | |
3951 (eq (char-after) ?<)) | |
3952 ;; Maybe an angle bracket arglist. | |
3953 (when (let ((c-record-type-identifiers nil) | |
3954 (c-record-found-types nil)) | |
3955 (c-forward-<>-arglist | |
3956 nil c-disallow-comma-in-<>-arglists)) | |
3957 (c-forward-syntactic-ws) | |
3958 (setq pos (point)) | |
3959 (if (and c-opt-identifier-concat-key | |
3960 (looking-at c-opt-identifier-concat-key)) | |
3961 ;; Continue if there's an identifier concatenation | |
3962 ;; operator after the template argument. | |
3963 (progn | |
3964 (when c-record-type-identifiers | |
3965 (c-record-ref-id (cons id-start id-end)) | |
3966 (setq c-last-identifier-range nil)) | |
3967 (forward-char 2) | |
3968 (c-forward-syntactic-ws) | |
3969 t) | |
3970 ;; `c-add-type' isn't called here since we don't | |
3971 ;; want to add types containing angle bracket | |
3972 ;; arglists. | |
3973 (when c-record-type-identifiers | |
3974 (c-record-type-id (cons id-start id-end)) | |
3975 (setq c-last-identifier-range nil)) | |
3976 (setq res 'template) | |
3977 nil))) | |
3978 ))))) | |
3979 | |
3980 (goto-char pos) | |
3981 res)) | |
3982 | |
3983 (defun c-forward-type () | |
3984 ;; Move forward over a type spec if at the beginning of one, | |
3985 ;; stopping at the next following token. Return t if it's a known | |
3986 ;; type that can't be a name, 'known if it's an otherwise known type | |
3987 ;; (according to `*-font-lock-extra-types'), 'prefix if it's a known | |
3988 ;; prefix of a type, 'found if it's a type that matches one in | |
3989 ;; `c-found-types', 'maybe if it's an identfier that might be a | |
3990 ;; type, or nil if it can't be a type (the point isn't moved then). | |
3991 ;; The point is assumed to be at the beginning of a token. | |
3992 ;; | |
3993 ;; Note that this function doesn't skip past the brace definition | |
3994 ;; that might be considered part of the type, e.g. | |
3995 ;; "enum {a, b, c} foo". | |
3996 (let ((start (point)) pos res res2 id-start id-end id-range) | |
3997 | |
3998 ;; Skip leading type modifiers. If any are found we know it's a | |
3999 ;; prefix of a type. | |
4000 (when c-opt-type-modifier-key | |
4001 (while (looking-at c-opt-type-modifier-key) | |
4002 (goto-char (match-end 1)) | |
4003 (c-forward-syntactic-ws) | |
4004 (setq res 'prefix))) | |
4005 | |
4006 (cond | |
4007 ((looking-at c-type-prefix-key) | |
4008 ;; Looking at a keyword that prefixes a type identifier, | |
4009 ;; e.g. "class". | |
4010 (goto-char (match-end 1)) | |
4011 (c-forward-syntactic-ws) | |
4012 (setq pos (point)) | |
4013 (if (memq (setq res2 (c-forward-name)) '(t template)) | |
4014 (progn | |
4015 (when (eq res2 t) | |
4016 ;; In many languages the name can be used without the | |
4017 ;; prefix, so we add it to `c-found-types'. | |
4018 (c-add-type pos (point)) | |
4019 (when c-record-type-identifiers | |
4020 (c-record-type-id c-last-identifier-range))) | |
4021 (setq res t)) | |
4022 ;; Invalid syntax. | |
4023 (goto-char start) | |
4024 (setq res nil))) | |
4025 | |
4026 ((progn | |
4027 (setq pos nil) | |
4028 (if (looking-at c-identifier-start) | |
4029 (save-excursion | |
4030 (setq id-start (point) | |
4031 res2 (c-forward-name)) | |
4032 (when res2 | |
4033 (setq id-end (point) | |
4034 id-range c-last-identifier-range)))) | |
4035 (and (cond ((looking-at c-primitive-type-key) | |
4036 (setq res t)) | |
4037 ((c-with-syntax-table c-identifier-syntax-table | |
4038 (looking-at c-known-type-key)) | |
4039 (setq res 'known))) | |
4040 (or (not id-end) | |
4041 (>= (save-excursion | |
4042 (save-match-data | |
4043 (goto-char (match-end 1)) | |
4044 (c-forward-syntactic-ws) | |
4045 (setq pos (point)))) | |
4046 id-end) | |
4047 (setq res nil)))) | |
4048 ;; Looking at a primitive or known type identifier. We've | |
4049 ;; checked for a name first so that we don't go here if the | |
4050 ;; known type match only is a prefix of another name. | |
4051 | |
4052 (setq id-end (match-end 1)) | |
4053 | |
4054 (when (and c-record-type-identifiers | |
4055 (or c-promote-possible-types (eq res t))) | |
4056 (c-record-type-id (cons (match-beginning 1) (match-end 1)))) | |
4057 | |
4058 (if (and c-opt-type-component-key | |
4059 (save-match-data | |
4060 (looking-at c-opt-type-component-key))) | |
4061 ;; There might be more keywords for the type. | |
4062 (let (safe-pos) | |
4063 (c-forward-keyword-clause) | |
4064 (while (progn | |
4065 (setq safe-pos (point)) | |
4066 (looking-at c-opt-type-component-key)) | |
4067 (when (and c-record-type-identifiers | |
4068 (looking-at c-primitive-type-key)) | |
4069 (c-record-type-id (cons (match-beginning 1) | |
4070 (match-end 1)))) | |
4071 (c-forward-keyword-clause)) | |
4072 (if (looking-at c-primitive-type-key) | |
4073 (progn | |
4074 (when c-record-type-identifiers | |
4075 (c-record-type-id (cons (match-beginning 1) | |
4076 (match-end 1)))) | |
4077 (c-forward-keyword-clause) | |
4078 (setq res t)) | |
4079 (goto-char safe-pos) | |
4080 (setq res 'prefix))) | |
4081 (unless (save-match-data (c-forward-keyword-clause)) | |
4082 (if pos | |
4083 (goto-char pos) | |
4084 (goto-char (match-end 1)) | |
4085 (c-forward-syntactic-ws))))) | |
4086 | |
4087 (res2 | |
4088 (cond ((eq res2 t) | |
4089 ;; A normal identifier. | |
4090 (goto-char id-end) | |
4091 (if (or res c-promote-possible-types) | |
4092 (progn | |
4093 (c-add-type id-start id-end) | |
4094 (when c-record-type-identifiers | |
4095 (c-record-type-id id-range)) | |
4096 (unless res | |
4097 (setq res 'found))) | |
4098 (setq res (if (c-check-type id-start id-end) | |
4099 ;; It's an identifier that has been used as | |
4100 ;; a type somewhere else. | |
4101 'found | |
4102 ;; It's an identifier that might be a type. | |
4103 'maybe)))) | |
4104 ((eq res2 'template) | |
4105 ;; A template is a type. | |
4106 (goto-char id-end) | |
4107 (setq res t)) | |
4108 (t | |
4109 ;; Otherwise it's an operator identifier, which is not a type. | |
4110 (goto-char start) | |
4111 (setq res nil))))) | |
4112 | |
4113 (when res | |
4114 ;; Skip trailing type modifiers. If any are found we know it's | |
4115 ;; a type. | |
4116 (when c-opt-type-modifier-key | |
4117 (while (looking-at c-opt-type-modifier-key) | |
4118 (goto-char (match-end 1)) | |
4119 (c-forward-syntactic-ws) | |
4120 (setq res t))) | |
4121 | |
4122 ;; Step over any type suffix operator. Do not let the existence | |
4123 ;; of these alter the classification of the found type, since | |
4124 ;; these operators typically are allowed in normal expressions | |
4125 ;; too. | |
4126 (when c-opt-type-suffix-key | |
4127 (while (looking-at c-opt-type-suffix-key) | |
4128 (goto-char (match-end 1)) | |
4129 (c-forward-syntactic-ws))) | |
4130 | |
4131 (when c-opt-type-concat-key | |
4132 ;; Look for a trailing operator that concatenate the type with | |
4133 ;; a following one, and if so step past that one through a | |
4134 ;; recursive call. | |
4135 (setq pos (point)) | |
4136 (let* ((c-promote-possible-types (or (memq res '(t known)) | |
4137 c-promote-possible-types)) | |
4138 ;; If we can't promote then set `c-record-found-types' so that | |
4139 ;; we can merge in the types from the second part afterwards if | |
4140 ;; it turns out to be a known type there. | |
4141 (c-record-found-types (and c-record-type-identifiers | |
4142 (not c-promote-possible-types)))) | |
4143 (if (and (looking-at c-opt-type-concat-key) | |
4144 | |
4145 (progn | |
4146 (goto-char (match-end 1)) | |
4147 (c-forward-syntactic-ws) | |
4148 (setq res2 (c-forward-type)))) | |
4149 | |
4150 (progn | |
4151 ;; If either operand certainly is a type then both are, but we | |
4152 ;; don't let the existence of the operator itself promote two | |
4153 ;; uncertain types to a certain one. | |
4154 (cond ((eq res t)) | |
4155 ((or (eq res 'known) (memq res2 '(t known))) | |
4156 (c-add-type id-start id-end) | |
4157 (when c-record-type-identifiers | |
4158 (c-record-type-id id-range)) | |
4159 (setq res t)) | |
4160 ((eq res 'found)) | |
4161 ((eq res2 'found) | |
4162 (setq res 'found)) | |
4163 (t | |
4164 (setq res 'maybe))) | |
4165 | |
4166 (when (and (eq res t) | |
4167 (consp c-record-found-types)) | |
4168 ;; Merge in the ranges of any types found by the second | |
4169 ;; `c-forward-type'. | |
4170 (setq c-record-type-identifiers | |
4171 ;; `nconc' doesn't mind that the tail of | |
4172 ;; `c-record-found-types' is t. | |
4173 (nconc c-record-found-types | |
4174 c-record-type-identifiers)))) | |
4175 | |
4176 (goto-char pos)))) | |
4177 | |
4178 (when (and c-record-found-types (memq res '(known found)) id-range) | |
4179 (setq c-record-found-types | |
4180 (cons id-range c-record-found-types)))) | |
4181 | |
4182 ;;(message "c-forward-type %s -> %s: %s" start (point) res) | |
4183 | |
4184 res)) | |
4185 | |
4186 | |
4187 ;; Handling of large scale constructs like statements and declarations. | |
4188 | |
1376 (defun c-beginning-of-inheritance-list (&optional lim) | 4189 (defun c-beginning-of-inheritance-list (&optional lim) |
1377 ;; Go to the first non-whitespace after the colon that starts a | 4190 ;; Go to the first non-whitespace after the colon that starts a |
1378 ;; multiple inheritance introduction. Optional LIM is the farthest | 4191 ;; multiple inheritance introduction. Optional LIM is the farthest |
1379 ;; back we should search. | 4192 ;; back we should search. |
1380 (let* ((lim (or lim (c-point 'bod)))) | 4193 (let* ((lim (or lim (save-excursion |
4194 (c-beginning-of-syntax) | |
4195 (point))))) | |
1381 (c-with-syntax-table c++-template-syntax-table | 4196 (c-with-syntax-table c++-template-syntax-table |
1382 (c-backward-token-1 0 t lim) | 4197 (c-backward-token-2 0 t lim) |
1383 (while (and (looking-at "[_a-zA-Z<,]") | 4198 (while (and (or (looking-at c-symbol-start) |
1384 (= (c-backward-token-1 1 t lim) 0))) | 4199 (looking-at "[<,]")) |
4200 (zerop (c-backward-token-2 1 t lim)))) | |
1385 (skip-chars-forward "^:")))) | 4201 (skip-chars-forward "^:")))) |
1386 | 4202 |
1387 (defun c-in-method-def-p () | 4203 (defun c-in-method-def-p () |
1388 ;; Return nil if we aren't in a method definition, otherwise the | 4204 ;; Return nil if we aren't in a method definition, otherwise the |
1389 ;; position of the initial [+-]. | 4205 ;; position of the initial [+-]. |
1412 (looking-at c-opt-asm-stmt-key)))) | 4228 (looking-at c-opt-asm-stmt-key)))) |
1413 | 4229 |
1414 (defun c-at-toplevel-p () | 4230 (defun c-at-toplevel-p () |
1415 "Return a determination as to whether point is at the `top-level'. | 4231 "Return a determination as to whether point is at the `top-level'. |
1416 Being at the top-level means that point is either outside any | 4232 Being at the top-level means that point is either outside any |
1417 enclosing block (such function definition), or inside a class, | 4233 enclosing block (such function definition), or only inside a class, |
1418 namespace or extern definition, but outside any method blocks. | 4234 namespace or other block that contains another declaration level. |
1419 | 4235 |
1420 If point is not at the top-level (e.g. it is inside a method | 4236 If point is not at the top-level (e.g. it is inside a method |
1421 definition), then nil is returned. Otherwise, if point is at a | 4237 definition), then nil is returned. Otherwise, if point is at a |
1422 top-level not enclosed within a class definition, t is returned. | 4238 top-level not enclosed within a class definition, t is returned. |
1423 Otherwise, a 2-vector is returned where the zeroth element is the | 4239 Otherwise, a 2-vector is returned where the zeroth element is the |
1426 brace." | 4242 brace." |
1427 (let ((paren-state (c-parse-state))) | 4243 (let ((paren-state (c-parse-state))) |
1428 (or (not (c-most-enclosing-brace paren-state)) | 4244 (or (not (c-most-enclosing-brace paren-state)) |
1429 (c-search-uplist-for-classkey paren-state)))) | 4245 (c-search-uplist-for-classkey paren-state)))) |
1430 | 4246 |
1431 (defun c-forward-to-cpp-define-body () | 4247 (defun c-just-after-func-arglist-p (&optional lim) |
1432 ;; Assuming point is at the "#" that introduces a preprocessor | |
1433 ;; directive, it's moved forward to the start of the definition body | |
1434 ;; if it's a "#define". Non-nil is returned in this case, in all | |
1435 ;; other cases nil is returned and point isn't moved. | |
1436 (when (and (looking-at | |
1437 (concat "#[ \t]*" | |
1438 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?" | |
1439 "\\([ \t]\\|\\\\\n\\)*")) | |
1440 (not (= (match-end 0) (c-point 'eol)))) | |
1441 (goto-char (match-end 0)))) | |
1442 | |
1443 (defun c-just-after-func-arglist-p (&optional containing lim) | |
1444 ;; Return t if we are between a function's argument list closing | 4248 ;; Return t if we are between a function's argument list closing |
1445 ;; paren and its opening brace. Note that the list close brace | 4249 ;; paren and its opening brace. Note that the list close brace |
1446 ;; could be followed by a "const" specifier or a member init hanging | 4250 ;; could be followed by a "const" specifier or a member init hanging |
1447 ;; colon. Optional CONTAINING is position of containing s-exp open | 4251 ;; colon. LIM is used as bound for some backward buffer searches; |
1448 ;; brace. If not supplied, point is used as search start. LIM is | 4252 ;; the search might continue past it. |
1449 ;; used as bound for some backward buffer searches; the search might | |
1450 ;; continue past it. | |
1451 ;; | 4253 ;; |
1452 ;; Note: This test is easily fooled. It only works reasonably well | 4254 ;; Note: This test is easily fooled. It only works reasonably well |
1453 ;; in the situations where `c-guess-basic-syntax' uses it. | 4255 ;; in the situations where `c-guess-basic-syntax' uses it. |
1454 (save-excursion | 4256 (save-excursion |
1455 (c-backward-syntactic-ws lim) | 4257 (if (c-mode-is-new-awk-p) |
1456 (let ((checkpoint (or containing (point)))) | 4258 (c-awk-backward-syntactic-ws lim) |
1457 (goto-char checkpoint) | 4259 (c-backward-syntactic-ws lim)) |
4260 (let ((checkpoint (point))) | |
1458 ;; could be looking at const specifier | 4261 ;; could be looking at const specifier |
1459 (if (and (eq (char-before) ?t) | 4262 (if (and (eq (char-before) ?t) |
1460 (forward-word -1) | 4263 (forward-word -1) |
1461 (looking-at "\\<const\\>[^_]")) | 4264 (looking-at "\\<const\\>[^_]")) |
1462 (c-backward-syntactic-ws lim) | 4265 (c-backward-syntactic-ws lim) |
1508 ;; inside a K&R style argument declaration list, nil otherwise. | 4311 ;; inside a K&R style argument declaration list, nil otherwise. |
1509 ;; `c-recognize-knr-p' is not checked. If LIM is non-nil, it's a | 4312 ;; `c-recognize-knr-p' is not checked. If LIM is non-nil, it's a |
1510 ;; position that bounds the backward search for the argument list. | 4313 ;; position that bounds the backward search for the argument list. |
1511 ;; | 4314 ;; |
1512 ;; Note: A declaration level context is assumed; the test can return | 4315 ;; Note: A declaration level context is assumed; the test can return |
1513 ;; false positives for statements and #define headers. This test is | 4316 ;; false positives for statements. This test is even more easily |
1514 ;; even more easily fooled than `c-just-after-func-arglist-p'. | 4317 ;; fooled than `c-just-after-func-arglist-p'. |
4318 | |
1515 (save-excursion | 4319 (save-excursion |
1516 (save-restriction | 4320 (save-restriction |
4321 | |
1517 ;; Go back to the closest preceding normal parenthesis sexp. We | 4322 ;; Go back to the closest preceding normal parenthesis sexp. We |
1518 ;; take that as the argument list in the function header. Then | 4323 ;; take that as the argument list in the function header. Then |
1519 ;; check that it's followed by some symbol before the next ';' | 4324 ;; check that it's followed by some symbol before the next ';' |
1520 ;; or '{'. If it does, it's the header of the K&R argdecl we're | 4325 ;; or '{'. If it does, it's the header of the K&R argdecl we're |
1521 ;; in. | 4326 ;; in. |
1522 (if lim (narrow-to-region lim (point))) | 4327 (if lim (narrow-to-region lim (point))) |
1523 (let (paren-end) | 4328 (let ((outside-macro (not (c-query-macro-start))) |
1524 (and (c-safe (setq paren-end (c-down-list-backward (point)))) | 4329 paren-end) |
1525 (eq (char-after paren-end) ?\)) | 4330 |
1526 (progn | 4331 (catch 'done |
1527 (goto-char (1+ paren-end)) | 4332 (while (if (and (c-safe (setq paren-end |
4333 (c-down-list-backward (point)))) | |
4334 (eq (char-after paren-end) ?\))) | |
4335 (progn | |
4336 (goto-char (1+ paren-end)) | |
4337 (if outside-macro | |
4338 (c-beginning-of-macro))) | |
4339 (throw 'done nil)))) | |
4340 | |
4341 (and (progn | |
1528 (c-forward-syntactic-ws) | 4342 (c-forward-syntactic-ws) |
1529 (looking-at "\\w\\|\\s_")) | 4343 (looking-at "\\w\\|\\s_")) |
1530 (c-safe (c-up-list-backward paren-end)) | 4344 (c-safe (c-up-list-backward paren-end)) |
4345 | |
4346 (save-excursion | |
4347 ;; If it's a K&R declaration then we're now at the | |
4348 ;; beginning of the function arglist. Check that there | |
4349 ;; isn't a '=' before it in this statement since that | |
4350 ;; means it some kind of initialization instead. | |
4351 (c-syntactic-skip-backward "^;=}{") | |
4352 (not (eq (char-before) ?=))) | |
4353 | |
1531 (point)))))) | 4354 (point)))))) |
1532 | 4355 |
1533 (defun c-skip-conditional () | 4356 (defun c-skip-conditional () |
1534 ;; skip forward over conditional at point, including any predicate | 4357 ;; skip forward over conditional at point, including any predicate |
1535 ;; statements in parentheses. No error checking is performed. | 4358 ;; statements in parentheses. No error checking is performed. |
1549 | 4372 |
1550 (defun c-after-conditional (&optional lim) | 4373 (defun c-after-conditional (&optional lim) |
1551 ;; If looking at the token after a conditional then return the | 4374 ;; If looking at the token after a conditional then return the |
1552 ;; position of its start, otherwise return nil. | 4375 ;; position of its start, otherwise return nil. |
1553 (save-excursion | 4376 (save-excursion |
1554 (and (= (c-backward-token-1 1 t lim) 0) | 4377 (and (zerop (c-backward-token-2 1 t lim)) |
1555 (or (looking-at c-block-stmt-1-key) | 4378 (or (looking-at c-block-stmt-1-key) |
1556 (and (eq (char-after) ?\() | 4379 (and (eq (char-after) ?\() |
1557 (= (c-backward-token-1 1 t lim) 0) | 4380 (zerop (c-backward-token-2 1 t lim)) |
1558 (looking-at c-block-stmt-2-key))) | 4381 (looking-at c-block-stmt-2-key))) |
1559 (point)))) | 4382 (point)))) |
1560 | 4383 |
1561 (defsubst c-backward-to-block-anchor (&optional lim) | 4384 (defsubst c-backward-to-block-anchor (&optional lim) |
1562 ;; Assuming point is at a brace that opens a statement block of some | 4385 ;; Assuming point is at a brace that opens a statement block of some |
1592 ;; declaration. That's the position where the definition body | 4415 ;; declaration. That's the position where the definition body |
1593 ;; starts, or the first variable initializer, or the ending | 4416 ;; starts, or the first variable initializer, or the ending |
1594 ;; semicolon. I.e. search forward for the closest following | 4417 ;; semicolon. I.e. search forward for the closest following |
1595 ;; (syntactically relevant) '{', '=' or ';' token. Point is left | 4418 ;; (syntactically relevant) '{', '=' or ';' token. Point is left |
1596 ;; _after_ the first found token, or at point-max if none is found. | 4419 ;; _after_ the first found token, or at point-max if none is found. |
1597 (c-with-syntax-table (if (c-major-mode-is 'c++-mode) | 4420 (if (c-major-mode-is 'c++-mode) |
1598 c++-template-syntax-table | 4421 ;; In C++ we need to take special care to handle those pesky |
1599 (syntax-table)) | 4422 ;; template brackets. |
1600 (while (and (c-syntactic-re-search-forward "[;{=]" nil 'move 1 t) | 4423 (while (and (c-syntactic-re-search-forward "[;{=<]" nil 'move t) |
1601 ;; In Pike it can be an operator identifier containing | 4424 (when (eq (char-before) ?<) |
1602 ;; '='. | 4425 (c-with-syntax-table c++-template-syntax-table |
1603 (c-major-mode-is 'pike-mode) | 4426 (if (c-safe (goto-char (c-up-list-forward (point)))) |
1604 (eq (char-before) ?=) | 4427 t |
1605 (c-on-identifier))))) | 4428 (goto-char (point-max)) |
4429 nil))))) | |
4430 (c-syntactic-re-search-forward "[;{=]" nil 'move t t))) | |
1606 | 4431 |
1607 (defun c-beginning-of-decl-1 (&optional lim) | 4432 (defun c-beginning-of-decl-1 (&optional lim) |
1608 ;; Go to the beginning of the current declaration, or the beginning | 4433 ;; Go to the beginning of the current declaration, or the beginning |
1609 ;; of the previous one if already at the start of it. Point won't | 4434 ;; of the previous one if already at the start of it. Point won't |
1610 ;; be moved out of any surrounding paren. Return a cons cell on the | 4435 ;; be moved out of any surrounding paren. Return a cons cell on the |
1618 ;; NB: Cases where the declaration continues after the block, as in | 4443 ;; NB: Cases where the declaration continues after the block, as in |
1619 ;; "struct foo { ... } bar;", are currently recognized as two | 4444 ;; "struct foo { ... } bar;", are currently recognized as two |
1620 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case. | 4445 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case. |
1621 (catch 'return | 4446 (catch 'return |
1622 (let* ((start (point)) | 4447 (let* ((start (point)) |
1623 (last-stmt-start (point)) | 4448 (last-stmt-start (point)) |
1624 (move (c-beginning-of-statement-1 lim t t))) | 4449 (move (c-beginning-of-statement-1 lim t t))) |
1625 | 4450 |
1626 (while (and (/= last-stmt-start (point)) | |
1627 (save-excursion | |
1628 (c-backward-syntactic-ws lim) | |
1629 (not (memq (char-before) '(?\; ?} ?: nil))))) | |
1630 ;; `c-beginning-of-statement-1' stops at a block start, but we | 4451 ;; `c-beginning-of-statement-1' stops at a block start, but we |
1631 ;; want to continue if the block doesn't begin a top level | 4452 ;; want to continue if the block doesn't begin a top level |
1632 ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob. | 4453 ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob. |
1633 (setq last-stmt-start (point) | 4454 (let ((beg (point)) tentative-move) |
1634 move (c-beginning-of-statement-1 lim t t))) | 4455 (while (and |
1635 | 4456 ;; Must check with c-opt-method-key in ObjC mode. |
1636 (when c-recognize-knr-p | 4457 (not (and c-opt-method-key |
1637 (let ((fallback-pos (point)) knr-argdecl-start) | 4458 (looking-at c-opt-method-key))) |
1638 ;; Handle K&R argdecls. Back up after the "statement" jumped | 4459 (/= last-stmt-start (point)) |
1639 ;; over by `c-beginning-of-statement-1', unless it was the | 4460 (progn |
1640 ;; function body, in which case we're sitting on the opening | 4461 (c-backward-syntactic-ws lim) |
1641 ;; brace now. Then test if we're in a K&R argdecl region and | 4462 (not (memq (char-before) '(?\; ?} ?: nil)))) |
1642 ;; that we started at the other side of the first argdecl in | 4463 ;; Check that we don't move from the first thing in a |
1643 ;; it. | 4464 ;; macro to its header. |
1644 (unless (eq (char-after) ?{) | 4465 (not (eq (setq tentative-move |
1645 (goto-char last-stmt-start)) | 4466 (c-beginning-of-statement-1 lim t t)) |
1646 (if (and (setq knr-argdecl-start (c-in-knr-argdecl lim)) | 4467 'macro))) |
1647 (< knr-argdecl-start start) | 4468 (setq last-stmt-start beg |
1648 (progn | 4469 beg (point) |
1649 (goto-char knr-argdecl-start) | 4470 move tentative-move)) |
1650 (not (eq (c-beginning-of-statement-1 lim t t) 'macro)))) | 4471 (goto-char beg)) |
1651 (throw 'return | 4472 |
1652 (cons (if (eq (char-after fallback-pos) ?{) | 4473 (when c-recognize-knr-p |
1653 'previous | 4474 (let ((fallback-pos (point)) knr-argdecl-start) |
1654 'same) | 4475 ;; Handle K&R argdecls. Back up after the "statement" jumped |
1655 knr-argdecl-start)) | 4476 ;; over by `c-beginning-of-statement-1', unless it was the |
1656 (goto-char fallback-pos)))) | 4477 ;; function body, in which case we're sitting on the opening |
1657 | 4478 ;; brace now. Then test if we're in a K&R argdecl region and |
1658 (when c-opt-access-key | 4479 ;; that we started at the other side of the first argdecl in |
1659 ;; Might have ended up before a protection label. This should | 4480 ;; it. |
1660 ;; perhaps be checked before `c-recognize-knr-p' to be really | 4481 (unless (eq (char-after) ?{) |
1661 ;; accurate, but we know that no language has both. | 4482 (goto-char last-stmt-start)) |
1662 (while (looking-at c-opt-access-key) | 4483 (if (and (setq knr-argdecl-start (c-in-knr-argdecl lim)) |
1663 (goto-char (match-end 0)) | 4484 (< knr-argdecl-start start) |
1664 (c-forward-syntactic-ws) | 4485 (progn |
1665 (when (>= (point) start) | 4486 (goto-char knr-argdecl-start) |
1666 (goto-char start) | 4487 (not (eq (c-beginning-of-statement-1 lim t t) 'macro)))) |
1667 (throw 'return (cons 'same nil))))) | 4488 (throw 'return |
1668 | 4489 (cons (if (eq (char-after fallback-pos) ?{) |
1669 ;; `c-beginning-of-statement-1' counts each brace block as a | 4490 'previous |
1670 ;; separate statement, so the result will be 'previous if we've | 4491 'same) |
1671 ;; moved over any. If they were brace list initializers we might | 4492 knr-argdecl-start)) |
1672 ;; not have moved over a declaration boundary though, so change it | 4493 (goto-char fallback-pos)))) |
1673 ;; to 'same if we've moved past a '=' before '{', but not ';'. | 4494 |
1674 ;; (This ought to be integrated into `c-beginning-of-statement-1', | 4495 (when c-opt-access-key |
1675 ;; so we avoid this extra pass which potentially can search over a | 4496 ;; Might have ended up before a protection label. This should |
1676 ;; large amount of text.) | 4497 ;; perhaps be checked before `c-recognize-knr-p' to be really |
1677 (if (and (eq move 'previous) | 4498 ;; accurate, but we know that no language has both. |
1678 (c-with-syntax-table (if (c-major-mode-is 'c++-mode) | 4499 (while (looking-at c-opt-access-key) |
1679 c++-template-syntax-table | 4500 (goto-char (match-end 0)) |
1680 (syntax-table)) | 4501 (c-forward-syntactic-ws) |
1681 (save-excursion | 4502 (when (>= (point) start) |
1682 (and (c-syntactic-re-search-forward "[;={]" start t 1 t) | 4503 (goto-char start) |
1683 (eq (char-before) ?=) | 4504 (throw 'return (cons 'same nil))))) |
1684 (c-syntactic-re-search-forward "[;{]" start t 1 t) | 4505 |
1685 (eq (char-before) ?{) | 4506 ;; `c-beginning-of-statement-1' counts each brace block as a |
1686 (c-safe (goto-char (c-up-list-forward (point))) t) | 4507 ;; separate statement, so the result will be 'previous if we've |
1687 (not (c-syntactic-re-search-forward ";" start t 1 t)))))) | 4508 ;; moved over any. If they were brace list initializers we might |
1688 (cons 'same nil) | 4509 ;; not have moved over a declaration boundary though, so change it |
1689 (cons move nil))))) | 4510 ;; to 'same if we've moved past a '=' before '{', but not ';'. |
4511 ;; (This ought to be integrated into `c-beginning-of-statement-1', | |
4512 ;; so we avoid this extra pass which potentially can search over a | |
4513 ;; large amount of text.) | |
4514 (if (and (eq move 'previous) | |
4515 (c-with-syntax-table (if (c-major-mode-is 'c++-mode) | |
4516 c++-template-syntax-table | |
4517 (syntax-table)) | |
4518 (save-excursion | |
4519 (and (c-syntactic-re-search-forward "[;={]" start t t t) | |
4520 (eq (char-before) ?=) | |
4521 (c-syntactic-re-search-forward "[;{]" start t t) | |
4522 (eq (char-before) ?{) | |
4523 (c-safe (goto-char (c-up-list-forward (point))) t) | |
4524 (not (c-syntactic-re-search-forward ";" start t t)))))) | |
4525 (cons 'same nil) | |
4526 (cons move nil))))) | |
1690 | 4527 |
1691 (defun c-end-of-decl-1 () | 4528 (defun c-end-of-decl-1 () |
1692 ;; Assuming point is at the start of a declaration (as detected by | 4529 ;; Assuming point is at the start of a declaration (as detected by |
1693 ;; e.g. `c-beginning-of-decl-1'), go to the end of it. Unlike | 4530 ;; e.g. `c-beginning-of-decl-1'), go to the end of it. Unlike |
1694 ;; `c-beginning-of-decl-1', this function handles the case when a | 4531 ;; `c-beginning-of-decl-1', this function handles the case when a |
1709 (c-in-knr-argdecl start)) | 4546 (c-in-knr-argdecl start)) |
1710 ;; Stopped at the ';' in a K&R argdecl section which is | 4547 ;; Stopped at the ';' in a K&R argdecl section which is |
1711 ;; detected using the same criteria as in | 4548 ;; detected using the same criteria as in |
1712 ;; `c-beginning-of-decl-1'. Move to the following block | 4549 ;; `c-beginning-of-decl-1'. Move to the following block |
1713 ;; start. | 4550 ;; start. |
1714 (c-syntactic-re-search-forward "{" nil 'move 1 t)) | 4551 (c-syntactic-re-search-forward "{" nil 'move t)) |
1715 | 4552 |
1716 (when (eq (char-before) ?{) | 4553 (when (eq (char-before) ?{) |
1717 ;; Encountered a block in the declaration. Jump over it. | 4554 ;; Encountered a block in the declaration. Jump over it. |
1718 (condition-case nil | 4555 (condition-case nil |
1719 (goto-char (c-up-list-forward (point))) | 4556 (goto-char (c-up-list-forward (point))) |
1720 (goto-char (point-max)) | 4557 (error (goto-char (point-max)) |
1721 (throw 'return nil)) | 4558 (throw 'return nil))) |
1722 (if (or (not c-opt-block-decls-with-vars-key) | 4559 (if (or (not c-opt-block-decls-with-vars-key) |
1723 (save-excursion | 4560 (save-excursion |
1724 (c-with-syntax-table decl-syntax-table | 4561 (c-with-syntax-table decl-syntax-table |
1725 (let ((lim (point))) | 4562 (let ((lim (point))) |
1726 (goto-char start) | 4563 (goto-char start) |
1727 (not (and | 4564 (not (and |
1728 ;; Check for `c-opt-block-decls-with-vars-key' | 4565 ;; Check for `c-opt-block-decls-with-vars-key' |
1729 ;; before the first paren. | 4566 ;; before the first paren. |
1730 (c-syntactic-re-search-forward | 4567 (c-syntactic-re-search-forward |
1731 (concat "[;=\(\[{]\\|\\<\\(" | 4568 (concat "[;=\(\[{]\\|\\(" |
1732 c-opt-block-decls-with-vars-key | 4569 c-opt-block-decls-with-vars-key |
1733 "\\)") | 4570 "\\)") |
1734 lim t 1 t) | 4571 lim t t t) |
1735 (match-beginning 1) | 4572 (match-beginning 1) |
1736 (not (eq (char-before) ?_)) | 4573 (not (eq (char-before) ?_)) |
1737 ;; Check that the first following paren is the block. | 4574 ;; Check that the first following paren is |
1738 (c-syntactic-re-search-forward "[;=\(\[{]" lim t 1 t) | 4575 ;; the block. |
4576 (c-syntactic-re-search-forward "[;=\(\[{]" | |
4577 lim t t t) | |
1739 (eq (char-before) ?{))))))) | 4578 (eq (char-before) ?{))))))) |
1740 ;; The declaration doesn't have any of the | 4579 ;; The declaration doesn't have any of the |
1741 ;; `c-opt-block-decls-with-vars' keywords in the | 4580 ;; `c-opt-block-decls-with-vars' keywords in the |
1742 ;; beginning, so it ends here at the end of the block. | 4581 ;; beginning, so it ends here at the end of the block. |
1743 (throw 'return t))) | 4582 (throw 'return t))) |
1744 | 4583 |
1745 (c-with-syntax-table decl-syntax-table | 4584 (c-with-syntax-table decl-syntax-table |
1746 (while (progn | 4585 (while (progn |
1747 (if (eq (char-before) ?\;) | 4586 (if (eq (char-before) ?\;) |
1748 (throw 'return t)) | 4587 (throw 'return t)) |
1749 (c-syntactic-re-search-forward ";" nil 'move 1 t)))) | 4588 (c-syntactic-re-search-forward ";" nil 'move t)))) |
1750 nil))) | 4589 nil))) |
1751 | 4590 |
1752 (defun c-beginning-of-member-init-list (&optional limit) | 4591 (defun c-beginning-of-member-init-list (&optional limit) |
1753 ;; Goes to the beginning of a member init list (i.e. just after the | 4592 ;; Goes to the beginning of a member init list (i.e. just after the |
1754 ;; ':') if inside one. Returns t in that case, nil otherwise. | 4593 ;; ':') if inside one. Returns t in that case, nil otherwise. |
1755 (or limit | 4594 (or limit |
1756 (setq limit (point-min))) | 4595 (setq limit (point-min))) |
1757 (skip-chars-forward " \t") | 4596 (skip-chars-forward " \t") |
4597 | |
1758 (if (eq (char-after) ?,) | 4598 (if (eq (char-after) ?,) |
1759 (forward-char 1) | 4599 (forward-char 1) |
1760 (c-backward-syntactic-ws limit)) | 4600 (c-backward-syntactic-ws limit)) |
1761 (while (and (< limit (point)) | 4601 |
1762 (eq (char-before) ?,)) | 4602 (catch 'exit |
1763 ;; this will catch member inits with multiple | 4603 (while (and (< limit (point)) |
1764 ;; line arglists | 4604 (eq (char-before) ?,)) |
1765 (forward-char -1) | 4605 |
1766 (c-backward-syntactic-ws limit) | 4606 ;; this will catch member inits with multiple |
1767 (if (eq (char-before) ?\)) | 4607 ;; line arglists |
1768 (c-backward-sexp 1)) | 4608 (forward-char -1) |
1769 (c-backward-syntactic-ws limit) | 4609 (c-backward-syntactic-ws limit) |
1770 ;; Skip over any template arg to the class. | 4610 (if (eq (char-before) ?\)) |
1771 (if (eq (char-before) ?>) | 4611 (unless (c-safe (c-backward-sexp 1)) |
1772 (c-with-syntax-table c++-template-syntax-table | 4612 (throw 'exit nil))) |
1773 (c-backward-sexp 1))) | 4613 (c-backward-syntactic-ws limit) |
1774 (c-backward-sexp 1) | 4614 |
1775 (c-backward-syntactic-ws limit) | 4615 ;; Skip over any template arg to the class. This way with a |
1776 ;; Skip backwards over a fully::qualified::name. | 4616 ;; syntax table is bogus but it'll have to do for now. |
1777 (while (and (eq (char-before) ?:) | 4617 (if (and (eq (char-before) ?>) |
1778 (save-excursion | 4618 (c-major-mode-is 'c++-mode)) |
1779 (forward-char -1) | 4619 (c-with-syntax-table c++-template-syntax-table |
1780 (eq (char-before) ?:))) | 4620 (unless (c-safe (c-backward-sexp 1)) |
1781 (backward-char 2) | 4621 (throw 'exit nil)))) |
1782 (c-backward-sexp 1)) | 4622 (c-safe (c-backward-sexp 1)) |
1783 ;; now continue checking | 4623 (c-backward-syntactic-ws limit) |
1784 (c-backward-syntactic-ws limit)) | 4624 |
1785 (and (< limit (point)) | 4625 ;; Skip backwards over a fully::qualified::name. |
1786 (eq (char-before) ?:))) | 4626 (while (and (eq (char-before) ?:) |
4627 (save-excursion | |
4628 (forward-char -1) | |
4629 (eq (char-before) ?:))) | |
4630 (backward-char 2) | |
4631 (c-safe (c-backward-sexp 1))) | |
4632 | |
4633 ;; If we've stepped over a number then this is a bitfield. | |
4634 (when (and c-opt-bitfield-key | |
4635 (looking-at "[0-9]")) | |
4636 (throw 'exit nil)) | |
4637 | |
4638 ;; now continue checking | |
4639 (c-backward-syntactic-ws limit)) | |
4640 | |
4641 (and (< limit (point)) | |
4642 (eq (char-before) ?:)))) | |
1787 | 4643 |
1788 (defun c-search-uplist-for-classkey (paren-state) | 4644 (defun c-search-uplist-for-classkey (paren-state) |
1789 ;; search for the containing class, returning a 2 element vector if | 4645 ;; search for the containing class, returning a 2 element vector if |
1790 ;; found. aref 0 contains the bufpos of the boi of the class key | 4646 ;; found. aref 0 contains the bufpos of the boi of the class key |
1791 ;; line, and aref 1 contains the bufpos of the open brace. | 4647 ;; line, and aref 1 contains the bufpos of the open brace. |
1805 ;; for us the search boundaries | 4661 ;; for us the search boundaries |
1806 (setq search-start (nth 1 paren-state) | 4662 (setq search-start (nth 1 paren-state) |
1807 search-end (nth 0 paren-state))) | 4663 search-end (nth 0 paren-state))) |
1808 ;; if search-end is nil, or if the search-end character isn't an | 4664 ;; if search-end is nil, or if the search-end character isn't an |
1809 ;; open brace, we are definitely not in a class | 4665 ;; open brace, we are definitely not in a class |
1810 (when (consp search-end) | 4666 (if (or (not search-end) |
1811 (setq search-end (car search-end))) | 4667 (< search-end (point-min)) |
1812 (unless (or (not search-end) | 4668 (not (eq (char-after search-end) ?{))) |
1813 (< search-end (point-min)) | 4669 nil |
1814 (not (eq (char-after search-end) ?{))) | |
1815 ;; now, we need to look more closely at search-start. if | 4670 ;; now, we need to look more closely at search-start. if |
1816 ;; search-start is nil, then our start boundary is really | 4671 ;; search-start is nil, then our start boundary is really |
1817 ;; point-min. | 4672 ;; point-min. |
1818 (if (not search-start) | 4673 (if (not search-start) |
1819 (setq search-start (point-min)) | 4674 (setq search-start (point-min)) |
1820 ;; if search-start is a cons cell, then we can start | 4675 ;; if search-start is a cons cell, then we can start |
1821 ;; searching from the end of the balanced sexp just ahead of | 4676 ;; searching from the end of the balanced sexp just ahead of |
1822 ;; us | 4677 ;; us |
1823 (if (consp search-start) | 4678 (if (consp search-start) |
1824 (setq search-start (cdr search-start)))) | 4679 (setq search-start (cdr search-start)) |
4680 ;; Otherwise we start searching within the surrounding paren sexp. | |
4681 (setq search-start (1+ search-start)))) | |
1825 ;; now we can do a quick regexp search from search-start to | 4682 ;; now we can do a quick regexp search from search-start to |
1826 ;; search-end and see if we can find a class key. watch for | 4683 ;; search-end and see if we can find a class key. watch for |
1827 ;; class like strings in literals | 4684 ;; class like strings in literals |
1828 (save-excursion | 4685 (save-excursion |
1829 (save-restriction | 4686 (save-restriction |
1831 (let (foundp class match-end) | 4688 (let (foundp class match-end) |
1832 (while (and (not foundp) | 4689 (while (and (not foundp) |
1833 (progn | 4690 (progn |
1834 (c-forward-syntactic-ws search-end) | 4691 (c-forward-syntactic-ws search-end) |
1835 (> search-end (point))) | 4692 (> search-end (point))) |
1836 (re-search-forward c-decl-block-key search-end t)) | 4693 ;; Add one to the search limit, to allow |
4694 ;; matching of the "{" in the regexp. | |
4695 (re-search-forward c-decl-block-key | |
4696 (1+ search-end) | |
4697 t)) | |
1837 (setq class (match-beginning 0) | 4698 (setq class (match-beginning 0) |
1838 match-end (match-end 0)) | 4699 match-end (match-end 0)) |
1839 (goto-char class) | 4700 (goto-char class) |
1840 (if (c-in-literal search-start) | 4701 (if (c-in-literal search-start) |
1841 (goto-char match-end) ; its in a comment or string, ignore | 4702 (goto-char match-end) ; its in a comment or string, ignore |
1855 (not (c-in-literal class))) | 4716 (not (c-in-literal class))) |
1856 (setq foundp nil)) | 4717 (setq foundp nil)) |
1857 ;; Check if this is an anonymous inner class. | 4718 ;; Check if this is an anonymous inner class. |
1858 ((and c-opt-inexpr-class-key | 4719 ((and c-opt-inexpr-class-key |
1859 (looking-at c-opt-inexpr-class-key)) | 4720 (looking-at c-opt-inexpr-class-key)) |
1860 (while (and (= (c-forward-token-1 1 t) 0) | 4721 (while (and (zerop (c-forward-token-2 1 t)) |
1861 (looking-at "(\\|\\w\\|\\s_\\|\\."))) | 4722 (looking-at "(\\|\\w\\|\\s_\\|\\."))) |
1862 (if (eq (point) search-end) | 4723 (if (eq (point) search-end) |
1863 ;; We're done. Just trap this case in the cond. | 4724 ;; We're done. Just trap this case in the cond. |
1864 nil | 4725 nil |
1865 ;; False alarm; all conditions aren't satisfied. | 4726 ;; False alarm; all conditions aren't satisfied. |
1898 ;; | 4759 ;; |
1899 ;; N.B.: This algorithm can potentially get confused by cpp macros | 4760 ;; N.B.: This algorithm can potentially get confused by cpp macros |
1900 ;; places in inconvenient locations. Its a trade-off we make for | 4761 ;; places in inconvenient locations. Its a trade-off we make for |
1901 ;; speed. | 4762 ;; speed. |
1902 (or | 4763 (or |
1903 ;; this will pick up enum lists | 4764 ;; This will pick up brace list declarations. |
1904 (c-safe | 4765 (c-safe |
1905 (save-excursion | 4766 (save-excursion |
1906 (goto-char containing-sexp) | 4767 (goto-char containing-sexp) |
1907 (c-forward-sexp -1) | 4768 (c-forward-sexp -1) |
1908 (let (bracepos) | 4769 (let (bracepos) |
1909 (if (and (or (looking-at "enum\\>[^_]") | 4770 (if (and (or (looking-at c-brace-list-key) |
1910 (progn (c-forward-sexp -1) | 4771 (progn (c-forward-sexp -1) |
1911 (looking-at "enum\\>[^_]"))) | 4772 (looking-at c-brace-list-key))) |
1912 (setq bracepos (c-down-list-forward (point))) | 4773 (setq bracepos (c-down-list-forward (point))) |
1913 (not (c-crosses-statement-barrier-p (point) | 4774 (not (c-crosses-statement-barrier-p (point) |
1914 (- bracepos 2)))) | 4775 (- bracepos 2)))) |
1915 (point))))) | 4776 (point))))) |
1916 ;; this will pick up array/aggregate init lists, even if they are nested. | 4777 ;; this will pick up array/aggregate init lists, even if they are nested. |
1939 ;; doesn't check for an identifier before it. | 4800 ;; doesn't check for an identifier before it. |
1940 (setq containing-sexp nil) | 4801 (setq containing-sexp nil) |
1941 ;; see if the open brace is preceded by = or [...] in | 4802 ;; see if the open brace is preceded by = or [...] in |
1942 ;; this statement, but watch out for operator= | 4803 ;; this statement, but watch out for operator= |
1943 (setq braceassignp 'dontknow) | 4804 (setq braceassignp 'dontknow) |
1944 (c-backward-token-1 1 t lim) | 4805 (c-backward-token-2 1 t lim) |
1945 ;; Checks to do only on the first sexp before the brace. | 4806 ;; Checks to do only on the first sexp before the brace. |
1946 (when (and (c-major-mode-is 'java-mode) | 4807 (when (and c-opt-inexpr-brace-list-key |
1947 (eq (char-after) ?\[)) | 4808 (eq (char-after) ?\[)) |
1948 ;; In Java, an initialization brace list may follow | 4809 ;; In Java, an initialization brace list may follow |
1949 ;; directly after "new Foo[]", so check for a "new" | 4810 ;; directly after "new Foo[]", so check for a "new" |
1950 ;; earlier. | 4811 ;; earlier. |
1951 (while (eq braceassignp 'dontknow) | 4812 (while (eq braceassignp 'dontknow) |
1952 (setq braceassignp | 4813 (setq braceassignp |
1953 (cond ((/= (c-backward-token-1 1 t lim) 0) nil) | 4814 (cond ((/= (c-backward-token-2 1 t lim) 0) nil) |
1954 ((looking-at "new\\>[^_]") t) | 4815 ((looking-at c-opt-inexpr-brace-list-key) t) |
1955 ((looking-at "\\sw\\|\\s_\\|[.[]") | 4816 ((looking-at "\\sw\\|\\s_\\|[.[]") |
1956 ;; Carry on looking if this is an | 4817 ;; Carry on looking if this is an |
1957 ;; identifier (may contain "." in Java) | 4818 ;; identifier (may contain "." in Java) |
1958 ;; or another "[]" sexp. | 4819 ;; or another "[]" sexp. |
1959 'dontknow) | 4820 'dontknow) |
1969 ((eq (char-after) ?=) | 4830 ((eq (char-after) ?=) |
1970 ;; We've seen a =, but must check earlier tokens so | 4831 ;; We've seen a =, but must check earlier tokens so |
1971 ;; that it isn't something that should be ignored. | 4832 ;; that it isn't something that should be ignored. |
1972 (setq braceassignp 'maybe) | 4833 (setq braceassignp 'maybe) |
1973 (while (and (eq braceassignp 'maybe) | 4834 (while (and (eq braceassignp 'maybe) |
1974 (zerop (c-backward-token-1 1 t lim))) | 4835 (zerop (c-backward-token-2 1 t lim))) |
1975 (setq braceassignp | 4836 (setq braceassignp |
1976 (cond | 4837 (cond |
1977 ;; Check for operator = | 4838 ;; Check for operator = |
1978 ((looking-at "operator\\>[^_]") nil) | 4839 ((looking-at "operator\\>[^_]") nil) |
1979 ;; Check for `<opchar>= in Pike. | 4840 ;; Check for `<opchar>= in Pike. |
2001 (not (c-in-literal)) | 4862 (not (c-in-literal)) |
2002 )))) | 4863 )))) |
2003 nil) | 4864 nil) |
2004 (t t)))))) | 4865 (t t)))))) |
2005 (if (and (eq braceassignp 'dontknow) | 4866 (if (and (eq braceassignp 'dontknow) |
2006 (/= (c-backward-token-1 1 t lim) 0)) | 4867 (/= (c-backward-token-2 1 t lim) 0)) |
2007 (setq braceassignp nil))) | 4868 (setq braceassignp nil))) |
2008 (if (not braceassignp) | 4869 (if (not braceassignp) |
2009 (if (eq (char-after) ?\;) | 4870 (if (eq (char-after) ?\;) |
2010 ;; Brace lists can't contain a semicolon, so we're done. | 4871 ;; Brace lists can't contain a semicolon, so we're done. |
2011 (setq containing-sexp nil) | 4872 (setq containing-sexp nil) |
2119 ;; If the class definition is at the start of | 4980 ;; If the class definition is at the start of |
2120 ;; a statement, we don't consider it an | 4981 ;; a statement, we don't consider it an |
2121 ;; in-expression class. | 4982 ;; in-expression class. |
2122 (let ((prev (point))) | 4983 (let ((prev (point))) |
2123 (while (and | 4984 (while (and |
2124 (= (c-backward-token-1 1 nil closest-lim) 0) | 4985 (= (c-backward-token-2 1 nil closest-lim) 0) |
2125 (eq (char-syntax (char-after)) ?w)) | 4986 (eq (char-syntax (char-after)) ?w)) |
2126 (setq prev (point))) | 4987 (setq prev (point))) |
2127 (goto-char prev) | 4988 (goto-char prev) |
2128 (not (c-looking-at-bos))) | 4989 (not (c-looking-at-bos))) |
2129 ;; Also, in Pike we treat it as an | 4990 ;; Also, in Pike we treat it as an |
2130 ;; in-expression class if it's used in an | 4991 ;; in-expression class if it's used in an |
2131 ;; object clone expression. | 4992 ;; object clone expression. |
2132 (save-excursion | 4993 (save-excursion |
2133 (and (c-major-mode-is 'pike-mode) | 4994 (and (c-major-mode-is 'pike-mode) |
2134 (progn (goto-char block-follows) | 4995 (progn (goto-char block-follows) |
2135 (= (c-forward-token-1 1 t) 0)) | 4996 (zerop (c-forward-token-2 1 t))) |
2136 (eq (char-after) ?\()))) | 4997 (eq (char-after) ?\()))) |
2137 (cons 'inexpr-class (point)))) | 4998 (cons 'inexpr-class (point)))) |
2138 ((and c-opt-inexpr-block-key | 4999 ((and c-opt-inexpr-block-key |
2139 (looking-at c-opt-inexpr-block-key)) | 5000 (looking-at c-opt-inexpr-block-key)) |
2140 (cons 'inexpr-statement (point))) | 5001 (cons 'inexpr-statement (point))) |
2181 (setq containing-sexp (car-safe paren-state))) | 5042 (setq containing-sexp (car-safe paren-state))) |
2182 (c-looking-at-inexpr-block (c-safe-position containing-sexp | 5043 (c-looking-at-inexpr-block (c-safe-position containing-sexp |
2183 paren-state) | 5044 paren-state) |
2184 containing-sexp))))) | 5045 containing-sexp))))) |
2185 | 5046 |
2186 (defun c-on-identifier () | |
2187 "Return non-nil if we're on or directly after an identifier. | |
2188 Keywords are recognized and not considered identifiers." | |
2189 (if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_)) | |
2190 (memq (char-syntax (or (char-before) ? )) '(?w ?_))) | |
2191 (save-excursion | |
2192 (skip-syntax-backward "w_") | |
2193 (not (looking-at c-keywords-regexp))) | |
2194 (if (c-major-mode-is 'pike-mode) | |
2195 ;; Handle the `<operator> syntax in Pike. | |
2196 (save-excursion | |
2197 (if (eq (char-after) ?\`) (forward-char)) | |
2198 (skip-chars-backward "!%&*+\\-/<=>^|~") | |
2199 (let ((pos (point))) | |
2200 (cond ((memq (char-before) '(?\) ?\])) | |
2201 (c-safe (backward-char 2))) | |
2202 ((memq (char-before) '(?\( ?\[)) | |
2203 (c-safe (backward-char 1)))) | |
2204 (if (not (looking-at "()\\|\\[]")) | |
2205 (goto-char pos))) | |
2206 (and (eq (char-before) ?\`) | |
2207 (looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]")))))) | |
2208 | |
2209 | |
2210 (defun c-most-enclosing-brace (paren-state &optional bufpos) | |
2211 ;; Return the bufpos of the innermost enclosing brace before bufpos | |
2212 ;; that hasn't been narrowed out, or nil if none was found. | |
2213 (let (enclosingp) | |
2214 (or bufpos (setq bufpos 134217727)) | |
2215 (while paren-state | |
2216 (setq enclosingp (car paren-state) | |
2217 paren-state (cdr paren-state)) | |
2218 (if (or (consp enclosingp) | |
2219 (>= enclosingp bufpos)) | |
2220 (setq enclosingp nil) | |
2221 (if (< enclosingp (point-min)) | |
2222 (setq enclosingp nil)) | |
2223 (setq paren-state nil))) | |
2224 enclosingp)) | |
2225 | |
2226 (defun c-least-enclosing-brace (paren-state &optional bufpos) | |
2227 ;; Return the bufpos of the outermost enclosing brace before bufpos | |
2228 ;; that hasn't been narrowed out, or nil if none was found. | |
2229 (let (pos elem) | |
2230 (or bufpos (setq bufpos 134217727)) | |
2231 (while paren-state | |
2232 (setq elem (car paren-state) | |
2233 paren-state (cdr paren-state)) | |
2234 (unless (or (consp elem) | |
2235 (>= elem bufpos)) | |
2236 (if (>= elem (point-min)) | |
2237 (setq pos elem)))) | |
2238 pos)) | |
2239 | |
2240 (defun c-safe-position (bufpos paren-state) | |
2241 ;; Return the closest known safe position higher up than BUFPOS, or | |
2242 ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is | |
2243 ;; nil, which is useful to find the closest limit before a given | |
2244 ;; limit that might be nil. | |
2245 (when bufpos | |
2246 (let ((c-macro-start (c-query-macro-start)) safepos) | |
2247 (if (and c-macro-start | |
2248 (< c-macro-start bufpos)) | |
2249 ;; Make sure bufpos is outside the macro we might be in. | |
2250 (setq bufpos c-macro-start)) | |
2251 (catch 'done | |
2252 (while paren-state | |
2253 (setq safepos | |
2254 (if (consp (car paren-state)) | |
2255 (cdr (car paren-state)) | |
2256 (car paren-state))) | |
2257 (if (< safepos bufpos) | |
2258 (throw 'done safepos) | |
2259 (setq paren-state (cdr paren-state)))) | |
2260 (if (eq c-macro-start bufpos) | |
2261 ;; Backed up bufpos to the macro start and got outside the | |
2262 ;; state. We know the macro is at the top level in this case, | |
2263 ;; so we can use the macro start as the safe position. | |
2264 c-macro-start))))) | |
2265 | |
2266 (defun c-narrow-out-enclosing-class (paren-state lim) | 5047 (defun c-narrow-out-enclosing-class (paren-state lim) |
2267 ;; Narrow the buffer so that the enclosing class is hidden. Uses | 5048 ;; Narrow the buffer so that the enclosing class is hidden. Uses |
2268 ;; and returns the value from c-search-uplist-for-classkey. | 5049 ;; and returns the value from c-search-uplist-for-classkey. |
2269 (setq paren-state (c-whack-state-after (point) paren-state)) | 5050 (setq paren-state (c-whack-state-after (point) paren-state)) |
2270 (let (inclass-p) | 5051 (let (inclass-p) |
2287 (c-point 'eol)))) | 5068 (c-point 'eol)))) |
2288 ;; return the class vector | 5069 ;; return the class vector |
2289 inclass-p)) | 5070 inclass-p)) |
2290 | 5071 |
2291 | 5072 |
2292 ;; c-guess-basic-syntax implements the main decision tree for | 5073 ;; `c-guess-basic-syntax' and the functions that precedes it below |
2293 ;; determining the syntactic analysis of the current line of code. | 5074 ;; implements the main decision tree for determining the syntactic |
2294 ;; Yes, it's huge and bloated! | 5075 ;; analysis of the current line of code. |
2295 | 5076 |
2296 ;; It's useful to break out some parts of the decision tree to | 5077 ;; Dynamically bound to t when `c-guess-basic-syntax' is called during |
2297 ;; separate functions, which are all collected below. Use dynamic | 5078 ;; auto newline analysis. |
2298 ;; binding to propagate back the syntax results from them. | 5079 (defvar c-auto-newline-analysis nil) |
2299 (defvar syntax) | 5080 |
2300 (defvar syntactic-relpos) | 5081 (defsubst c-add-syntax (symbol &rest args) |
5082 ;; A simple function to prepend a new syntax element to | |
5083 ;; `c-syntactic-context'. Using `setq' on it is unsafe since it | |
5084 ;; should always be dynamically bound but since we read it first | |
5085 ;; we'll fail properly anyway if this function is misused. | |
5086 (setq c-syntactic-context (cons (cons symbol args) | |
5087 c-syntactic-context))) | |
5088 | |
5089 (defsubst c-append-syntax (symbol &rest args) | |
5090 ;; Like `c-add-syntax' but appends to the end of the syntax list. | |
5091 ;; (Normally not necessary.) | |
5092 (setq c-syntactic-context (nconc c-syntactic-context | |
5093 (list (cons symbol args))))) | |
2301 | 5094 |
2302 (defun c-add-stmt-syntax (syntax-symbol | 5095 (defun c-add-stmt-syntax (syntax-symbol |
5096 syntax-extra-args | |
2303 stop-at-boi-only | 5097 stop-at-boi-only |
5098 at-block-start | |
2304 containing-sexp | 5099 containing-sexp |
2305 paren-state | 5100 paren-state) |
2306 &optional at-block-start) | |
2307 ;; Do the generic processing to anchor the given syntax symbol on | 5101 ;; Do the generic processing to anchor the given syntax symbol on |
2308 ;; the preceding statement: Skip over any labels and containing | 5102 ;; the preceding statement: Skip over any labels and containing |
2309 ;; statements on the same line, and then search backward until we | 5103 ;; statements on the same line, and then search backward until we |
2310 ;; find a statement or block start that begins at boi without a | 5104 ;; find a statement or block start that begins at boi without a |
2311 ;; label or comment. | 5105 ;; label or comment. |
2312 ;; | 5106 ;; |
2313 ;; Point is assumed to be at the prospective anchor point for the | 5107 ;; Point is assumed to be at the prospective anchor point for the |
2314 ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to | 5108 ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to |
2315 ;; skip past block opens and containing statement. All the added | 5109 ;; skip past open parens and containing statements. All the added |
2316 ;; syntax elements will get the same anchor point. | 5110 ;; syntax elements will get the same anchor point. |
5111 ;; | |
5112 ;; SYNTAX-EXTRA-ARGS are a list of the extra arguments for the | |
5113 ;; syntax symbol. They are appended after the anchor point. | |
2317 ;; | 5114 ;; |
2318 ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the | 5115 ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the |
2319 ;; line if another statement precedes the current one on this line. | 5116 ;; line if another statement precedes the current one on this line. |
2320 ;; | 5117 ;; |
2321 ;; If AT-BLOCK-START is non-nil, point is taken to be at the | 5118 ;; If AT-BLOCK-START is non-nil, point is taken to be at the |
2323 ;; inside an expression. If AT-BLOCK-START is nil, this is found | 5120 ;; inside an expression. If AT-BLOCK-START is nil, this is found |
2324 ;; out by checking whether the character at point is "{" or not. | 5121 ;; out by checking whether the character at point is "{" or not. |
2325 (if (= (point) (c-point 'boi)) | 5122 (if (= (point) (c-point 'boi)) |
2326 ;; This is by far the most common case, so let's give it special | 5123 ;; This is by far the most common case, so let's give it special |
2327 ;; treatment. | 5124 ;; treatment. |
2328 (c-add-syntax syntax-symbol (point)) | 5125 (apply 'c-add-syntax syntax-symbol (point) syntax-extra-args) |
2329 | 5126 |
2330 (let* ((savepos (point)) | 5127 (let ((savepos (point)) |
2331 (syms (list syntax-symbol)) | 5128 (syntax-last c-syntactic-context) |
2332 (syms-tail syms) | 5129 (boi (c-point 'boi)) |
2333 (boi (c-point 'boi)) | 5130 (prev-paren (if at-block-start ?{ (char-after))) |
2334 (prev-paren (if at-block-start ?{ (char-after))) | 5131 step-type step-tmp at-comment special-list) |
2335 step-type step-tmp at-comment add-inexpr-stmt) | 5132 (apply 'c-add-syntax syntax-symbol nil syntax-extra-args) |
2336 | 5133 |
2337 ;; Begin by skipping any labels and containing statements that | 5134 ;; Begin by skipping any labels and containing statements that |
2338 ;; are on the same line. | 5135 ;; are on the same line. |
2339 (while (and (/= (point) boi) | 5136 (while (and (/= (point) boi) |
2340 (if (memq (setq step-tmp | 5137 (if (memq (setq step-tmp |
2349 | 5146 |
2350 (catch 'done | 5147 (catch 'done |
2351 ;; Loop if we have to back out of the containing block. | 5148 ;; Loop if we have to back out of the containing block. |
2352 (while | 5149 (while |
2353 (progn | 5150 (progn |
5151 | |
2354 ;; Loop if we have to back up another statement. | 5152 ;; Loop if we have to back up another statement. |
2355 (while | 5153 (while |
2356 (progn | 5154 (progn |
2357 | 5155 |
2358 ;; Always start by skipping over any comments that | 5156 ;; Always start by skipping over any comments that |
2359 ;; stands between the statement and boi. | 5157 ;; stands between the statement and boi. |
2360 (while (and (/= (setq savepos (point)) boi) | 5158 (while (and (/= (setq savepos (point)) boi) |
2361 (c-forward-comment -1)) | 5159 (c-backward-single-comment)) |
2362 (setq at-comment t | 5160 (setq at-comment t |
2363 boi (c-point 'boi))) | 5161 boi (c-point 'boi))) |
2364 (goto-char savepos) | 5162 (goto-char savepos) |
2365 | 5163 |
2366 (and | 5164 (and |
2395 ;; one level, but not if we're still on the | 5193 ;; one level, but not if we're still on the |
2396 ;; same line. This so e.g. a sequence of "else | 5194 ;; same line. This so e.g. a sequence of "else |
2397 ;; if" clauses won't indent deeper and deeper. | 5195 ;; if" clauses won't indent deeper and deeper. |
2398 (when (and (eq step-type 'up) | 5196 (when (and (eq step-type 'up) |
2399 (< (point) boi)) | 5197 (< (point) boi)) |
2400 (setcdr syms-tail (list 'substatement)) | 5198 (c-add-syntax 'substatement nil)) |
2401 (setq syms-tail (cdr syms-tail))) | |
2402 | 5199 |
2403 (setq boi (c-point 'boi)) | 5200 (setq boi (c-point 'boi)) |
2404 (/= (point) savepos))))) | 5201 (/= (point) savepos))))) |
2405 | 5202 |
2406 (setq savepos (point) | 5203 (setq savepos (point) |
2408 (setq at-comment nil) | 5205 (setq at-comment nil) |
2409 | 5206 |
2410 (when (and (eq step-type 'same) | 5207 (when (and (eq step-type 'same) |
2411 containing-sexp) | 5208 containing-sexp) |
2412 (goto-char containing-sexp) | 5209 (goto-char containing-sexp) |
5210 | |
5211 ;; Don't stop in the middle of a special brace list opener | |
5212 ;; like "({". | |
5213 (when (and c-special-brace-lists | |
5214 (setq special-list | |
5215 (c-looking-at-special-brace-list))) | |
5216 (setq containing-sexp (car (car special-list))) | |
5217 (goto-char containing-sexp)) | |
5218 | |
2413 (setq paren-state (c-whack-state-after containing-sexp | 5219 (setq paren-state (c-whack-state-after containing-sexp |
2414 paren-state) | 5220 paren-state) |
2415 containing-sexp (c-most-enclosing-brace paren-state)) | 5221 containing-sexp (c-most-enclosing-brace paren-state) |
2416 | 5222 savepos (point) |
2417 | 5223 boi (c-point 'boi)) |
2418 (when (eq (setq prev-paren (char-after)) ?\() | 5224 |
2419 (c-backward-syntactic-ws containing-sexp) | 5225 (if (eq (setq prev-paren (char-after)) ?\() |
2420 (when (c-on-identifier) | 5226 (progn |
2421 ;; Arrived at a function arglist start. Exit with | 5227 (c-backward-syntactic-ws containing-sexp) |
2422 ;; the position of the first argument inside it. | 5228 (when (/= savepos boi) |
2423 (goto-char savepos) | 5229 (if (and (or (not (looking-at "\\>")) |
2424 (throw 'done t)) | 5230 (not (c-on-identifier))) |
2425 ;; We're in an in-expression statement. Remember | 5231 (not special-list) |
2426 ;; this. We'll iterate below, but won't add any | 5232 (save-excursion |
2427 ;; syntax element. | 5233 (c-forward-syntactic-ws) |
2428 (setq add-inexpr-stmt t)) | 5234 (forward-char) |
2429 | 5235 (c-forward-syntactic-ws) |
2430 (setq savepos (point) | 5236 (eq (char-after) ?{))) |
2431 boi (c-point 'boi) | 5237 ;; We're in an in-expression statement. |
2432 step-type (c-beginning-of-statement-1 containing-sexp)) | 5238 ;; This syntactic element won't get an anchor pos. |
5239 (c-add-syntax 'inexpr-statement) | |
5240 (c-add-syntax 'arglist-cont-nonempty nil savepos))) | |
5241 (goto-char (max boi | |
5242 (if containing-sexp | |
5243 (1+ containing-sexp) | |
5244 (point-min)))) | |
5245 (setq step-type 'same)) | |
5246 (setq step-type | |
5247 (c-beginning-of-statement-1 containing-sexp))) | |
2433 | 5248 |
2434 (let ((at-bod (and (eq step-type 'same) | 5249 (let ((at-bod (and (eq step-type 'same) |
2435 (/= savepos (point)) | 5250 (/= savepos (point)) |
2436 (eq prev-paren ?{)))) | 5251 (eq prev-paren ?{)))) |
5252 | |
2437 (when (= savepos boi) | 5253 (when (= savepos boi) |
2438 ;; If the open brace was at boi, we're always | 5254 ;; If the open brace was at boi, we're always |
2439 ;; done. The c-beginning-of-statement-1 call | 5255 ;; done. The c-beginning-of-statement-1 call |
2440 ;; above is necessary anyway, to decide the type | 5256 ;; above is necessary anyway, to decide the type |
2441 ;; of block-intro to add. | 5257 ;; of block-intro to add. |
2442 (goto-char savepos) | 5258 (goto-char savepos) |
2443 (setq savepos nil)) | 5259 (setq savepos nil)) |
2444 | 5260 |
2445 (when (eq prev-paren ?{) | 5261 (when (eq prev-paren ?{) |
2446 (setcdr syms-tail (list (if at-bod | 5262 (c-add-syntax (if at-bod |
2447 'defun-block-intro | 5263 'defun-block-intro |
2448 'statement-block-intro))) | 5264 'statement-block-intro) |
2449 (setq syms-tail (cdr syms-tail))) | 5265 nil)) |
2450 | 5266 |
2451 (when (and (not at-bod) savepos) | 5267 (when (and (not at-bod) savepos) |
2452 ;; Loop if the brace wasn't at boi, and we didn't | 5268 ;; Loop if the brace wasn't at boi, and we didn't |
2453 ;; arrive at a defun block. | 5269 ;; arrive at a defun block. |
2454 (if (eq step-type 'same) | 5270 (if (eq step-type 'same) |
2460 (memq step-type '(up previous beginning))) | 5276 (memq step-type '(up previous beginning))) |
2461 (setq stop-at-boi-only t)) | 5277 (setq stop-at-boi-only t)) |
2462 (setq boi (c-point 'boi))))) | 5278 (setq boi (c-point 'boi))))) |
2463 ))) | 5279 ))) |
2464 | 5280 |
2465 (while syms | 5281 ;; Fill in the current point as the anchor for all the symbols |
2466 (c-add-syntax (car syms) (point)) | 5282 ;; added above. |
2467 (setq syms (cdr syms))) | 5283 (let ((p c-syntactic-context)) |
2468 (if add-inexpr-stmt | 5284 (while (not (eq p syntax-last)) |
2469 (c-add-syntax 'inexpr-statement)) | 5285 (if (cdr (car p)) |
5286 (setcar (cdr (car p)) (point))) | |
5287 (setq p (cdr p)))) | |
5288 | |
2470 ))) | 5289 ))) |
2471 | 5290 |
2472 (defun c-add-class-syntax (symbol classkey paren-state) | 5291 (defun c-add-class-syntax (symbol classkey paren-state) |
2473 ;; The inclass and class-close syntactic symbols are added in | 5292 ;; The inclass and class-close syntactic symbols are added in |
2474 ;; several places and some work is needed to fix everything. | 5293 ;; several places and some work is needed to fix everything. |
2497 containing-sexp | 5316 containing-sexp |
2498 paren-state) | 5317 paren-state) |
2499 ;; This function contains the decision tree reached through both | 5318 ;; This function contains the decision tree reached through both |
2500 ;; cases 18 and 10. It's a continued statement or top level | 5319 ;; cases 18 and 10. It's a continued statement or top level |
2501 ;; construct of some kind. | 5320 ;; construct of some kind. |
5321 | |
2502 (let (special-brace-list) | 5322 (let (special-brace-list) |
2503 (goto-char indent-point) | 5323 (goto-char indent-point) |
2504 (skip-chars-forward " \t") | 5324 (skip-chars-forward " \t") |
5325 | |
2505 (cond | 5326 (cond |
2506 ;; (CASE A removed.) | 5327 ;; (CASE A removed.) |
2507 ;; CASE B: open braces for class or brace-lists | 5328 ;; CASE B: open braces for class or brace-lists |
2508 ((setq special-brace-list | 5329 ((setq special-brace-list |
2509 (or (and c-special-brace-lists | 5330 (or (and c-special-brace-lists |
2510 (c-looking-at-special-brace-list)) | 5331 (c-looking-at-special-brace-list)) |
2511 (eq char-after-ip ?{))) | 5332 (eq char-after-ip ?{))) |
5333 | |
2512 (cond | 5334 (cond |
2513 ;; CASE B.1: class-open | 5335 ;; CASE B.1: class-open |
2514 ((save-excursion | 5336 ((save-excursion |
2515 (goto-char indent-point) | 5337 (skip-chars-forward "{") |
2516 (skip-chars-forward " \t{") | |
2517 (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) | 5338 (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) |
2518 (and decl | 5339 (and decl |
2519 (setq beg-of-same-or-containing-stmt (aref decl 0))) | 5340 (setq beg-of-same-or-containing-stmt (aref decl 0))) |
2520 )) | 5341 )) |
2521 (c-add-syntax 'class-open beg-of-same-or-containing-stmt)) | 5342 (c-add-syntax 'class-open beg-of-same-or-containing-stmt)) |
5343 | |
2522 ;; CASE B.2: brace-list-open | 5344 ;; CASE B.2: brace-list-open |
2523 ((or (consp special-brace-list) | 5345 ((or (consp special-brace-list) |
2524 (save-excursion | 5346 (save-excursion |
2525 (goto-char beg-of-same-or-containing-stmt) | 5347 (goto-char beg-of-same-or-containing-stmt) |
2526 (looking-at "enum\\>[^_]")) | 5348 (c-syntactic-re-search-forward "=\\([^=]\\|$\\)" |
2527 (save-excursion | 5349 indent-point t t t))) |
2528 (goto-char indent-point) | |
2529 (while (and (> (point) beg-of-same-or-containing-stmt) | |
2530 (= (c-backward-token-1 1 t) 0) | |
2531 (/= (char-after) ?=))) | |
2532 (eq (char-after) ?=))) | |
2533 ;; The most semantically accurate symbol here is | 5350 ;; The most semantically accurate symbol here is |
2534 ;; brace-list-open, but we report it simply as a statement-cont. | 5351 ;; brace-list-open, but we normally report it simply as a |
2535 ;; The reason is that one normally adjusts brace-list-open for | 5352 ;; statement-cont. The reason is that one normally adjusts |
2536 ;; brace lists as top-level constructs, and brace lists inside | 5353 ;; brace-list-open for brace lists as top-level constructs, |
2537 ;; statements is a completely different context. | 5354 ;; and brace lists inside statements is a completely different |
5355 ;; context. C.f. case 5A.3. | |
2538 (c-beginning-of-statement-1 containing-sexp) | 5356 (c-beginning-of-statement-1 containing-sexp) |
2539 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state)) | 5357 (c-add-stmt-syntax (if c-auto-newline-analysis |
5358 ;; Turn off the dwim above when we're | |
5359 ;; analyzing the nature of the brace | |
5360 ;; for the auto newline feature. | |
5361 'brace-list-open | |
5362 'statement-cont) | |
5363 nil nil nil | |
5364 containing-sexp paren-state)) | |
5365 | |
2540 ;; CASE B.3: The body of a function declared inside a normal | 5366 ;; CASE B.3: The body of a function declared inside a normal |
2541 ;; block. Can occur e.g. in Pike and when using gcc | 5367 ;; block. Can occur e.g. in Pike and when using gcc |
2542 ;; extensions. Might also trigger it with some macros followed | 5368 ;; extensions. Might also trigger it with some macros followed |
2543 ;; by blocks, and this gives sane indentation then too. | 5369 ;; by blocks, and this gives sane indentation then too. |
2544 ;; C.f. cases 16F and 17G. | 5370 ;; C.f. cases E, 16F and 17G. |
2545 ((progn | 5371 ((and (not (c-looking-at-bos)) |
2546 (goto-char indent-point) | 5372 (eq (c-beginning-of-statement-1 containing-sexp nil nil t) |
2547 (and (not (c-looking-at-bos)) | 5373 'same)) |
2548 (eq (c-beginning-of-statement-1 containing-sexp nil nil t) | 5374 (c-add-stmt-syntax 'defun-open nil t nil |
2549 'same))) | 5375 containing-sexp paren-state)) |
2550 (c-add-stmt-syntax 'defun-open t containing-sexp paren-state)) | 5376 |
2551 ;; CASE B.4: Continued statement with block open. | 5377 ;; CASE B.4: Continued statement with block open. |
2552 (t | 5378 (t |
2553 (goto-char beg-of-same-or-containing-stmt) | 5379 (goto-char beg-of-same-or-containing-stmt) |
2554 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state) | 5380 (c-add-stmt-syntax 'statement-cont nil nil nil |
5381 containing-sexp paren-state) | |
2555 (c-add-syntax 'block-open)) | 5382 (c-add-syntax 'block-open)) |
2556 )) | 5383 )) |
5384 | |
2557 ;; CASE C: iostream insertion or extraction operator | 5385 ;; CASE C: iostream insertion or extraction operator |
2558 ((and (looking-at "<<\\|>>") | 5386 ((and (looking-at "\\(<<\\|>>\\)\\([^=]\\|$\\)") |
2559 (save-excursion | 5387 (save-excursion |
2560 (goto-char beg-of-same-or-containing-stmt) | 5388 (goto-char beg-of-same-or-containing-stmt) |
2561 (while (and (re-search-forward "<<\\|>>" indent-point 'move) | 5389 ;; If there is no preceding streamop in the statement |
2562 (c-in-literal beg-of-same-or-containing-stmt))) | 5390 ;; then indent this line as a normal statement-cont. |
2563 ;; if we ended up at indent-point, then the first streamop is on a | 5391 (when (c-syntactic-re-search-forward |
2564 ;; separate line. Indent the line like a statement-cont instead | 5392 "\\(<<\\|>>\\)\\([^=]\\|$\\)" indent-point 'move t t) |
2565 (when (/= (point) indent-point) | |
2566 (c-add-syntax 'stream-op (c-point 'boi)) | 5393 (c-add-syntax 'stream-op (c-point 'boi)) |
2567 t)))) | 5394 t)))) |
5395 | |
5396 ;; CASE E: In the "K&R region" of a function declared inside a | |
5397 ;; normal block. C.f. case B.3. | |
5398 ((and (save-excursion | |
5399 ;; Check that the next token is a '{'. This works as | |
5400 ;; long as no language that allows nested function | |
5401 ;; definitions doesn't allow stuff like member init | |
5402 ;; lists, K&R declarations or throws clauses there. | |
5403 ;; | |
5404 ;; Note that we do a forward search for something ahead | |
5405 ;; of the indentation line here. That's not good since | |
5406 ;; the user might not have typed it yet. Unfortunately | |
5407 ;; it's exceedingly tricky to recognize a function | |
5408 ;; prototype in a code block without resorting to this. | |
5409 (c-forward-syntactic-ws) | |
5410 (eq (char-after) ?{)) | |
5411 (not (c-looking-at-bos)) | |
5412 (eq (c-beginning-of-statement-1 containing-sexp nil nil t) | |
5413 'same)) | |
5414 (c-add-stmt-syntax 'func-decl-cont nil t nil | |
5415 containing-sexp paren-state)) | |
5416 | |
2568 ;; CASE D: continued statement. | 5417 ;; CASE D: continued statement. |
2569 (t | 5418 (t |
2570 (c-beginning-of-statement-1 containing-sexp) | 5419 (c-beginning-of-statement-1 containing-sexp) |
2571 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state)) | 5420 (c-add-stmt-syntax 'statement-cont nil nil nil |
5421 containing-sexp paren-state)) | |
2572 ))) | 5422 ))) |
2573 | 5423 |
2574 (defun c-guess-basic-syntax () | 5424 (defun c-guess-basic-syntax () |
2575 "Return the syntactic context of the current line." | 5425 "Return the syntactic context of the current line." |
2576 (save-excursion | 5426 (save-excursion |
2578 (beginning-of-line) | 5428 (beginning-of-line) |
2579 (let* ((indent-point (point)) | 5429 (let* ((indent-point (point)) |
2580 (case-fold-search nil) | 5430 (case-fold-search nil) |
2581 (paren-state (c-parse-state)) | 5431 (paren-state (c-parse-state)) |
2582 literal containing-sexp char-before-ip char-after-ip lim | 5432 literal containing-sexp char-before-ip char-after-ip lim |
2583 syntax placeholder c-in-literal-cache step-type | 5433 c-syntactic-context placeholder c-in-literal-cache step-type |
2584 tmpsymbol keyword injava-inher special-brace-list | 5434 tmpsymbol keyword injava-inher special-brace-list |
2585 ;; narrow out any enclosing class or extern "C" block | 5435 ;; narrow out any enclosing class or extern "C" block |
2586 (inclass-p (c-narrow-out-enclosing-class paren-state | 5436 (inclass-p (c-narrow-out-enclosing-class paren-state |
2587 indent-point)) | 5437 indent-point)) |
2588 ;; c-state-cache is shadowed here. That means we must | 5438 ;; `c-state-cache' is shadowed here so that we don't |
2589 ;; not do any changes during the execution of this | 5439 ;; throw it away due to the narrowing that might be done |
2590 ;; function, since c-check-state-cache then would change | 5440 ;; by the function above. That means we must not do any |
2591 ;; this local variable and leave a bogus value in the | 5441 ;; changes during the execution of this function, since |
2592 ;; global one. | 5442 ;; `c-invalidate-state-cache' then would change this local |
5443 ;; variable and leave a bogus value in the global one. | |
2593 (c-state-cache (if inclass-p | 5444 (c-state-cache (if inclass-p |
2594 (c-whack-state-before (point-min) paren-state) | 5445 (c-whack-state-before (point-min) paren-state) |
2595 paren-state)) | 5446 paren-state)) |
2596 (c-state-cache-start (point-min)) | 5447 (c-state-cache-start (point-min)) |
2597 inenclosing-p macro-start in-macro-expr | 5448 inenclosing-p macro-start in-macro-expr |
2598 ;; There's always at most one syntactic element which got | 5449 ;; There's always at most one syntactic element which got |
2599 ;; a relpos. It's stored in syntactic-relpos. | 5450 ;; a relpos. It's stored in syntactic-relpos. |
2600 syntactic-relpos | 5451 syntactic-relpos |
2601 (c-stmt-delim-chars c-stmt-delim-chars)) | 5452 (c-stmt-delim-chars c-stmt-delim-chars)) |
2602 ;; check for meta top-level enclosing constructs, possible | 5453 ;; Check for meta top-level enclosing constructs such as |
2603 ;; extern language definitions, possibly (in C++) namespace | 5454 ;; extern language definitions. |
2604 ;; definitions. | |
2605 (save-excursion | 5455 (save-excursion |
2606 (save-restriction | 5456 (save-restriction |
2607 (widen) | 5457 (widen) |
2608 (if (and inclass-p | 5458 (when (and inclass-p |
2609 (progn | 5459 (progn |
2610 (goto-char (aref inclass-p 0)) | 5460 (goto-char (aref inclass-p 0)) |
2611 (looking-at c-other-decl-block-key))) | 5461 (looking-at c-other-decl-block-key))) |
2612 (let ((enclosing (match-string 1))) | 5462 (setq inenclosing-p (match-string 1)) |
2613 (cond | 5463 (if (string-equal inenclosing-p "extern") |
2614 ((string-equal enclosing "extern") | 5464 ;; Compatibility with legacy choice of name for the |
2615 (setq inenclosing-p 'extern)) | 5465 ;; extern-lang syntactic symbols. |
2616 ((string-equal enclosing "namespace") | 5466 (setq inenclosing-p "extern-lang"))))) |
2617 (setq inenclosing-p 'namespace)) | |
2618 ))))) | |
2619 | 5467 |
2620 ;; Init some position variables: | 5468 ;; Init some position variables: |
2621 ;; | 5469 ;; |
2622 ;; containing-sexp is the open paren of the closest | 5470 ;; containing-sexp is the open paren of the closest |
2623 ;; surrounding sexp or nil if there is none that hasn't been | 5471 ;; surrounding sexp or nil if there is none that hasn't been |
2680 (cond | 5528 (cond |
2681 ;; CASE 1: in a string. | 5529 ;; CASE 1: in a string. |
2682 ((eq literal 'string) | 5530 ((eq literal 'string) |
2683 (c-add-syntax 'string (c-point 'bopl))) | 5531 (c-add-syntax 'string (c-point 'bopl))) |
2684 ;; CASE 2: in a C or C++ style comment. | 5532 ;; CASE 2: in a C or C++ style comment. |
2685 ((memq literal '(c c++)) | 5533 ((and (memq literal '(c c++)) |
2686 (c-add-syntax literal (car (c-literal-limits lim)))) | 5534 ;; This is a kludge for XEmacs where we use |
5535 ;; `buffer-syntactic-context', which doesn't correctly | |
5536 ;; recognize "\*/" to end a block comment. | |
5537 ;; `parse-partial-sexp' which is used by | |
5538 ;; `c-literal-limits' will however do that in most | |
5539 ;; versions, which results in that we get nil from | |
5540 ;; `c-literal-limits' even when `c-in-literal' claims | |
5541 ;; we're inside a comment. | |
5542 (setq placeholder (c-literal-limits lim))) | |
5543 (c-add-syntax literal (car placeholder))) | |
2687 ;; CASE 3: in a cpp preprocessor macro continuation. | 5544 ;; CASE 3: in a cpp preprocessor macro continuation. |
2688 ((and (save-excursion | 5545 ((and (save-excursion |
2689 (when (c-beginning-of-macro) | 5546 (when (c-beginning-of-macro) |
2690 (setq macro-start (point)))) | 5547 (setq macro-start (point)))) |
2691 (/= macro-start (c-point 'boi)) | 5548 (/= macro-start (c-point 'boi)) |
2710 (c-add-syntax tmpsymbol macro-start) | 5567 (c-add-syntax tmpsymbol macro-start) |
2711 (setq macro-start nil)) | 5568 (setq macro-start nil)) |
2712 ;; CASE 11: an else clause? | 5569 ;; CASE 11: an else clause? |
2713 ((looking-at "else\\>[^_]") | 5570 ((looking-at "else\\>[^_]") |
2714 (c-beginning-of-statement-1 containing-sexp) | 5571 (c-beginning-of-statement-1 containing-sexp) |
2715 (c-add-stmt-syntax 'else-clause t containing-sexp paren-state)) | 5572 (c-add-stmt-syntax 'else-clause nil t nil |
5573 containing-sexp paren-state)) | |
2716 ;; CASE 12: while closure of a do/while construct? | 5574 ;; CASE 12: while closure of a do/while construct? |
2717 ((and (looking-at "while\\>[^_]") | 5575 ((and (looking-at "while\\>[^_]") |
2718 (save-excursion | 5576 (save-excursion |
2719 (prog1 (eq (c-beginning-of-statement-1 containing-sexp) | 5577 (prog1 (eq (c-beginning-of-statement-1 containing-sexp) |
2720 'beginning) | 5578 'beginning) |
2721 (setq placeholder (point))))) | 5579 (setq placeholder (point))))) |
2722 (goto-char placeholder) | 5580 (goto-char placeholder) |
2723 (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state)) | 5581 (c-add-stmt-syntax 'do-while-closure nil t nil |
5582 containing-sexp paren-state)) | |
2724 ;; CASE 13: A catch or finally clause? This case is simpler | 5583 ;; CASE 13: A catch or finally clause? This case is simpler |
2725 ;; than if-else and do-while, because a block is required | 5584 ;; than if-else and do-while, because a block is required |
2726 ;; after every try, catch and finally. | 5585 ;; after every try, catch and finally. |
2727 ((save-excursion | 5586 ((save-excursion |
2728 (and (cond ((c-major-mode-is 'c++-mode) | 5587 (and (cond ((c-major-mode-is 'c++-mode) |
2740 (c-safe (c-backward-sexp) t) | 5599 (c-safe (c-backward-sexp) t) |
2741 t)) | 5600 t)) |
2742 (looking-at "\\(try\\|catch\\)\\>[^_]") | 5601 (looking-at "\\(try\\|catch\\)\\>[^_]") |
2743 (setq placeholder (point)))) | 5602 (setq placeholder (point)))) |
2744 (goto-char placeholder) | 5603 (goto-char placeholder) |
2745 (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state)) | 5604 (c-add-stmt-syntax 'catch-clause nil t nil |
5605 containing-sexp paren-state)) | |
2746 ;; CASE 18: A substatement we can recognize by keyword. | 5606 ;; CASE 18: A substatement we can recognize by keyword. |
2747 ((save-excursion | 5607 ((save-excursion |
2748 (and c-opt-block-stmt-key | 5608 (and c-opt-block-stmt-key |
2749 (not (eq char-before-ip ?\;)) | 5609 (if (c-mode-is-new-awk-p) |
5610 (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29 | |
5611 (not (eq char-before-ip ?\;))) | |
2750 (not (memq char-after-ip '(?\) ?\] ?,))) | 5612 (not (memq char-after-ip '(?\) ?\] ?,))) |
2751 (or (not (eq char-before-ip ?})) | 5613 (or (not (eq char-before-ip ?})) |
2752 (c-looking-at-inexpr-block-backward c-state-cache)) | 5614 (c-looking-at-inexpr-block-backward c-state-cache)) |
2753 (> (point) | 5615 (> (point) |
2754 (progn | 5616 (progn |
2778 (if (looking-at c-block-stmt-2-key) | 5640 (if (looking-at c-block-stmt-2-key) |
2779 ;; Require a parenthesis after these keywords. | 5641 ;; Require a parenthesis after these keywords. |
2780 ;; Necessary to catch e.g. synchronized in Java, | 5642 ;; Necessary to catch e.g. synchronized in Java, |
2781 ;; which can be used both as statement and | 5643 ;; which can be used both as statement and |
2782 ;; modifier. | 5644 ;; modifier. |
2783 (and (= (c-forward-token-1 1 nil) 0) | 5645 (and (zerop (c-forward-token-2 1 nil)) |
2784 (eq (char-after) ?\()) | 5646 (eq (char-after) ?\()) |
2785 (looking-at c-opt-block-stmt-key)))) | 5647 (looking-at c-opt-block-stmt-key)))) |
2786 (if (eq step-type 'up) | 5648 (if (eq step-type 'up) |
2787 ;; CASE 18A: Simple substatement. | 5649 ;; CASE 18A: Simple substatement. |
2788 (progn | 5650 (progn |
2789 (goto-char placeholder) | 5651 (goto-char placeholder) |
2790 (cond | 5652 (cond |
2791 ((eq char-after-ip ?{) | 5653 ((eq char-after-ip ?{) |
2792 (c-add-stmt-syntax 'substatement-open nil | 5654 (c-add-stmt-syntax 'substatement-open nil nil nil |
2793 containing-sexp paren-state)) | 5655 containing-sexp paren-state)) |
2794 ((save-excursion | 5656 ((save-excursion |
2795 (goto-char indent-point) | 5657 (goto-char indent-point) |
2796 (back-to-indentation) | 5658 (back-to-indentation) |
2797 (looking-at c-label-key)) | 5659 (looking-at c-label-key)) |
2798 (c-add-stmt-syntax 'substatement-label nil | 5660 (c-add-stmt-syntax 'substatement-label nil nil nil |
2799 containing-sexp paren-state)) | 5661 containing-sexp paren-state)) |
2800 (t | 5662 (t |
2801 (c-add-stmt-syntax 'substatement nil | 5663 (c-add-stmt-syntax 'substatement nil nil nil |
2802 containing-sexp paren-state)))) | 5664 containing-sexp paren-state)))) |
2803 ;; CASE 18B: Some other substatement. This is shared | 5665 ;; CASE 18B: Some other substatement. This is shared |
2804 ;; with case 10. | 5666 ;; with case 10. |
2805 (c-guess-continued-construct indent-point | 5667 (c-guess-continued-construct indent-point |
2806 char-after-ip | 5668 char-after-ip |
2827 (setq tmpsymbol (if (eq char-after-ip ?{) | 5689 (setq tmpsymbol (if (eq char-after-ip ?{) |
2828 'inline-open | 5690 'inline-open |
2829 'lambda-intro-cont))) | 5691 'lambda-intro-cont))) |
2830 (goto-char (cdr placeholder)) | 5692 (goto-char (cdr placeholder)) |
2831 (back-to-indentation) | 5693 (back-to-indentation) |
2832 (c-add-stmt-syntax tmpsymbol t | 5694 (c-add-stmt-syntax tmpsymbol nil t nil |
2833 (c-most-enclosing-brace c-state-cache (point)) | 5695 (c-most-enclosing-brace c-state-cache (point)) |
2834 (c-whack-state-after (point) paren-state)) | 5696 (c-whack-state-after (point) paren-state)) |
2835 (unless (eq (point) (cdr placeholder)) | 5697 (unless (eq (point) (cdr placeholder)) |
2836 (c-add-syntax (car placeholder)))) | 5698 (c-add-syntax (car placeholder)))) |
2837 ;; CASE 5: Line is at top level. | 5699 ;; CASE 5: Line is at top level. |
2842 ((setq special-brace-list | 5704 ((setq special-brace-list |
2843 (or (and c-special-brace-lists | 5705 (or (and c-special-brace-lists |
2844 (c-looking-at-special-brace-list)) | 5706 (c-looking-at-special-brace-list)) |
2845 (eq char-after-ip ?{))) | 5707 (eq char-after-ip ?{))) |
2846 (cond | 5708 (cond |
2847 ;; CASE 5A.1: extern language or namespace construct | 5709 ;; CASE 5A.1: Non-class declaration block open. |
2848 ((save-excursion | 5710 ((save-excursion |
2849 (goto-char indent-point) | 5711 (goto-char indent-point) |
2850 (skip-chars-forward " \t") | 5712 (skip-chars-forward " \t") |
2851 (and (c-safe (progn (c-backward-sexp 2) t)) | 5713 (and (c-safe (c-backward-sexp 2) t) |
2852 (looking-at c-other-decl-block-key) | 5714 (looking-at c-other-decl-block-key) |
2853 (setq keyword (match-string 1) | 5715 (setq keyword (match-string 1) |
2854 placeholder (point)) | 5716 placeholder (point)) |
2855 (or (and (string-equal keyword "namespace") | 5717 (if (string-equal keyword "extern") |
2856 (setq tmpsymbol 'namespace-open)) | 5718 ;; Special case for extern-lang-open. The |
2857 (and (string-equal keyword "extern") | 5719 ;; check for a following string is disabled |
2858 (progn | 5720 ;; since it doesn't disambiguate anything. |
2859 (c-forward-sexp 1) | 5721 (and ;;(progn |
2860 (c-forward-syntactic-ws) | 5722 ;; (c-forward-sexp 1) |
2861 (eq (char-after) ?\")) | 5723 ;; (c-forward-syntactic-ws) |
2862 (setq tmpsymbol 'extern-lang-open))) | 5724 ;; (eq (char-after) ?\")) |
5725 (setq tmpsymbol 'extern-lang-open)) | |
5726 (setq tmpsymbol (intern (concat keyword "-open")))) | |
2863 )) | 5727 )) |
2864 (goto-char placeholder) | 5728 (goto-char placeholder) |
2865 (c-add-syntax tmpsymbol (c-point 'boi))) | 5729 (c-add-syntax tmpsymbol (c-point 'boi))) |
2866 ;; CASE 5A.2: we are looking at a class opening brace | 5730 ;; CASE 5A.2: we are looking at a class opening brace |
2867 ((save-excursion | 5731 ((save-excursion |
2872 (setq placeholder (aref decl 0))) | 5736 (setq placeholder (aref decl 0))) |
2873 )) | 5737 )) |
2874 (c-add-syntax 'class-open placeholder)) | 5738 (c-add-syntax 'class-open placeholder)) |
2875 ;; CASE 5A.3: brace list open | 5739 ;; CASE 5A.3: brace list open |
2876 ((save-excursion | 5740 ((save-excursion |
2877 (c-beginning-of-statement-1 lim t) | 5741 (c-beginning-of-decl-1 lim) |
2878 (if (looking-at "typedef\\>[^_]") | 5742 (while (looking-at c-specifier-key) |
2879 (progn (c-forward-sexp 1) | 5743 (goto-char (match-end 1)) |
2880 (c-forward-syntactic-ws indent-point))) | 5744 (c-forward-syntactic-ws indent-point)) |
2881 (setq placeholder (c-point 'boi)) | 5745 (setq placeholder (c-point 'boi)) |
2882 (or (consp special-brace-list) | 5746 (or (consp special-brace-list) |
2883 (and (or (save-excursion | 5747 (and (or (save-excursion |
2884 (goto-char indent-point) | 5748 (goto-char indent-point) |
2885 (setq tmpsymbol nil) | 5749 (setq tmpsymbol nil) |
2886 (while (and (> (point) placeholder) | 5750 (while (and (> (point) placeholder) |
2887 (= (c-backward-token-1 1 t) 0) | 5751 (zerop (c-backward-token-2 1 t)) |
2888 (/= (char-after) ?=)) | 5752 (/= (char-after) ?=)) |
2889 (if (and (not tmpsymbol) | 5753 (and c-opt-inexpr-brace-list-key |
2890 (looking-at "new\\>[^_]")) | 5754 (not tmpsymbol) |
2891 (setq tmpsymbol 'topmost-intro-cont))) | 5755 (looking-at c-opt-inexpr-brace-list-key) |
5756 (setq tmpsymbol 'topmost-intro-cont))) | |
2892 (eq (char-after) ?=)) | 5757 (eq (char-after) ?=)) |
2893 (looking-at "enum\\>[^_]")) | 5758 (looking-at c-brace-list-key)) |
2894 (save-excursion | 5759 (save-excursion |
2895 (while (and (< (point) indent-point) | 5760 (while (and (< (point) indent-point) |
2896 (= (c-forward-token-1 1 t) 0) | 5761 (zerop (c-forward-token-2 1 t)) |
2897 (not (memq (char-after) '(?\; ?\())))) | 5762 (not (memq (char-after) '(?\; ?\())))) |
2898 (not (memq (char-after) '(?\; ?\())) | 5763 (not (memq (char-after) '(?\; ?\())) |
2899 )))) | 5764 )))) |
2900 (if (and (c-major-mode-is 'java-mode) | 5765 (if (and (not c-auto-newline-analysis) |
5766 (c-major-mode-is 'java-mode) | |
2901 (eq tmpsymbol 'topmost-intro-cont)) | 5767 (eq tmpsymbol 'topmost-intro-cont)) |
2902 ;; We're in Java and have found that the open brace | 5768 ;; We're in Java and have found that the open brace |
2903 ;; belongs to a "new Foo[]" initialization list, | 5769 ;; belongs to a "new Foo[]" initialization list, |
2904 ;; which means the brace list is part of an | 5770 ;; which means the brace list is part of an |
2905 ;; expression and not a top level definition. We | 5771 ;; expression and not a top level definition. We |
2906 ;; therefore treat it as any topmost continuation | 5772 ;; therefore treat it as any topmost continuation |
2907 ;; even though the semantically correct symbol still | 5773 ;; even though the semantically correct symbol still |
2908 ;; is brace-list-open, on the same grounds as in | 5774 ;; is brace-list-open, on the same grounds as in |
2909 ;; case 10B.2. | 5775 ;; case B.2. |
2910 (progn | 5776 (progn |
2911 (c-beginning-of-statement-1 lim) | 5777 (c-beginning-of-statement-1 lim) |
2912 (c-add-syntax 'topmost-intro-cont (c-point 'boi))) | 5778 (c-add-syntax 'topmost-intro-cont (c-point 'boi))) |
2913 (c-add-syntax 'brace-list-open placeholder))) | 5779 (c-add-syntax 'brace-list-open placeholder))) |
2914 ;; CASE 5A.4: inline defun open | 5780 ;; CASE 5A.4: inline defun open |
2922 (c-add-syntax 'defun-open (c-point 'boi)) | 5788 (c-add-syntax 'defun-open (c-point 'boi)) |
2923 ;; Bogus to use bol here, but it's the legacy. | 5789 ;; Bogus to use bol here, but it's the legacy. |
2924 (c-add-syntax 'defun-open (c-point 'bol))) | 5790 (c-add-syntax 'defun-open (c-point 'bol))) |
2925 ))) | 5791 ))) |
2926 ;; CASE 5B: first K&R arg decl or member init | 5792 ;; CASE 5B: first K&R arg decl or member init |
2927 ((c-just-after-func-arglist-p nil lim) | 5793 ((c-just-after-func-arglist-p lim) |
2928 (cond | 5794 (cond |
2929 ;; CASE 5B.1: a member init | 5795 ;; CASE 5B.1: a member init |
2930 ((or (eq char-before-ip ?:) | 5796 ((or (eq char-before-ip ?:) |
2931 (eq char-after-ip ?:)) | 5797 (eq char-after-ip ?:)) |
2932 ;; this line should be indented relative to the beginning | 5798 ;; this line should be indented relative to the beginning |
2974 ((or (and (c-major-mode-is 'c++-mode) | 5840 ((or (and (c-major-mode-is 'c++-mode) |
2975 (progn | 5841 (progn |
2976 (when (eq char-after-ip ?,) | 5842 (when (eq char-after-ip ?,) |
2977 (skip-chars-forward " \t") | 5843 (skip-chars-forward " \t") |
2978 (forward-char)) | 5844 (forward-char)) |
2979 (looking-at c-opt-decl-spec-key))) | 5845 (looking-at c-opt-postfix-decl-spec-key))) |
2980 (and (or (eq char-before-ip ?:) | 5846 (and (or (eq char-before-ip ?:) |
2981 ;; watch out for scope operator | 5847 ;; watch out for scope operator |
2982 (save-excursion | 5848 (save-excursion |
2983 (and (eq char-after-ip ?:) | 5849 (and (eq char-after-ip ?:) |
2984 (c-safe (progn (forward-char 1) t)) | 5850 (c-safe (forward-char 1) t) |
2985 (not (eq (char-after) ?:)) | 5851 (not (eq (char-after) ?:)) |
2986 ))) | 5852 ))) |
2987 (save-excursion | 5853 (save-excursion |
2988 (c-backward-syntactic-ws lim) | 5854 (c-backward-syntactic-ws lim) |
2989 (if (eq char-before-ip ?:) | 5855 (if (eq char-before-ip ?:) |
2998 (c-beginning-of-statement-1 lim) | 5864 (c-beginning-of-statement-1 lim) |
2999 (point))) | 5865 (point))) |
3000 cont done) | 5866 cont done) |
3001 (save-excursion | 5867 (save-excursion |
3002 (while (not done) | 5868 (while (not done) |
3003 (cond ((looking-at c-opt-decl-spec-key) | 5869 (cond ((looking-at c-opt-postfix-decl-spec-key) |
3004 (setq injava-inher (cons cont (point)) | 5870 (setq injava-inher (cons cont (point)) |
3005 done t)) | 5871 done t)) |
3006 ((or (not (c-safe (c-forward-sexp -1) t)) | 5872 ((or (not (c-safe (c-forward-sexp -1) t)) |
3007 (<= (point) fence)) | 5873 (<= (point) fence)) |
3008 (setq done t)) | 5874 (setq done t)) |
3055 c++-template-syntax-table | 5921 c++-template-syntax-table |
3056 (syntax-table)) | 5922 (syntax-table)) |
3057 (save-excursion | 5923 (save-excursion |
3058 ;; Note: We use the fact that lim is always after any | 5924 ;; Note: We use the fact that lim is always after any |
3059 ;; preceding brace sexp. | 5925 ;; preceding brace sexp. |
3060 (while (and (= (c-backward-token-1 1 t lim) 0) | 5926 (while (and (zerop (c-backward-token-2 1 t lim)) |
3061 (not (looking-at "[;<,=]")))) | 5927 (not (looking-at "[;<,=]")))) |
3062 (or (memq (char-after) '(?, ?=)) | 5928 (or (memq (char-after) '(?, ?=)) |
3063 (and (c-major-mode-is 'c++-mode) | 5929 (and (c-major-mode-is 'c++-mode) |
3064 (= (c-backward-token-1 1 nil lim) 0) | 5930 (zerop (c-backward-token-2 1 nil lim)) |
3065 (eq (char-after) ?<))))) | 5931 (eq (char-after) ?<))))) |
3066 (goto-char indent-point) | 5932 (goto-char indent-point) |
3067 (c-beginning-of-member-init-list lim) | 5933 (setq placeholder |
5934 (c-beginning-of-member-init-list lim)) | |
3068 (cond | 5935 (cond |
3069 ;; CASE 5D.1: hanging member init colon, but watch out | 5936 ;; CASE 5D.1: hanging member init colon, but watch out |
3070 ;; for bogus matches on access specifiers inside classes. | 5937 ;; for bogus matches on access specifiers inside classes. |
3071 ((and (save-excursion | 5938 ((and placeholder |
5939 (save-excursion | |
3072 (setq placeholder (point)) | 5940 (setq placeholder (point)) |
3073 (c-backward-token-1 1 t lim) | 5941 (c-backward-token-2 1 t lim) |
3074 (and (eq (char-after) ?:) | 5942 (and (eq (char-after) ?:) |
3075 (not (eq (char-before) ?:)))) | 5943 (not (eq (char-before) ?:)))) |
3076 (save-excursion | 5944 (save-excursion |
3077 (goto-char placeholder) | 5945 (goto-char placeholder) |
3078 (back-to-indentation) | 5946 (back-to-indentation) |
3116 ((and (c-major-mode-is 'c++-mode) | 5984 ((and (c-major-mode-is 'c++-mode) |
3117 (save-excursion | 5985 (save-excursion |
3118 (c-beginning-of-statement-1 lim) | 5986 (c-beginning-of-statement-1 lim) |
3119 (setq placeholder (point)) | 5987 (setq placeholder (point)) |
3120 (if (looking-at "static\\>[^_]") | 5988 (if (looking-at "static\\>[^_]") |
3121 (c-forward-token-1 1 nil indent-point)) | 5989 (c-forward-token-2 1 nil indent-point)) |
3122 (and (looking-at c-class-key) | 5990 (and (looking-at c-class-key) |
3123 (= (c-forward-token-1 2 nil indent-point) 0) | 5991 (zerop (c-forward-token-2 2 nil indent-point)) |
3124 (if (eq (char-after) ?<) | 5992 (if (eq (char-after) ?<) |
3125 (c-with-syntax-table c++-template-syntax-table | 5993 (c-with-syntax-table c++-template-syntax-table |
3126 (= (c-forward-token-1 1 t indent-point) 0)) | 5994 (zerop (c-forward-token-2 1 t indent-point))) |
3127 t) | 5995 t) |
3128 (eq (char-after) ?:)))) | 5996 (eq (char-after) ?:)))) |
3129 (goto-char placeholder) | 5997 (goto-char placeholder) |
3130 (c-add-syntax 'inher-cont (c-point 'boi))) | 5998 (c-add-syntax 'inher-cont (c-point 'boi))) |
3131 ;; CASE 5D.5: Continuation of the "expression part" of a | 5999 ;; CASE 5D.5: Continuation of the "expression part" of a |
3142 ;; new variable declaration starts here. Use | 6010 ;; new variable declaration starts here. Use |
3143 ;; topmost-intro-cont for it, for consistency with | 6011 ;; topmost-intro-cont for it, for consistency with |
3144 ;; the first variable declaration. C.f. case 5N. | 6012 ;; the first variable declaration. C.f. case 5N. |
3145 'topmost-intro-cont | 6013 'topmost-intro-cont |
3146 'statement-cont) | 6014 'statement-cont) |
3147 nil containing-sexp paren-state)) | 6015 nil nil nil containing-sexp paren-state)) |
3148 )) | 6016 )) |
3149 ;; CASE 5E: we are looking at a access specifier | 6017 ;; CASE 5E: we are looking at a access specifier |
3150 ((and inclass-p | 6018 ((and inclass-p |
3151 c-opt-access-key | 6019 c-opt-access-key |
3152 (looking-at c-opt-access-key)) | 6020 (looking-at c-opt-access-key)) |
3153 (setq placeholder (c-add-class-syntax 'inclass inclass-p | 6021 (setq placeholder (c-add-class-syntax 'inclass inclass-p |
3154 paren-state)) | 6022 paren-state)) |
3155 ;; Append access-label with the same anchor point as inclass gets. | 6023 ;; Append access-label with the same anchor point as inclass gets. |
3156 (nconc syntax (list (cons 'access-label placeholder)))) | 6024 (c-append-syntax 'access-label placeholder)) |
3157 ;; CASE 5F: extern-lang-close or namespace-close? | 6025 ;; CASE 5F: Close of a non-class declaration level block. |
3158 ((and inenclosing-p | 6026 ((and inenclosing-p |
3159 (eq char-after-ip ?})) | 6027 (eq char-after-ip ?})) |
3160 (setq tmpsymbol (if (eq inenclosing-p 'extern) | 6028 (c-add-syntax (intern (concat inenclosing-p "-close")) |
3161 'extern-lang-close | 6029 (aref inclass-p 0))) |
3162 'namespace-close)) | |
3163 (c-add-syntax tmpsymbol (aref inclass-p 0))) | |
3164 ;; CASE 5G: we are looking at the brace which closes the | 6030 ;; CASE 5G: we are looking at the brace which closes the |
3165 ;; enclosing nested class decl | 6031 ;; enclosing nested class decl |
3166 ((and inclass-p | 6032 ((and inclass-p |
3167 (eq char-after-ip ?}) | 6033 (eq char-after-ip ?}) |
3168 (save-excursion | 6034 (save-excursion |
3169 (save-restriction | 6035 (save-restriction |
3170 (widen) | 6036 (widen) |
3171 (forward-char 1) | 6037 (forward-char 1) |
3172 (and (c-safe (progn (c-backward-sexp 1) t)) | 6038 (and (c-safe (c-backward-sexp 1) t) |
3173 (= (point) (aref inclass-p 1)) | 6039 (= (point) (aref inclass-p 1)) |
3174 )))) | 6040 )))) |
3175 (c-add-class-syntax 'class-close inclass-p paren-state)) | 6041 (c-add-class-syntax 'class-close inclass-p paren-state)) |
3176 ;; CASE 5H: we could be looking at subsequent knr-argdecls | 6042 ;; CASE 5H: we could be looking at subsequent knr-argdecls |
3177 ((and c-recognize-knr-p | 6043 ((and c-recognize-knr-p |
3191 ;; CASE 5I: ObjC method definition. | 6057 ;; CASE 5I: ObjC method definition. |
3192 ((and c-opt-method-key | 6058 ((and c-opt-method-key |
3193 (looking-at c-opt-method-key)) | 6059 (looking-at c-opt-method-key)) |
3194 (c-beginning-of-statement-1 lim) | 6060 (c-beginning-of-statement-1 lim) |
3195 (c-add-syntax 'objc-method-intro (c-point 'boi))) | 6061 (c-add-syntax 'objc-method-intro (c-point 'boi))) |
6062 ;; CASE 5P: AWK pattern or function or continuation | |
6063 ;; thereof. | |
6064 ((c-mode-is-new-awk-p) | |
6065 (setq placeholder (point)) | |
6066 (c-add-stmt-syntax | |
6067 (if (and (eq (c-beginning-of-statement-1) 'same) | |
6068 (/= (point) placeholder)) | |
6069 'topmost-intro-cont | |
6070 'topmost-intro) | |
6071 nil nil nil | |
6072 containing-sexp paren-state)) | |
3196 ;; CASE 5N: At a variable declaration that follows a class | 6073 ;; CASE 5N: At a variable declaration that follows a class |
3197 ;; definition or some other block declaration that doesn't | 6074 ;; definition or some other block declaration that doesn't |
3198 ;; end at the closing '}'. C.f. case 5D.5. | 6075 ;; end at the closing '}'. C.f. case 5D.5. |
3199 ((progn | 6076 ((progn |
3200 (c-backward-syntactic-ws lim) | 6077 (c-backward-syntactic-ws lim) |
3210 ;; The '}' is unbalanced. | 6087 ;; The '}' is unbalanced. |
3211 nil | 6088 nil |
3212 (c-end-of-decl-1) | 6089 (c-end-of-decl-1) |
3213 (> (point) indent-point)))))) | 6090 (> (point) indent-point)))))) |
3214 (goto-char placeholder) | 6091 (goto-char placeholder) |
3215 (c-add-stmt-syntax 'topmost-intro-cont nil | 6092 (c-add-stmt-syntax 'topmost-intro-cont nil nil nil |
3216 containing-sexp paren-state)) | 6093 containing-sexp paren-state)) |
3217 ;; CASE 5J: we are at the topmost level, make | 6094 ;; CASE 5J: we are at the topmost level, make |
3218 ;; sure we skip back past any access specifiers | 6095 ;; sure we skip back past any access specifiers |
3219 ((progn | 6096 ((progn |
3220 (while (and inclass-p | 6097 (while (and inclass-p |
3221 c-opt-access-key | 6098 c-opt-access-key |
3222 (not (bobp)) | 6099 (not (bobp)) |
3223 (save-excursion | 6100 (save-excursion |
3224 (c-safe (progn (c-backward-sexp 1) t)) | 6101 (c-safe (c-backward-sexp 1) t) |
3225 (looking-at c-opt-access-key))) | 6102 (looking-at c-opt-access-key))) |
3226 (c-backward-sexp 1) | 6103 (c-backward-sexp 1) |
3227 (c-backward-syntactic-ws lim)) | 6104 (c-backward-syntactic-ws lim)) |
3228 (or (bobp) | 6105 (or (bobp) |
3229 (memq (char-before) '(?\; ?})) | 6106 (if (c-mode-is-new-awk-p) |
6107 (not (c-awk-prev-line-incomplete-p)) | |
6108 (memq (char-before) '(?\; ?}))) | |
3230 (and (c-major-mode-is 'objc-mode) | 6109 (and (c-major-mode-is 'objc-mode) |
3231 (progn | 6110 (progn |
3232 (c-beginning-of-statement-1 lim) | 6111 (c-beginning-of-statement-1 lim) |
3233 (eq (char-after) ?@))))) | 6112 (eq (char-after) ?@))))) |
3234 ;; real beginning-of-line could be narrowed out due to | 6113 ;; real beginning-of-line could be narrowed out due to |
3241 (if inclass-p | 6120 (if inclass-p |
3242 (progn | 6121 (progn |
3243 (goto-char (aref inclass-p 1)) | 6122 (goto-char (aref inclass-p 1)) |
3244 (or (= (point) (c-point 'boi)) | 6123 (or (= (point) (c-point 'boi)) |
3245 (goto-char (aref inclass-p 0))) | 6124 (goto-char (aref inclass-p 0))) |
3246 (cond | 6125 (if inenclosing-p |
3247 ((eq inenclosing-p 'extern) | 6126 (c-add-syntax (intern (concat "in" inenclosing-p)) |
3248 (c-add-syntax 'inextern-lang (c-point 'boi))) | 6127 (c-point 'boi)) |
3249 ((eq inenclosing-p 'namespace) | 6128 (c-add-class-syntax 'inclass inclass-p paren-state)) |
3250 (c-add-syntax 'innamespace (c-point 'boi))) | |
3251 (t (c-add-class-syntax 'inclass inclass-p paren-state))) | |
3252 )) | 6129 )) |
3253 (when (and c-syntactic-indentation-in-macros | 6130 (when (and c-syntactic-indentation-in-macros |
3254 macro-start | 6131 macro-start |
3255 (/= macro-start (c-point 'boi indent-point))) | 6132 (/= macro-start (c-point 'boi indent-point))) |
3256 (c-add-syntax 'cpp-define-intro) | 6133 (c-add-syntax 'cpp-define-intro) |
3282 (save-excursion | 6159 (save-excursion |
3283 (goto-char containing-sexp) | 6160 (goto-char containing-sexp) |
3284 (c-looking-at-special-brace-list))) | 6161 (c-looking-at-special-brace-list))) |
3285 (eq (char-after containing-sexp) ?{))) | 6162 (eq (char-after containing-sexp) ?{))) |
3286 (cond | 6163 (cond |
3287 ;; CASE 7A: we are looking at the arglist closing paren | 6164 ;; CASE 7A: we are looking at the arglist closing paren. |
6165 ;; C.f. case 7F. | |
3288 ((memq char-after-ip '(?\) ?\])) | 6166 ((memq char-after-ip '(?\) ?\])) |
3289 (goto-char containing-sexp) | 6167 (goto-char containing-sexp) |
3290 (setq placeholder (c-point 'boi)) | 6168 (setq placeholder (c-point 'boi)) |
3291 (when (and (c-safe (backward-up-list 1) t) | 6169 (if (and (c-safe (backward-up-list 1) t) |
3292 (> (point) placeholder)) | 6170 (> (point) placeholder)) |
3293 (forward-char) | 6171 (progn |
3294 (skip-chars-forward " \t") | 6172 (forward-char) |
3295 (setq placeholder (point))) | 6173 (skip-chars-forward " \t")) |
3296 (c-add-syntax 'arglist-close placeholder)) | 6174 (goto-char placeholder)) |
6175 (c-add-stmt-syntax 'arglist-close (list containing-sexp) t nil | |
6176 (c-most-enclosing-brace paren-state (point)) | |
6177 (c-whack-state-after (point) paren-state))) | |
3297 ;; CASE 7B: Looking at the opening brace of an | 6178 ;; CASE 7B: Looking at the opening brace of an |
3298 ;; in-expression block or brace list. C.f. cases 4, 16A | 6179 ;; in-expression block or brace list. C.f. cases 4, 16A |
3299 ;; and 17E. | 6180 ;; and 17E. |
3300 ((and (eq char-after-ip ?{) | 6181 ((and (eq char-after-ip ?{) |
3301 (progn | 6182 (progn |
3313 ;; a function arglist. That makes us skip out of | 6194 ;; a function arglist. That makes us skip out of |
3314 ;; this case. | 6195 ;; this case. |
3315 ))) | 6196 ))) |
3316 (goto-char placeholder) | 6197 (goto-char placeholder) |
3317 (back-to-indentation) | 6198 (back-to-indentation) |
3318 (c-add-stmt-syntax (car tmpsymbol) t | 6199 (c-add-stmt-syntax (car tmpsymbol) nil t nil |
3319 (c-most-enclosing-brace paren-state (point)) | 6200 (c-most-enclosing-brace paren-state (point)) |
3320 (c-whack-state-after (point) paren-state)) | 6201 (c-whack-state-after (point) paren-state)) |
3321 (if (/= (point) placeholder) | 6202 (if (/= (point) placeholder) |
3322 (c-add-syntax (cdr tmpsymbol)))) | 6203 (c-add-syntax (cdr tmpsymbol)))) |
3323 ;; CASE 7C: we are looking at the first argument in an empty | 6204 ;; CASE 7C: we are looking at the first argument in an empty |
3334 (c-add-syntax 'arglist-intro placeholder)) | 6215 (c-add-syntax 'arglist-intro placeholder)) |
3335 ;; CASE 7D: we are inside a conditional test clause. treat | 6216 ;; CASE 7D: we are inside a conditional test clause. treat |
3336 ;; these things as statements | 6217 ;; these things as statements |
3337 ((progn | 6218 ((progn |
3338 (goto-char containing-sexp) | 6219 (goto-char containing-sexp) |
3339 (and (c-safe (progn (c-forward-sexp -1) t)) | 6220 (and (c-safe (c-forward-sexp -1) t) |
3340 (looking-at "\\<for\\>[^_]"))) | 6221 (looking-at "\\<for\\>[^_]"))) |
3341 (goto-char (1+ containing-sexp)) | 6222 (goto-char (1+ containing-sexp)) |
3342 (c-forward-syntactic-ws indent-point) | 6223 (c-forward-syntactic-ws indent-point) |
3343 (if (eq char-before-ip ?\;) | 6224 (if (eq char-before-ip ?\;) |
3344 (c-add-syntax 'statement (point)) | 6225 (c-add-syntax 'statement (point)) |
3357 ))) | 6238 ))) |
3358 ;; CASE 7F: we are looking at an arglist continuation line, | 6239 ;; CASE 7F: we are looking at an arglist continuation line, |
3359 ;; but the preceding argument is on the same line as the | 6240 ;; but the preceding argument is on the same line as the |
3360 ;; opening paren. This case includes multi-line | 6241 ;; opening paren. This case includes multi-line |
3361 ;; mathematical paren groupings, but we could be on a | 6242 ;; mathematical paren groupings, but we could be on a |
3362 ;; for-list continuation line | 6243 ;; for-list continuation line. C.f. case 7A. |
3363 ((progn | 6244 ((progn |
3364 (goto-char (1+ containing-sexp)) | 6245 (goto-char (1+ containing-sexp)) |
3365 (skip-chars-forward " \t") | 6246 (skip-chars-forward " \t") |
3366 (and (not (eolp)) | 6247 (and (not (eolp)) |
3367 (not (looking-at "\\\\$")))) | 6248 (not (looking-at "\\\\$")))) |
3368 (goto-char containing-sexp) | 6249 (goto-char containing-sexp) |
3369 (setq placeholder (c-point 'boi)) | 6250 (setq placeholder (c-point 'boi)) |
3370 (when (and (c-safe (backward-up-list 1) t) | 6251 (if (and (c-safe (backward-up-list 1) t) |
3371 (> (point) placeholder)) | 6252 (> (point) placeholder)) |
3372 (forward-char) | 6253 (progn |
3373 (skip-chars-forward " \t") | 6254 (forward-char) |
3374 (setq placeholder (point))) | 6255 (skip-chars-forward " \t")) |
3375 (c-add-syntax 'arglist-cont-nonempty placeholder)) | 6256 (goto-char placeholder)) |
6257 (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) | |
6258 t nil | |
6259 (c-most-enclosing-brace c-state-cache (point)) | |
6260 (c-whack-state-after (point) paren-state))) | |
3376 ;; CASE 7G: we are looking at just a normal arglist | 6261 ;; CASE 7G: we are looking at just a normal arglist |
3377 ;; continuation line | 6262 ;; continuation line |
3378 (t (c-forward-syntactic-ws indent-point) | 6263 (t (c-forward-syntactic-ws indent-point) |
3379 (c-add-syntax 'arglist-cont (c-point 'boi))) | 6264 (c-add-syntax 'arglist-cont (c-point 'boi))) |
3380 )) | 6265 )) |
3381 ;; CASE 8: func-local multi-inheritance line | 6266 ;; CASE 8: func-local multi-inheritance line |
3382 ((and (c-major-mode-is 'c++-mode) | 6267 ((and (c-major-mode-is 'c++-mode) |
3383 (save-excursion | 6268 (save-excursion |
3384 (goto-char indent-point) | 6269 (goto-char indent-point) |
3385 (skip-chars-forward " \t") | 6270 (skip-chars-forward " \t") |
3386 (looking-at c-opt-decl-spec-key))) | 6271 (looking-at c-opt-postfix-decl-spec-key))) |
3387 (goto-char indent-point) | 6272 (goto-char indent-point) |
3388 (skip-chars-forward " \t") | 6273 (skip-chars-forward " \t") |
3389 (cond | 6274 (cond |
3390 ;; CASE 8A: non-hanging colon on an inher intro | 6275 ;; CASE 8A: non-hanging colon on an inher intro |
3391 ((eq char-after-ip ?:) | 6276 ((eq char-after-ip ?:) |
3398 (t | 6283 (t |
3399 (c-beginning-of-inheritance-list lim) | 6284 (c-beginning-of-inheritance-list lim) |
3400 (c-add-syntax 'inher-cont (point)) | 6285 (c-add-syntax 'inher-cont (point)) |
3401 ))) | 6286 ))) |
3402 ;; CASE 9: we are inside a brace-list | 6287 ;; CASE 9: we are inside a brace-list |
3403 ((setq special-brace-list | 6288 ((and (not (c-mode-is-new-awk-p)) ; Maybe this isn't needed (ACM, 2002/3/29) |
3404 (or (and c-special-brace-lists | 6289 (setq special-brace-list |
3405 (save-excursion | 6290 (or (and c-special-brace-lists |
3406 (goto-char containing-sexp) | 6291 (save-excursion |
3407 (c-looking-at-special-brace-list))) | 6292 (goto-char containing-sexp) |
3408 (c-inside-bracelist-p containing-sexp paren-state))) | 6293 (c-looking-at-special-brace-list))) |
6294 (c-inside-bracelist-p containing-sexp paren-state)))) | |
3409 (cond | 6295 (cond |
3410 ;; CASE 9A: In the middle of a special brace list opener. | 6296 ;; CASE 9A: In the middle of a special brace list opener. |
3411 ((and (consp special-brace-list) | 6297 ((and (consp special-brace-list) |
3412 (save-excursion | 6298 (save-excursion |
3413 (goto-char containing-sexp) | 6299 (goto-char containing-sexp) |
3416 (goto-char (car (car special-brace-list))) | 6302 (goto-char (car (car special-brace-list))) |
3417 (skip-chars-backward " \t") | 6303 (skip-chars-backward " \t") |
3418 (if (and (bolp) | 6304 (if (and (bolp) |
3419 (assoc 'statement-cont | 6305 (assoc 'statement-cont |
3420 (setq placeholder (c-guess-basic-syntax)))) | 6306 (setq placeholder (c-guess-basic-syntax)))) |
3421 (setq syntax placeholder) | 6307 (setq c-syntactic-context placeholder) |
3422 (c-beginning-of-statement-1 | 6308 (c-beginning-of-statement-1 |
3423 (c-safe-position (1- containing-sexp) paren-state)) | 6309 (c-safe-position (1- containing-sexp) paren-state)) |
3424 (c-forward-token-1 0) | 6310 (c-forward-token-2 0) |
3425 (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1)) | 6311 (while (looking-at c-specifier-key) |
6312 (goto-char (match-end 1)) | |
6313 (c-forward-syntactic-ws)) | |
3426 (c-add-syntax 'brace-list-open (c-point 'boi)))) | 6314 (c-add-syntax 'brace-list-open (c-point 'boi)))) |
3427 ;; CASE 9B: brace-list-close brace | 6315 ;; CASE 9B: brace-list-close brace |
3428 ((if (consp special-brace-list) | 6316 ((if (consp special-brace-list) |
3429 ;; Check special brace list closer. | 6317 ;; Check special brace list closer. |
3430 (progn | 6318 (progn |
3436 ;; We were between the special close char and the `)'. | 6324 ;; We were between the special close char and the `)'. |
3437 (and (eq (char-after) ?\)) | 6325 (and (eq (char-after) ?\)) |
3438 (eq (1+ (point)) (cdr (car special-brace-list)))) | 6326 (eq (1+ (point)) (cdr (car special-brace-list)))) |
3439 ;; We were before the special close char. | 6327 ;; We were before the special close char. |
3440 (and (eq (char-after) (cdr (cdr special-brace-list))) | 6328 (and (eq (char-after) (cdr (cdr special-brace-list))) |
3441 (= (c-forward-token-1) 0) | 6329 (zerop (c-forward-token-2)) |
3442 (eq (1+ (point)) (cdr (car special-brace-list))))))) | 6330 (eq (1+ (point)) (cdr (car special-brace-list))))))) |
3443 ;; Normal brace list check. | 6331 ;; Normal brace list check. |
3444 (and (eq char-after-ip ?}) | 6332 (and (eq char-after-ip ?}) |
3445 (c-safe (progn (goto-char (c-up-list-backward (point))) | 6333 (c-safe (goto-char (c-up-list-backward (point))) t) |
3446 t)) | |
3447 (= (point) containing-sexp))) | 6334 (= (point) containing-sexp))) |
3448 (if (eq (point) (c-point 'boi)) | 6335 (if (eq (point) (c-point 'boi)) |
3449 (c-add-syntax 'brace-list-close (point)) | 6336 (c-add-syntax 'brace-list-close (point)) |
3450 (setq lim (c-most-enclosing-brace c-state-cache (point))) | 6337 (setq lim (c-most-enclosing-brace c-state-cache (point))) |
3451 (c-beginning-of-statement-1 lim) | 6338 (c-beginning-of-statement-1 lim) |
3452 (c-add-stmt-syntax 'brace-list-close t lim | 6339 (c-add-stmt-syntax 'brace-list-close nil t t lim |
3453 (c-whack-state-after (point) paren-state) | 6340 (c-whack-state-after (point) paren-state)))) |
3454 t))) | |
3455 (t | 6341 (t |
3456 ;; Prepare for the rest of the cases below by going to the | 6342 ;; Prepare for the rest of the cases below by going to the |
3457 ;; token following the opening brace | 6343 ;; token following the opening brace |
3458 (if (consp special-brace-list) | 6344 (if (consp special-brace-list) |
3459 (progn | 6345 (progn |
3460 (goto-char (car (car special-brace-list))) | 6346 (goto-char (car (car special-brace-list))) |
3461 (c-forward-token-1 1 nil indent-point)) | 6347 (c-forward-token-2 1 nil indent-point)) |
3462 (goto-char containing-sexp)) | 6348 (goto-char containing-sexp)) |
3463 (forward-char) | 6349 (forward-char) |
3464 (let ((start (point))) | 6350 (let ((start (point))) |
3465 (c-forward-syntactic-ws indent-point) | 6351 (c-forward-syntactic-ws indent-point) |
3466 (goto-char (max start (c-point 'bol)))) | 6352 (goto-char (max start (c-point 'bol)))) |
3473 (goto-char containing-sexp)) | 6359 (goto-char containing-sexp)) |
3474 (if (eq (point) (c-point 'boi)) | 6360 (if (eq (point) (c-point 'boi)) |
3475 (c-add-syntax 'brace-list-intro (point)) | 6361 (c-add-syntax 'brace-list-intro (point)) |
3476 (setq lim (c-most-enclosing-brace c-state-cache (point))) | 6362 (setq lim (c-most-enclosing-brace c-state-cache (point))) |
3477 (c-beginning-of-statement-1 lim) | 6363 (c-beginning-of-statement-1 lim) |
3478 (c-add-stmt-syntax 'brace-list-intro t lim | 6364 (c-add-stmt-syntax 'brace-list-intro nil t t lim |
3479 (c-whack-state-after (point) paren-state) | 6365 (c-whack-state-after (point) paren-state)))) |
3480 t))) | |
3481 ;; CASE 9D: this is just a later brace-list-entry or | 6366 ;; CASE 9D: this is just a later brace-list-entry or |
3482 ;; brace-entry-open | 6367 ;; brace-entry-open |
3483 (t (if (or (eq char-after-ip ?{) | 6368 (t (if (or (eq char-after-ip ?{) |
3484 (and c-special-brace-lists | 6369 (and c-special-brace-lists |
3485 (save-excursion | 6370 (save-excursion |
3489 (c-add-syntax 'brace-entry-open (point)) | 6374 (c-add-syntax 'brace-entry-open (point)) |
3490 (c-add-syntax 'brace-list-entry (point)) | 6375 (c-add-syntax 'brace-list-entry (point)) |
3491 )) | 6376 )) |
3492 )))) | 6377 )))) |
3493 ;; CASE 10: A continued statement or top level construct. | 6378 ;; CASE 10: A continued statement or top level construct. |
3494 ((and (not (memq char-before-ip '(?\; ?:))) | 6379 ((and (if (c-mode-is-new-awk-p) |
3495 (or (not (eq char-before-ip ?})) | 6380 (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29 |
3496 (c-looking-at-inexpr-block-backward c-state-cache)) | 6381 (and (not (memq char-before-ip '(?\; ?:))) |
6382 (or (not (eq char-before-ip ?})) | |
6383 (c-looking-at-inexpr-block-backward c-state-cache)))) | |
3497 (> (point) | 6384 (> (point) |
3498 (save-excursion | 6385 (save-excursion |
3499 (c-beginning-of-statement-1 containing-sexp) | 6386 (c-beginning-of-statement-1 containing-sexp) |
3500 (setq placeholder (point)))) | 6387 (setq placeholder (point)))) |
3501 (/= placeholder containing-sexp)) | 6388 (/= placeholder containing-sexp)) |
3508 ;; CASE 14: A case or default label | 6395 ;; CASE 14: A case or default label |
3509 ((looking-at c-label-kwds-regexp) | 6396 ((looking-at c-label-kwds-regexp) |
3510 (goto-char containing-sexp) | 6397 (goto-char containing-sexp) |
3511 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp)) | 6398 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp)) |
3512 (c-backward-to-block-anchor lim) | 6399 (c-backward-to-block-anchor lim) |
3513 (c-add-stmt-syntax 'case-label t lim paren-state)) | 6400 (c-add-stmt-syntax 'case-label nil t nil |
6401 lim paren-state)) | |
3514 ;; CASE 15: any other label | 6402 ;; CASE 15: any other label |
3515 ((looking-at c-label-key) | 6403 ((looking-at c-label-key) |
3516 (goto-char containing-sexp) | 6404 (goto-char containing-sexp) |
3517 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp)) | 6405 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp)) |
3518 (save-excursion | 6406 (save-excursion |
3523 ;; let's analyze all labels as switch labels, so | 6411 ;; let's analyze all labels as switch labels, so |
3524 ;; that they get lined up consistently. | 6412 ;; that they get lined up consistently. |
3525 'case-label | 6413 'case-label |
3526 'label))) | 6414 'label))) |
3527 (c-backward-to-block-anchor lim) | 6415 (c-backward-to-block-anchor lim) |
3528 (c-add-stmt-syntax tmpsymbol t lim paren-state)) | 6416 (c-add-stmt-syntax tmpsymbol nil t nil |
6417 lim paren-state)) | |
3529 ;; CASE 16: block close brace, possibly closing the defun or | 6418 ;; CASE 16: block close brace, possibly closing the defun or |
3530 ;; the class | 6419 ;; the class |
3531 ((eq char-after-ip ?}) | 6420 ((eq char-after-ip ?}) |
3532 ;; From here on we have the next containing sexp in lim. | 6421 ;; From here on we have the next containing sexp in lim. |
3533 (setq lim (c-most-enclosing-brace paren-state)) | 6422 (setq lim (c-most-enclosing-brace paren-state)) |
3537 ;; cases where it's preceded by a statement keyword, | 6426 ;; cases where it's preceded by a statement keyword, |
3538 ;; which works even when used in an "invalid" context, | 6427 ;; which works even when used in an "invalid" context, |
3539 ;; e.g. a macro argument. | 6428 ;; e.g. a macro argument. |
3540 ((c-after-conditional) | 6429 ((c-after-conditional) |
3541 (c-backward-to-block-anchor lim) | 6430 (c-backward-to-block-anchor lim) |
3542 (c-add-stmt-syntax 'block-close t lim paren-state)) | 6431 (c-add-stmt-syntax 'block-close nil t nil |
6432 lim paren-state)) | |
3543 ;; CASE 16A: closing a lambda defun or an in-expression | 6433 ;; CASE 16A: closing a lambda defun or an in-expression |
3544 ;; block? C.f. cases 4, 7B and 17E. | 6434 ;; block? C.f. cases 4, 7B and 17E. |
3545 ((setq placeholder (c-looking-at-inexpr-block | 6435 ((setq placeholder (c-looking-at-inexpr-block |
3546 (c-safe-position containing-sexp paren-state) | 6436 (c-safe-position containing-sexp paren-state) |
3547 nil)) | 6437 nil)) |
3552 (back-to-indentation) | 6442 (back-to-indentation) |
3553 (if (= containing-sexp (point)) | 6443 (if (= containing-sexp (point)) |
3554 (c-add-syntax tmpsymbol (point)) | 6444 (c-add-syntax tmpsymbol (point)) |
3555 (goto-char (cdr placeholder)) | 6445 (goto-char (cdr placeholder)) |
3556 (back-to-indentation) | 6446 (back-to-indentation) |
3557 (c-add-stmt-syntax tmpsymbol t | 6447 (c-add-stmt-syntax tmpsymbol nil t nil |
3558 (c-most-enclosing-brace paren-state (point)) | 6448 (c-most-enclosing-brace paren-state (point)) |
3559 (c-whack-state-after (point) paren-state)) | 6449 (c-whack-state-after (point) paren-state)) |
3560 (if (/= (point) (cdr placeholder)) | 6450 (if (/= (point) (cdr placeholder)) |
3561 (c-add-syntax (car placeholder))))) | 6451 (c-add-syntax (car placeholder))))) |
3562 ;; CASE 16B: does this close an inline or a function in | 6452 ;; CASE 16B: does this close an inline or a function in |
3563 ;; an extern block or namespace? | 6453 ;; a non-class declaration level block? |
3564 ((setq placeholder (c-search-uplist-for-classkey paren-state)) | 6454 ((setq placeholder (c-search-uplist-for-classkey paren-state)) |
3565 (c-backward-to-decl-anchor lim) | 6455 (c-backward-to-decl-anchor lim) |
3566 (back-to-indentation) | 6456 (back-to-indentation) |
3567 (if (save-excursion | 6457 (if (save-excursion |
3568 (goto-char (aref placeholder 0)) | 6458 (goto-char (aref placeholder 0)) |
3582 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) | 6472 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) |
3583 (setq placeholder (point))))) | 6473 (setq placeholder (point))))) |
3584 (back-to-indentation) | 6474 (back-to-indentation) |
3585 (if (/= (point) containing-sexp) | 6475 (if (/= (point) containing-sexp) |
3586 (goto-char placeholder)) | 6476 (goto-char placeholder)) |
3587 (c-add-stmt-syntax 'defun-close t lim paren-state)) | 6477 (c-add-stmt-syntax 'defun-close nil t nil |
6478 lim paren-state)) | |
3588 ;; CASE 16C: if there an enclosing brace that hasn't | 6479 ;; CASE 16C: if there an enclosing brace that hasn't |
3589 ;; been narrowed out by a class, then this is a | 6480 ;; been narrowed out by a class, then this is a |
3590 ;; block-close. C.f. case 17H. | 6481 ;; block-close. C.f. case 17H. |
3591 ((and (not inenclosing-p) lim) | 6482 ((and (not inenclosing-p) lim) |
3592 ;; If the block is preceded by a case/switch label on | 6483 ;; If the block is preceded by a case/switch label on |
3601 (if (looking-at c-label-kwds-regexp) | 6492 (if (looking-at c-label-kwds-regexp) |
3602 (c-add-syntax 'block-close (point)) | 6493 (c-add-syntax 'block-close (point)) |
3603 (goto-char containing-sexp) | 6494 (goto-char containing-sexp) |
3604 ;; c-backward-to-block-anchor not necessary here; those | 6495 ;; c-backward-to-block-anchor not necessary here; those |
3605 ;; situations are handled in case 16E above. | 6496 ;; situations are handled in case 16E above. |
3606 (c-add-stmt-syntax 'block-close t lim paren-state))) | 6497 (c-add-stmt-syntax 'block-close nil t nil |
6498 lim paren-state))) | |
3607 ;; CASE 16D: find out whether we're closing a top-level | 6499 ;; CASE 16D: find out whether we're closing a top-level |
3608 ;; class or a defun | 6500 ;; class or a defun |
3609 (t | 6501 (t |
3610 (save-restriction | 6502 (save-restriction |
3611 (narrow-to-region (point-min) indent-point) | 6503 (narrow-to-region (point-min) indent-point) |
3632 (/= (point) (c-point 'boi))))) | 6524 (/= (point) (c-point 'boi))))) |
3633 (cond | 6525 (cond |
3634 ;; CASE 17B: continued statement | 6526 ;; CASE 17B: continued statement |
3635 ((and (eq step-type 'same) | 6527 ((and (eq step-type 'same) |
3636 (/= (point) indent-point)) | 6528 (/= (point) indent-point)) |
3637 (c-add-stmt-syntax 'statement-cont nil | 6529 (c-add-stmt-syntax 'statement-cont nil nil nil |
3638 containing-sexp paren-state)) | 6530 containing-sexp paren-state)) |
3639 ;; CASE 17A: After a case/default label? | 6531 ;; CASE 17A: After a case/default label? |
3640 ((progn | 6532 ((progn |
3641 (while (and (eq step-type 'label) | 6533 (while (and (eq step-type 'label) |
3642 (not (looking-at c-label-kwds-regexp))) | 6534 (not (looking-at c-label-kwds-regexp))) |
3644 (c-beginning-of-statement-1 containing-sexp))) | 6536 (c-beginning-of-statement-1 containing-sexp))) |
3645 (eq step-type 'label)) | 6537 (eq step-type 'label)) |
3646 (c-add-stmt-syntax (if (eq char-after-ip ?{) | 6538 (c-add-stmt-syntax (if (eq char-after-ip ?{) |
3647 'statement-case-open | 6539 'statement-case-open |
3648 'statement-case-intro) | 6540 'statement-case-intro) |
3649 t containing-sexp paren-state)) | 6541 nil t nil containing-sexp paren-state)) |
3650 ;; CASE 17D: any old statement | 6542 ;; CASE 17D: any old statement |
3651 ((progn | 6543 ((progn |
3652 (while (eq step-type 'label) | 6544 (while (eq step-type 'label) |
3653 (setq step-type | 6545 (setq step-type |
3654 (c-beginning-of-statement-1 containing-sexp))) | 6546 (c-beginning-of-statement-1 containing-sexp))) |
3655 (eq step-type 'previous)) | 6547 (eq step-type 'previous)) |
3656 (c-add-stmt-syntax 'statement t containing-sexp paren-state) | 6548 (c-add-stmt-syntax 'statement nil t nil |
6549 containing-sexp paren-state) | |
3657 (if (eq char-after-ip ?{) | 6550 (if (eq char-after-ip ?{) |
3658 (c-add-syntax 'block-open))) | 6551 (c-add-syntax 'block-open))) |
3659 ;; CASE 17I: Inside a substatement block. | 6552 ;; CASE 17I: Inside a substatement block. |
3660 ((progn | 6553 ((progn |
3661 ;; The following tests are all based on containing-sexp. | 6554 ;; The following tests are all based on containing-sexp. |
3662 (goto-char containing-sexp) | 6555 (goto-char containing-sexp) |
3663 ;; From here on we have the next containing sexp in lim. | 6556 ;; From here on we have the next containing sexp in lim. |
3664 (setq lim (c-most-enclosing-brace paren-state containing-sexp)) | 6557 (setq lim (c-most-enclosing-brace paren-state containing-sexp)) |
3665 (c-after-conditional)) | 6558 (c-after-conditional)) |
3666 (c-backward-to-block-anchor lim) | 6559 (c-backward-to-block-anchor lim) |
3667 (c-add-stmt-syntax 'statement-block-intro t lim paren-state) | 6560 (c-add-stmt-syntax 'statement-block-intro nil t nil |
6561 lim paren-state) | |
3668 (if (eq char-after-ip ?{) | 6562 (if (eq char-after-ip ?{) |
3669 (c-add-syntax 'block-open))) | 6563 (c-add-syntax 'block-open))) |
3670 ;; CASE 17E: first statement in an in-expression block. | 6564 ;; CASE 17E: first statement in an in-expression block. |
3671 ;; C.f. cases 4, 7B and 16A. | 6565 ;; C.f. cases 4, 7B and 16A. |
3672 ((setq placeholder (c-looking-at-inexpr-block | 6566 ((setq placeholder (c-looking-at-inexpr-block |
3678 (back-to-indentation) | 6572 (back-to-indentation) |
3679 (if (= containing-sexp (point)) | 6573 (if (= containing-sexp (point)) |
3680 (c-add-syntax tmpsymbol (point)) | 6574 (c-add-syntax tmpsymbol (point)) |
3681 (goto-char (cdr placeholder)) | 6575 (goto-char (cdr placeholder)) |
3682 (back-to-indentation) | 6576 (back-to-indentation) |
3683 (c-add-stmt-syntax tmpsymbol t | 6577 (c-add-stmt-syntax tmpsymbol nil t nil |
3684 (c-most-enclosing-brace c-state-cache (point)) | 6578 (c-most-enclosing-brace c-state-cache (point)) |
3685 (c-whack-state-after (point) paren-state)) | 6579 (c-whack-state-after (point) paren-state)) |
3686 (if (/= (point) (cdr placeholder)) | 6580 (if (/= (point) (cdr placeholder)) |
3687 (c-add-syntax (car placeholder)))) | 6581 (c-add-syntax (car placeholder)))) |
3688 (if (eq char-after-ip ?{) | 6582 (if (eq char-after-ip ?{) |
3689 (c-add-syntax 'block-open))) | 6583 (c-add-syntax 'block-open))) |
3690 ;; CASE 17F: first statement in an inline, or first | 6584 ;; CASE 17F: first statement in an inline, or first |
3691 ;; statement in a top-level defun. we can tell this is it | 6585 ;; statement in a top-level defun. we can tell this is it |
3692 ;; if there are no enclosing braces that haven't been | 6586 ;; if there are no enclosing braces that haven't been |
3693 ;; narrowed out by a class (i.e. don't use bod here). | 6587 ;; narrowed out by a class (i.e. don't use bod here). |
3694 ;; However, we first check for statements that we can | |
3695 ;; recognize by keywords. That increases the robustness in | |
3696 ;; cases where statements are used on the top level, | |
3697 ;; e.g. in macro definitions. | |
3698 ((save-excursion | 6588 ((save-excursion |
3699 (save-restriction | 6589 (save-restriction |
3700 (widen) | 6590 (widen) |
3701 (c-narrow-out-enclosing-class paren-state containing-sexp) | 6591 (c-narrow-out-enclosing-class paren-state containing-sexp) |
3702 (not (c-most-enclosing-brace paren-state)))) | 6592 (not (c-most-enclosing-brace paren-state)))) |
3713 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) | 6603 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) |
3714 (setq placeholder (point)))) | 6604 (setq placeholder (point)))) |
3715 (back-to-indentation) | 6605 (back-to-indentation) |
3716 (if (/= (point) containing-sexp) | 6606 (if (/= (point) containing-sexp) |
3717 (goto-char placeholder)) | 6607 (goto-char placeholder)) |
3718 (c-add-stmt-syntax 'defun-block-intro t lim paren-state)) | 6608 (c-add-stmt-syntax 'defun-block-intro nil t nil |
6609 lim paren-state)) | |
3719 ;; CASE 17H: First statement in a block. C.f. case 16C. | 6610 ;; CASE 17H: First statement in a block. C.f. case 16C. |
3720 (t | 6611 (t |
3721 ;; If the block is preceded by a case/switch label on the | 6612 ;; If the block is preceded by a case/switch label on the |
3722 ;; same line, we anchor at the first preceding label at | 6613 ;; same line, we anchor at the first preceding label at |
3723 ;; boi. The default handling in c-add-stmt-syntax is | 6614 ;; boi. The default handling in c-add-stmt-syntax is |
3729 (if (looking-at c-label-kwds-regexp) | 6620 (if (looking-at c-label-kwds-regexp) |
3730 (c-add-syntax 'statement-block-intro (point)) | 6621 (c-add-syntax 'statement-block-intro (point)) |
3731 (goto-char containing-sexp) | 6622 (goto-char containing-sexp) |
3732 ;; c-backward-to-block-anchor not necessary here; those | 6623 ;; c-backward-to-block-anchor not necessary here; those |
3733 ;; situations are handled in case 17I above. | 6624 ;; situations are handled in case 17I above. |
3734 (c-add-stmt-syntax 'statement-block-intro t lim paren-state)) | 6625 (c-add-stmt-syntax 'statement-block-intro nil t nil |
6626 lim paren-state)) | |
3735 (if (eq char-after-ip ?{) | 6627 (if (eq char-after-ip ?{) |
3736 (c-add-syntax 'block-open))) | 6628 (c-add-syntax 'block-open))) |
3737 )) | 6629 )) |
3738 ) | 6630 ) |
3739 ;; now we need to look at any modifiers | 6631 ;; now we need to look at any modifiers |
3740 (goto-char indent-point) | 6632 (goto-char indent-point) |
3741 (skip-chars-forward " \t") | 6633 (skip-chars-forward " \t") |
3742 ;; are we looking at a comment only line? | 6634 ;; are we looking at a comment only line? |
3743 (when (and (looking-at c-comment-start-regexp) | 6635 (when (and (looking-at c-comment-start-regexp) |
3744 (/= (c-forward-token-1 0 nil (c-point 'eol)) 0)) | 6636 (/= (c-forward-token-2 0 nil (c-point 'eol)) 0)) |
3745 (c-add-syntax 'comment-intro)) | 6637 (c-append-syntax 'comment-intro)) |
3746 ;; we might want to give additional offset to friends (in C++). | 6638 ;; we might want to give additional offset to friends (in C++). |
3747 (when (and c-opt-friend-key | 6639 (when (and c-opt-friend-key |
3748 (looking-at c-opt-friend-key)) | 6640 (looking-at c-opt-friend-key)) |
3749 (c-add-syntax 'friend)) | 6641 (c-append-syntax 'friend)) |
6642 | |
6643 ;; Set syntactic-relpos. | |
6644 (let ((p c-syntactic-context)) | |
6645 (while (and p | |
6646 (if (integerp (car-safe (cdr-safe (car p)))) | |
6647 (progn | |
6648 (setq syntactic-relpos (car (cdr (car p)))) | |
6649 nil) | |
6650 t)) | |
6651 (setq p (cdr p)))) | |
6652 | |
3750 ;; Start of or a continuation of a preprocessor directive? | 6653 ;; Start of or a continuation of a preprocessor directive? |
3751 (if (and macro-start | 6654 (if (and macro-start |
3752 (eq macro-start (c-point 'boi)) | 6655 (eq macro-start (c-point 'boi)) |
3753 (not (and (c-major-mode-is 'pike-mode) | 6656 (not (and (c-major-mode-is 'pike-mode) |
3754 (eq (char-after (1+ macro-start)) ?\")))) | 6657 (eq (char-after (1+ macro-start)) ?\")))) |
3755 (c-add-syntax 'cpp-macro) | 6658 (c-append-syntax 'cpp-macro) |
3756 (when (and c-syntactic-indentation-in-macros macro-start) | 6659 (when (and c-syntactic-indentation-in-macros macro-start) |
3757 (if in-macro-expr | 6660 (if in-macro-expr |
3758 (when (or (< syntactic-relpos macro-start) | 6661 (when (or |
3759 (not (or (assq 'arglist-intro syntax) | 6662 (< syntactic-relpos macro-start) |
3760 (assq 'arglist-cont syntax) | 6663 (not (or |
3761 (assq 'arglist-cont-nonempty syntax) | 6664 (assq 'arglist-intro c-syntactic-context) |
3762 (assq 'arglist-close syntax)))) | 6665 (assq 'arglist-cont c-syntactic-context) |
6666 (assq 'arglist-cont-nonempty c-syntactic-context) | |
6667 (assq 'arglist-close c-syntactic-context)))) | |
3763 ;; If inside a cpp expression, i.e. anywhere in a | 6668 ;; If inside a cpp expression, i.e. anywhere in a |
3764 ;; cpp directive except a #define body, we only let | 6669 ;; cpp directive except a #define body, we only let |
3765 ;; through the syntactic analysis that is internal | 6670 ;; through the syntactic analysis that is internal |
3766 ;; in the expression. That means the arglist | 6671 ;; in the expression. That means the arglist |
3767 ;; elements, if they are anchored inside the cpp | 6672 ;; elements, if they are anchored inside the cpp |
3768 ;; expression. | 6673 ;; expression. |
3769 (setq syntax `((cpp-macro-cont . ,macro-start)))) | 6674 (setq c-syntactic-context nil) |
6675 (c-add-syntax 'cpp-macro-cont macro-start)) | |
3770 (when (and (eq macro-start syntactic-relpos) | 6676 (when (and (eq macro-start syntactic-relpos) |
3771 (not (assq 'cpp-define-intro syntax)) | 6677 (not (assq 'cpp-define-intro c-syntactic-context)) |
3772 (save-excursion | 6678 (save-excursion |
3773 (goto-char macro-start) | 6679 (goto-char macro-start) |
3774 (or (not (c-forward-to-cpp-define-body)) | 6680 (or (not (c-forward-to-cpp-define-body)) |
3775 (<= (point) (c-point 'boi indent-point))))) | 6681 (<= (point) (c-point 'boi indent-point))))) |
3776 ;; Inside a #define body and the syntactic analysis is | 6682 ;; Inside a #define body and the syntactic analysis is |
3777 ;; anchored on the start of the #define. In this case | 6683 ;; anchored on the start of the #define. In this case |
3778 ;; we add cpp-define-intro to get the extra | 6684 ;; we add cpp-define-intro to get the extra |
3779 ;; indentation of the #define body. | 6685 ;; indentation of the #define body. |
3780 (c-add-syntax 'cpp-define-intro))))) | 6686 (c-add-syntax 'cpp-define-intro))))) |
3781 ;; return the syntax | 6687 ;; return the syntax |
3782 syntax)))) | 6688 c-syntactic-context)))) |
3783 | 6689 |
3784 | 6690 |
3785 (defun c-echo-parsing-error (&optional quiet) | 6691 ;; Indentation calculation. |
3786 (when (and c-report-syntactic-errors c-parsing-error (not quiet)) | |
3787 (c-benign-error "%s" c-parsing-error)) | |
3788 c-parsing-error) | |
3789 | 6692 |
3790 (defun c-evaluate-offset (offset langelem symbol) | 6693 (defun c-evaluate-offset (offset langelem symbol) |
3791 ;; offset can be a number, a function, a variable, a list, or one of | 6694 ;; offset can be a number, a function, a variable, a list, or one of |
3792 ;; the symbols + or - | 6695 ;; the symbols + or - |
3793 (cond | 6696 (cond |
3797 ((eq offset '--) (* 2 (- c-basic-offset))) | 6700 ((eq offset '--) (* 2 (- c-basic-offset))) |
3798 ((eq offset '*) (/ c-basic-offset 2)) | 6701 ((eq offset '*) (/ c-basic-offset 2)) |
3799 ((eq offset '/) (/ (- c-basic-offset) 2)) | 6702 ((eq offset '/) (/ (- c-basic-offset) 2)) |
3800 ((numberp offset) offset) | 6703 ((numberp offset) offset) |
3801 ((functionp offset) (c-evaluate-offset | 6704 ((functionp offset) (c-evaluate-offset |
3802 (funcall offset langelem) langelem symbol)) | 6705 (funcall offset |
6706 (cons (car langelem) | |
6707 (car-safe (cdr langelem)))) | |
6708 langelem symbol)) | |
3803 ((vectorp offset) offset) | 6709 ((vectorp offset) offset) |
3804 ((null offset) nil) | 6710 ((null offset) nil) |
3805 ((listp offset) | 6711 ((listp offset) |
3806 (let (done) | 6712 (let (done) |
3807 (while (and (not done) offset) | 6713 (while (and (not done) offset) |
3811 (c-benign-error "No offset found for syntactic symbol %s" symbol)) | 6717 (c-benign-error "No offset found for syntactic symbol %s" symbol)) |
3812 done)) | 6718 done)) |
3813 (t (symbol-value offset)) | 6719 (t (symbol-value offset)) |
3814 )) | 6720 )) |
3815 | 6721 |
3816 (defun c-get-offset (langelem) | 6722 (defun c-calc-offset (langelem) |
3817 "Get offset from LANGELEM which is a cons cell of the form: | 6723 ;; Get offset from LANGELEM which is a list beginning with the |
3818 \(SYMBOL . RELPOS). The symbol is matched against `c-offsets-alist' | 6724 ;; syntactic symbol and followed by any analysis data it provides. |
3819 and the offset found there is returned." | 6725 ;; That data may be zero or more elements, but if at least one is |
6726 ;; given then the first is the relpos (or nil). The symbol is | |
6727 ;; matched against `c-offsets-alist' and the offset calculated from | |
6728 ;; that is returned. | |
3820 (let* ((symbol (car langelem)) | 6729 (let* ((symbol (car langelem)) |
3821 (match (assq symbol c-offsets-alist)) | 6730 (match (assq symbol c-offsets-alist)) |
3822 (offset (cdr-safe match))) | 6731 (offset (cdr-safe match))) |
3823 (if match | 6732 (if match |
3824 (setq offset (c-evaluate-offset offset langelem symbol)) | 6733 (setq offset (c-evaluate-offset offset langelem symbol)) |
3830 (or (and (numberp offset) offset) | 6739 (or (and (numberp offset) offset) |
3831 (and (symbolp offset) (symbol-value offset)) | 6740 (and (symbolp offset) (symbol-value offset)) |
3832 0)) | 6741 0)) |
3833 )) | 6742 )) |
3834 | 6743 |
6744 (defun c-get-offset (langelem) | |
6745 ;; This is a compatibility wrapper for `c-calc-offset' in case | |
6746 ;; someone is calling it directly. It takes an old style syntactic | |
6747 ;; element on the form (SYMBOL . RELPOS) and converts it to the new | |
6748 ;; list form. | |
6749 (if (cdr langelem) | |
6750 (c-calc-offset (list (car langelem) (cdr langelem))) | |
6751 (c-calc-offset langelem))) | |
6752 | |
3835 (defun c-get-syntactic-indentation (langelems) | 6753 (defun c-get-syntactic-indentation (langelems) |
3836 "Apply `c-get-offset' to a list of langelem cells to get the total | 6754 ;; Calculate the syntactic indentation from a syntactic description |
3837 syntactic indentation. The anchor position, whose column is used as a | 6755 ;; as returned by `c-guess-syntax'. |
3838 base for all the collected offsets, is taken from the first element | 6756 ;; |
3839 with a relpos." | |
3840 ;; Note that topmost-intro always has a relpos at bol, for | 6757 ;; Note that topmost-intro always has a relpos at bol, for |
3841 ;; historical reasons. It's often used together with other symbols | 6758 ;; historical reasons. It's often used together with other symbols |
3842 ;; that has more sane positions. Since we always use the first | 6759 ;; that has more sane positions. Since we always use the first |
3843 ;; found relpos, we rely on that these other symbols always precede | 6760 ;; found relpos, we rely on that these other symbols always precede |
3844 ;; topmost-intro in the LANGELEMS list. | 6761 ;; topmost-intro in the LANGELEMS list. |
3845 (let ((indent 0) anchor) | 6762 (let ((indent 0) anchor) |
3846 (catch 'done | 6763 |
3847 (while langelems | 6764 (while langelems |
3848 (let ((res (c-get-offset (car langelems)))) | 6765 (let* ((c-syntactic-element (car langelems)) |
3849 (if (vectorp res) | 6766 (res (c-calc-offset c-syntactic-element))) |
3850 (throw 'done (elt res 0)) | 6767 |
3851 (unless anchor | 6768 (if (vectorp res) |
3852 (let ((relpos (cdr (car langelems)))) | 6769 ;; Got an absolute column that overrides any indentation |
3853 (if relpos | 6770 ;; we've collected so far, but not the relative |
3854 (setq anchor relpos)))) | 6771 ;; indentation we might get for the nested structures |
3855 (setq indent (+ indent res) | 6772 ;; further down the langelems list. |
3856 langelems (cdr langelems))))) | 6773 (setq indent (elt res 0) |
3857 (+ indent | 6774 anchor (point-min)) ; A position at column 0. |
3858 (if anchor | 6775 |
3859 (save-excursion | 6776 ;; Got a relative change of the current calculated |
3860 (goto-char anchor) | 6777 ;; indentation. |
3861 (current-column)) | 6778 (setq indent (+ indent res)) |
3862 0))))) | 6779 |
6780 ;; Use the anchor position from the first syntactic | |
6781 ;; element with one. | |
6782 (unless anchor | |
6783 (let ((relpos (car-safe (cdr (car langelems))))) | |
6784 (if relpos | |
6785 (setq anchor relpos))))) | |
6786 | |
6787 (setq langelems (cdr langelems)))) | |
6788 | |
6789 (if anchor | |
6790 (+ indent (save-excursion | |
6791 (goto-char anchor) | |
6792 (current-column))) | |
6793 indent))) | |
3863 | 6794 |
3864 | 6795 |
3865 (cc-provide 'cc-engine) | 6796 (cc-provide 'cc-engine) |
3866 | 6797 |
3867 ;;; cc-engine.el ends here | 6798 ;;; cc-engine.el ends here |