Bump Emacs version to 21.3.50.
[bpt/emacs.git] / lisp / progmodes / cc-engine.el
Content-type: text/html HCoop Git - bpt/emacs.git/blame - lisp/progmodes/cc-engine.el


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 8) line 1, <$fd> line 4197.
CommitLineData
785eecbb
RS
1;;; cc-engine.el --- core syntax guessing engine for CC mode
2
130c507e 3;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
785eecbb 4
ce8c7486
GM
5;; Authors: 2000- Martin Stjernholm
6;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
0ec8351b 7;; 1992-1997 Barry A. Warsaw
785eecbb
RS
8;; 1987 Dave Detlefs and Stewart Clamen
9;; 1985 Richard M. Stallman
0ec8351b 10;; Maintainer: bug-cc-mode@gnu.org
785eecbb 11;; Created: 22-Apr-1997 (split from cc-mode.el)
6430c434 12;; Version: See cc-mode.el
785eecbb
RS
13;; Keywords: c languages oop
14
15;; This file is part of GNU Emacs.
16
17;; GNU Emacs is free software; you can redistribute it and/or modify
18;; it under the terms of the GNU General Public License as published by
19;; the Free Software Foundation; either version 2, or (at your option)
20;; any later version.
21
22;; GNU Emacs is distributed in the hope that it will be useful,
23;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25;; GNU General Public License for more details.
26
27;; You should have received a copy of the GNU General Public License
a66cd3ee 28;; along with GNU Emacs; see the file COPYING. If not, write to
130c507e 29;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
785eecbb
RS
30;; Boston, MA 02111-1307, USA.
31
3afbc435
PJ
32;;; Commentary:
33
a66cd3ee
MS
34;; The functions which have docstring documentation can be considered
35;; part of an API which other packages can use in CC Mode buffers.
36;; Otoh, undocumented functions and functions with the documentation
37;; in comments are considered purely internal and can change semantics
38;; or even disappear in the future.
39;;
40;; (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
42;; clearly spelled out.)
43
3afbc435
PJ
44;;; Code:
45
0ec8351b 46(eval-when-compile
51f606de 47 (let ((load-path
130c507e
GM
48 (if (and (boundp 'byte-compile-dest-file)
49 (stringp byte-compile-dest-file))
50 (cons (file-name-directory byte-compile-dest-file) load-path)
51f606de 51 load-path)))
130c507e
GM
52 (require 'cc-bytecomp)))
53
54(cc-require 'cc-defs)
55(cc-require 'cc-vars)
56(cc-require 'cc-langs)
57
58;; Silence the compiler.
59(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
0ec8351b 60
51f606de 61\f
a66cd3ee
MS
62(defun c-calculate-state (arg prevstate)
63 ;; 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
65 ;; the state off, and if arg is positive, turn the state on
66 (if (or (not arg)
67 (zerop (setq arg (prefix-numeric-value arg))))
68 (not prevstate)
69 (> arg 0)))
70
71\f
130c507e 72(defvar c-in-literal-cache t)
a66cd3ee 73(defvar c-parsing-error nil)
130c507e 74
64001211
RS
75;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
76;; 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
78;; the byte compiler.
79(defvar c-maybe-labelp nil)
80
a66cd3ee
MS
81;; Macros used internally in c-beginning-of-statement-1 for the
82;; automaton actions.
83(defmacro c-bos-push-state ()
84 '(setq stack (cons (cons state saved-pos)
85 stack)))
86(defmacro c-bos-pop-state (&optional do-if-done)
87 `(if (setq state (car (car stack))
88 saved-pos (cdr (car stack))
89 stack (cdr stack))
90 t
91 ,do-if-done
92 (throw 'loop nil)))
93(defmacro c-bos-pop-state-and-retry ()
94 '(throw 'loop (setq state (car (car stack))
95 saved-pos (cdr (car stack))
96 ;; Throw nil if stack is empty, else throw non-nil.
97 stack (cdr stack))))
98(defmacro c-bos-save-pos ()
99 '(setq saved-pos (vector pos tok ptok pptok)))
100(defmacro c-bos-restore-pos ()
101 '(unless (eq (elt saved-pos 0) start)
102 (setq pos (elt saved-pos 0)
103 tok (elt saved-pos 1)
104 ptok (elt saved-pos 2)
105 pptok (elt saved-pos 3))
106 (goto-char pos)
107 (setq sym nil)))
108(defmacro c-bos-save-error-info (missing got)
109 `(setq saved-pos (vector pos ,missing ,got)))
110(defmacro c-bos-report-error ()
111 '(unless noerror
112 (setq c-parsing-error
113 (format "No matching `%s' found for `%s' on line %d"
114 (elt saved-pos 1)
115 (elt saved-pos 2)
116 (1+ (count-lines (point-min)
117 (c-point 'bol (elt saved-pos 0))))))))
118
119(defun c-beginning-of-statement-1 (&optional lim ignore-labels
120 noerror comma-delim)
121 "Move to the start of the current statement or declaration, or to
122the previous one if already at the beginning of one. Only
123statements/declarations on the same level are considered, i.e. don't
124move into or out of sexps (not even normal expression parentheses).
125
126Stop at statement continuations like \"else\", \"catch\", \"finally\"
127and the \"while\" in \"do ... while\" if the start point is within
128them. If starting at such a continuation, move to the corresponding
129statement start. If at the beginning of a statement, move to the
130closest containing statement if there is any. This might also stop at
131a continuation clause.
132
133Labels are treated as separate statements if IGNORE-LABELS is non-nil.
134The function is not overly intelligent in telling labels from other
135uses of colons; if used outside a statement context it might trip up
136on e.g. inherit colons, so IGNORE-LABELS should be used then. There
137should be no such mistakes in a statement context, however.
138
139Macros are ignored unless point is within one, in which case the
140content of the macro is treated as normal code. Aside from any normal
141statement starts found in it, stop at the first token of the content
142in the macro, i.e. the expression of an \"#if\" or the start of the
143definition in a \"#define\". Also stop at start of macros before
144leaving them.
145
146Return 'label if stopped at a label, 'same if stopped at the beginning
147of the current statement, 'up if stepped to a containing statement,
148'previous if stepped to a preceding statement, 'beginning if stepped
149from a statement continuation clause to its start clause, or 'macro if
150stepped to a macro start. Note that 'same and not 'label is returned
151if stopped at the same label without crossing the colon character.
152
153LIM may be given to limit the search. If the search hits the limit,
154point will be left at the closest following token, or at the start
155position if that is less ('same is returned in this case).
156
157NOERROR turns off error logging to `c-parsing-error'.
158
159Normally only ';' is considered to delimit statements, but if
160COMMA-DELIM is non-nil then ',' is treated likewise."
161
162 ;; The bulk of this function is a pushdown automaton that looks at
163 ;; statement boundaries and the tokens in c-opt-block-stmt-key.
164 ;;
165 ;; Note: The position of a boundary is the following token.
166 ;;
167 ;; Begin with current token, stop when stack is empty and the
168 ;; position has been moved.
169 ;;
170 ;; Common state:
171 ;; "else": Push state, goto state `else':
172 ;; boundary: Goto state `else-boundary':
173 ;; "if": Pop state.
174 ;; boundary: Error, 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.
191 ;;
192 ;; In addition to the above there is some special handling of labels
193 ;; and macros.
194
195 (let ((case-fold-search nil)
196 (start (point))
197 macro-start
198 (delims (if comma-delim '(?\; ?,) '(?\;)))
199 (c-stmt-delim-chars (if comma-delim
200 c-stmt-delim-chars-with-comma
201 c-stmt-delim-chars))
202 pos ; Current position.
203 boundary-pos ; Position of last boundary.
204 after-labels-pos ; Value of tok after first found colon.
205 last-label-pos ; Value of tok after last found colon.
206 sym ; Current symbol in the alphabet.
207 state ; Current state in the automaton.
208 saved-pos ; Current saved positions.
209 stack ; Stack of conses (state . saved-pos).
210 (cond-key (or c-opt-block-stmt-key
211 "\\<\\>")) ; Matches nothing.
212 (ret 'same)
213 tok ptok pptok ; Pos of last three sexps or bounds.
214 c-in-literal-cache c-maybe-labelp saved)
215
216 (save-restriction
217 (if lim (narrow-to-region lim (point-max)))
218
219 (if (save-excursion
220 (and (c-beginning-of-macro)
221 (/= (point) start)))
222 (setq macro-start (point)))
223
224 ;; Try to skip over unary operator characters, to register
225 ;; that we've moved.
226 (while (progn
227 (setq pos (point))
228 (c-backward-syntactic-ws)
229 (/= (skip-chars-backward "-+!*&~@`#") 0)))
230
231 ;; First check for bare semicolon. Later on we ignore the
232 ;; boundaries for statements that doesn't contain any sexp.
233 ;; The only thing that is affected is that the error checking
234 ;; is a little less strict, and we really don't bother.
235 (if (and (memq (char-before) delims)
236 (progn (forward-char -1)
237 (setq saved (point))
238 (c-backward-syntactic-ws)
239 (or (memq (char-before) delims)
240 (memq (char-before) '(?: nil))
241 (eq (char-syntax (char-before)) ?\())))
242 (setq ret 'previous
243 pos saved)
244
245 ;; Begin at start and not pos to detect macros if we stand
246 ;; directly after the #.
247 (goto-char start)
248 (if (looking-at "\\<\\|\\W")
249 ;; Record this as the first token if not starting inside it.
250 (setq tok start))
251
252 (while
253 (catch 'loop ;; Throw nil to break, non-nil to continue.
254 (cond
255 ;; Check for macro start.
256 ((save-excursion
257 (and macro-start
258 (looking-at "[ \t]*[a-zA-Z0-9!]")
259 (progn (skip-chars-backward " \t")
260 (eq (char-before) ?#))
261 (progn (setq saved (1- (point)))
262 (beginning-of-line)
263 (not (eq (char-before (1- (point))) ?\\)))
264 (progn (skip-chars-forward " \t")
265 (eq (point) saved))))
266 (goto-char saved)
267 (if (and (c-forward-to-cpp-define-body)
268 (progn (c-forward-syntactic-ws start)
269 (< (point) start)))
270 ;; Stop at the first token in the content of the macro.
271 (setq pos (point)
272 ignore-labels t) ; Avoid the label check on exit.
273 (setq pos saved
274 ret 'macro
275 ignore-labels t))
276 (throw 'loop nil))
277
278 ;; Do a round through the automaton if we found a
279 ;; boundary or if looking at a statement keyword.
280 ((or sym
281 (and (looking-at cond-key)
282 (setq sym (intern (match-string 1)))))
283
284 (when (and (< pos start) (null stack))
285 (throw 'loop nil))
286
287 ;; The state handling. Continue in the common state for
288 ;; unhandled cases.
289 (or (cond
290 ((eq state 'else)
291 (if (eq sym 'boundary)
292 (setq state 'else-boundary)
293 (c-bos-report-error)
294 (c-bos-pop-state-and-retry)))
295
296 ((eq state 'else-boundary)
297 (cond ((eq sym 'if)
298 (c-bos-pop-state (setq ret 'beginning)))
299 ((eq sym 'boundary)
300 (c-bos-report-error)
301 (c-bos-pop-state))))
302
303 ((eq state 'while)
304 (if (and (eq sym 'boundary)
305 ;; Since this can cause backtracking we do a
306 ;; little more careful analysis to avoid it:
307 ;; If there's a label in front of the while
308 ;; it can't be part of a do-while.
309 (not after-labels-pos))
310 (progn (c-bos-save-pos)
311 (setq state 'while-boundary))
312 (c-bos-pop-state-and-retry)))
313
314 ((eq state 'while-boundary)
315 (cond ((eq sym 'do)
316 (c-bos-pop-state (setq ret 'beginning)))
317 ((eq sym 'boundary)
318 (c-bos-restore-pos)
319 (c-bos-pop-state))))
320
321 ((eq state 'catch)
322 (if (eq sym 'boundary)
323 (setq state 'catch-boundary)
324 (c-bos-report-error)
325 (c-bos-pop-state-and-retry)))
326
327 ((eq state 'catch-boundary)
328 (cond
329 ((eq sym 'try)
330 (c-bos-pop-state (setq ret 'beginning)))
331 ((eq sym 'catch)
332 (setq state 'catch))
333 ((eq sym 'boundary)
334 (c-bos-report-error)
335 (c-bos-pop-state)))))
336
337 ;; This is state common.
338 (cond ((eq sym 'boundary)
339 (if (< pos start)
340 (c-bos-pop-state)
341 (c-bos-push-state)))
342 ((eq sym 'else)
343 (c-bos-push-state)
344 (c-bos-save-error-info 'if 'else)
345 (setq state 'else))
346 ((eq sym 'while)
347 (when (or (not pptok)
348 (memq (char-after pptok) delims))
349 ;; Since this can cause backtracking we do a
350 ;; little more careful analysis to avoid it: If
351 ;; the while isn't followed by a semicolon it
352 ;; can't be a do-while.
353 (c-bos-push-state)
354 (setq state 'while)))
355 ((memq sym '(catch finally))
356 (c-bos-push-state)
357 (c-bos-save-error-info 'try sym)
358 (setq state 'catch))))
359
360 (when c-maybe-labelp
361 ;; We're either past a statement boundary or at the
362 ;; start of a statement, so throw away any label data
363 ;; for the previous one.
364 (setq after-labels-pos nil
365 last-label-pos nil
366 c-maybe-labelp nil))))
367
368 ;; Step to next sexp, but not if we crossed a boundary, since
369 ;; that doesn't consume an sexp.
370 (if (eq sym 'boundary)
371 (setq ret 'previous)
372 (while
041ec7f6 373 (progn
a66cd3ee
MS
374 (or (c-safe (goto-char (scan-sexps (point) -1)) t)
375 (throw 'loop nil))
376 (cond ((looking-at "\\\\$")
377 ;; Step again if we hit a line continuation.
378 t)
379 (macro-start
380 ;; If we started inside a macro then this
381 ;; sexp is always interesting.
382 nil)
383 (t
384 ;; Otherwise check that we didn't step
385 ;; into a macro from the end.
386 (let ((macro-start
387 (save-excursion
388 (and (c-beginning-of-macro)
389 (point)))))
390 (when macro-start
391 (goto-char macro-start)
392 t))))))
393
394 ;; Check for statement boundary.
395 (when (save-excursion
396 (if (if (eq (char-after) ?{)
397 (c-looking-at-inexpr-block lim nil)
398 (eq (char-syntax (char-after)) ?\())
399 ;; Need to move over parens and
400 ;; in-expression blocks to get a good start
401 ;; position for the boundary check.
402 (c-forward-sexp 1))
403 (setq boundary-pos (c-crosses-statement-barrier-p
404 (point) pos)))
405 (setq pptok ptok
406 ptok tok
407 tok boundary-pos
408 sym 'boundary)
409 (throw 'loop t)))
410
411 (when (and (numberp c-maybe-labelp) (not ignore-labels))
412 ;; c-crosses-statement-barrier-p has found a colon, so
413 ;; we might be in a label now.
414 (if (not after-labels-pos)
415 (setq after-labels-pos tok))
416 (setq last-label-pos tok
417 c-maybe-labelp t))
418
419 ;; ObjC method def?
420 (when (and c-opt-method-key
421 (setq saved (c-in-method-def-p)))
422 (setq pos saved
423 ignore-labels t) ; Avoid the label check on exit.
424 (throw 'loop nil))
425
426 (setq sym nil
427 pptok ptok
428 ptok tok
429 tok (point)
430 pos tok))) ; Not nil.
431
432 ;; If the stack isn't empty there might be errors to report.
433 (while stack
434 (if (and (vectorp saved-pos) (eq (length saved-pos) 3))
435 (c-bos-report-error))
436 (setq saved-pos (cdr (car stack))
437 stack (cdr stack)))
438
439 (when (and (eq ret 'same)
440 (not (memq sym '(boundary ignore nil))))
441 ;; Need to investigate closer whether we've crossed
442 ;; between a substatement and its containing statement.
443 (if (setq saved (if (looking-at c-block-stmt-1-key)
444 ptok
445 pptok))
446 (cond ((> start saved) (setq pos saved))
447 ((= start saved) (setq ret 'up)))))
448
449 (when (and c-maybe-labelp (not ignore-labels) after-labels-pos)
450 ;; We're in a label. Maybe we should step to the statement
451 ;; after it.
452 (if (< after-labels-pos start)
453 (setq pos after-labels-pos)
454 (setq ret 'label)
455 (if (< last-label-pos start)
456 (setq pos last-label-pos)))))
457
458 ;; Skip over the unary operators that can start the statement.
459 (goto-char pos)
460 (while (progn
461 (c-backward-syntactic-ws)
462 (/= (skip-chars-backward "-+!*&~@`#") 0))
463 (setq pos (point)))
464 (goto-char pos)
465 ret)))
785eecbb 466
785eecbb 467(defun c-crosses-statement-barrier-p (from to)
a66cd3ee
MS
468 "Return non-nil if buffer positions FROM to TO cross one or more
469statement or declaration boundaries. The returned value is actually
470the position of the earliest boundary char.
471
472The variable `c-maybe-labelp' is set to the position of the first `:' that
473might start a label (i.e. not part of `::' and not preceded by `?'). If a
474single `?' is found, then `c-maybe-labelp' is cleared."
475 (let ((skip-chars c-stmt-delim-chars)
476 lit-range)
477 (save-excursion
478 (catch 'done
479 (goto-char from)
480 (while (progn (skip-chars-forward skip-chars to)
785eecbb 481 (< (point) to))
a66cd3ee
MS
482 (if (setq lit-range (c-literal-limits from))
483 (goto-char (setq from (cdr lit-range)))
484 (cond ((eq (char-after) ?:)
485 (forward-char)
486 (if (and (eq (char-after) ?:)
487 (< (point) to))
488 ;; Ignore scope operators.
489 (forward-char)
490 (setq c-maybe-labelp (1- (point)))))
491 ((eq (char-after) ??)
492 ;; A question mark. Can't be a label, so stop
493 ;; looking for more : and ?.
494 (setq c-maybe-labelp nil
495 skip-chars (substring c-stmt-delim-chars 0 -2)))
496 (t (throw 'done (point))))))
497 nil))))
785eecbb
RS
498
499\f
a66cd3ee
MS
500;; This is a dynamically bound cache used together with
501;; c-query-macro-start and c-query-and-set-macro-start. It only works
502;; as long as point doesn't cross a macro boundary.
503(defvar c-macro-start 'unknown)
504
505(defsubst c-query-and-set-macro-start ()
506 (if (symbolp c-macro-start)
507 (setq c-macro-start (save-excursion
508 (and (c-beginning-of-macro)
509 (point))))
510 c-macro-start))
511
512(defsubst c-query-macro-start ()
513 (if (symbolp c-macro-start)
514 (save-excursion
515 (and (c-beginning-of-macro)
516 (point)))
517 c-macro-start))
518
130c507e 519(defun c-beginning-of-macro (&optional lim)
a66cd3ee
MS
520 "Go to the beginning of a cpp macro definition.
521Leave point at the beginning of the macro and return t if in a cpp
522macro definition, otherwise return nil and leave point unchanged."
130c507e 523 (let ((here (point)))
a66cd3ee
MS
524 (save-restriction
525 (if lim (narrow-to-region lim (point-max)))
526 (beginning-of-line)
527 (while (eq (char-before (1- (point))) ?\\)
528 (forward-line -1))
529 (back-to-indentation)
530 (if (and (<= (point) here)
531 (looking-at "#[ \t]*[a-zA-Z0-9!]"))
532 t
533 (goto-char here)
534 nil))))
535
536(defun c-end-of-macro ()
537 "Go to the end of a cpp macro definition.
538More accurately, move point to the end of the closest following line
539that doesn't end with a line continuation backslash."
540 (while (progn
541 (end-of-line)
542 (when (and (eq (char-before) ?\\)
543 (not (eobp)))
544 (forward-char)
545 t))))
546
547(defun c-forward-comment (count)
548 ;; Insulation from various idiosyncrasies in implementations of
549 ;; `forward-comment'.
550 ;;
551 ;; Note: Some emacsen considers incorrectly that any line comment
552 ;; ending with a backslash continues to the next line. I can't
553 ;; think of any way to work around that in a reliable way without
554 ;; changing the buffer, though. Suggestions welcome. ;) (No,
555 ;; temporarily changing the syntax for backslash doesn't work since
556 ;; we must treat escapes in string literals correctly.)
557 ;;
558 ;; Another note: When moving backwards over a block comment, there's
559 ;; a bug in forward-comment that can make it stop at "/*" inside a
560 ;; line comment. Haven't yet found a reasonably cheap way to kludge
561 ;; around that one either. :\
562 (let ((here (point)))
563 (if (>= count 0)
564 (when (forward-comment count)
565 (if (eobp)
566 ;; Some emacsen (e.g. XEmacs 21) return t when moving
567 ;; forwards at eob.
568 nil
569 ;; Emacs includes the ending newline in a b-style (c++)
570 ;; comment, but XEmacs doesn't. We depend on the Emacs
571 ;; behavior (which also is symmetric).
572 (if (and (eolp) (nth 7 (parse-partial-sexp here (point))))
573 (condition-case nil (forward-char 1)))
574 t))
575 ;; When we got newline terminated comments,
576 ;; forward-comment in all supported emacsen so far will
577 ;; stop at eol of each line not ending with a comment when
578 ;; moving backwards. The following corrects for it when
579 ;; count is -1. The other common case, when count is
580 ;; large and negative, works regardless. It's too much
581 ;; work to correct for the rest of the cases.
582 (skip-chars-backward " \t\n\r\f")
583 (if (bobp)
584 ;; Some emacsen return t when moving backwards at bob.
585 nil
586 (re-search-forward "[\n\r]" here t)
587 (let* ((res (if (forward-comment count)
588 (if (eolp) (forward-comment -1) t)))
589 (savepos (point)))
590 ;; XEmacs treats line continuations as whitespace (but only
591 ;; in the backward direction).
592 (while (and (progn (end-of-line) (< (point) here))
593 (eq (char-before) ?\\))
594 (setq res nil
595 savepos (point))
596 (forward-line))
597 (goto-char savepos)
598 res)))))
130c507e 599
a66cd3ee
MS
600(defun c-forward-comment-lc (count)
601 ;; Like `c-forward-comment', but treat line continuations as
602 ;; whitespace.
603 (catch 'done
604 (if (> count 0)
605 (while (if (c-forward-comment 1)
606 (progn
607 (setq count (1- count))
608 (> count 0))
609 (if (looking-at "\\\\$")
610 (progn
611 (forward-char)
612 t)
613 (throw 'done nil))))
614 (while (if (c-forward-comment -1)
615 (progn
616 (setq count (1+ count))
617 (< count 0))
618 (if (and (eolp) (eq (char-before) ?\\))
619 (progn
620 (backward-char)
621 t)
622 (throw 'done nil)))))
623 t))
785eecbb
RS
624
625(defun c-forward-syntactic-ws (&optional lim)
a66cd3ee
MS
626 "Forward skip of syntactic whitespace.
627Syntactic whitespace is defined as whitespace characters, comments,
628and preprocessor directives. However if point starts inside a comment
629or preprocessor directive, the content of it is not treated as
630whitespace. LIM sets an upper limit of the forward movement, if
631specified."
632 (let ((here (point-max)))
633 (or lim (setq lim here))
e1c458ae 634 (while (/= here (point))
a66cd3ee
MS
635 ;; If forward-comment in at least XEmacs 21 is given a large
636 ;; positive value, it'll loop all the way through if it hits eob.
637 (while (c-forward-comment 5))
e1c458ae 638 (setq here (point))
a66cd3ee
MS
639 (cond
640 ;; Skip line continuations.
641 ((looking-at "\\\\$")
642 (forward-char))
643 ;; Skip preprocessor directives.
644 ((and (looking-at "#[ \t]*[a-zA-Z0-9!]")
645 (progn (skip-chars-backward " \t")
646 (bolp)))
647 (end-of-line)
648 (while (and (<= (point) lim)
649 (eq (char-before) ?\\)
650 (= (forward-line 1) 0))
651 (end-of-line))
652 (when (> (point) lim)
653 ;; Don't move past the macro if that'd take us past the limit.
654 (goto-char here)))
655 ;; Skip in-comment line continuations (used for Pike refdoc).
656 ((and c-opt-in-comment-lc (looking-at c-opt-in-comment-lc))
657 (goto-char (match-end 0)))))
658 (goto-char (min (point) lim))))
e1c458ae 659
785eecbb 660(defun c-backward-syntactic-ws (&optional lim)
a66cd3ee
MS
661 "Backward skip of syntactic whitespace.
662Syntactic whitespace is defined as whitespace characters, comments,
663and preprocessor directives. However if point starts inside a comment
664or preprocessor directive, the content of it is not treated as
665whitespace. LIM sets a lower limit of the backward movement, if
666specified."
667 (let ((start-line (c-point 'bol))
668 (here (point-min))
669 (line-cont 'maybe)
670 prev-pos)
671 (or lim (setq lim here))
e1c458ae 672 (while (/= here (point))
a66cd3ee
MS
673 (setq prev-pos (point))
674 ;; If forward-comment in Emacs 19.34 is given a large negative
675 ;; value, it'll loop all the way through if it hits bob.
676 (while (c-forward-comment -5))
e1c458ae 677 (setq here (point))
a66cd3ee
MS
678 (cond
679 ((and (eolp)
680 (eq (char-before) ?\\)
681 (if (<= prev-pos (c-point 'eonl))
682 t
683 ;; Passed a line continuation, but not from the line we
684 ;; started on.
685 (forward-char)
686 (setq line-cont nil)))
687 (backward-char)
688 (setq line-cont t))
689 ((progn
690 (when (eq line-cont 'maybe)
691 (save-excursion
692 (end-of-line)
693 (setq line-cont (eq (char-before) ?\\))))
694 (or line-cont
695 (and (< (point) start-line)
696 (c-beginning-of-macro))))
697 (if (< (point) lim)
698 ;; Don't move past the macro if we began inside it or at
699 ;; the end of the same line, or if the move would take us
700 ;; past the limit.
701 (goto-char here))
702 (setq line-cont nil))
703 ;; Skip in-comment line continuations (used for Pike refdoc).
704 ((and c-opt-in-comment-lc
705 (save-excursion
706 (and (c-safe (beginning-of-line)
707 (backward-char 2)
708 t)
709 (looking-at c-opt-in-comment-lc)
710 (eq (match-end 0) here))))
711 (goto-char (match-beginning 0)))))
712 (goto-char (max (point) lim))))
b2acd789
RS
713
714(defun c-forward-token-1 (&optional count balanced lim)
a66cd3ee
MS
715 "Move forward by tokens.
716A token is defined as all symbols and identifiers which aren't
717syntactic whitespace \(note that e.g. \"->\" is considered to be two
718tokens). Point is always either left at the beginning of a token or
719not moved at all. COUNT specifies the number of tokens to move; a
720negative COUNT moves in the opposite direction. A COUNT of 0 moves to
721the next token beginning only if not already at one. If BALANCED is
722true, move over balanced parens, otherwise move into them. Also, if
723BALANCED is true, never move out of an enclosing paren. LIM sets the
724limit for the movement and defaults to the point limit.
725
726Return the number of tokens left to move \(positive or negative). If
727BALANCED is true, a move over a balanced paren counts as one. Note
728that if COUNT is 0 and no appropriate token beginning is found, 1 will
729be returned. Thus, a return value of 0 guarantees that point is at
730the requested position and a return value less \(without signs) than
731COUNT guarantees that point is at the beginning of some token."
0ec8351b
BW
732 (or count (setq count 1))
733 (if (< count 0)
734 (- (c-backward-token-1 (- count) balanced lim))
735 (let ((jump-syntax (if balanced
736 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
737 '(?w ?_ ?\" ?\\ ?/ ?')))
738 (last (point))
739 (prev (point)))
0ec8351b
BW
740 (save-restriction
741 (if lim (narrow-to-region (point-min) lim))
130c507e
GM
742 (if (/= (point)
743 (progn (c-forward-syntactic-ws) (point)))
744 ;; Skip whitespace. Count this as a move if we did in fact
745 ;; move and aren't out of bounds.
746 (or (eobp)
747 (setq count (max (1- count) 0))))
748 (if (and (= count 0)
749 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
750 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
751 (eobp)))
752 ;; If count is zero we should jump if in the middle of a
753 ;; token or if there is whitespace between point and the
754 ;; following token beginning.
755 (setq count 1))
0ec8351b
BW
756 (if (eobp)
757 (goto-char last)
130c507e 758 ;; Avoid having the limit tests inside the loop.
0ec8351b
BW
759 (condition-case nil
760 (while (> count 0)
761 (setq prev last
762 last (point))
763 (if (memq (char-syntax (char-after)) jump-syntax)
764 (goto-char (scan-sexps (point) 1))
765 (forward-char))
a66cd3ee 766 (c-forward-syntactic-ws)
0ec8351b
BW
767 (setq count (1- count)))
768 (error (goto-char last)))
769 (when (eobp)
770 (goto-char prev)
771 (setq count (1+ count)))))
772 count)))
b2acd789
RS
773
774(defun c-backward-token-1 (&optional count balanced lim)
a66cd3ee
MS
775 "Move backward by tokens.
776See `c-forward-token-1' for details."
0ec8351b
BW
777 (or count (setq count 1))
778 (if (< count 0)
779 (- (c-forward-token-1 (- count) balanced lim))
780 (let ((jump-syntax (if balanced
781 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
782 '(?w ?_ ?\" ?\\ ?/ ?')))
783 last)
784 (if (and (= count 0)
785 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
786 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
787 (/= (point)
a66cd3ee
MS
788 (save-excursion
789 (c-forward-syntactic-ws (1+ lim))
790 (point)))
0ec8351b
BW
791 (eobp)))
792 ;; If count is zero we should jump if in the middle of a
793 ;; token or if there is whitespace between point and the
794 ;; following token beginning.
795 (setq count 1))
0ec8351b
BW
796 (save-restriction
797 (if lim (narrow-to-region lim (point-max)))
798 (or (bobp)
799 (progn
130c507e 800 ;; Avoid having the limit tests inside the loop.
0ec8351b
BW
801 (condition-case nil
802 (while (progn
803 (setq last (point))
804 (> count 0))
a66cd3ee 805 (c-backward-syntactic-ws)
0ec8351b
BW
806 (if (memq (char-syntax (char-before)) jump-syntax)
807 (goto-char (scan-sexps (point) -1))
808 (backward-char))
809 (setq count (1- count)))
810 (error (goto-char last)))
811 (if (bobp) (goto-char last)))))
812 count)))
b2acd789 813
a66cd3ee
MS
814(defun c-syntactic-re-search-forward (regexp &optional bound noerror count
815 paren-level)
816 ;; Like `re-search-forward', but only report matches that are found
817 ;; in syntactically significant text. I.e. matches that begins in
818 ;; comments, macros or string literals are ignored. The start point
819 ;; is assumed to be outside any comment, macro or string literal, or
820 ;; else the content of that region is taken as syntactically
821 ;; significant text. If PAREN-LEVEL is non-nil, an additional
822 ;; restriction is added to ignore matches in nested paren sexps, and
823 ;; the search will also not go outside the current paren sexp.
824 (or bound (setq bound (point-max)))
825 (or count (setq count 1))
826 (if paren-level (setq paren-level -1))
827 (let ((start (point))
828 (pos (point))
829 match-pos state)
830 (condition-case err
831 (while (and (> count 0)
832 (re-search-forward regexp bound noerror))
833 (setq match-pos (point)
834 state (parse-partial-sexp pos (match-beginning 0)
835 paren-level nil state)
836 pos (point))
837 (cond ((nth 3 state)
838 ;; Match inside a string. Skip to the end of it
839 ;; before continuing.
840 (let ((ender (make-string 1 (nth 3 state))))
841 (while (progn
842 (search-forward ender bound noerror)
843 (setq state (parse-partial-sexp pos (point)
844 nil nil state)
845 pos (point))
846 (nth 3 state)))))
847 ((nth 7 state)
848 ;; Match inside a line comment. Skip to eol. Use
849 ;; re-search-forward for it to get the right bound
850 ;; behavior.
851 (re-search-forward "[\n\r]" bound noerror))
852 ((nth 4 state)
853 ;; Match inside a block comment. Skip to the '*/'.
854 (re-search-forward "\\*/" bound noerror))
855 ((save-excursion (c-beginning-of-macro start))
856 ;; Match inside a macro. Skip to the end of it.
857 (c-end-of-macro))
858 ((and paren-level (/= (car state) 0))
859 (if (> (car state) 0)
860 ;; Match inside a nested paren sexp. Skip out of it.
861 (setq state (parse-partial-sexp pos bound 0 nil state)
862 pos (point))
863 ;; Have exited the current paren sexp. The
864 ;; parse-partial-sexp above has left us just after
865 ;; the closing paren in this case. Just make
866 ;; re-search-forward above fail in the appropriate
867 ;; way; we'll adjust the leave off point below if
868 ;; necessary.
869 (setq bound (point))))
870 (t
871 ;; A real match.
872 (setq count (1- count)))))
873 (error
874 (goto-char start)
875 (signal (car err) (cdr err))))
876 (if (= count 0)
877 (progn
878 (goto-char match-pos)
879 match-pos)
880 ;; Search failed. Set point as appropriate.
881 (cond ((eq noerror t)
882 (goto-char start))
883 (paren-level
884 (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1)
885 (backward-char)))
886 (t
887 (goto-char bound)))
888 nil)))
889
b2acd789 890\f
a66cd3ee
MS
891(defun c-in-literal (&optional lim detect-cpp)
892 "Return the type of literal point is in, if any.
893The return value is `c' if in a C-style comment, `c++' if in a C++
894style comment, `string' if in a string literal, `pound' if DETECT-CPP
895is non-nil and on a preprocessor line, or nil if somewhere else.
896Optional LIM is used as the backward limit of the search. If omitted,
897or nil, `c-beginning-of-defun' is used.
898
899The last point calculated is cached if the cache is enabled, i.e. if
900`c-in-literal-cache' is bound to a two element vector."
130c507e 901 (if (and (vectorp c-in-literal-cache)
785eecbb
RS
902 (= (point) (aref c-in-literal-cache 0)))
903 (aref c-in-literal-cache 1)
904 (let ((rtn (save-excursion
905 (let* ((lim (or lim (c-point 'bod)))
785eecbb
RS
906 (state (parse-partial-sexp lim (point))))
907 (cond
908 ((nth 3 state) 'string)
909 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
a66cd3ee 910 ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
785eecbb
RS
911 (t nil))))))
912 ;; cache this result if the cache is enabled
130c507e
GM
913 (if (not c-in-literal-cache)
914 (setq c-in-literal-cache (vector (point) rtn)))
785eecbb
RS
915 rtn)))
916
e1c458ae
RS
917;; XEmacs has a built-in function that should make this much quicker.
918;; I don't think we even need the cache, which makes our lives more
a66cd3ee
MS
919;; complicated anyway. In this case, lim is only used to detect
920;; cpp directives.
921(defun c-fast-in-literal (&optional lim detect-cpp)
e1c458ae
RS
922 (let ((context (buffer-syntactic-context)))
923 (cond
924 ((eq context 'string) 'string)
925 ((eq context 'comment) 'c++)
926 ((eq context 'block-comment) 'c)
a66cd3ee 927 ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound))))
e1c458ae
RS
928
929(if (fboundp 'buffer-syntactic-context)
930 (defalias 'c-in-literal 'c-fast-in-literal))
931
51f606de 932(defun c-literal-limits (&optional lim near not-in-delimiter)
a66cd3ee
MS
933 "Return a cons of the beginning and end positions of the comment or
934string surrounding point (including both delimiters), or nil if point
935isn't in one. If LIM is non-nil, it's used as the \"safe\" position
936to start parsing from. If NEAR is non-nil, then the limits of any
937literal next to point is returned. \"Next to\" means there's only [
938\t] between point and the literal. The search for such a literal is
939done first in forward direction. If NOT-IN-DELIMITER is non-nil, the
940case when point is inside a starting delimiter won't be recognized.
941This only has effect for comments, which have starting delimiters with
942more than one character."
e1c458ae 943 (save-excursion
0ec8351b
BW
944 (let* ((pos (point))
945 (lim (or lim (c-point 'bod)))
e1c458ae
RS
946 (state (parse-partial-sexp lim (point))))
947 (cond ((nth 3 state)
948 ;; String. Search backward for the start.
949 (while (nth 3 state)
950 (search-backward (make-string 1 (nth 3 state)))
951 (setq state (parse-partial-sexp lim (point))))
0ec8351b 952 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
e1c458ae
RS
953 (point-max))))
954 ((nth 7 state)
0ec8351b 955 ;; Line comment. Search from bol for the comment starter.
e1c458ae
RS
956 (beginning-of-line)
957 (setq state (parse-partial-sexp lim (point))
958 lim (point))
959 (while (not (nth 7 state))
960 (search-forward "//") ; Should never fail.
961 (setq state (parse-partial-sexp
962 lim (point) nil nil state)
963 lim (point)))
964 (backward-char 2)
51f606de 965 (cons (point) (progn (c-forward-comment 1) (point))))
e1c458ae 966 ((nth 4 state)
0ec8351b 967 ;; Block comment. Search backward for the comment starter.
e1c458ae
RS
968 (while (nth 4 state)
969 (search-backward "/*") ; Should never fail.
970 (setq state (parse-partial-sexp lim (point))))
51f606de
GM
971 (cons (point) (progn (c-forward-comment 1) (point))))
972 ((and (not not-in-delimiter)
973 (not (nth 5 state))
974 (eq (char-before) ?/)
975 (looking-at "[/*]"))
e1c458ae 976 ;; We're standing in a comment starter.
51f606de
GM
977 (backward-char 1)
978 (cons (point) (progn (c-forward-comment 1) (point))))
0ec8351b
BW
979 (near
980 (goto-char pos)
981 ;; Search forward for a literal.
982 (skip-chars-forward " \t")
983 (cond
984 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
985 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
986 (point-max))))
987 ((looking-at "/[/*]") ; Line or block comment.
51f606de 988 (cons (point) (progn (c-forward-comment 1) (point))))
0ec8351b
BW
989 (t
990 ;; Search backward.
991 (skip-chars-backward " \t")
992 (let ((end (point)) beg)
993 (cond
994 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String.
995 (setq beg (c-safe (c-backward-sexp 1) (point))))
996 ((and (c-safe (forward-char -2) t)
997 (looking-at "*/"))
998 ;; Block comment. Due to the nature of line
999 ;; comments, they will always be covered by the
1000 ;; normal case above.
1001 (goto-char end)
51f606de 1002 (c-forward-comment -1)
0ec8351b
BW
1003 ;; If LIM is bogus, beg will be bogus.
1004 (setq beg (point))))
1005 (if beg (cons beg end))))))
e1c458ae
RS
1006 ))))
1007
51f606de 1008(defun c-literal-limits-fast (&optional lim near not-in-delimiter)
0ec8351b 1009 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
51f606de 1010 ;; returns the pos of the comment start.
e1c458ae 1011 (save-excursion
51f606de
GM
1012 (let* ((pos (point))
1013 (lim (or lim (c-point 'bod)))
1014 (state (parse-partial-sexp lim (point))))
e1c458ae
RS
1015 (cond ((nth 3 state) ; String.
1016 (goto-char (nth 8 state))
0ec8351b 1017 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
e1c458ae
RS
1018 (point-max))))
1019 ((nth 4 state) ; Comment.
1020 (goto-char (nth 8 state))
51f606de
GM
1021 (cons (point) (progn (c-forward-comment 1) (point))))
1022 ((and (not not-in-delimiter)
1023 (not (nth 5 state))
1024 (eq (char-before) ?/)
1025 (looking-at "[/*]"))
1026 ;; We're standing in a comment starter.
1027 (backward-char 1)
1028 (cons (point) (progn (c-forward-comment 1) (point))))
1029 (near
1030 (goto-char pos)
1031 ;; Search forward for a literal.
1032 (skip-chars-forward " \t")
1033 (cond
1034 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
1035 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
1036 (point-max))))
1037 ((looking-at "/[/*]") ; Line or block comment.
1038 (cons (point) (progn (c-forward-comment 1) (point))))
1039 (t
1040 ;; Search backward.
1041 (skip-chars-backward " \t")
1042 (let ((end (point)) beg)
1043 (cond
1044 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String.
1045 (setq beg (c-safe (c-backward-sexp 1) (point))))
1046 ((and (c-safe (forward-char -2) t)
1047 (looking-at "*/"))
1048 ;; Block comment. Due to the nature of line
1049 ;; comments, they will always be covered by the
1050 ;; normal case above.
1051 (goto-char end)
1052 (c-forward-comment -1)
1053 ;; If LIM is bogus, beg will be bogus.
1054 (setq beg (point))))
1055 (if beg (cons beg end))))))
e1c458ae
RS
1056 ))))
1057
51f606de
GM
1058(if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8))
1059 (defalias 'c-literal-limits 'c-literal-limits-fast))
1060
e1c458ae 1061(defun c-collect-line-comments (range)
a66cd3ee
MS
1062 "If the argument is a cons of two buffer positions (such as returned by
1063`c-literal-limits'), and that range contains a C++ style line comment,
1064then an extended range is returned that contains all adjacent line
1065comments (i.e. all comments that starts in the same column with no
1066empty lines or non-whitespace characters between them). Otherwise the
1067argument is returned."
e1c458ae
RS
1068 (save-excursion
1069 (condition-case nil
1070 (if (and (consp range) (progn
1071 (goto-char (car range))
1072 (looking-at "//")))
b2acd789
RS
1073 (let ((col (current-column))
1074 (beg (point))
130c507e 1075 (bopl (c-point 'bopl))
b2acd789 1076 (end (cdr range)))
130c507e
GM
1077 ;; Got to take care in the backward direction to handle
1078 ;; comments which are preceded by code.
51f606de 1079 (while (and (c-forward-comment -1)
130c507e 1080 (>= (point) bopl)
b2acd789
RS
1081 (looking-at "//")
1082 (= col (current-column)))
130c507e
GM
1083 (setq beg (point)
1084 bopl (c-point 'bopl)))
b2acd789 1085 (goto-char end)
51f606de
GM
1086 (while (and (progn (skip-chars-forward " \t")
1087 (looking-at "//"))
1088 (= col (current-column))
1089 (prog1 (zerop (forward-line 1))
1090 (setq end (point)))))
b2acd789 1091 (cons beg end))
e1c458ae
RS
1092 range)
1093 (error range))))
1094
0ec8351b 1095(defun c-literal-type (range)
a66cd3ee
MS
1096 "Convenience function that given the result of `c-literal-limits',
1097returns nil or the type of literal that the range surrounds. It's
1098much faster than using `c-in-literal' and is intended to be used when
1099you need both the type of a literal and its limits."
0ec8351b 1100 (if (consp range)
51f606de
GM
1101 (save-excursion
1102 (goto-char (car range))
1103 (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
1104 ((looking-at "//") 'c++)
1105 (t 'c))) ; Assuming the range is valid.
0ec8351b
BW
1106 range))
1107
e1c458ae 1108
785eecbb
RS
1109\f
1110;; utilities for moving and querying around syntactic elements
a66cd3ee
MS
1111
1112(defvar c-state-cache nil)
1113(make-variable-buffer-local 'c-state-cache)
1114;; The state cache used by `c-parse-state' to cut down the amount of
1115;; searching. It's the result from some earlier `c-parse-state' call.
1116;; The use of the cached info is more effective if the next
1117;; `c-parse-state' call is on a line close by the one the cached state
1118;; was made at; the cache can actually slow down a little if the
1119;; cached state was made very far back in the buffer. The cache is
1120;; most effective if `c-parse-state' is used on each line while moving
1121;; forward.
1122
1123(defvar c-state-cache-start nil)
1124;; This (point-min) when `c-state-cache' was calculated, to detect
1125;; that the start point hasn't changed due to narrowing.
785eecbb
RS
1126
1127(defun c-parse-state ()
a66cd3ee
MS
1128 ;; Finds and records all noteworthy parens between some good point
1129 ;; earlier in the file and point. That good point is at least the
1130 ;; beginning of the top-level construct we are in, or the beginning
1131 ;; of the preceding top-level construct if we aren't in one.
785eecbb 1132 ;;
a66cd3ee
MS
1133 ;; The returned value is a list of the noteworthy parens with the
1134 ;; last one first. If an element in the list is an integer, it's
1135 ;; the position of an open paren which has not been closed before
1136 ;; point. If an element is a cons, it gives the position of a
1137 ;; closed brace paren pair; the car is the start paren position and
1138 ;; the cdr is the position following the closing paren. Only the
1139 ;; last closed brace paren pair before each open paren is recorded,
1140 ;; and thus the state never contains two cons elements in
1141 ;; succession.
1142 (save-restriction
1143 (let* ((here (point))
1144 (c-macro-start (c-query-macro-start))
1145 (in-macro-start (or c-macro-start (point)))
1146 old-state last-pos pairs pos)
1147 ;; Somewhat ugly use of c-check-state-cache to get rid of the
1148 ;; part of the state cache that is after point. Can't use
1149 ;; c-whack-state-after for the same reasons as in that function.
1150 (c-check-state-cache (point) nil nil)
1151 ;; Get the latest position we know are directly inside the
1152 ;; closest containing paren of the cached state.
1153 (setq last-pos (and c-state-cache
1154 (if (consp (car c-state-cache))
1155 (cdr (car c-state-cache))
1156 (1+ (car c-state-cache)))))
1157 ;; Check if the found last-pos is in a macro. If it is, and
1158 ;; we're not in the same macro, we must discard everything on
1159 ;; c-state-cache that is inside the macro before using it.
1160 (when last-pos
1161 (save-excursion
1162 (goto-char last-pos)
1163 (when (and (c-beginning-of-macro)
1164 (/= (point) in-macro-start))
1165 (c-check-state-cache (point) nil nil)
1166 ;; Set last-pos again, just like above.
1167 (setq last-pos (and c-state-cache
1168 (if (consp (car c-state-cache))
1169 (cdr (car c-state-cache))
1170 (1+ (car c-state-cache))))))))
1171 (setq pos
1172 ;; Find the start position for the forward search. (Can't
1173 ;; search in the backward direction since point might be
1174 ;; in some kind of literal.)
1175 (or (when last-pos
1176 ;; There's a cached state with a containing paren. Pop
1177 ;; off the stale containing sexps from it by going
1178 ;; forward out of parens as far as possible.
1179 (narrow-to-region (point-min) here)
1180 (let (placeholder pair-beg)
1181 (while (and c-state-cache
1182 (setq placeholder
1183 (c-up-list-forward last-pos)))
1184 (setq last-pos placeholder)
1185 (if (consp (car c-state-cache))
1186 (setq pair-beg (car-safe (cdr c-state-cache))
1187 c-state-cache (cdr-safe (cdr c-state-cache)))
1188 (setq pair-beg (car c-state-cache)
1189 c-state-cache (cdr c-state-cache))))
1190 (when (and pair-beg (eq (char-after pair-beg) ?{))
1191 ;; The last paren pair we moved out from was a brace
1192 ;; pair. Modify the state to record this as a closed
1193 ;; pair now.
1194 (if (consp (car-safe c-state-cache))
1195 (setq c-state-cache (cdr c-state-cache)))
1196 (setq c-state-cache (cons (cons pair-beg last-pos)
1197 c-state-cache))))
1198 ;; Check if the preceding balanced paren is within a
1199 ;; macro; it should be ignored if we're outside the
1200 ;; macro. There's no need to check any further upwards;
1201 ;; if the macro contains an unbalanced opening paren then
1202 ;; we're smoked anyway.
1203 (when (and (<= (point) in-macro-start)
1204 (consp (car c-state-cache)))
1205 (save-excursion
1206 (goto-char (car (car c-state-cache)))
1207 (when (c-beginning-of-macro)
1208 (setq here (point)
1209 c-state-cache (cdr c-state-cache)))))
1210 (when c-state-cache
1211 (setq old-state c-state-cache)
1212 last-pos))
1213 (save-excursion
785eecbb 1214 ;; go back 2 bods, but ignore any bogus positions
a66cd3ee
MS
1215 ;; returned by beginning-of-defun (i.e. open paren in
1216 ;; column zero)
1217 (goto-char here)
785eecbb 1218 (let ((cnt 2))
a66cd3ee
MS
1219 (while (not (or (bobp) (zerop cnt)))
1220 (c-beginning-of-defun-1)
1221 (if (eq (char-after) ?\{)
1222 (setq cnt (1- cnt)))))
1223 (point))))
1224 (narrow-to-region (point-min) here)
1225 (while pos
1226 ;; Find the balanced brace pairs.
1227 (setq pairs nil)
1228 (while (and (setq last-pos (c-down-list-forward pos))
1229 (setq pos (c-up-list-forward last-pos)))
1230 (if (eq (char-before last-pos) ?{)
1231 (setq pairs (cons (cons last-pos pos) pairs))))
1232 ;; Should ignore any pairs that are in a macro, providing
1233 ;; we're not in the same one.
1234 (when (and pairs (< (car (car pairs)) in-macro-start))
1235 (while (and (save-excursion
1236 (goto-char (car (car pairs)))
1237 (c-beginning-of-macro))
1238 (setq pairs (cdr pairs)))))
1239 ;; Record the last brace pair.
1240 (when pairs
1241 (if (and (eq c-state-cache old-state)
1242 (consp (car-safe c-state-cache)))
1243 ;; There's a closed pair on the cached state but we've
1244 ;; found a later one, so remove it.
1245 (setq c-state-cache (cdr c-state-cache)))
1246 (setq pairs (car pairs))
1247 (setcar pairs (1- (car pairs)))
1248 (setq c-state-cache (cons pairs c-state-cache)))
1249 (if last-pos
1250 ;; Prepare to loop, but record the open paren only if it's
1251 ;; outside a macro or within the same macro as point.
1252 (progn
1253 (setq pos last-pos)
1254 (if (or (>= last-pos in-macro-start)
1255 (save-excursion
1256 (goto-char last-pos)
1257 (not (c-beginning-of-macro))))
1258 (setq c-state-cache (cons (1- pos) c-state-cache))))
1259 (if (setq last-pos (c-up-list-forward pos))
1260 ;; Found a close paren without a corresponding opening
1261 ;; one. Maybe we didn't go back far enough, so try to
1262 ;; scan backward for the start paren and then start over.
1263 (progn
1264 (setq pos (c-up-list-backward pos)
1265 c-state-cache nil)
1266 (unless pos
1267 (setq pos last-pos
1268 c-parsing-error
1269 (format "Unbalanced close paren at line %d"
1270 (1+ (count-lines (point-min)
1271 (c-point 'bol last-pos)))))))
1272 (setq pos nil))))
1273 c-state-cache)))
1274
1275;; Debug tool to catch cache inconsistencies.
1276(defvar c-debug-parse-state nil)
1277(unless (fboundp 'c-real-parse-state)
1278 (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
1279(cc-bytecomp-defun c-real-parse-state)
1280(defun c-debug-parse-state ()
1281 (let ((res1 (c-real-parse-state)) res2)
1282 (let ((c-state-cache nil))
1283 (setq res2 (c-real-parse-state)))
1284 (unless (equal res1 res2)
1285 (error "c-parse-state inconsistency: using cache: %s, from scratch: %s"
1286 res1 res2))
1287 res1))
1288(defun c-toggle-parse-state-debug (&optional arg)
1289 (interactive "P")
1290 (setq c-debug-parse-state (c-calculate-state arg c-debug-parse-state))
1291 (fset 'c-parse-state (symbol-function (if c-debug-parse-state
1292 'c-debug-parse-state
1293 'c-real-parse-state)))
1294 (c-keep-region-active))
1295
1296(defun c-check-state-cache (beg end old-length)
1297 ;; Used on `after-change-functions' to adjust `c-state-cache'.
1298 ;; Prefer speed to finesse here, since there will be many more calls
1299 ;; to this function than times `c-state-cache' is used.
1300 ;;
1301 ;; This is much like `c-whack-state-after', but it never changes a
1302 ;; paren pair element into an open paren element. Doing that would
1303 ;; mean that the new open paren wouldn't have the required preceding
1304 ;; paren pair element.
1305 (if (not (eq c-state-cache-start (point-min)))
1306 (setq c-state-cache-start (point-min)
1307 c-state-cache nil)
1308 (while (and c-state-cache
1309 (let ((elem (car c-state-cache)))
1310 (if (consp elem)
1311 (or (<= beg (car elem))
1312 (< beg (cdr elem)))
1313 (<= beg elem))))
1314 (setq c-state-cache (cdr c-state-cache)))))
1315
1316(defun c-whack-state-before (bufpos paren-state)
1317 ;; Whack off any state information from PAREN-STATE which lies
1318 ;; before BUFPOS. Not destructive on PAREN-STATE.
1319 (let* ((newstate (list nil))
1320 (ptr newstate)
1321 car)
1322 (while paren-state
1323 (setq car (car paren-state)
1324 paren-state (cdr paren-state))
1325 (if (< (if (consp car) (car car) car) bufpos)
1326 (setq paren-state nil)
1327 (setcdr ptr (list car))
1328 (setq ptr (cdr ptr))))
1329 (cdr newstate)))
1330
1331(defun c-whack-state-after (bufpos paren-state)
1332 ;; Whack off any state information from PAREN-STATE which lies at or
1333 ;; after BUFPOS. Not destructive on PAREN-STATE.
1334 (catch 'done
1335 (while paren-state
1336 (let ((car (car paren-state)))
1337 (if (consp car)
1338 ;; just check the car, because in a balanced brace
1339 ;; expression, it must be impossible for the corresponding
1340 ;; close brace to be before point, but the open brace to
1341 ;; be after.
1342 (if (<= bufpos (car car))
1343 nil ; whack it off
1344 (if (< bufpos (cdr car))
1345 ;; its possible that the open brace is before
1346 ;; bufpos, but the close brace is after. In that
1347 ;; case, convert this to a non-cons element. The
1348 ;; rest of the state is before bufpos, so we're
1349 ;; done.
1350 (throw 'done (cons (car car) (cdr paren-state)))
1351 ;; we know that both the open and close braces are
1352 ;; before bufpos, so we also know that everything else
1353 ;; on state is before bufpos.
1354 (throw 'done paren-state)))
1355 (if (<= bufpos car)
785eecbb 1356 nil ; whack it off
a66cd3ee
MS
1357 ;; it's before bufpos, so everything else should too.
1358 (throw 'done paren-state)))
1359 (setq paren-state (cdr paren-state)))
1360 nil)))
785eecbb
RS
1361
1362\f
1363(defun c-beginning-of-inheritance-list (&optional lim)
1364 ;; Go to the first non-whitespace after the colon that starts a
1365 ;; multiple inheritance introduction. Optional LIM is the farthest
1366 ;; back we should search.
a66cd3ee
MS
1367 (let* ((lim (or lim (c-point 'bod))))
1368 (c-with-syntax-table c++-template-syntax-table
1369 (c-backward-token-1 0 t lim)
1370 (while (and (looking-at "[_a-zA-Z<,]")
1371 (= (c-backward-token-1 1 t lim) 0)))
1372 (skip-chars-forward "^:"))))
785eecbb 1373
785eecbb
RS
1374(defun c-in-method-def-p ()
1375 ;; Return nil if we aren't in a method definition, otherwise the
1376 ;; position of the initial [+-].
1377 (save-excursion
1378 (beginning-of-line)
a66cd3ee
MS
1379 (and c-opt-method-key
1380 (looking-at c-opt-method-key)
785eecbb
RS
1381 (point))
1382 ))
1383
a66cd3ee
MS
1384;; Contributed by Kevin Ryde <user42@zip.com.au>.
1385(defun c-in-gcc-asm-p ()
1386 ;; Return non-nil if point is within a gcc \"asm\" block.
1387 ;;
1388 ;; This should be called with point inside an argument list.
1389 ;;
1390 ;; Only one level of enclosing parentheses is considered, so for
1391 ;; instance `nil' is returned when in a function call within an asm
1392 ;; operand.
1393
1394 (and c-opt-asm-stmt-key
1395 (save-excursion
1396 (beginning-of-line)
1397 (backward-up-list 1)
1398 (c-beginning-of-statement-1 (point-min) nil t)
1399 (looking-at c-opt-asm-stmt-key))))
1400
abb7e5cf
SM
1401(defun c-at-toplevel-p ()
1402 "Return a determination as to whether point is at the `top-level'.
1403Being at the top-level means that point is either outside any
a66cd3ee
MS
1404enclosing block (such function definition), or inside a class,
1405namespace or extern definition, but outside any method blocks.
abb7e5cf
SM
1406
1407If point is not at the top-level (e.g. it is inside a method
1408definition), then nil is returned. Otherwise, if point is at a
1409top-level not enclosed within a class definition, t is returned.
1410Otherwise, a 2-vector is returned where the zeroth element is the
1411buffer position of the start of the class declaration, and the first
1412element is the buffer position of the enclosing class's opening
1413brace."
a66cd3ee
MS
1414 (let ((paren-state (c-parse-state)))
1415 (or (not (c-most-enclosing-brace paren-state))
1416 (c-search-uplist-for-classkey paren-state))))
1417
1418(defun c-forward-to-cpp-define-body ()
1419 ;; Assuming point is at the "#" that introduces a preprocessor
1420 ;; directive, it's moved forward to the start of the definition body
1421 ;; if it's a "#define". Non-nil is returned in this case, in all
1422 ;; other cases nil is returned and point isn't moved.
1423 (when (and (looking-at
1424 (concat "#[ \t]*"
1425 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
1426 "\\([ \t]\\|\\\\\n\\)*"))
1427 (not (= (match-end 0) (c-point 'eol))))
1428 (goto-char (match-end 0))))
1429
1430(defun c-just-after-func-arglist-p (&optional containing lim)
785eecbb
RS
1431 ;; Return t if we are between a function's argument list closing
1432 ;; paren and its opening brace. Note that the list close brace
1433 ;; could be followed by a "const" specifier or a member init hanging
1434 ;; colon. Optional CONTAINING is position of containing s-exp open
a66cd3ee
MS
1435 ;; brace. If not supplied, point is used as search start. LIM is
1436 ;; used as bound for some backward buffer searches; the search might
1437 ;; continue past it.
1438 ;;
1439 ;; Note: This test is easily fooled. It only works reasonably well
1440 ;; in the situations where `c-guess-basic-syntax' uses it.
785eecbb 1441 (save-excursion
a66cd3ee 1442 (c-backward-syntactic-ws lim)
785eecbb
RS
1443 (let ((checkpoint (or containing (point))))
1444 (goto-char checkpoint)
1445 ;; could be looking at const specifier
1446 (if (and (eq (char-before) ?t)
1447 (forward-word -1)
a66cd3ee
MS
1448 (looking-at "\\<const\\>[^_]"))
1449 (c-backward-syntactic-ws lim)
785eecbb
RS
1450 ;; otherwise, we could be looking at a hanging member init
1451 ;; colon
1452 (goto-char checkpoint)
ce8c7486
GM
1453 (while (eq (char-before) ?,)
1454 ;; this will catch member inits with multiple
1455 ;; line arglists
1456 (forward-char -1)
1457 (c-backward-syntactic-ws (c-point 'bol))
1458 (if (eq (char-before) ?\))
1459 (c-backward-sexp 2)
1460 (c-backward-sexp 1))
a66cd3ee 1461 (c-backward-syntactic-ws lim))
785eecbb
RS
1462 (if (and (eq (char-before) ?:)
1463 (progn
1464 (forward-char -1)
a66cd3ee
MS
1465 (c-backward-syntactic-ws lim)
1466 (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)")))
785eecbb
RS
1467 nil
1468 (goto-char checkpoint))
1469 )
a66cd3ee 1470 (setq checkpoint (point))
785eecbb 1471 (and (eq (char-before) ?\))
a66cd3ee
MS
1472 ;; Check that it isn't a cpp expression, e.g. the
1473 ;; expression of an #if directive or the "function header"
1474 ;; of a #define.
1475 (or (not (c-beginning-of-macro))
1476 (and (c-forward-to-cpp-define-body)
1477 (< (point) checkpoint)))
1478 ;; check if we are looking at an ObjC method def
1479 (or (not c-opt-method-key)
785eecbb 1480 (progn
a66cd3ee 1481 (goto-char checkpoint)
0ec8351b 1482 (c-forward-sexp -1)
785eecbb 1483 (forward-char -1)
a66cd3ee 1484 (c-backward-syntactic-ws lim)
785eecbb
RS
1485 (not (or (memq (char-before) '(?- ?+))
1486 ;; or a class category
1487 (progn
0ec8351b 1488 (c-forward-sexp -2)
785eecbb
RS
1489 (looking-at c-class-key))
1490 )))))
1491 )))
1492
a66cd3ee
MS
1493(defun c-in-knr-argdecl (&optional lim)
1494 ;; Return the position of the first argument declaration if point is
1495 ;; inside a K&R style argument declaration list, nil otherwise.
1496 ;; `c-recognize-knr-p' is not checked. If LIM is non-nil, it's a
1497 ;; position that bounds the backward search for the argument list.
1498 ;;
1499 ;; Note: A declaration level context is assumed; the test can return
1500 ;; false positives for statements and #define headers. This test is
1501 ;; even more easily fooled than `c-just-after-func-arglist-p'.
1502 (save-excursion
1503 (save-restriction
1504 ;; Go back to the closest preceding normal parenthesis sexp. We
1505 ;; take that as the argument list in the function header. Then
1506 ;; check that it's followed by some symbol before the next ';'
1507 ;; or '{'. If it does, it's the header of the K&R argdecl we're
1508 ;; in.
1509 (if lim (narrow-to-region lim (point)))
1510 (let (paren-end)
1511 (and (c-safe (setq paren-end (c-down-list-backward (point))))
1512 (eq (char-after paren-end) ?\))
1513 (progn
1514 (goto-char (1+ paren-end))
1515 (c-forward-syntactic-ws)
1516 (looking-at "\\w\\|\\s_"))
1517 (c-safe (c-up-list-backward paren-end))
1518 (point))))))
785eecbb
RS
1519
1520(defun c-skip-conditional ()
1521 ;; skip forward over conditional at point, including any predicate
1522 ;; statements in parentheses. No error checking is performed.
0ec8351b
BW
1523 (c-forward-sexp (cond
1524 ;; else if()
a66cd3ee
MS
1525 ((looking-at (concat "\\<else"
1526 "\\([ \t\n]\\|\\\\\n\\)+"
1527 "if\\>\\([^_]\\|$\\)"))
1528 3)
0ec8351b 1529 ;; do, else, try, finally
a66cd3ee
MS
1530 ((looking-at (concat "\\<\\("
1531 "do\\|else\\|try\\|finally"
1532 "\\)\\>\\([^_]\\|$\\)"))
130c507e 1533 1)
ce8c7486 1534 ;; for, if, while, switch, catch, synchronized, foreach
0ec8351b 1535 (t 2))))
785eecbb 1536
a66cd3ee
MS
1537(defun c-after-conditional (&optional lim)
1538 ;; If looking at the token after a conditional then return the
1539 ;; position of its start, otherwise return nil.
1540 (save-excursion
1541 (and (= (c-backward-token-1 1 t lim) 0)
1542 (or (looking-at c-block-stmt-1-key)
1543 (and (eq (char-after) ?\()
1544 (= (c-backward-token-1 1 t lim) 0)
1545 (looking-at c-block-stmt-2-key)))
1546 (point))))
1547
1548(defsubst c-backward-to-block-anchor (&optional lim)
1549 ;; Assuming point is at a brace that opens a statement block of some
1550 ;; kind, move to the proper anchor point for that block. It might
1551 ;; need to be adjusted further by c-add-stmt-syntax, but the
1552 ;; position at return is suitable as start position for that
1553 ;; function.
1554 (unless (= (point) (c-point 'boi))
1555 (let ((start (c-after-conditional lim)))
1556 (if start
1557 (goto-char start)))))
1558
1559(defun c-backward-to-decl-anchor (&optional lim)
1560 ;; Assuming point is at a brace that opens the block of a top level
1561 ;; declaration of some kind, move to the proper anchor point for
1562 ;; that block.
1563 (unless (= (point) (c-point 'boi))
1564 ;; What we have below is actually an extremely stripped variant of
1565 ;; c-beginning-of-statement-1.
1566 (let ((pos (point)))
1567 ;; Switch syntax table to avoid stopping at line continuations.
1568 (save-restriction
1569 (if lim (narrow-to-region lim (point-max)))
1570 (while (and (progn
1571 (c-backward-syntactic-ws)
1572 (c-safe (goto-char (scan-sexps (point) -1)) t))
1573 (not (c-crosses-statement-barrier-p (point) pos)))
1574 (setq pos (point)))
1575 (goto-char pos)))))
1576
1577(defsubst c-search-decl-header-end ()
1578 ;; Search forward for the end of the "header" of the current
1579 ;; declaration. That's the position where the definition body
1580 ;; starts, or the first variable initializer, or the ending
1581 ;; semicolon. I.e. search forward for the closest following
1582 ;; (syntactically relevant) '{', '=' or ';' token. Point is left
1583 ;; _after_ the first found token, or at point-max if none is found.
1584 (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
1585 c++-template-syntax-table
1586 (syntax-table))
1587 (while (and (c-syntactic-re-search-forward "[;{=]" nil 'move 1 t)
1588 ;; In Pike it can be an operator identifier containing
1589 ;; '='.
1590 (c-major-mode-is 'pike-mode)
1591 (eq (char-before) ?=)
1592 (c-on-identifier)))))
1593
1594(defun c-beginning-of-decl-1 (&optional lim)
1595 ;; Go to the beginning of the current declaration, or the beginning
1596 ;; of the previous one if already at the start of it. Point won't
1597 ;; be moved out of any surrounding paren. Return a cons cell on the
1598 ;; form (MOVE . KNR-POS). MOVE is like the return value from
1599 ;; `c-beginning-of-statement-1'. If point skipped over some K&R
1600 ;; style argument declarations (and they are to be recognized) then
1601 ;; KNR-POS is set to the start of the first such argument
1602 ;; declaration, otherwise KNR-POS is nil. If LIM is non-nil, it's a
1603 ;; position that bounds the backward search.
1604 ;;
1605 ;; NB: Cases where the declaration continues after the block, as in
1606 ;; "struct foo { ... } bar;", are currently recognized as two
1607 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case.
1608 (catch 'return
1609 (let* ((start (point))
1610 (last-stmt-start (point))
b3cf7e18 1611 (move (c-beginning-of-statement-1 lim t t)))
a66cd3ee
MS
1612
1613 (while (and (/= last-stmt-start (point))
1614 (save-excursion
1615 (c-backward-syntactic-ws lim)
1616 (not (memq (char-before) '(?\; ?} ?: nil)))))
1617 ;; `c-beginning-of-statement-1' stops at a block start, but we
1618 ;; want to continue if the block doesn't begin a top level
1619 ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob.
1620 (setq last-stmt-start (point)
b3cf7e18 1621 move (c-beginning-of-statement-1 lim t t)))
a66cd3ee
MS
1622
1623 (when c-recognize-knr-p
1624 (let ((fallback-pos (point)) knr-argdecl-start)
1625 ;; Handle K&R argdecls. Back up after the "statement" jumped
1626 ;; over by `c-beginning-of-statement-1', unless it was the
1627 ;; function body, in which case we're sitting on the opening
1628 ;; brace now. Then test if we're in a K&R argdecl region and
1629 ;; that we started at the other side of the first argdecl in
1630 ;; it.
1631 (unless (eq (char-after) ?{)
1632 (goto-char last-stmt-start))
1633 (if (and (setq knr-argdecl-start (c-in-knr-argdecl lim))
1634 (< knr-argdecl-start start)
1635 (progn
1636 (goto-char knr-argdecl-start)
b3cf7e18 1637 (not (eq (c-beginning-of-statement-1 lim t t) 'macro))))
a66cd3ee
MS
1638 (throw 'return
1639 (cons (if (eq (char-after fallback-pos) ?{)
1640 'previous
1641 'same)
1642 knr-argdecl-start))
1643 (goto-char fallback-pos))))
1644
b3cf7e18
MS
1645 (when c-opt-access-key
1646 ;; Might have ended up before a protection label. This should
1647 ;; perhaps be checked before `c-recognize-knr-p' to be really
1648 ;; accurate, but we know that no language has both.
1649 (while (looking-at c-opt-access-key)
1650 (goto-char (match-end 0))
1651 (c-forward-syntactic-ws)
1652 (when (>= (point) start)
1653 (goto-char start)
1654 (throw 'return (cons 'same nil)))))
1655
a66cd3ee
MS
1656 ;; `c-beginning-of-statement-1' counts each brace block as a
1657 ;; separate statement, so the result will be 'previous if we've
1658 ;; moved over any. If they were brace list initializers we might
1659 ;; not have moved over a declaration boundary though, so change it
1660 ;; to 'same if we've moved past a '=' before '{', but not ';'.
1661 ;; (This ought to be integrated into `c-beginning-of-statement-1',
1662 ;; so we avoid this extra pass which potentially can search over a
1663 ;; large amount of text.)
1664 (if (and (eq move 'previous)
1665 (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
1666 c++-template-syntax-table
1667 (syntax-table))
1668 (save-excursion
1669 (and (c-syntactic-re-search-forward "[;={]" start t 1 t)
1670 (eq (char-before) ?=)
1671 (c-syntactic-re-search-forward "[;{]" start t 1 t)
1672 (eq (char-before) ?{)
1673 (c-safe (goto-char (c-up-list-forward (point))) t)
1674 (not (c-syntactic-re-search-forward ";" start t 1 t))))))
1675 (cons 'same nil)
1676 (cons move nil)))))
1677
1678(defun c-end-of-decl-1 ()
1679 ;; Assuming point is at the start of a declaration (as detected by
1680 ;; e.g. `c-beginning-of-decl-1'), go to the end of it. Unlike
1681 ;; `c-beginning-of-decl-1', this function handles the case when a
1682 ;; block is followed by identifiers in e.g. struct declarations in C
1683 ;; or C++. If a proper end was found then t is returned, otherwise
1684 ;; point is moved as far as possible within the current sexp and nil
1685 ;; is returned. This function doesn't handle macros; use
1686 ;; `c-end-of-macro' instead in those cases.
ce8c7486 1687 (let ((start (point))
a66cd3ee
MS
1688 (decl-syntax-table (if (c-major-mode-is 'c++-mode)
1689 c++-template-syntax-table
1690 (syntax-table))))
1691 (catch 'return
1692 (c-search-decl-header-end)
1693
1694 (when (and c-recognize-knr-p
1695 (eq (char-before) ?\;)
1696 (c-in-knr-argdecl start))
1697 ;; Stopped at the ';' in a K&R argdecl section which is
1698 ;; detected using the same criteria as in
1699 ;; `c-beginning-of-decl-1'. Move to the following block
1700 ;; start.
1701 (c-syntactic-re-search-forward "{" nil 'move 1 t))
1702
1703 (when (eq (char-before) ?{)
1704 ;; Encountered a block in the declaration. Jump over it.
1705 (condition-case nil
1706 (goto-char (c-up-list-forward (point)))
1707 (goto-char (point-max))
1708 (throw 'return nil))
1709 (if (or (not c-opt-block-decls-with-vars-key)
1710 (save-excursion
1711 (c-with-syntax-table decl-syntax-table
1712 (let ((lim (point)))
1713 (goto-char start)
b3cf7e18
MS
1714 (not (and
1715 ;; Check for `c-opt-block-decls-with-vars-key'
1716 ;; before the first paren.
1717 (c-syntactic-re-search-forward
1718 (concat "[;=\(\[{]\\|\\<\\("
1719 c-opt-block-decls-with-vars-key
1720 "\\)")
1721 lim t 1 t)
1722 (match-beginning 1)
1723 (not (eq (char-before) ?_))
1724 ;; Check that the first following paren is the block.
1725 (c-syntactic-re-search-forward "[;=\(\[{]" lim t 1 t)
1726 (eq (char-before) ?{)))))))
a66cd3ee
MS
1727 ;; The declaration doesn't have any of the
1728 ;; `c-opt-block-decls-with-vars' keywords in the
1729 ;; beginning, so it ends here at the end of the block.
1730 (throw 'return t)))
1731
1732 (c-with-syntax-table decl-syntax-table
1733 (while (progn
1734 (if (eq (char-before) ?\;)
1735 (throw 'return t))
1736 (c-syntactic-re-search-forward ";" nil 'move 1 t))))
1737 nil)))
ce8c7486
GM
1738
1739(defun c-beginning-of-member-init-list (&optional limit)
1740 ;; Goes to the beginning of a member init list (i.e. just after the
1741 ;; ':') if inside one. Returns t in that case, nil otherwise.
1742 (or limit
1743 (setq limit (point-min)))
1744 (skip-chars-forward " \t")
1745 (if (eq (char-after) ?,)
1746 (forward-char 1)
1747 (c-backward-syntactic-ws limit))
174acba3
SM
1748 (while (and (< limit (point))
1749 (eq (char-before) ?,))
1750 ;; this will catch member inits with multiple
1751 ;; line arglists
1752 (forward-char -1)
1753 (c-backward-syntactic-ws limit)
1754 (if (eq (char-before) ?\))
130c507e 1755 (c-backward-sexp 1))
174acba3
SM
1756 (c-backward-syntactic-ws limit)
1757 ;; Skip over any template arg to the class.
1758 (if (eq (char-before) ?>)
1759 (c-with-syntax-table c++-template-syntax-table
1760 (c-backward-sexp 1)))
1761 (c-backward-sexp 1)
1762 (c-backward-syntactic-ws limit)
1763 ;; Skip backwards over a fully::qualified::name.
1764 (while (and (eq (char-before) ?:)
1765 (save-excursion
1766 (forward-char -1)
1767 (eq (char-before) ?:)))
1768 (backward-char 2)
1769 (c-backward-sexp 1))
1770 ;; now continue checking
1771 (c-backward-syntactic-ws limit))
ce8c7486
GM
1772 (and (< limit (point))
1773 (eq (char-before) ?:)))
1774
a66cd3ee 1775(defun c-search-uplist-for-classkey (paren-state)
785eecbb 1776 ;; search for the containing class, returning a 2 element vector if
0ec8351b
BW
1777 ;; found. aref 0 contains the bufpos of the boi of the class key
1778 ;; line, and aref 1 contains the bufpos of the open brace.
a66cd3ee
MS
1779 (if (null paren-state)
1780 ;; no paren-state means we cannot be inside a class
785eecbb 1781 nil
a66cd3ee 1782 (let ((carcache (car paren-state))
785eecbb
RS
1783 search-start search-end)
1784 (if (consp carcache)
1785 ;; a cons cell in the first element means that there is some
1786 ;; balanced sexp before the current bufpos. this we can
1787 ;; ignore. the nth 1 and nth 2 elements define for us the
1788 ;; search boundaries
a66cd3ee
MS
1789 (setq search-start (nth 2 paren-state)
1790 search-end (nth 1 paren-state))
785eecbb
RS
1791 ;; if the car was not a cons cell then nth 0 and nth 1 define
1792 ;; for us the search boundaries
a66cd3ee
MS
1793 (setq search-start (nth 1 paren-state)
1794 search-end (nth 0 paren-state)))
785eecbb
RS
1795 ;; if search-end is nil, or if the search-end character isn't an
1796 ;; open brace, we are definitely not in a class
1797 (if (or (not search-end)
1798 (< search-end (point-min))
1799 (not (eq (char-after search-end) ?{)))
1800 nil
1801 ;; now, we need to look more closely at search-start. if
1802 ;; search-start is nil, then our start boundary is really
1803 ;; point-min.
1804 (if (not search-start)
1805 (setq search-start (point-min))
1806 ;; if search-start is a cons cell, then we can start
1807 ;; searching from the end of the balanced sexp just ahead of
1808 ;; us
1809 (if (consp search-start)
1810 (setq search-start (cdr search-start))))
1811 ;; now we can do a quick regexp search from search-start to
1812 ;; search-end and see if we can find a class key. watch for
1813 ;; class like strings in literals
1814 (save-excursion
1815 (save-restriction
1816 (goto-char search-start)
a66cd3ee 1817 (let (foundp class match-end)
785eecbb
RS
1818 (while (and (not foundp)
1819 (progn
a66cd3ee 1820 (c-forward-syntactic-ws search-end)
785eecbb 1821 (> search-end (point)))
a66cd3ee 1822 (re-search-forward c-decl-block-key search-end t))
785eecbb
RS
1823 (setq class (match-beginning 0)
1824 match-end (match-end 0))
a66cd3ee 1825 (goto-char class)
785eecbb 1826 (if (c-in-literal search-start)
a66cd3ee
MS
1827 (goto-char match-end) ; its in a comment or string, ignore
1828 (c-skip-ws-forward)
785eecbb
RS
1829 (setq foundp (vector (c-point 'boi) search-end))
1830 (cond
1831 ;; check for embedded keywords
1832 ((let ((char (char-after (1- class))))
1833 (and char
1834 (memq (char-syntax char) '(?w ?_))))
1835 (goto-char match-end)
1836 (setq foundp nil))
1837 ;; make sure we're really looking at the start of a
a66cd3ee
MS
1838 ;; class definition, and not an ObjC method.
1839 ((and c-opt-method-key
1840 (re-search-forward c-opt-method-key search-end t)
0ec8351b 1841 (not (c-in-literal class)))
785eecbb 1842 (setq foundp nil))
0ec8351b 1843 ;; Check if this is an anonymous inner class.
a66cd3ee
MS
1844 ((and c-opt-inexpr-class-key
1845 (looking-at c-opt-inexpr-class-key))
0ec8351b
BW
1846 (while (and (= (c-forward-token-1 1 t) 0)
1847 (looking-at "(\\|\\w\\|\\s_\\|\\.")))
1848 (if (eq (point) search-end)
1849 ;; We're done. Just trap this case in the cond.
1850 nil
1851 ;; False alarm; all conditions aren't satisfied.
1852 (setq foundp nil)))
785eecbb
RS
1853 ;; Its impossible to define a regexp for this, and
1854 ;; nearly so to do it programmatically.
1855 ;;
1856 ;; ; picks up forward decls
1857 ;; = picks up init lists
1858 ;; ) picks up return types
1859 ;; > picks up templates, but remember that we can
1860 ;; inherit from templates!
1861 ((let ((skipchars "^;=)"))
1862 ;; try to see if we found the `class' keyword
1863 ;; inside a template arg list
1864 (save-excursion
1865 (skip-chars-backward "^<>" search-start)
1866 (if (eq (char-before) ?<)
1867 (setq skipchars (concat skipchars ">"))))
0ec8351b
BW
1868 (while (progn
1869 (skip-chars-forward skipchars search-end)
1870 (c-in-literal class))
1871 (forward-char))
785eecbb
RS
1872 (/= (point) search-end))
1873 (setq foundp nil))
1874 )))
1875 foundp))
1876 )))))
1877
a66cd3ee 1878(defun c-inside-bracelist-p (containing-sexp paren-state)
785eecbb
RS
1879 ;; return the buffer position of the beginning of the brace list
1880 ;; statement if we're inside a brace list, otherwise return nil.
1881 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
130c507e
GM
1882 ;; paren. BRACE-STATE is the remainder of the state of enclosing
1883 ;; braces
785eecbb
RS
1884 ;;
1885 ;; N.B.: This algorithm can potentially get confused by cpp macros
1886 ;; places in inconvenient locations. Its a trade-off we make for
1887 ;; speed.
1888 (or
1889 ;; this will pick up enum lists
b2acd789
RS
1890 (c-safe
1891 (save-excursion
1892 (goto-char containing-sexp)
0ec8351b 1893 (c-forward-sexp -1)
b2acd789 1894 (let (bracepos)
a66cd3ee 1895 (if (and (or (looking-at "enum\\>[^_]")
0ec8351b 1896 (progn (c-forward-sexp -1)
a66cd3ee
MS
1897 (looking-at "enum\\>[^_]")))
1898 (setq bracepos (c-down-list-forward (point)))
b2acd789
RS
1899 (not (c-crosses-statement-barrier-p (point)
1900 (- bracepos 2))))
1901 (point)))))
785eecbb
RS
1902 ;; this will pick up array/aggregate init lists, even if they are nested.
1903 (save-excursion
0ec8351b
BW
1904 (let ((class-key
1905 ;; Pike can have class definitions anywhere, so we must
1906 ;; check for the class key here.
1907 (and (c-major-mode-is 'pike-mode)
a66cd3ee
MS
1908 c-decl-block-key))
1909 bufpos braceassignp lim next-containing)
785eecbb
RS
1910 (while (and (not bufpos)
1911 containing-sexp)
a66cd3ee
MS
1912 (when paren-state
1913 (if (consp (car paren-state))
1914 (setq lim (cdr (car paren-state))
1915 paren-state (cdr paren-state))
1916 (setq lim (car paren-state)))
1917 (when paren-state
1918 (setq next-containing (car paren-state)
1919 paren-state (cdr paren-state))))
785eecbb 1920 (goto-char containing-sexp)
a66cd3ee
MS
1921 (if (c-looking-at-inexpr-block next-containing next-containing)
1922 ;; We're in an in-expression block of some kind. Do not
1923 ;; check nesting. We deliberately set the limit to the
1924 ;; containing sexp, so that c-looking-at-inexpr-block
1925 ;; doesn't check for an identifier before it.
0ec8351b
BW
1926 (setq containing-sexp nil)
1927 ;; see if the open brace is preceded by = or [...] in
1928 ;; this statement, but watch out for operator=
a66cd3ee 1929 (setq braceassignp 'dontknow)
6393fef2
RS
1930 (c-backward-token-1 1 t lim)
1931 ;; Checks to do only on the first sexp before the brace.
1932 (when (and (c-major-mode-is 'java-mode)
1933 (eq (char-after) ?\[))
1934 ;; In Java, an initialization brace list may follow
1935 ;; directly after "new Foo[]", so check for a "new"
1936 ;; earlier.
1937 (while (eq braceassignp 'dontknow)
1938 (setq braceassignp
1939 (cond ((/= (c-backward-token-1 1 t lim) 0) nil)
130c507e 1940 ((looking-at "new\\>[^_]") t)
6393fef2
RS
1941 ((looking-at "\\sw\\|\\s_\\|[.[]")
1942 ;; Carry on looking if this is an
1943 ;; identifier (may contain "." in Java)
1944 ;; or another "[]" sexp.
1945 'dontknow)
1946 (t nil)))))
1947 ;; Checks to do on all sexps before the brace, up to the
1948 ;; beginning of the statement.
1949 (while (eq braceassignp 'dontknow)
0ec8351b
BW
1950 (cond ((eq (char-after) ?\;)
1951 (setq braceassignp nil))
1952 ((and class-key
1953 (looking-at class-key))
1954 (setq braceassignp nil))
1955 ((eq (char-after) ?=)
1956 ;; We've seen a =, but must check earlier tokens so
1957 ;; that it isn't something that should be ignored.
1958 (setq braceassignp 'maybe)
1959 (while (and (eq braceassignp 'maybe)
1960 (zerop (c-backward-token-1 1 t lim)))
1961 (setq braceassignp
1962 (cond
1963 ;; Check for operator =
a66cd3ee 1964 ((looking-at "operator\\>[^_]") nil)
130c507e
GM
1965 ;; Check for `<opchar>= in Pike.
1966 ((and (c-major-mode-is 'pike-mode)
1967 (or (eq (char-after) ?`)
1968 ;; Special case for Pikes
1969 ;; `[]=, since '[' is not in
1970 ;; the punctuation class.
1971 (and (eq (char-after) ?\[)
1972 (eq (char-before) ?`))))
1973 nil)
0ec8351b
BW
1974 ((looking-at "\\s.") 'maybe)
1975 ;; make sure we're not in a C++ template
1976 ;; argument assignment
a66cd3ee
MS
1977 ((and
1978 (c-major-mode-is 'c++-mode)
1979 (save-excursion
1980 (let ((here (point))
1981 (pos< (progn
1982 (skip-chars-backward "^<>")
1983 (point))))
1984 (and (eq (char-before) ?<)
1985 (not (c-crosses-statement-barrier-p
1986 pos< here))
1987 (not (c-in-literal))
1988 ))))
0ec8351b 1989 nil)
6393fef2
RS
1990 (t t))))))
1991 (if (and (eq braceassignp 'dontknow)
1992 (/= (c-backward-token-1 1 t lim) 0))
1993 (setq braceassignp nil)))
1994 (if (not braceassignp)
0ec8351b
BW
1995 (if (eq (char-after) ?\;)
1996 ;; Brace lists can't contain a semicolon, so we're done.
1997 (setq containing-sexp nil)
a66cd3ee
MS
1998 ;; Go up one level.
1999 (setq containing-sexp next-containing
2000 lim nil
2001 next-containing nil))
0ec8351b
BW
2002 ;; we've hit the beginning of the aggregate list
2003 (c-beginning-of-statement-1
a66cd3ee 2004 (c-most-enclosing-brace paren-state))
0ec8351b 2005 (setq bufpos (point))))
a66cd3ee 2006 )
785eecbb
RS
2007 bufpos))
2008 ))
2009
0ec8351b
BW
2010(defun c-looking-at-special-brace-list (&optional lim)
2011