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