1 ;;; cc-engine.el --- core syntax guessing engine for CC mode
3 ;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
5 ;; Authors: 2000- Martin Stjernholm
6 ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
7 ;; 1992-1997 Barry A. Warsaw
8 ;; 1987 Dave Detlefs and Stewart Clamen
9 ;; 1985 Richard M. Stallman
10 ;; Maintainer: bug-cc-mode@gnu.org
11 ;; Created: 22-Apr-1997 (split from cc-mode.el)
12 ;; Version: See cc-mode.el
13 ;; Keywords: c languages oop
15 ;; This file is part of GNU Emacs.
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)
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.
27 ;; You should have received a copy of the GNU General Public License
28 ;; along with GNU Emacs; see the file COPYING. If not, write to
29 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 ;; Boston, MA 02111-1307, USA.
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.
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.)
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)
52 (require 'cc-bytecomp)))
56 (cc-require 'cc-langs)
58 ;; Silence the compiler.
59 (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
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
67 (zerop (setq arg (prefix-numeric-value arg))))
72 (defvar c-in-literal-cache t)
73 (defvar c-parsing-error nil)
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
79 (defvar c-maybe-labelp nil)
81 ;; Macros used internally in c-beginning-of-statement-1 for the
83 (defmacro c-bos-push-state ()
84 '(setq stack (cons (cons state saved-pos)
86 (defmacro c-bos-pop-state (&optional do-if-done)
87 `(if (setq state (car (car stack))
88 saved-pos (cdr (car stack))
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.
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))
108 (defmacro c-bos-save-error-info (missing got)
109 `(setq saved-pos (vector pos ,missing ,got)))
110 (defmacro c-bos-report-error ()
112 (setq c-parsing-error
113 (format "No matching `%s' found for `%s' on line %d"
116 (1+ (count-lines (point-min)
117 (c-point 'bol (elt saved-pos 0))))))))
119 (defun c-beginning-of-statement-1 (&optional lim ignore-labels
121 "Move to the start of the current statement or declaration, or to
122 the previous one if already at the beginning of one. Only
123 statements/declarations on the same level are considered, i.e. don't
124 move into or out of sexps (not even normal expression parentheses).
126 Stop at statement continuations like \"else\", \"catch\", \"finally\"
127 and the \"while\" in \"do ... while\" if the start point is within
128 them. If starting at such a continuation, move to the corresponding
129 statement start. If at the beginning of a statement, move to the
130 closest containing statement if there is any. This might also stop at
131 a continuation clause.
133 Labels are treated as separate statements if IGNORE-LABELS is non-nil.
134 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
136 on e.g. inherit colons, so IGNORE-LABELS should be used then. There
137 should be no such mistakes in a statement context, however.
139 Macros are ignored unless point is within one, in which case the
140 content of the macro is treated as normal code. Aside from any normal
141 statement starts found in it, stop at the first token of the content
142 in the macro, i.e. the expression of an \"#if\" or the start of the
143 definition in a \"#define\". Also stop at start of macros before
146 Return 'label if stopped at a label, 'same if stopped at the beginning
147 of the current statement, 'up if stepped to a containing statement,
148 'previous if stepped to a preceding statement, 'beginning if stepped
149 from a statement continuation clause to its start clause, or 'macro if
150 stepped to a macro start. Note that 'same and not 'label is returned
151 if stopped at the same label without crossing the colon character.
153 LIM may be given to limit the search. If the search hits the limit,
154 point will be left at the closest following token, or at the start
155 position if that is less ('same is returned in this case).
157 NOERROR turns off error logging to `c-parsing-error'.
159 Normally only ';' is considered to delimit statements, but if
160 COMMA-DELIM is non-nil then ',' is treated likewise."
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.
165 ;; Note: The position of a boundary is the following token.
167 ;; Begin with current token, stop when stack is empty and the
168 ;; position has been moved.
171 ;; "else": Push state, goto state `else':
172 ;; boundary: Goto state `else-boundary':
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':
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':
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.
192 ;; In addition to the above there is some special handling of labels
195 (let ((case-fold-search nil)
198 (delims (if comma-delim '(?\; ?,) '(?\;)))
199 (c-stmt-delim-chars (if comma-delim
200 c-stmt-delim-chars-with-comma
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.
213 tok ptok pptok ; Pos of last three sexps or bounds.
214 c-in-literal-cache c-maybe-labelp saved)
217 (if lim (narrow-to-region lim (point-max)))
220 (and (c-beginning-of-macro)
222 (setq macro-start (point)))
224 ;; Try to skip over unary operator characters, to register
228 (c-backward-syntactic-ws)
229 (/= (skip-chars-backward "-+!*&~@`#") 0)))
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)
238 (c-backward-syntactic-ws)
239 (or (memq (char-before) delims)
240 (memq (char-before) '(?: nil))
241 (eq (char-syntax (char-before)) ?\())))
245 ;; Begin at start and not pos to detect macros if we stand
246 ;; directly after the #.
248 (if (looking-at "\\<\\|\\W")
249 ;; Record this as the first token if not starting inside it.
253 (catch 'loop ;; Throw nil to break, non-nil to continue.
255 ;; Check for 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)))
263 (not (eq (char-before (1- (point))) ?\\)))
264 (progn (skip-chars-forward " \t")
265 (eq (point) saved))))
267 (if (and (c-forward-to-cpp-define-body)
268 (progn (c-forward-syntactic-ws start)
270 ;; Stop at the first token in the content of the macro.
272 ignore-labels t) ; Avoid the label check on exit.
278 ;; Do a round through the automaton if we found a
279 ;; boundary or if looking at a statement keyword.
281 (and (looking-at cond-key)
282 (setq sym (intern (match-string 1)))))
284 (when (and (< pos start) (null stack))
287 ;; The state handling. Continue in the common state for
291 (if (eq sym 'boundary)
292 (setq state 'else-boundary)
294 (c-bos-pop-state-and-retry)))
296 ((eq state 'else-boundary)
298 (c-bos-pop-state (setq ret 'beginning)))
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)))
314 ((eq state 'while-boundary)
316 (c-bos-pop-state (setq ret 'beginning)))
322 (if (eq sym 'boundary)
323 (setq state 'catch-boundary)
325 (c-bos-pop-state-and-retry)))
327 ((eq state 'catch-boundary)
330 (c-bos-pop-state (setq ret 'beginning)))
335 (c-bos-pop-state)))))
337 ;; This is state common.
338 (cond ((eq sym 'boundary)
344 (c-bos-save-error-info 'if 'else)
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.
354 (setq state 'while)))
355 ((memq sym '(catch finally))
357 (c-bos-save-error-info 'try sym)
358 (setq state 'catch))))
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
366 c-maybe-labelp nil))))
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)
374 (or (c-safe (goto-char (scan-sexps (point) -1)) t)
376 (cond ((looking-at "\\\\$")
377 ;; Step again if we hit a line continuation.
380 ;; If we started inside a macro then this
381 ;; sexp is always interesting.
384 ;; Otherwise check that we didn't step
385 ;; into a macro from the end.
388 (and (c-beginning-of-macro)
391 (goto-char macro-start)
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.
403 (setq boundary-pos (c-crosses-statement-barrier-p
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
420 (when (and c-opt-method-key
421 (setq saved (c-in-method-def-p)))
423 ignore-labels t) ; Avoid the label check on exit.
430 pos tok))) ; Not nil.
432 ;; If the stack isn't empty there might be errors to report.
434 (if (and (vectorp saved-pos) (eq (length saved-pos) 3))
435 (c-bos-report-error))
436 (setq saved-pos (cdr (car stack))
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)
446 (cond ((> start saved) (setq pos saved))
447 ((= start saved) (setq ret 'up)))))
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
452 (if (< after-labels-pos start)
453 (setq pos after-labels-pos)
455 (if (< last-label-pos start)
456 (setq pos last-label-pos)))))
458 ;; Skip over the unary operators that can start the statement.
461 (c-backward-syntactic-ws)
462 (/= (skip-chars-backward "-+!*&~@`#") 0))
467 (defun c-crosses-statement-barrier-p (from to)
468 "Return non-nil if buffer positions FROM to TO cross one or more
469 statement or declaration boundaries. The returned value is actually
470 the position of the earliest boundary char.
472 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
474 single `?' is found, then `c-maybe-labelp' is cleared."
475 (let ((skip-chars c-stmt-delim-chars)
480 (while (progn (skip-chars-forward skip-chars to)
482 (if (setq lit-range (c-literal-limits from))
483 (goto-char (setq from (cdr lit-range)))
484 (cond ((eq (char-after) ?:)
486 (if (and (eq (char-after) ?:)
488 ;; Ignore scope operators.
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))))))
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)
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)
512 (defsubst c-query-macro-start ()
513 (if (symbolp c-macro-start)
515 (and (c-beginning-of-macro)
519 (defun c-beginning-of-macro (&optional lim)
520 "Go to the beginning of a cpp macro definition.
521 Leave point at the beginning of the macro and return t if in a cpp
522 macro definition, otherwise return nil and leave point unchanged."
523 (let ((here (point)))
525 (if lim (narrow-to-region lim (point-max)))
527 (while (eq (char-before (1- (point))) ?\\)
529 (back-to-indentation)
530 (if (and (<= (point) here)
531 (looking-at "#[ \t]*[a-zA-Z0-9!]"))
536 (defun c-end-of-macro ()
537 "Go to the end of a cpp macro definition.
538 More accurately, move point to the end of the closest following line
539 that doesn't end with a line continuation backslash."
542 (when (and (eq (char-before) ?\\)
547 (defun c-forward-comment (count)
548 ;; Insulation from various idiosyncrasies in implementations of
549 ;; `forward-comment'.
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.)
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)))
564 (when (forward-comment count)
566 ;; Some emacsen (e.g. XEmacs 21) return t when moving
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)))
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")
584 ;; Some emacsen return t when moving backwards at bob.
586 (re-search-forward "[\n\r]" here t)
587 (let* ((res (if (forward-comment count)
588 (if (eolp) (forward-comment -1) t)))
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) ?\\))
600 (defun c-forward-comment-lc (count)
601 ;; Like `c-forward-comment', but treat line continuations as
605 (while (if (c-forward-comment 1)
607 (setq count (1- count))
609 (if (looking-at "\\\\$")
614 (while (if (c-forward-comment -1)
616 (setq count (1+ count))
618 (if (and (eolp) (eq (char-before) ?\\))
622 (throw 'done nil)))))
625 (defun c-forward-syntactic-ws (&optional lim)
626 "Forward skip of syntactic whitespace.
627 Syntactic whitespace is defined as whitespace characters, comments,
628 and preprocessor directives. However if point starts inside a comment
629 or preprocessor directive, the content of it is not treated as
630 whitespace. LIM sets an upper limit of the forward movement, if
632 (let ((here (point-max)))
633 (or lim (setq lim here))
634 (while (/= here (point))
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))
640 ;; Skip line continuations.
641 ((looking-at "\\\\$")
643 ;; Skip preprocessor directives.
644 ((and (looking-at "#[ \t]*[a-zA-Z0-9!]")
645 (progn (skip-chars-backward " \t")
648 (while (and (<= (point) lim)
649 (eq (char-before) ?\\)
650 (= (forward-line 1) 0))
652 (when (> (point) lim)
653 ;; Don't move past the macro if that'd take us past the limit.
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))))
660 (defun c-backward-syntactic-ws (&optional lim)
661 "Backward skip of syntactic whitespace.
662 Syntactic whitespace is defined as whitespace characters, comments,
663 and preprocessor directives. However if point starts inside a comment
664 or preprocessor directive, the content of it is not treated as
665 whitespace. LIM sets a lower limit of the backward movement, if
667 (let ((start-line (c-point 'bol))
671 (or lim (setq lim here))
672 (while (/= here (point))
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))
680 (eq (char-before) ?\\)
681 (if (<= prev-pos (c-point 'eonl))
683 ;; Passed a line continuation, but not from the line we
686 (setq line-cont nil)))
690 (when (eq line-cont 'maybe)
693 (setq line-cont (eq (char-before) ?\\))))
695 (and (< (point) start-line)
696 (c-beginning-of-macro))))
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
702 (setq line-cont nil))
703 ;; Skip in-comment line continuations (used for Pike refdoc).
704 ((and c-opt-in-comment-lc
706 (and (c-safe (beginning-of-line)
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))))
714 (defun c-forward-token-1 (&optional count balanced lim)
715 "Move forward by tokens.
716 A token is defined as all symbols and identifiers which aren't
717 syntactic whitespace \(note that e.g. \"->\" is considered to be two
718 tokens). Point is always either left at the beginning of a token or
719 not moved at all. COUNT specifies the number of tokens to move; a
720 negative COUNT moves in the opposite direction. A COUNT of 0 moves to
721 the next token beginning only if not already at one. If BALANCED is
722 true, move over balanced parens, otherwise move into them. Also, if
723 BALANCED is true, never move out of an enclosing paren. LIM sets the
724 limit for the movement and defaults to the point limit.
726 Return the number of tokens left to move \(positive or negative). If
727 BALANCED is true, a move over a balanced paren counts as one. Note
728 that if COUNT is 0 and no appropriate token beginning is found, 1 will
729 be returned. Thus, a return value of 0 guarantees that point is at
730 the requested position and a return value less \(without signs) than
731 COUNT guarantees that point is at the beginning of some token."
732 (or count (setq count 1))
734 (- (c-backward-token-1 (- count) balanced lim))
735 (let ((jump-syntax (if balanced
736 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
737 '(?w ?_ ?\" ?\\ ?/ ?')))
741 (if lim (narrow-to-region (point-min) lim))
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.
747 (setq count (max (1- count) 0))))
749 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
750 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
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.
758 ;; Avoid having the limit tests inside the loop.
763 (if (memq (char-syntax (char-after)) jump-syntax)
764 (goto-char (scan-sexps (point) 1))
766 (c-forward-syntactic-ws)
767 (setq count (1- count)))
768 (error (goto-char last)))
771 (setq count (1+ count)))))
774 (defun c-backward-token-1 (&optional count balanced lim)
775 "Move backward by tokens.
776 See `c-forward-token-1' for details."
777 (or count (setq count 1))
779 (- (c-forward-token-1 (- count) balanced lim))
780 (let ((jump-syntax (if balanced
781 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
782 '(?w ?_ ?\" ?\\ ?/ ?')))
785 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
786 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
789 (c-forward-syntactic-ws (1+ lim))
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.
797 (if lim (narrow-to-region lim (point-max)))
800 ;; Avoid having the limit tests inside the loop.
805 (c-backward-syntactic-ws)
806 (if (memq (char-syntax (char-before)) jump-syntax)
807 (goto-char (scan-sexps (point) -1))
809 (setq count (1- count)))
810 (error (goto-char last)))
811 (if (bobp) (goto-char last)))))
814 (defun c-syntactic-re-search-forward (regexp &optional bound noerror count
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))
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)
838 ;; Match inside a string. Skip to the end of it
839 ;; before continuing.
840 (let ((ender (make-string 1 (nth 3 state))))
842 (search-forward ender bound noerror)
843 (setq state (parse-partial-sexp pos (point)
848 ;; Match inside a line comment. Skip to eol. Use
849 ;; re-search-forward for it to get the right bound
851 (re-search-forward "[\n\r]" bound noerror))
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.
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)
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
869 (setq bound (point))))
872 (setq count (1- count)))))
875 (signal (car err) (cdr err))))
878 (goto-char match-pos)
880 ;; Search failed. Set point as appropriate.
881 (cond ((eq noerror t)
884 (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1)
891 (defun c-in-literal (&optional lim detect-cpp)
892 "Return the type of literal point is in, if any.
893 The return value is `c' if in a C-style comment, `c++' if in a C++
894 style comment, `string' if in a string literal, `pound' if DETECT-CPP
895 is non-nil and on a preprocessor line, or nil if somewhere else.
896 Optional LIM is used as the backward limit of the search. If omitted,
897 or nil, `c-beginning-of-defun' is used.
899 The 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."
901 (if (and (vectorp c-in-literal-cache)
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)))
906 (state (parse-partial-sexp lim (point))))
908 ((nth 3 state) 'string)
909 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
910 ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
912 ;; cache this result if the cache is enabled
913 (if (not c-in-literal-cache)
914 (setq c-in-literal-cache (vector (point) rtn)))
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
919 ;; complicated anyway. In this case, lim is only used to detect
921 (defun c-fast-in-literal (&optional lim detect-cpp)
922 (let ((context (buffer-syntactic-context)))
924 ((eq context 'string) 'string)
925 ((eq context 'comment) 'c++)
926 ((eq context 'block-comment) 'c)
927 ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound))))
929 (if (fboundp 'buffer-syntactic-context)
930 (defalias 'c-in-literal 'c-fast-in-literal))
932 (defun c-literal-limits (&optional lim near not-in-delimiter)
933 "Return a cons of the beginning and end positions of the comment or
934 string surrounding point (including both delimiters), or nil if point
935 isn't in one. If LIM is non-nil, it's used as the \"safe\" position
936 to start parsing from. If NEAR is non-nil, then the limits of any
937 literal 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
939 done first in forward direction. If NOT-IN-DELIMITER is non-nil, the
940 case when point is inside a starting delimiter won't be recognized.
941 This only has effect for comments, which have starting delimiters with
942 more than one character."
945 (lim (or lim (c-point 'bod)))
946 (state (parse-partial-sexp lim (point))))
948 ;; String. Search backward for the start.
950 (search-backward (make-string 1 (nth 3 state)))
951 (setq state (parse-partial-sexp lim (point))))
952 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
955 ;; Line comment. Search from bol for the comment starter.
957 (setq state (parse-partial-sexp 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)
965 (cons (point) (progn (c-forward-comment 1) (point))))
967 ;; Block comment. Search backward for the comment starter.
969 (search-backward "/*") ; Should never fail.
970 (setq state (parse-partial-sexp lim (point))))
971 (cons (point) (progn (c-forward-comment 1) (point))))
972 ((and (not not-in-delimiter)
974 (eq (char-before) ?/)
976 ;; We're standing in a comment starter.
978 (cons (point) (progn (c-forward-comment 1) (point))))
981 ;; Search forward for a literal.
982 (skip-chars-forward " \t")
984 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
985 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
987 ((looking-at "/[/*]") ; Line or block comment.
988 (cons (point) (progn (c-forward-comment 1) (point))))
991 (skip-chars-backward " \t")
992 (let ((end (point)) beg)
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)
998 ;; Block comment. Due to the nature of line
999 ;; comments, they will always be covered by the
1000 ;; normal case above.
1002 (c-forward-comment -1)
1003 ;; If LIM is bogus, beg will be bogus.
1004 (setq beg (point))))
1005 (if beg (cons beg end))))))
1008 (defun c-literal-limits-fast (&optional lim near not-in-delimiter)
1009 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
1010 ;; returns the pos of the comment start.
1012 (let* ((pos (point))
1013 (lim (or lim (c-point 'bod)))
1014 (state (parse-partial-sexp lim (point))))
1015 (cond ((nth 3 state) ; String.
1016 (goto-char (nth 8 state))
1017 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
1019 ((nth 4 state) ; Comment.
1020 (goto-char (nth 8 state))
1021 (cons (point) (progn (c-forward-comment 1) (point))))
1022 ((and (not not-in-delimiter)
1024 (eq (char-before) ?/)
1025 (looking-at "[/*]"))
1026 ;; We're standing in a comment starter.
1028 (cons (point) (progn (c-forward-comment 1) (point))))
1031 ;; Search forward for a literal.
1032 (skip-chars-forward " \t")
1034 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
1035 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
1037 ((looking-at "/[/*]") ; Line or block comment.
1038 (cons (point) (progn (c-forward-comment 1) (point))))
1041 (skip-chars-backward " \t")
1042 (let ((end (point)) beg)
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)
1048 ;; Block comment. Due to the nature of line
1049 ;; comments, they will always be covered by the
1050 ;; normal case above.
1052 (c-forward-comment -1)
1053 ;; If LIM is bogus, beg will be bogus.
1054 (setq beg (point))))
1055 (if beg (cons beg end))))))
1058 (if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8))
1059 (defalias 'c-literal-limits 'c-literal-limits-fast))
1061 (defun c-collect-line-comments (range)
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,
1064 then an extended range is returned that contains all adjacent line
1065 comments (i.e. all comments that starts in the same column with no
1066 empty lines or non-whitespace characters between them). Otherwise the
1067 argument is returned."
1070 (if (and (consp range) (progn
1071 (goto-char (car range))
1073 (let ((col (current-column))
1075 (bopl (c-point 'bopl))
1077 ;; Got to take care in the backward direction to handle
1078 ;; comments which are preceded by code.
1079 (while (and (c-forward-comment -1)
1082 (= col (current-column)))
1084 bopl (c-point 'bopl)))
1086 (while (and (progn (skip-chars-forward " \t")
1088 (= col (current-column))
1089 (prog1 (zerop (forward-line 1))
1090 (setq end (point)))))
1095 (defun c-literal-type (range)
1096 "Convenience function that given the result of `c-literal-limits',
1097 returns nil or the type of literal that the range surrounds. It's
1098 much faster than using `c-in-literal' and is intended to be used when
1099 you need both the type of a literal and its limits."
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.
1110 ;; utilities for moving and querying around syntactic elements
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
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.
1127 (defun c-parse-state ()
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.
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
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.
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))))))))
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.)
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
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
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)
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)))
1206 (goto-char (car (car c-state-cache)))
1207 (when (c-beginning-of-macro)
1209 c-state-cache (cdr c-state-cache)))))
1211 (setq old-state c-state-cache)
1214 ;; go back 2 bods, but ignore any bogus positions
1215 ;; returned by beginning-of-defun (i.e. open paren in
1219 (while (not (or (bobp) (zerop cnt)))
1220 (c-beginning-of-defun-1)
1221 (if (eq (char-after) ?\{)
1222 (setq cnt (1- cnt)))))
1224 (narrow-to-region (point-min) here)
1226 ;; Find the balanced brace pairs.
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.
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)))
1250 ;; Prepare to loop, but record the open paren only if it's
1251 ;; outside a macro or within the same macro as point.
1254 (if (or (>= last-pos in-macro-start)
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.
1264 (setq pos (c-up-list-backward pos)
1269 (format "Unbalanced close paren at line %d"
1270 (1+ (count-lines (point-min)
1271 (c-point 'bol last-pos)))))))
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"
1288 (defun c-toggle-parse-state-debug (&optional arg)
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))
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.
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)
1308 (while (and c-state-cache
1309 (let ((elem (car c-state-cache)))
1311 (or (<= beg (car elem))
1314 (setq c-state-cache (cdr c-state-cache)))))
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))
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))))
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.
1336 (let ((car (car paren-state)))
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
1342 (if (<= bufpos (car car))
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
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)))
1357 ;; it's before bufpos, so everything else should too.
1358 (throw 'done paren-state)))
1359 (setq paren-state (cdr paren-state)))
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.
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 "^:"))))
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 [+-].
1379 (and c-opt-method-key
1380 (looking-at c-opt-method-key)
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.
1388 ;; This should be called with point inside an argument list.
1390 ;; Only one level of enclosing parentheses is considered, so for
1391 ;; instance `nil' is returned when in a function call within an asm
1394 (and c-opt-asm-stmt-key
1397 (backward-up-list 1)
1398 (c-beginning-of-statement-1 (point-min) nil t)
1399 (looking-at c-opt-asm-stmt-key))))
1401 (defun c-at-toplevel-p ()
1402 "Return a determination as to whether point is at the `top-level'.
1403 Being at the top-level means that point is either outside any
1404 enclosing block (such function definition), or inside a class,
1405 namespace or extern definition, but outside any method blocks.
1407 If point is not at the top-level (e.g. it is inside a method
1408 definition), then nil is returned. Otherwise, if point is at a
1409 top-level not enclosed within a class definition, t is returned.
1410 Otherwise, a 2-vector is returned where the zeroth element is the
1411 buffer position of the start of the class declaration, and the first
1412 element is the buffer position of the enclosing class's opening
1414 (let ((paren-state (c-parse-state)))
1415 (or (not (c-most-enclosing-brace paren-state))
1416 (c-search-uplist-for-classkey paren-state))))
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
1425 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
1426 "\\([ \t]\\|\\\\\n\\)*"))
1427 (not (= (match-end 0) (c-point 'eol))))
1428 (goto-char (match-end 0))))
1430 (defun c-just-after-func-arglist-p (&optional containing lim)
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
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.
1439 ;; Note: This test is easily fooled. It only works reasonably well
1440 ;; in the situations where `c-guess-basic-syntax' uses it.
1442 (c-backward-syntactic-ws lim)
1443 (let ((checkpoint (or containing (point))))
1444 (goto-char checkpoint)
1445 ;; could be looking at const specifier
1446 (if (and (eq (char-before) ?t)
1448 (looking-at "\\<const\\>[^_]"))
1449 (c-backward-syntactic-ws lim)
1450 ;; otherwise, we could be looking at a hanging member init
1452 (goto-char checkpoint)
1453 (while (eq (char-before) ?,)
1454 ;; this will catch member inits with multiple
1457 (c-backward-syntactic-ws (c-point 'bol))
1458 (if (eq (char-before) ?\))
1460 (c-backward-sexp 1))
1461 (c-backward-syntactic-ws lim))
1462 (if (and (eq (char-before) ?:)
1465 (c-backward-syntactic-ws lim)
1466 (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)")))
1468 (goto-char checkpoint))
1470 (setq checkpoint (point))
1471 (and (eq (char-before) ?\))
1472 ;; Check that it isn't a cpp expression, e.g. the
1473 ;; expression of an #if directive or the "function header"
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)
1481 (goto-char checkpoint)
1484 (c-backward-syntactic-ws lim)
1485 (not (or (memq (char-before) '(?- ?+))
1486 ;; or a class category
1489 (looking-at c-class-key))
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.
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'.
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
1509 (if lim (narrow-to-region lim (point)))
1511 (and (c-safe (setq paren-end (c-down-list-backward (point))))
1512 (eq (char-after paren-end) ?\))
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))
1520 (defun c-skip-conditional ()
1521 ;; skip forward over conditional at point, including any predicate
1522 ;; statements in parentheses. No error checking is performed.
1523 (c-forward-sexp (cond
1525 ((looking-at (concat "\\<else"
1526 "\\([ \t\n]\\|\\\\\n\\)+"
1527 "if\\>\\([^_]\\|$\\)"))
1529 ;; do, else, try, finally
1530 ((looking-at (concat "\\<\\("
1531 "do\\|else\\|try\\|finally"
1532 "\\)\\>\\([^_]\\|$\\)"))
1534 ;; for, if, while, switch, catch, synchronized, foreach
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.
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)))
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
1554 (unless (= (point) (c-point 'boi))
1555 (let ((start (c-after-conditional lim)))
1557 (goto-char start)))))
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
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.
1569 (if lim (narrow-to-region lim (point-max)))
1571 (c-backward-syntactic-ws)
1572 (c-safe (goto-char (scan-sexps (point) -1)) t))
1573 (not (c-crosses-statement-barrier-p (point) pos)))
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
1587 (while (and (c-syntactic-re-search-forward "[;{=]" nil 'move 1 t)
1588 ;; In Pike it can be an operator identifier containing
1590 (c-major-mode-is 'pike-mode)
1591 (eq (char-before) ?=)
1592 (c-on-identifier)))))
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.
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.
1609 (let* ((start (point))
1610 (last-stmt-start (point))
1611 (move (c-beginning-of-statement-1 lim t t)))
1613 (while (and (/= last-stmt-start (point))
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)
1621 move (c-beginning-of-statement-1 lim t t)))
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
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)
1636 (goto-char knr-argdecl-start)
1637 (not (eq (c-beginning-of-statement-1 lim t t) 'macro))))
1639 (cons (if (eq (char-after fallback-pos) ?{)
1643 (goto-char fallback-pos))))
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)
1654 (throw 'return (cons 'same nil)))))
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
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))))))
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.
1687 (let ((start (point))
1688 (decl-syntax-table (if (c-major-mode-is 'c++-mode)
1689 c++-template-syntax-table
1692 (c-search-decl-header-end)
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
1701 (c-syntactic-re-search-forward "{" nil 'move 1 t))
1703 (when (eq (char-before) ?{)
1704 ;; Encountered a block in the declaration. Jump over it.
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)
1711 (c-with-syntax-table decl-syntax-table
1712 (let ((lim (point)))
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
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) ?{)))))))
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.
1732 (c-with-syntax-table decl-syntax-table
1734 (if (eq (char-before) ?\;)
1736 (c-syntactic-re-search-forward ";" nil 'move 1 t))))
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.
1743 (setq limit (point-min)))
1744 (skip-chars-forward " \t")
1745 (if (eq (char-after) ?,)
1747 (c-backward-syntactic-ws limit))
1748 (while (and (< limit (point))
1749 (eq (char-before) ?,))
1750 ;; this will catch member inits with multiple
1753 (c-backward-syntactic-ws limit)
1754 (if (eq (char-before) ?\))
1755 (c-backward-sexp 1))
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)))
1762 (c-backward-syntactic-ws limit)
1763 ;; Skip backwards over a fully::qualified::name.
1764 (while (and (eq (char-before) ?:)
1767 (eq (char-before) ?:)))
1769 (c-backward-sexp 1))
1770 ;; now continue checking
1771 (c-backward-syntactic-ws limit))
1772 (and (< limit (point))
1773 (eq (char-before) ?:)))
1775 (defun c-search-uplist-for-classkey (paren-state)
1776 ;; search for the containing class, returning a 2 element vector if
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.
1779 (if (null paren-state)
1780 ;; no paren-state means we cannot be inside a class
1782 (let ((carcache (car paren-state))
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
1789 (setq search-start (nth 2 paren-state)
1790 search-end (nth 1 paren-state))
1791 ;; if the car was not a cons cell then nth 0 and nth 1 define
1792 ;; for us the search boundaries
1793 (setq search-start (nth 1 paren-state)
1794 search-end (nth 0 paren-state)))
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) ?{)))
1801 ;; now, we need to look more closely at search-start. if
1802 ;; search-start is nil, then our start boundary is really
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
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
1816 (goto-char search-start)
1817 (let (foundp class match-end)
1818 (while (and (not foundp)
1820 (c-forward-syntactic-ws search-end)
1821 (> search-end (point)))
1822 (re-search-forward c-decl-block-key search-end t))
1823 (setq class (match-beginning 0)
1824 match-end (match-end 0))
1826 (if (c-in-literal search-start)
1827 (goto-char match-end) ; its in a comment or string, ignore
1829 (setq foundp (vector (c-point 'boi) search-end))
1831 ;; check for embedded keywords
1832 ((let ((char (char-after (1- class))))
1834 (memq (char-syntax char) '(?w ?_))))
1835 (goto-char match-end)
1837 ;; make sure we're really looking at the start of a
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)
1841 (not (c-in-literal class)))
1843 ;; Check if this is an anonymous inner class.
1844 ((and c-opt-inexpr-class-key
1845 (looking-at c-opt-inexpr-class-key))
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.
1851 ;; False alarm; all conditions aren't satisfied.
1853 ;; Its impossible to define a regexp for this, and
1854 ;; nearly so to do it programmatically.
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
1865 (skip-chars-backward "^<>" search-start)
1866 (if (eq (char-before) ?<)
1867 (setq skipchars (concat skipchars ">"))))
1869 (skip-chars-forward skipchars search-end)
1870 (c-in-literal class))
1872 (/= (point) search-end))
1878 (defun c-inside-bracelist-p (containing-sexp paren-state)
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
1882 ;; paren. BRACE-STATE is the remainder of the state of enclosing
1885 ;; N.B.: This algorithm can potentially get confused by cpp macros
1886 ;; places in inconvenient locations. Its a trade-off we make for
1889 ;; this will pick up enum lists
1892 (goto-char containing-sexp)
1895 (if (and (or (looking-at "enum\\>[^_]")
1896 (progn (c-forward-sexp -1)
1897 (looking-at "enum\\>[^_]")))
1898 (setq bracepos (c-down-list-forward (point)))
1899 (not (c-crosses-statement-barrier-p (point)
1902 ;; this will pick up array/aggregate init lists, even if they are nested.
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)
1909 bufpos braceassignp lim next-containing)
1910 (while (and (not bufpos)
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)))
1918 (setq next-containing (car paren-state)
1919 paren-state (cdr paren-state))))
1920 (goto-char containing-sexp)
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.
1926 (setq containing-sexp nil)
1927 ;; see if the open brace is preceded by = or [...] in
1928 ;; this statement, but watch out for operator=
1929 (setq braceassignp 'dontknow)
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"
1937 (while (eq braceassignp 'dontknow)
1939 (cond ((/= (c-backward-token-1 1 t lim) 0) nil)
1940 ((looking-at "new\\>[^_]") t)
1941 ((looking-at "\\sw\\|\\s_\\|[.[]")
1942 ;; Carry on looking if this is an
1943 ;; identifier (may contain "." in Java)
1944 ;; or another "[]" sexp.
1947 ;; Checks to do on all sexps before the brace, up to the
1948 ;; beginning of the statement.
1949 (while (eq braceassignp 'dontknow)
1950 (cond ((eq (char-after) ?\;)
1951 (setq braceassignp nil))
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)))
1963 ;; Check for operator =
1964 ((looking-at "operator\\>[^_]") nil)
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) ?`))))
1974 ((looking-at "\\s.") 'maybe)
1975 ;; make sure we're not in a C++ template
1976 ;; argument assignment
1978 (c-major-mode-is 'c++-mode)
1980 (let ((here (point))
1982 (skip-chars-backward "^<>")
1984 (and (eq (char-before) ?<)
1985 (not (c-crosses-statement-barrier-p
1987 (not (c-in-literal))
1991 (if (and (eq braceassignp 'dontknow)
1992 (/= (c-backward-token-1 1 t lim) 0))
1993 (setq braceassignp nil)))
1994 (if (not braceassignp)
1995 (if (eq (char-after) ?\;)
1996 ;; Brace lists can't contain a semicolon, so we're done.
1997 (setq containing-sexp nil)
1999 (setq containing-sexp next-containing
2001 next-containing nil))
2002 ;; we've hit the beginning of the aggregate list
2003 (c-beginning-of-statement-1
2004 (c-most-enclosing-brace paren-state))
2005 (setq bufpos (point))))
2010 (defun c-looking-at-special-brace-list (&optional lim)
2011 ;; If we're looking at the start of a pike-style list, ie `({Â })',
2012 ;; `([Â ])', `(<Â >)' etc, a cons of a cons of its starting and ending
2013 ;; positions and its entry in c-special-brace-lists is returned, nil
2014 ;; otherwise. The ending position is nil if the list is still open.
2015 ;; LIM is the limit for forward search. The point may either be at
2016 ;; the `(' or at the following paren character. Tries to check the
2017 ;; matching closer, but assumes it's correct if no balanced paren is
2018 ;; found (i.e. the case `({ ... } ... )' is detected as _not_ being
2019 ;; a special brace list).
2020 (if c-special-brace-lists
2025 (c-forward-syntactic-ws)
2026 (if (eq (char-after) ?\()
2029 (c-forward-syntactic-ws)
2030 (setq type (assq (char-after) c-special-brace-lists)))
2031 (if (setq type (assq (char-after) c-special-brace-lists))
2033 (c-backward-syntactic-ws)
2035 (setq beg (if (eq (char-after) ?\()
2039 (if (and (c-safe (goto-char beg)
2042 (= (char-before) ?\)))
2043 (c-safe (goto-char beg)
2046 ;; Kludges needed to handle inner
2047 ;; chars both with and without
2049 (or (/= (char-syntax (char-before)) ?\))
2050 (= (char-before) (cdr type)))))
2051 (if (or (/= (char-syntax (char-before)) ?\))
2053 (c-forward-syntactic-ws)
2056 (cons (cons beg end) type))
2057 (cons (list beg) type)))))
2060 (defun c-looking-at-bos (&optional lim)
2061 ;; Return non-nil if between two statements or declarations, assuming
2062 ;; point is not inside a literal or comment.
2064 (c-backward-syntactic-ws lim)
2066 ;; Return t if at the start inside some parenthesis expression
2067 ;; too, to catch macros that have statements as arguments.
2068 (memq (char-before) '(?\; ?} ?\())
2069 (and (eq (char-before) ?{)
2070 (not (and c-special-brace-lists
2071 (progn (backward-char)
2072 (c-looking-at-special-brace-list))))))))
2074 (defun c-looking-at-inexpr-block (lim containing-sexp)
2075 ;; Returns non-nil if we're looking at the beginning of a block
2076 ;; inside an expression. The value returned is actually a cons of
2077 ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
2078 ;; position of the beginning of the construct. LIM limits the
2079 ;; backward search. CONTAINING-SEXP is the start position of the
2080 ;; closest containing list. If it's nil, the containing paren isn't
2081 ;; used to decide whether we're inside an expression or not. If
2082 ;; both LIM and CONTAINING-SEXP is used, LIM needs to be farther
2085 (let ((res 'maybe) passed-bracket
2086 (closest-lim (or containing-sexp lim (point-min)))
2087 ;; Look at the character after point only as a last resort
2088 ;; when we can't disambiguate.
2089 (block-follows (and (eq (char-after) ?{) (point))))
2090 (while (and (eq res 'maybe)
2091 (progn (c-backward-syntactic-ws)
2092 (> (point) closest-lim))
2094 (progn (backward-char)
2095 (looking-at "[\]\).]\\|\\w\\|\\s_"))
2096 (progn (forward-char)
2097 (goto-char (scan-sexps (point) -1))))
2101 c-opt-inexpr-class-key
2102 (looking-at c-opt-inexpr-class-key))
2103 (and (not passed-bracket)
2104 (or (not (looking-at c-class-key))
2105 ;; If the class definition is at the start of
2106 ;; a statement, we don't consider it an
2107 ;; in-expression class.
2108 (let ((prev (point)))
2110 (= (c-backward-token-1 1 nil closest-lim) 0)
2111 (eq (char-syntax (char-after)) ?w))
2112 (setq prev (point)))
2114 (not (c-looking-at-bos)))
2115 ;; Also, in Pike we treat it as an
2116 ;; in-expression class if it's used in an
2117 ;; object clone expression.
2119 (and (c-major-mode-is 'pike-mode)
2120 (progn (goto-char block-follows)
2121 (= (c-forward-token-1 1 t) 0))
2122 (eq (char-after) ?\())))
2123 (cons 'inexpr-class (point))))
2124 ((and c-opt-inexpr-block-key
2125 (looking-at c-opt-inexpr-block-key))
2126 (cons 'inexpr-statement (point)))
2127 ((and c-opt-lambda-key
2128 (looking-at c-opt-lambda-key))
2129 (cons 'inlambda (point)))
2130 ((and c-opt-block-stmt-key
2131 (looking-at c-opt-block-stmt-key))
2134 (if (eq (char-after) ?\[)
2135 (setq passed-bracket t))
2138 (when (and block-follows
2140 (eq (char-after containing-sexp) ?\())
2141 (goto-char containing-sexp)
2142 (if (or (save-excursion
2143 (c-backward-syntactic-ws lim)
2144 (and (> (point) (or lim (point-min)))
2146 (and c-special-brace-lists
2147 (c-looking-at-special-brace-list)))
2149 (cons 'inexpr-statement (point))))
2152 (defun c-looking-at-inexpr-block-backward (paren-state)
2153 ;; Returns non-nil if we're looking at the end of an in-expression
2154 ;; block, otherwise the same as `c-looking-at-inexpr-block'.
2155 ;; PAREN-STATE is the paren state relevant at the current position.
2157 ;; We currently only recognize a block.
2158 (let ((here (point))
2159 (elem (car-safe paren-state))
2161 (when (and (consp elem)
2162 (progn (goto-char (cdr elem))
2163 (c-forward-syntactic-ws here)
2165 (goto-char (car elem))
2166 (if (setq paren-state (cdr paren-state))
2167 (setq containing-sexp (car-safe paren-state)))
2168 (c-looking-at-inexpr-block (c-safe-position containing-sexp
2170 containing-sexp)))))
2172 (defun c-on-identifier ()
2173 "Return non-nil if we're on or directly after an identifier.
2174 Keywords are recognized and not considered identifiers."
2175 (if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_))
2176 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
2178 (skip-syntax-backward "w_")
2179 (not (looking-at c-keywords-regexp)))
2180 (if (c-major-mode-is 'pike-mode)
2181 ;; Handle the `<operator> syntax in Pike.
2183 (if (eq (char-after) ?\`) (forward-char))
2184 (skip-chars-backward "!%&*+\\-/<=>^|~")
2185 (let ((pos (point)))
2186 (cond ((memq (char-before) '(?\) ?\]))
2187 (c-safe (backward-char 2)))
2188 ((memq (char-before) '(?\( ?\[))
2189 (c-safe (backward-char 1))))
2190 (if (not (looking-at "()\\|\\[]"))
2192 (and (eq (char-before) ?\`)
2193 (looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
2196 (defun c-most-enclosing-brace (paren-state &optional bufpos)
2197 ;; Return the bufpos of the innermost enclosing brace before bufpos
2198 ;; that hasn't been narrowed out, or nil if none was found.
2200 (or bufpos (setq bufpos 134217727))
2202 (setq enclosingp (car paren-state)
2203 paren-state (cdr paren-state))
2204 (if (or (consp enclosingp)
2205 (>= enclosingp bufpos))
2206 (setq enclosingp nil)
2207 (if (< enclosingp (point-min))
2208 (setq enclosingp nil))
2209 (setq paren-state nil)))
2212 (defun c-least-enclosing-brace (paren-state &optional bufpos)
2213 ;; Return the bufpos of the outermost enclosing brace before bufpos
2214 ;; that hasn't been narrowed out, or nil if none was found.
2216 (or bufpos (setq bufpos 134217727))
2218 (setq elem (car paren-state)
2219 paren-state (cdr paren-state))
2220 (unless (or (consp elem)
2222 (if (>= elem (point-min))
2226 (defun c-safe-position (bufpos paren-state)
2227 ;; Return the closest known safe position higher up than BUFPOS, or
2228 ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is
2229 ;; nil, which is useful to find the closest limit before a given
2230 ;; limit that might be nil.
2232 (let ((c-macro-start (c-query-macro-start)) safepos)
2233 (if (and c-macro-start
2234 (< c-macro-start bufpos))
2235 ;; Make sure bufpos is outside the macro we might be in.
2236 (setq bufpos c-macro-start))
2240 (if (consp (car paren-state))
2241 (cdr (car paren-state))
2243 (if (< safepos bufpos)
2244 (throw 'done safepos)
2245 (setq paren-state (cdr paren-state))))
2246 (if (eq c-macro-start bufpos)
2247 ;; Backed up bufpos to the macro start and got outside the
2248 ;; state. We know the macro is at the top level in this case,
2249 ;; so we can use the macro start as the safe position.
2252 (defun c-narrow-out-enclosing-class (paren-state lim)
2253 ;; Narrow the buffer so that the enclosing class is hidden. Uses
2254 ;; and returns the value from c-search-uplist-for-classkey.
2255 (setq paren-state (c-whack-state-after (point) paren-state))
2258 (setq inclass-p (c-search-uplist-for-classkey paren-state))
2261 (goto-char (1+ (aref inclass-p 1)))
2262 (c-skip-ws-forward lim)
2263 ;; if point is now left of the class opening brace, we're
2264 ;; hosed, so try a different tact
2265 (if (<= (point) (aref inclass-p 1))
2267 (goto-char (1+ (aref inclass-p 1)))
2268 (c-forward-syntactic-ws lim)))
2270 ;; end point is the end of the current line
2274 ;; return the class vector
2278 ;; c-guess-basic-syntax implements the main decision tree for
2279 ;; determining the syntactic analysis of the current line of code.
2280 ;; Yes, it's huge and bloated!
2282 ;; It's useful to break out some parts of the decision tree to
2283 ;; separate functions, which are all collected below. Use dynamic
2284 ;; binding to propagate back the syntax results from them.
2286 (defvar syntactic-relpos)
2288 (defun c-add-stmt-syntax (syntax-symbol
2292 &optional at-block-start)
2293 ;; Do the generic processing to anchor the given syntax symbol on
2294 ;; the preceding statement: Skip over any labels and containing
2295 ;; statements on the same line, and then search backward until we
2296 ;; find a statement or block start that begins at boi without a
2297 ;; label or comment.
2299 ;; Point is assumed to be at the prospective anchor point for the
2300 ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to
2301 ;; skip past block opens and containing statement. All the added
2302 ;; syntax elements will get the same anchor point.
2304 ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the
2305 ;; line if another statement precedes the current one on this line.
2307 ;; If AT-BLOCK-START is non-nil, point is taken to be at the
2308 ;; beginning of a block or brace list, which then might be nested
2309 ;; inside an expression. If AT-BLOCK-START is nil, this is found
2310 ;; out by checking whether the character at point is "{" or not.
2311 (if (= (point) (c-point 'boi))
2312 ;; This is by far the most common case, so let's give it special
2314 (c-add-syntax syntax-symbol (point))
2316 (let* ((savepos (point))
2317 (syms (list syntax-symbol))
2319 (boi (c-point 'boi))
2320 (prev-paren (if at-block-start ?{ (char-after)))
2321 step-type step-tmp at-comment add-inexpr-stmt)
2323 ;; Begin by skipping any labels and containing statements that
2324 ;; are on the same line.
2325 (while (and (/= (point) boi)
2326 (if (memq (setq step-tmp
2327 (c-beginning-of-statement-1 boi nil t))
2332 (/= (point) savepos))
2333 (setq savepos (point)
2334 step-type step-tmp))
2337 ;; Loop if we have to back out of the containing block.
2340 ;; Loop if we have to back up another statement.
2344 ;; Always start by skipping over any comments that
2345 ;; stands between the statement and boi.
2346 (while (and (/= (setq savepos (point)) boi)
2347 (c-forward-comment -1))
2349 boi (c-point 'boi)))
2354 (eq step-type 'label)
2358 ;; Current position might not be good enough;
2359 ;; skip backward another statement.
2360 (setq step-type (c-beginning-of-statement-1
2363 (if (and (not stop-at-boi-only)
2365 (memq step-type '(up previous)))
2366 ;; If stop-at-boi-only is nil, we shouldn't
2367 ;; back up over previous or containing
2368 ;; statements to try to reach boi, so go
2369 ;; back to the last position and exit.
2373 (if (and (not stop-at-boi-only)
2374 (memq step-type '(up previous beginning)))
2375 ;; If we've moved into another statement
2376 ;; then we should no longer try to stop
2378 (setq stop-at-boi-only t))
2380 ;; Record this a substatement if we skipped up
2381 ;; one level, but not if we're still on the
2382 ;; same line. This so e.g. a sequence of "else
2383 ;; if" clauses won't indent deeper and deeper.
2384 (when (and (eq step-type 'up)
2386 (setcdr syms-tail (list 'substatement))
2387 (setq syms-tail (cdr syms-tail)))
2389 (setq boi (c-point 'boi))
2390 (/= (point) savepos)))))
2392 (setq savepos (point)
2394 (setq at-comment nil)
2396 (when (and (eq step-type 'same)
2398 (goto-char containing-sexp)
2399 (setq paren-state (c-whack-state-after containing-sexp
2401 containing-sexp (c-most-enclosing-brace paren-state))
2404 (when (eq (setq prev-paren (char-after)) ?\()
2405 (c-backward-syntactic-ws containing-sexp)
2406 (when (c-on-identifier)
2407 ;; Arrived at a function arglist start. Exit with
2408 ;; the position of the first argument inside it.
2411 ;; We're in an in-expression statement. Remember
2412 ;; this. We'll iterate below, but won't add any
2414 (setq add-inexpr-stmt t))
2416 (setq savepos (point)
2418 step-type (c-beginning-of-statement-1 containing-sexp))
2420 (let ((at-bod (and (eq step-type 'same)
2421 (/= savepos (point))
2422 (eq prev-paren ?{))))
2423 (when (= savepos boi)
2424 ;; If the open brace was at boi, we're always
2425 ;; done. The c-beginning-of-statement-1 call
2426 ;; above is necessary anyway, to decide the type
2427 ;; of block-intro to add.
2431 (when (eq prev-paren ?{)
2432 (setcdr syms-tail (list (if at-bod
2434 'statement-block-intro)))
2435 (setq syms-tail (cdr syms-tail)))
2437 (when (and (not at-bod) savepos)
2438 ;; Loop if the brace wasn't at boi, and we didn't
2439 ;; arrive at a defun block.
2440 (if (eq step-type 'same)
2441 ;; Avoid backing up another sexp if the point
2442 ;; we're at now is found to be good enough in
2444 (setq step-type nil))
2445 (if (and (not stop-at-boi-only)
2446 (memq step-type '(up previous beginning)))
2447 (setq stop-at-boi-only t))
2448 (setq boi (c-point 'boi)))))
2452 (c-add-syntax (car syms) (point))
2453 (setq syms (cdr syms)))
2455 (c-add-syntax 'inexpr-statement))
2458 (defun c-add-class-syntax (symbol classkey paren-state)
2459 ;; The inclass and class-close syntactic symbols are added in
2460 ;; several places and some work is needed to fix everything.
2461 ;; Therefore it's collected here.
2464 (let (inexpr anchor containing-sexp)
2465 (goto-char (aref classkey 1))
2466 (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
2467 (c-add-syntax symbol (setq anchor (point)))
2468 (c-add-syntax symbol (setq anchor (aref classkey 0)))
2469 (if (and c-opt-inexpr-class-key
2470 (setq containing-sexp (c-most-enclosing-brace paren-state
2472 inexpr (cdr (c-looking-at-inexpr-block
2473 (c-safe-position containing-sexp
2476 (/= inexpr (c-point 'boi inexpr)))
2477 (c-add-syntax 'inexpr-class)))
2480 (defun c-guess-continued-construct (indent-point
2482 beg-of-same-or-containing-stmt
2485 ;; This function contains the decision tree reached through both
2486 ;; cases 18 and 10. It's a continued statement or top level
2487 ;; construct of some kind.
2488 (let (special-brace-list)
2489 (goto-char indent-point)
2490 (skip-chars-forward " \t")
2492 ;; (CASE A removed.)
2493 ;; CASE B: open braces for class or brace-lists
2494 ((setq special-brace-list
2495 (or (and c-special-brace-lists
2496 (c-looking-at-special-brace-list))
2497 (eq char-after-ip ?{)))
2499 ;; CASE B.1: class-open
2501 (goto-char indent-point)
2502 (skip-chars-forward " \t{")
2503 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
2505 (setq beg-of-same-or-containing-stmt (aref decl 0)))
2507 (c-add-syntax 'class-open beg-of-same-or-containing-stmt))
2508 ;; CASE B.2: brace-list-open
2509 ((or (consp special-brace-list)
2511 (goto-char beg-of-same-or-containing-stmt)
2512 (looking-at "enum\\>[^_]"))
2514 (goto-char indent-point)
2515 (while (and (> (point) beg-of-same-or-containing-stmt)
2516 (= (c-backward-token-1 1 t) 0)
2517 (/= (char-after) ?=)))
2518 (eq (char-after) ?=)))
2519 ;; The most semantically accurate symbol here is
2520 ;; brace-list-open, but we report it simply as a statement-cont.
2521 ;; The reason is that one normally adjusts brace-list-open for
2522 ;; brace lists as top-level constructs, and brace lists inside
2523 ;; statements is a completely different context.
2524 (c-beginning-of-statement-1 containing-sexp)
2525 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state))
2526 ;; CASE B.3: The body of a function declared inside a normal
2527 ;; block. Can occur e.g. in Pike and when using gcc
2528 ;; extensions. Might also trigger it with some macros followed
2529 ;; by blocks, and this gives sane indentation then too.
2530 ;; C.f. cases 16F and 17G.
2532 (goto-char indent-point)
2533 (and (not (c-looking-at-bos))
2534 (eq (c-beginning-of-statement-1 containing-sexp nil nil t)
2536 (c-add-stmt-syntax 'defun-open t containing-sexp paren-state))
2537 ;; CASE B.4: Continued statement with block open.
2539 (goto-char beg-of-same-or-containing-stmt)
2540 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state)
2541 (c-add-syntax 'block-open))
2543 ;; CASE C: iostream insertion or extraction operator
2544 ((and (looking-at "<<\\|>>")
2546 (goto-char beg-of-same-or-containing-stmt)
2547 (while (and (re-search-forward "<<\\|>>" indent-point 'move)
2548 (c-in-literal beg-of-same-or-containing-stmt)))
2549 ;; if we ended up at indent-point, then the first streamop is on a
2550 ;; separate line. Indent the line like a statement-cont instead
2551 (when (/= (point) indent-point)
2552 (c-add-syntax 'stream-op (c-point 'boi))
2554 ;; CASE D: continued statement.
2556 (c-beginning-of-statement-1 containing-sexp)
2557 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state))
2560 (defun c-guess-basic-syntax ()
2561 "Return the syntactic context of the current line."
2565 (let* ((indent-point (point))
2566 (case-fold-search nil)
2567 (paren-state (c-parse-state))
2568 literal containing-sexp char-before-ip char-after-ip lim
2569 syntax placeholder c-in-literal-cache step-type
2570 tmpsymbol keyword injava-inher special-brace-list
2571 ;; narrow out any enclosing class or extern "C" block
2572 (inclass-p (c-narrow-out-enclosing-class paren-state
2574 ;; c-state-cache is shadowed here. That means we must
2575 ;; not do any changes during the execution of this
2576 ;; function, since c-check-state-cache then would change
2577 ;; this local variable and leave a bogus value in the
2579 (c-state-cache (if inclass-p
2580 (c-whack-state-before (point-min) paren-state)
2582 (c-state-cache-start (point-min))
2583 inenclosing-p macro-start in-macro-expr
2584 ;; There's always at most one syntactic element which got
2585 ;; a relpos. It's stored in syntactic-relpos.
2587 (c-stmt-delim-chars c-stmt-delim-chars))
2588 ;; check for meta top-level enclosing constructs, possible
2589 ;; extern language definitions, possibly (in C++) namespace
2596 (goto-char (aref inclass-p 0))
2597 (looking-at c-other-decl-block-key)))
2598 (let ((enclosing (match-string 1)))
2600 ((string-equal enclosing "extern")
2601 (setq inenclosing-p 'extern))
2602 ((string-equal enclosing "namespace")
2603 (setq inenclosing-p 'namespace))
2606 ;; Init some position variables:
2608 ;; containing-sexp is the open paren of the closest
2609 ;; surrounding sexp or nil if there is none that hasn't been
2612 ;; lim is the position after the closest preceding brace sexp
2613 ;; (nested sexps are ignored), or the position after
2614 ;; containing-sexp if there is none, or (point-min) if
2615 ;; containing-sexp is nil.
2617 ;; c-state-cache is the state from c-parse-state at
2618 ;; indent-point, without any parens outside the region
2619 ;; narrowed by c-narrow-out-enclosing-class.
2621 ;; paren-state is the state from c-parse-state outside
2622 ;; containing-sexp, or at indent-point if containing-sexp is
2623 ;; nil. paren-state is not limited to the narrowed region, as
2624 ;; opposed to c-state-cache.
2627 (setq containing-sexp (car paren-state)
2628 paren-state (cdr paren-state))
2629 (if (consp containing-sexp)
2631 (setq lim (cdr containing-sexp))
2632 (if (cdr c-state-cache)
2633 ;; Ignore balanced paren. The next entry
2634 ;; can't be another one.
2635 (setq containing-sexp (car (cdr c-state-cache))
2636 paren-state (cdr paren-state))
2637 ;; If there is no surrounding open paren then
2638 ;; put the last balanced pair back on paren-state.
2639 (setq paren-state (cons containing-sexp paren-state)
2640 containing-sexp nil)))
2641 (setq lim (1+ containing-sexp))))
2642 (setq lim (point-min)))
2644 ;; If we're in a parenthesis list then ',' delimits the
2645 ;; "statements" rather than being an operator (with the
2646 ;; exception of the "for" clause). This difference is
2647 ;; typically only noticeable when statements are used in macro
2649 (when (and containing-sexp
2650 (eq (char-after containing-sexp) ?\())
2651 (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
2653 ;; cache char before and after indent point, and move point to
2654 ;; the most likely position to perform the majority of tests
2655 (goto-char indent-point)
2656 (c-backward-syntactic-ws lim)
2657 (setq char-before-ip (char-before))
2658 (goto-char indent-point)
2659 (skip-chars-forward " \t")
2660 (setq char-after-ip (char-after))
2662 ;; are we in a literal?
2663 (setq literal (c-in-literal lim))
2665 ;; now figure out syntactic qualities of the current line
2667 ;; CASE 1: in a string.
2668 ((eq literal 'string)
2669 (c-add-syntax 'string (c-point 'bopl)))
2670 ;; CASE 2: in a C or C++ style comment.
2671 ((memq literal '(c c++))
2672 (c-add-syntax literal (car (c-literal-limits lim))))
2673 ;; CASE 3: in a cpp preprocessor macro continuation.
2674 ((and (save-excursion
2675 (when (c-beginning-of-macro)
2676 (setq macro-start (point))))
2677 (/= macro-start (c-point 'boi))
2679 (setq tmpsymbol 'cpp-macro-cont)
2680 (or (not c-syntactic-indentation-in-macros)
2682 (goto-char macro-start)
2683 ;; If at the beginning of the body of a #define
2684 ;; directive then analyze as cpp-define-intro
2685 ;; only. Go on with the syntactic analysis
2686 ;; otherwise. in-macro-expr is set if we're in a
2687 ;; cpp expression, i.e. before the #define body
2688 ;; or anywhere in a non-#define directive.
2689 (if (c-forward-to-cpp-define-body)
2690 (let ((indent-boi (c-point 'boi indent-point)))
2691 (setq in-macro-expr (> (point) indent-boi)
2692 tmpsymbol 'cpp-define-intro)
2693 (= (point) indent-boi))
2694 (setq in-macro-expr t)
2696 (c-add-syntax tmpsymbol macro-start)
2697 (setq macro-start nil))
2698 ;; CASE 11: an else clause?
2699 ((looking-at "else\\>[^_]")
2700 (c-beginning-of-statement-1 containing-sexp)
2701 (c-add-stmt-syntax 'else-clause t containing-sexp paren-state))
2702 ;; CASE 12: while closure of a do/while construct?
2703 ((and (looking-at "while\\>[^_]")
2705 (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
2707 (setq placeholder (point)))))
2708 (goto-char placeholder)
2709 (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state))
2710 ;; CASE 13: A catch or finally clause? This case is simpler
2711 ;; than if-else and do-while, because a block is required
2712 ;; after every try, catch and finally.
2714 (and (cond ((c-major-mode-is 'c++-mode)
2715 (looking-at "catch\\>[^_]"))
2716 ((c-major-mode-is 'java-mode)
2717 (looking-at "\\(catch\\|finally\\)\\>[^_]")))
2718 (and (c-safe (c-backward-syntactic-ws)
2721 (eq (char-after) ?{)
2722 (c-safe (c-backward-syntactic-ws)
2725 (if (eq (char-after) ?\()
2726 (c-safe (c-backward-sexp) t)
2728 (looking-at "\\(try\\|catch\\)\\>[^_]")
2729 (setq placeholder (point))))
2730 (goto-char placeholder)
2731 (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state))
2732 ;; CASE 18: A substatement we can recognize by keyword.
2734 (and c-opt-block-stmt-key
2735 (not (eq char-before-ip ?\;))
2736 (not (memq char-after-ip '(?\) ?\] ?,)))
2737 (or (not (eq char-before-ip ?}))
2738 (c-looking-at-inexpr-block-backward c-state-cache))
2741 ;; Ought to cache the result from the
2742 ;; c-beginning-of-statement-1 calls here.
2743 (setq placeholder (point))
2744 (while (eq (setq step-type
2745 (c-beginning-of-statement-1 lim))
2747 (if (eq step-type 'previous)
2748 (goto-char placeholder)
2749 (setq placeholder (point))
2750 (if (and (eq step-type 'same)
2751 (not (looking-at c-opt-block-stmt-key)))
2752 ;; Step up to the containing statement if we
2753 ;; stayed in the same one.
2757 (c-beginning-of-statement-1 lim))
2760 (setq placeholder (point))
2761 ;; There was no containing statement afterall.
2762 (goto-char placeholder)))))
2764 (if (looking-at c-block-stmt-2-key)
2765 ;; Require a parenthesis after these keywords.
2766 ;; Necessary to catch e.g. synchronized in Java,
2767 ;; which can be used both as statement and
2769 (and (= (c-forward-token-1 1 nil) 0)
2770 (eq (char-after) ?\())
2771 (looking-at c-opt-block-stmt-key))))
2772 (if (eq step-type 'up)
2773 ;; CASE 18A: Simple substatement.
2775 (goto-char placeholder)
2777 ((eq char-after-ip ?{)
2778 (c-add-stmt-syntax 'substatement-open nil
2779 containing-sexp paren-state))
2781 (goto-char indent-point)
2782 (back-to-indentation)
2783 (looking-at c-label-key))
2784 (c-add-stmt-syntax 'substatement-label nil
2785 containing-sexp paren-state))
2787 (c-add-stmt-syntax 'substatement nil
2788 containing-sexp paren-state))))
2789 ;; CASE 18B: Some other substatement. This is shared
2791 (c-guess-continued-construct indent-point
2796 ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
2798 ((and (or c-opt-inexpr-class-key
2799 c-opt-inexpr-block-key
2801 (setq placeholder (c-looking-at-inexpr-block
2802 (c-safe-position containing-sexp paren-state)
2804 (setq tmpsymbol (assq (car placeholder)
2805 '((inexpr-class . class-open)
2806 (inexpr-statement . block-open))))
2808 ;; It's a statement block or an anonymous class.
2809 (setq tmpsymbol (cdr tmpsymbol))
2810 ;; It's a Pike lambda. Check whether we are between the
2811 ;; lambda keyword and the argument list or at the defun
2813 (setq tmpsymbol (if (eq char-after-ip ?{)
2815 'lambda-intro-cont)))
2816 (goto-char (cdr placeholder))
2817 (back-to-indentation)
2818 (c-add-stmt-syntax tmpsymbol t
2819 (c-most-enclosing-brace c-state-cache (point))
2820 (c-whack-state-after (point) paren-state))
2821 (unless (eq (point) (cdr placeholder))
2822 (c-add-syntax (car placeholder))))
2823 ;; CASE 5: Line is at top level.
2824 ((null containing-sexp)
2826 ;; CASE 5A: we are looking at a defun, brace list, class,
2827 ;; or inline-inclass method opening brace
2828 ((setq special-brace-list
2829 (or (and c-special-brace-lists
2830 (c-looking-at-special-brace-list))
2831 (eq char-after-ip ?{)))
2833 ;; CASE 5A.1: extern language or namespace construct
2835 (goto-char indent-point)
2836 (skip-chars-forward " \t")
2837 (and (c-safe (progn (c-backward-sexp 2) t))
2838 (looking-at c-other-decl-block-key)
2839 (setq keyword (match-string 1)
2840 placeholder (point))
2841 (or (and (string-equal keyword "namespace")
2842 (setq tmpsymbol 'namespace-open))
2843 (and (string-equal keyword "extern")
2846 (c-forward-syntactic-ws)
2847 (eq (char-after) ?\"))
2848 (setq tmpsymbol 'extern-lang-open)))
2850 (goto-char placeholder)
2851 (c-add-syntax tmpsymbol (c-point 'boi)))
2852 ;; CASE 5A.2: we are looking at a class opening brace
2854 (goto-char indent-point)
2855 (skip-chars-forward " \t{")
2856 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
2858 (setq placeholder (aref decl 0)))
2860 (c-add-syntax 'class-open placeholder))
2861 ;; CASE 5A.3: brace list open
2863 (c-beginning-of-statement-1 lim t)
2864 (if (looking-at "typedef\\>[^_]")
2865 (progn (c-forward-sexp 1)
2866 (c-forward-syntactic-ws indent-point)))
2867 (setq placeholder (c-point 'boi))
2868 (or (consp special-brace-list)
2869 (and (or (save-excursion
2870 (goto-char indent-point)
2871 (setq tmpsymbol nil)
2872 (while (and (> (point) placeholder)
2873 (= (c-backward-token-1 1 t) 0)
2874 (/= (char-after) ?=))
2875 (if (and (not tmpsymbol)
2876 (looking-at "new\\>[^_]"))
2877 (setq tmpsymbol 'topmost-intro-cont)))
2878 (eq (char-after) ?=))
2879 (looking-at "enum\\>[^_]"))
2881 (while (and (< (point) indent-point)
2882 (= (c-forward-token-1 1 t) 0)
2883 (not (memq (char-after) '(?\; ?\()))))
2884 (not (memq (char-after) '(?\; ?\()))
2886 (if (and (c-major-mode-is 'java-mode)
2887 (eq tmpsymbol 'topmost-intro-cont))
2888 ;; We're in Java and have found that the open brace
2889 ;; belongs to a "new Foo[]" initialization list,
2890 ;; which means the brace list is part of an
2891 ;; expression and not a top level definition. We
2892 ;; therefore treat it as any topmost continuation
2893 ;; even though the semantically correct symbol still
2894 ;; is brace-list-open, on the same grounds as in
2897 (c-beginning-of-statement-1 lim)
2898 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
2899 (c-add-syntax 'brace-list-open placeholder)))
2900 ;; CASE 5A.4: inline defun open
2901 ((and inclass-p (not inenclosing-p))
2902 (c-add-syntax 'inline-open)
2903 (c-add-class-syntax 'inclass inclass-p paren-state))
2904 ;; CASE 5A.5: ordinary defun open
2906 (goto-char placeholder)
2907 (if (or inclass-p macro-start)
2908 (c-add-syntax 'defun-open (c-point 'boi))
2909 ;; Bogus to use bol here, but it's the legacy.
2910 (c-add-syntax 'defun-open (c-point 'bol)))
2912 ;; CASE 5B: first K&R arg decl or member init
2913 ((c-just-after-func-arglist-p nil lim)
2915 ;; CASE 5B.1: a member init
2916 ((or (eq char-before-ip ?:)
2917 (eq char-after-ip ?:))
2918 ;; this line should be indented relative to the beginning
2919 ;; of indentation for the topmost-intro line that contains
2920 ;; the prototype's open paren
2921 ;; TBD: is the following redundant?
2922 (if (eq char-before-ip ?:)
2924 (c-backward-syntactic-ws lim)
2925 ;; TBD: is the preceding redundant?
2926 (if (eq (char-before) ?:)
2927 (progn (forward-char -1)
2928 (c-backward-syntactic-ws lim)))
2929 (if (eq (char-before) ?\))
2930 (c-backward-sexp 1))
2931 (setq placeholder (point))
2933 (and (c-safe (c-backward-sexp 1) t)
2934 (looking-at "throw[^_]")
2935 (c-safe (c-backward-sexp 1) t)
2936 (setq placeholder (point))))
2937 (goto-char placeholder)
2938 (c-add-syntax 'member-init-intro (c-point 'boi))
2939 ;; we don't need to add any class offset since this
2940 ;; should be relative to the ctor's indentation
2942 ;; CASE 5B.2: K&R arg decl intro
2944 (c-beginning-of-statement-1 lim)
2945 (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
2947 (c-add-class-syntax 'inclass inclass-p paren-state)))
2948 ;; CASE 5B.3: Inside a member init list.
2949 ((c-beginning-of-member-init-list lim)
2950 (c-forward-syntactic-ws)
2951 (c-add-syntax 'member-init-cont (point)))
2952 ;; CASE 5B.4: Nether region after a C++ or Java func
2953 ;; decl, which could include a `throws' declaration.
2955 (c-beginning-of-statement-1 lim)
2956 (c-add-syntax 'func-decl-cont (c-point 'boi))
2958 ;; CASE 5C: inheritance line. could be first inheritance
2959 ;; line, or continuation of a multiple inheritance
2960 ((or (and (c-major-mode-is 'c++-mode)
2962 (when (eq char-after-ip ?,)
2963 (skip-chars-forward " \t")
2965 (looking-at c-opt-decl-spec-key)))
2966 (and (or (eq char-before-ip ?:)
2967 ;; watch out for scope operator
2969 (and (eq char-after-ip ?:)
2970 (c-safe (progn (forward-char 1) t))
2971 (not (eq (char-after) ?:))
2974 (c-backward-syntactic-ws lim)
2975 (if (eq char-before-ip ?:)
2978 (c-backward-syntactic-ws lim)))
2979 (back-to-indentation)
2980 (looking-at c-class-key)))
2982 (and (c-major-mode-is 'java-mode)
2983 (let ((fence (save-excursion
2984 (c-beginning-of-statement-1 lim)
2989 (cond ((looking-at c-opt-decl-spec-key)
2990 (setq injava-inher (cons cont (point))
2992 ((or (not (c-safe (c-forward-sexp -1) t))
2998 (not (c-crosses-statement-barrier-p (cdr injava-inher)
3002 ;; CASE 5C.1: non-hanging colon on an inher intro
3003 ((eq char-after-ip ?:)
3004 (c-beginning-of-statement-1 lim)
3005 (c-add-syntax 'inher-intro (c-point 'boi))
3006 ;; don't add inclass symbol since relative point already
3007 ;; contains any class offset
3009 ;; CASE 5C.2: hanging colon on an inher intro
3010 ((eq char-before-ip ?:)
3011 (c-beginning-of-statement-1 lim)
3012 (c-add-syntax 'inher-intro (c-point 'boi))
3014 (c-add-class-syntax 'inclass inclass-p paren-state)))
3015 ;; CASE 5C.3: in a Java implements/extends
3017 (let ((where (cdr injava-inher))
3018 (cont (car injava-inher)))
3020 (cond ((looking-at "throws\\>[^_]")
3021 (c-add-syntax 'func-decl-cont
3022 (progn (c-beginning-of-statement-1 lim)
3024 (cont (c-add-syntax 'inher-cont where))
3025 (t (c-add-syntax 'inher-intro
3026 (progn (goto-char (cdr injava-inher))
3027 (c-beginning-of-statement-1 lim)
3030 ;; CASE 5C.4: a continued inheritance line
3032 (c-beginning-of-inheritance-list lim)
3033 (c-add-syntax 'inher-cont (point))
3034 ;; don't add inclass symbol since relative point already
3035 ;; contains any class offset
3037 ;; CASE 5D: this could be a top-level initialization, a
3038 ;; member init list continuation, or a template argument
3039 ;; list continuation.
3040 ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
3041 c++-template-syntax-table
3044 ;; Note: We use the fact that lim is always after any
3045 ;; preceding brace sexp.
3046 (while (and (= (c-backward-token-1 1 t lim) 0)
3047 (not (looking-at "[;<,=]"))))
3048 (or (memq (char-after) '(?, ?=))
3049 (and (c-major-mode-is 'c++-mode)
3050 (= (c-backward-token-1 1 nil lim) 0)
3051 (eq (char-after) ?<)))))
3052 (goto-char indent-point)
3053 (c-beginning-of-member-init-list lim)
3055 ;; CASE 5D.1: hanging member init colon, but watch out
3056 ;; for bogus matches on access specifiers inside classes.
3057 ((and (save-excursion
3058 (setq placeholder (point))
3059 (c-backward-token-1 1 t lim)
3060 (and (eq (char-after) ?:)
3061 (not (eq (char-before) ?:))))
3063 (goto-char placeholder)
3064 (back-to-indentation)
3066 (/= (car (save-excursion
3067 (parse-partial-sexp (point) placeholder)))
3070 (if c-opt-access-key
3071 (not (looking-at c-opt-access-key)) t)
3072 (not (looking-at c-class-key))
3073 (if c-opt-bitfield-key
3074 (not (looking-at c-opt-bitfield-key)) t))
3076 (goto-char placeholder)
3077 (c-forward-syntactic-ws)
3078 (c-add-syntax 'member-init-cont (point))
3079 ;; we do not need to add class offset since relative
3080 ;; point is the member init above us
3082 ;; CASE 5D.2: non-hanging member init colon
3084 (c-forward-syntactic-ws indent-point)
3085 (eq (char-after) ?:))
3086 (skip-chars-forward " \t:")
3087 (c-add-syntax 'member-init-cont (point)))
3088 ;; CASE 5D.3: perhaps a template list continuation?
3089 ((and (c-major-mode-is 'c++-mode)
3092 (c-with-syntax-table c++-template-syntax-table
3093 (goto-char indent-point)
3094 (setq placeholder (c-up-list-backward (point)))
3096 (eq (char-after placeholder) ?<))))))
3097 ;; we can probably indent it just like an arglist-cont
3098 (goto-char placeholder)
3099 (c-beginning-of-statement-1 lim t)
3100 (c-add-syntax 'template-args-cont (c-point 'boi)))
3101 ;; CASE 5D.4: perhaps a multiple inheritance line?
3102 ((and (c-major-mode-is 'c++-mode)
3104 (c-beginning-of-statement-1 lim)
3105 (setq placeholder (point))
3106 (if (looking-at "static\\>[^_]")
3107 (c-forward-token-1 1 nil indent-point))
3108 (and (looking-at c-class-key)
3109 (= (c-forward-token-1 2 nil indent-point) 0)
3110 (if (eq (char-after) ?<)
3111 (c-with-syntax-table c++-template-syntax-table
3112 (= (c-forward-token-1 1 t indent-point) 0))
3114 (eq (char-after) ?:))))
3115 (goto-char placeholder)
3116 (c-add-syntax 'inher-cont (c-point 'boi)))
3117 ;; CASE 5D.5: Continuation of the "expression part" of a
3118 ;; top level construct.
3120 (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
3123 (c-backward-syntactic-ws)
3124 (eq (char-before) ?}))))
3126 (if (eq char-before-ip ?,)
3127 ;; A preceding comma at the top level means that a
3128 ;; new variable declaration starts here. Use
3129 ;; topmost-intro-cont for it, for consistency with
3130 ;; the first variable declaration. C.f. case 5N.
3133 nil containing-sexp paren-state))
3135 ;; CASE 5E: we are looking at a access specifier
3138 (looking-at c-opt-access-key))
3139 (setq placeholder (c-add-class-syntax 'inclass inclass-p
3141 ;; Append access-label with the same anchor point as inclass gets.
3142 (nconc syntax (list (cons 'access-label placeholder))))
3143 ;; CASE 5F: extern-lang-close or namespace-close?
3145 (eq char-after-ip ?}))
3146 (setq tmpsymbol (if (eq inenclosing-p 'extern)
3149 (c-add-syntax tmpsymbol (aref inclass-p 0)))
3150 ;; CASE 5G: we are looking at the brace which closes the
3151 ;; enclosing nested class decl
3153 (eq char-after-ip ?})
3158 (and (c-safe (progn (c-backward-sexp 1) t))
3159 (= (point) (aref inclass-p 1))
3161 (c-add-class-syntax 'class-close inclass-p paren-state))
3162 ;; CASE 5H: we could be looking at subsequent knr-argdecls
3163 ((and c-recognize-knr-p
3164 (not (eq char-before-ip ?}))
3166 (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
3168 ;; Do an extra check to avoid tripping up on
3169 ;; statements that occur in invalid contexts
3170 ;; (e.g. in macro bodies where we don't really
3171 ;; know the context of what we're looking at).
3172 (not (and c-opt-block-stmt-key
3173 (looking-at c-opt-block-stmt-key)))))
3174 (< placeholder indent-point))
3175 (goto-char placeholder)
3176 (c-add-syntax 'knr-argdecl (point)))
3177 ;; CASE 5I: ObjC method definition.
3178 ((and c-opt-method-key
3179 (looking-at c-opt-method-key))
3180 (c-beginning-of-statement-1 lim)
3181 (c-add-syntax 'objc-method-intro (c-point 'boi)))
3182 ;; CASE 5N: At a variable declaration that follows a class
3183 ;; definition or some other block declaration that doesn't
3184 ;; end at the closing '}'. C.f. case 5D.5.
3186 (c-backward-syntactic-ws lim)
3187 (and (eq (char-before) ?})
3189 (let ((start (point)))
3191 ;; Speed up the backward search a bit.
3192 (goto-char (car (car paren-state))))
3193 (c-beginning-of-decl-1 containing-sexp)
3194 (setq placeholder (point))
3195 (if (= start (point))
3196 ;; The '}' is unbalanced.
3199 (> (point) indent-point))))))
3200 (goto-char placeholder)
3201 (c-add-stmt-syntax 'topmost-intro-cont nil
3202 containing-sexp paren-state))
3203 ;; CASE 5J: we are at the topmost level, make
3204 ;; sure we skip back past any access specifiers
3206 (while (and inclass-p
3210 (c-safe (progn (c-backward-sexp 1) t))
3211 (looking-at c-opt-access-key)))
3213 (c-backward-syntactic-ws lim))
3215 (memq (char-before) '(?\; ?}))
3216 (and (c-major-mode-is 'objc-mode)
3218 (c-beginning-of-statement-1 lim)
3219 (eq (char-after) ?@)))))
3220 ;; real beginning-of-line could be narrowed out due to
3221 ;; enclosure in a class block
3224 (c-add-syntax 'topmost-intro (c-point 'bol))
3225 ;; Using bol instead of boi above is highly bogus, and
3226 ;; it makes our lives hard to remain compatible. :P
3229 (goto-char (aref inclass-p 1))
3230 (or (= (point) (c-point 'boi))
3231 (goto-char (aref inclass-p 0)))
3233 ((eq inenclosing-p 'extern)
3234 (c-add-syntax 'inextern-lang (c-point 'boi)))
3235 ((eq inenclosing-p 'namespace)
3236 (c-add-syntax 'innamespace (c-point 'boi)))
3237 (t (c-add-class-syntax 'inclass inclass-p paren-state)))
3239 (when (and c-syntactic-indentation-in-macros
3241 (/= macro-start (c-point 'boi indent-point)))
3242 (c-add-syntax 'cpp-define-intro)
3243 (setq macro-start nil))
3245 ;; CASE 5K: we are at an ObjC method definition
3246 ;; continuation line.
3247 ((and c-opt-method-key
3249 (c-beginning-of-statement-1 lim)
3251 (looking-at c-opt-method-key)))
3252 (c-add-syntax 'objc-method-args-cont (point)))
3253 ;; CASE 5L: we are at the first argument of a template
3254 ;; arglist that begins on the previous line.
3255 ((eq (char-before) ?<)
3256 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
3257 (c-add-syntax 'template-args-cont (c-point 'boi)))
3258 ;; CASE 5M: we are at a topmost continuation line
3260 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
3261 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
3263 ;; (CASE 6 has been removed.)
3264 ;; CASE 7: line is an expression, not a statement. Most
3265 ;; likely we are either in a function prototype or a function
3266 ;; call argument list
3267 ((not (or (and c-special-brace-lists
3269 (goto-char containing-sexp)
3270 (c-looking-at-special-brace-list)))
3271 (eq (char-after containing-sexp) ?{)))
3273 ;; CASE 7A: we are looking at the arglist closing paren
3274 ((memq char-after-ip '(?\) ?\]))
3275 (goto-char containing-sexp)
3276 (setq placeholder (c-point 'boi))
3277 (when (and (c-safe (backward-up-list 1) t)
3278 (> (point) placeholder))
3280 (skip-chars-forward " \t")
3281 (setq placeholder (point)))
3282 (c-add-syntax 'arglist-close placeholder))
3283 ;; CASE 7B: Looking at the opening brace of an
3284 ;; in-expression block or brace list. C.f. cases 4, 16A
3286 ((and (eq char-after-ip ?{)
3288 (setq placeholder (c-inside-bracelist-p (point)
3291 (setq tmpsymbol '(brace-list-open . inexpr-class))
3292 (setq tmpsymbol '(block-open . inexpr-statement)
3294 (cdr-safe (c-looking-at-inexpr-block
3295 (c-safe-position containing-sexp
3298 ;; placeholder is nil if it's a block directly in
3299 ;; a function arglist. That makes us skip out of
3302 (goto-char placeholder)
3303 (back-to-indentation)
3304 (c-add-stmt-syntax (car tmpsymbol) t
3305 (c-most-enclosing-brace paren-state (point))
3306 (c-whack-state-after (point) paren-state))
3307 (if (/= (point) placeholder)
3308 (c-add-syntax (cdr tmpsymbol))))
3309 ;; CASE 7C: we are looking at the first argument in an empty
3310 ;; argument list. Use arglist-close if we're actually
3311 ;; looking at a close paren or bracket.
3312 ((memq char-before-ip '(?\( ?\[))
3313 (goto-char containing-sexp)
3314 (setq placeholder (c-point 'boi))
3315 (when (and (c-safe (backward-up-list 1) t)
3316 (> (point) placeholder))
3318 (skip-chars-forward " \t")
3319 (setq placeholder (point)))
3320 (c-add-syntax 'arglist-intro placeholder))
3321 ;; CASE 7D: we are inside a conditional test clause. treat
3322 ;; these things as statements
3324 (goto-char containing-sexp)
3325 (and (c-safe (progn (c-forward-sexp -1) t))
3326 (looking-at "\\<for\\>[^_]")))
3327 (goto-char (1+ containing-sexp))
3328 (c-forward-syntactic-ws indent-point)
3329 (if (eq char-before-ip ?\;)
3330 (c-add-syntax 'statement (point))
3331 (c-add-syntax 'statement-cont (point))
3333 ;; CASE 7E: maybe a continued ObjC method call. This is the
3334 ;; case when we are inside a [] bracketed exp, and what
3335 ;; precede the opening bracket is not an identifier.
3336 ((and c-opt-method-key
3337 (eq (char-after containing-sexp) ?\[)
3339 (goto-char (1- containing-sexp))
3340 (c-backward-syntactic-ws (c-point 'bod))
3341 (if (not (looking-at c-symbol-key))
3342 (c-add-syntax 'objc-method-call-cont containing-sexp))
3344 ;; CASE 7F: we are looking at an arglist continuation line,
3345 ;; but the preceding argument is on the same line as the
3346 ;; opening paren. This case includes multi-line
3347 ;; mathematical paren groupings, but we could be on a
3348 ;; for-list continuation line
3350 (goto-char (1+ containing-sexp))
3351 (skip-chars-forward " \t")
3353 (not (looking-at "\\\\$"))))
3354 (goto-char containing-sexp)
3355 (setq placeholder (c-point 'boi))
3356 (when (and (c-safe (backward-up-list 1) t)
3357 (> (point) placeholder))
3359 (skip-chars-forward " \t")
3360 (setq placeholder (point)))
3361 (c-add-syntax 'arglist-cont-nonempty placeholder))
3362 ;; CASE 7G: we are looking at just a normal arglist
3363 ;; continuation line
3364 (t (c-forward-syntactic-ws indent-point)
3365 (c-add-syntax 'arglist-cont (c-point 'boi)))
3367 ;; CASE 8: func-local multi-inheritance line
3368 ((and (c-major-mode-is 'c++-mode)
3370 (goto-char indent-point)
3371 (skip-chars-forward " \t")
3372 (looking-at c-opt-decl-spec-key)))
3373 (goto-char indent-point)
3374 (skip-chars-forward " \t")
3376 ;; CASE 8A: non-hanging colon on an inher intro
3377 ((eq char-after-ip ?:)
3378 (c-backward-syntactic-ws lim)
3379 (c-add-syntax 'inher-intro (c-point 'boi)))
3380 ;; CASE 8B: hanging colon on an inher intro
3381 ((eq char-before-ip ?:)
3382 (c-add-syntax 'inher-intro (c-point 'boi)))
3383 ;; CASE 8C: a continued inheritance line
3385 (c-beginning-of-inheritance-list lim)
3386 (c-add-syntax 'inher-cont (point))
3388 ;; CASE 9: we are inside a brace-list
3389 ((setq special-brace-list
3390 (or (and c-special-brace-lists
3392 (goto-char containing-sexp)
3393 (c-looking-at-special-brace-list)))
3394 (c-inside-bracelist-p containing-sexp paren-state)))
3396 ;; CASE 9A: In the middle of a special brace list opener.
3397 ((and (consp special-brace-list)
3399 (goto-char containing-sexp)
3400 (eq (char-after) ?\())
3401 (eq char-after-ip (car (cdr special-brace-list))))
3402 (goto-char (car (car special-brace-list)))
3403 (skip-chars-backward " \t")
3405 (assoc 'statement-cont
3406 (setq placeholder (c-guess-basic-syntax))))
3407 (setq syntax placeholder)
3408 (c-beginning-of-statement-1
3409 (c-safe-position (1- containing-sexp) paren-state))
3410 (c-forward-token-1 0)
3411 (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1))
3412 (c-add-syntax 'brace-list-open (c-point 'boi))))
3413 ;; CASE 9B: brace-list-close brace
3414 ((if (consp special-brace-list)
3415 ;; Check special brace list closer.
3417 (goto-char (car (car special-brace-list)))
3419 (goto-char indent-point)
3420 (back-to-indentation)
3422 ;; We were between the special close char and the `)'.
3423 (and (eq (char-after) ?\))
3424 (eq (1+ (point)) (cdr (car special-brace-list))))
3425 ;; We were before the special close char.
3426 (and (eq (char-after) (cdr (cdr special-brace-list)))
3427 (= (c-forward-token-1) 0)
3428 (eq (1+ (point)) (cdr (car special-brace-list)))))))
3429 ;; Normal brace list check.
3430 (and (eq char-after-ip ?})
3431 (c-safe (progn (goto-char (c-up-list-backward (point)))
3433 (= (point) containing-sexp)))
3434 (if (eq (point) (c-point 'boi))
3435 (c-add-syntax 'brace-list-close (point))
3436 (setq lim (c-most-enclosing-brace c-state-cache (point)))
3437 (c-beginning-of-statement-1 lim)
3438 (c-add-stmt-syntax 'brace-list-close t lim
3439 (c-whack-state-after (point) paren-state)
3442 ;; Prepare for the rest of the cases below by going to the
3443 ;; token following the opening brace
3444 (if (consp special-brace-list)
3446 (goto-char (car (car special-brace-list)))
3447 (c-forward-token-1 1 nil indent-point))
3448 (goto-char containing-sexp))
3450 (let ((start (point)))
3451 (c-forward-syntactic-ws indent-point)
3452 (goto-char (max start (c-point 'bol))))
3453 (c-skip-ws-forward indent-point)
3455 ;; CASE 9C: we're looking at the first line in a brace-list
3456 ((= (point) indent-point)
3457 (if (consp special-brace-list)
3458 (goto-char (car (car special-brace-list)))
3459 (goto-char containing-sexp))
3460 (if (eq (point) (c-point 'boi))
3461 (c-add-syntax 'brace-list-intro (point))
3462 (setq lim (c-most-enclosing-brace c-state-cache (point)))
3463 (c-beginning-of-statement-1 lim)
3464 (c-add-stmt-syntax 'brace-list-intro t lim
3465 (c-whack-state-after (point) paren-state)
3467 ;; CASE 9D: this is just a later brace-list-entry or
3469 (t (if (or (eq char-after-ip ?{)
3470 (and c-special-brace-lists
3472 (goto-char indent-point)
3473 (c-forward-syntactic-ws (c-point 'eol))
3474 (c-looking-at-special-brace-list (point)))))
3475 (c-add-syntax 'brace-entry-open (point))
3476 (c-add-syntax 'brace-list-entry (point))
3479 ;; CASE 10: A continued statement or top level construct.
3480 ((and (not (memq char-before-ip '(?\; ?:)))
3481 (or (not (eq char-before-ip ?}))
3482 (c-looking-at-inexpr-block-backward c-state-cache))
3485 (c-beginning-of-statement-1 containing-sexp)
3486 (setq placeholder (point))))
3487 (/= placeholder containing-sexp))
3488 ;; This is shared with case 18.
3489 (c-guess-continued-construct indent-point
3494 ;; CASE 14: A case or default label
3495 ((looking-at c-label-kwds-regexp)
3496 (goto-char containing-sexp)
3497 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
3498 (c-backward-to-block-anchor lim)
3499 (c-add-stmt-syntax 'case-label t lim paren-state))
3500 ;; CASE 15: any other label
3501 ((looking-at c-label-key)
3502 (goto-char containing-sexp)
3503 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
3506 (if (and (eq (c-beginning-of-statement-1 lim) 'up)
3507 (looking-at "switch\\>[^_]"))
3508 ;; If the surrounding statement is a switch then
3509 ;; let's analyze all labels as switch labels, so
3510 ;; that they get lined up consistently.
3513 (c-backward-to-block-anchor lim)
3514 (c-add-stmt-syntax tmpsymbol t lim paren-state))
3515 ;; CASE 16: block close brace, possibly closing the defun or
3517 ((eq char-after-ip ?})
3518 ;; From here on we have the next containing sexp in lim.
3519 (setq lim (c-most-enclosing-brace paren-state))
3520 (goto-char containing-sexp)
3522 ;; CASE 16E: Closing a statement block? This catches
3523 ;; cases where it's preceded by a statement keyword,
3524 ;; which works even when used in an "invalid" context,
3525 ;; e.g. a macro argument.
3526 ((c-after-conditional)
3527 (c-backward-to-block-anchor lim)
3528 (c-add-stmt-syntax 'block-close t lim paren-state))
3529 ;; CASE 16A: closing a lambda defun or an in-expression
3530 ;; block? C.f. cases 4, 7B and 17E.
3531 ((setq placeholder (c-looking-at-inexpr-block
3532 (c-safe-position containing-sexp paren-state)
3534 (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
3537 (goto-char containing-sexp)
3538 (back-to-indentation)
3539 (if (= containing-sexp (point))
3540 (c-add-syntax tmpsymbol (point))
3541 (goto-char (cdr placeholder))
3542 (back-to-indentation)
3543 (c-add-stmt-syntax tmpsymbol t
3544 (c-most-enclosing-brace paren-state (point))
3545 (c-whack-state-after (point) paren-state))
3546 (if (/= (point) (cdr placeholder))
3547 (c-add-syntax (car placeholder)))))
3548 ;; CASE 16B: does this close an inline or a function in
3549 ;; an extern block or namespace?
3550 ((setq placeholder (c-search-uplist-for-classkey paren-state))
3551 (c-backward-to-decl-anchor lim)
3552 (back-to-indentation)
3554 (goto-char (aref placeholder 0))
3555 (looking-at c-other-decl-block-key))
3556 (c-add-syntax 'defun-close (point))
3557 (c-add-syntax 'inline-close (point))))
3558 ;; CASE 16F: Can be a defun-close of a function declared
3559 ;; in a statement block, e.g. in Pike or when using gcc
3560 ;; extensions. Might also trigger it with some macros
3561 ;; followed by blocks, and this gives sane indentation
3562 ;; then too. Let it through to be handled below.
3563 ;; C.f. cases B.3 and 17G.
3564 ((and (not inenclosing-p)
3567 (and (not (c-looking-at-bos))
3568 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
3569 (setq placeholder (point)))))
3570 (back-to-indentation)
3571 (if (/= (point) containing-sexp)
3572 (goto-char placeholder))
3573 (c-add-stmt-syntax 'defun-close t lim paren-state))
3574 ;; CASE 16C: if there an enclosing brace that hasn't
3575 ;; been narrowed out by a class, then this is a
3576 ;; block-close. C.f. case 17H.
3577 ((and (not inenclosing-p) lim)
3578 ;; If the block is preceded by a case/switch label on
3579 ;; the same line, we anchor at the first preceding label
3580 ;; at boi. The default handling in c-add-stmt-syntax is
3581 ;; really fixes it better, but we do like this to keep
3582 ;; the indentation compatible with version 5.28 and
3584 (while (and (/= (setq placeholder (point)) (c-point 'boi))
3585 (eq (c-beginning-of-statement-1 lim) 'label)))
3586 (goto-char placeholder)
3587 (if (looking-at c-label-kwds-regexp)
3588 (c-add-syntax 'block-close (point))
3589 (goto-char containing-sexp)
3590 ;; c-backward-to-block-anchor not necessary here; those
3591 ;; situations are handled in case 16E above.
3592 (c-add-stmt-syntax 'block-close t lim paren-state)))
3593 ;; CASE 16D: find out whether we're closing a top-level
3597 (narrow-to-region (point-min) indent-point)
3598 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
3600 (c-add-class-syntax 'class-close decl paren-state)
3601 (goto-char containing-sexp)
3602 (c-backward-to-decl-anchor lim)
3603 (back-to-indentation)
3604 (c-add-syntax 'defun-close (point)))))
3606 ;; CASE 17: Statement or defun catchall.
3608 (goto-char indent-point)
3609 ;; Back up statements until we find one that starts at boi.
3610 (while (let* ((prev-point (point))
3611 (last-step-type (c-beginning-of-statement-1
3613 (if (= (point) prev-point)
3615 (setq step-type (or step-type last-step-type))
3617 (setq step-type last-step-type)
3618 (/= (point) (c-point 'boi)))))
3620 ;; CASE 17B: continued statement
3621 ((and (eq step-type 'same)
3622 (/= (point) indent-point))
3623 (c-add-stmt-syntax 'statement-cont nil
3624 containing-sexp paren-state))
3625 ;; CASE 17A: After a case/default label?
3627 (while (and (eq step-type 'label)
3628 (not (looking-at c-label-kwds-regexp)))
3630 (c-beginning-of-statement-1 containing-sexp)))
3631 (eq step-type 'label))
3632 (c-add-stmt-syntax (if (eq char-after-ip ?{)
3633 'statement-case-open
3634 'statement-case-intro)
3635 t containing-sexp paren-state))
3636 ;; CASE 17D: any old statement
3638 (while (eq step-type 'label)
3640 (c-beginning-of-statement-1 containing-sexp)))
3641 (eq step-type 'previous))
3642 (c-add-stmt-syntax 'statement t containing-sexp paren-state)
3643 (if (eq char-after-ip ?{)
3644 (c-add-syntax 'block-open)))
3645 ;; CASE 17I: Inside a substatement block.
3647 ;; The following tests are all based on containing-sexp.
3648 (goto-char containing-sexp)
3649 ;; From here on we have the next containing sexp in lim.
3650 (setq lim (c-most-enclosing-brace paren-state containing-sexp))
3651 (c-after-conditional))
3652 (c-backward-to-block-anchor lim)
3653 (c-add-stmt-syntax 'statement-block-intro t lim paren-state)
3654 (if (eq char-after-ip ?{)
3655 (c-add-syntax 'block-open)))
3656 ;; CASE 17E: first statement in an in-expression block.
3657 ;; C.f. cases 4, 7B and 16A.
3658 ((setq placeholder (c-looking-at-inexpr-block
3659 (c-safe-position containing-sexp paren-state)
3661 (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
3663 'statement-block-intro))
3664 (back-to-indentation)
3665 (if (= containing-sexp (point))
3666 (c-add-syntax tmpsymbol (point))
3667 (goto-char (cdr placeholder))
3668 (back-to-indentation)
3669 (c-add-stmt-syntax tmpsymbol t
3670 (c-most-enclosing-brace c-state-cache (point))
3671 (c-whack-state-after (point) paren-state))
3672 (if (/= (point) (cdr placeholder))
3673 (c-add-syntax (car placeholder))))
3674 (if (eq char-after-ip ?{)
3675 (c-add-syntax 'block-open)))
3676 ;; CASE 17F: first statement in an inline, or first
3677 ;; statement in a top-level defun. we can tell this is it
3678 ;; if there are no enclosing braces that haven't been
3679 ;; narrowed out by a class (i.e. don't use bod here).
3680 ;; However, we first check for statements that we can
3681 ;; recognize by keywords. That increases the robustness in
3682 ;; cases where statements are used on the top level,
3683 ;; e.g. in macro definitions.
3687 (c-narrow-out-enclosing-class paren-state containing-sexp)
3688 (not (c-most-enclosing-brace paren-state))))
3689 (c-backward-to-decl-anchor lim)
3690 (back-to-indentation)
3691 (c-add-syntax 'defun-block-intro (point)))
3692 ;; CASE 17G: First statement in a function declared inside
3693 ;; a normal block. This can occur in Pike and with
3694 ;; e.g. the gcc extensions. Might also trigger it with
3695 ;; some macros followed by blocks, and this gives sane
3696 ;; indentation then too. C.f. cases B.3 and 16F.
3698 (and (not (c-looking-at-bos))
3699 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
3700 (setq placeholder (point))))
3701 (back-to-indentation)
3702 (if (/= (point) containing-sexp)
3703 (goto-char placeholder))
3704 (c-add-stmt-syntax 'defun-block-intro t lim paren-state))
3705 ;; CASE 17H: First statement in a block. C.f. case 16C.
3707 ;; If the block is preceded by a case/switch label on the
3708 ;; same line, we anchor at the first preceding label at
3709 ;; boi. The default handling in c-add-stmt-syntax is
3710 ;; really fixes it better, but we do like this to keep the
3711 ;; indentation compatible with version 5.28 and earlier.
3712 (while (and (/= (setq placeholder (point)) (c-point 'boi))
3713 (eq (c-beginning-of-statement-1 lim) 'label)))
3714 (goto-char placeholder)
3715 (if (looking-at c-label-kwds-regexp)
3716 (c-add-syntax 'statement-block-intro (point))
3717 (goto-char containing-sexp)
3718 ;; c-backward-to-block-anchor not necessary here; those
3719 ;; situations are handled in case 17I above.
3720 (c-add-stmt-syntax 'statement-block-intro t lim paren-state))
3721 (if (eq char-after-ip ?{)
3722 (c-add-syntax 'block-open)))
3725 ;; now we need to look at any modifiers
3726 (goto-char indent-point)
3727 (skip-chars-forward " \t")
3728 ;; are we looking at a comment only line?
3729 (when (and (looking-at c-comment-start-regexp)
3730 (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
3731 (c-add-syntax 'comment-intro))
3732 ;; we might want to give additional offset to friends (in C++).
3733 (when (and c-opt-friend-key
3734 (looking-at c-opt-friend-key))
3735 (c-add-syntax 'friend))
3736 ;; Start of or a continuation of a preprocessor directive?
3737 (if (and macro-start
3738 (eq macro-start (c-point 'boi))
3739 (not (and (c-major-mode-is 'pike-mode)
3740 (eq (char-after (1+ macro-start)) ?\"))))
3741 (c-add-syntax 'cpp-macro)
3742 (when (and c-syntactic-indentation-in-macros macro-start)
3744 (when (or (< syntactic-relpos macro-start)
3745 (not (or (assq 'arglist-intro syntax)
3746 (assq 'arglist-cont syntax)
3747 (assq 'arglist-cont-nonempty syntax)
3748 (assq 'arglist-close syntax))))
3749 ;; If inside a cpp expression, i.e. anywhere in a
3750 ;; cpp directive except a #define body, we only let
3751 ;; through the syntactic analysis that is internal
3752 ;; in the expression. That means the arglist
3753 ;; elements, if they are anchored inside the cpp
3755 (setq syntax `((cpp-macro-cont . ,macro-start))))
3756 (when (and (eq macro-start syntactic-relpos)
3757 (not (assq 'cpp-define-intro syntax))
3759 (goto-char macro-start)
3760 (or (not (c-forward-to-cpp-define-body))
3761 (<= (point) (c-point 'boi indent-point)))))
3762 ;; Inside a #define body and the syntactic analysis is
3763 ;; anchored on the start of the #define. In this case
3764 ;; we add cpp-define-intro to get the extra
3765 ;; indentation of the #define body.
3766 (c-add-syntax 'cpp-define-intro)))))
3767 ;; return the syntax
3771 (defun c-echo-parsing-error (&optional quiet)
3772 (when (and c-report-syntactic-errors c-parsing-error (not quiet))
3773 (c-benign-error "%s" c-parsing-error))
3776 (defun c-evaluate-offset (offset langelem symbol)
3777 ;; offset can be a number, a function, a variable, a list, or one of
3778 ;; the symbols + or -
3780 ((eq offset '+) c-basic-offset)
3781 ((eq offset '-) (- c-basic-offset))
3782 ((eq offset '++) (* 2 c-basic-offset))
3783 ((eq offset '--) (* 2 (- c-basic-offset)))
3784 ((eq offset '*) (/ c-basic-offset 2))
3785 ((eq offset '/) (/ (- c-basic-offset) 2))
3786 ((numberp offset) offset)
3787 ((functionp offset) (c-evaluate-offset
3788 (funcall offset langelem) langelem symbol))
3789 ((vectorp offset) offset)
3793 (while (and (not done) offset)
3794 (setq done (c-evaluate-offset (car offset) langelem symbol)
3795 offset (cdr offset)))
3796 (if (and c-strict-syntax-p (not done))
3797 (c-benign-error "No offset found for syntactic symbol %s" symbol))
3799 (t (symbol-value offset))
3802 (defun c-get-offset (langelem)
3803 "Get offset from LANGELEM which is a cons cell of the form:
3804 \(SYMBOL . RELPOS). The symbol is matched against `c-offsets-alist'
3805 and the offset found there is returned."
3806 (let* ((symbol (car langelem))
3807 (match (assq symbol c-offsets-alist))
3808 (offset (cdr-safe match)))
3810 (setq offset (c-evaluate-offset offset langelem symbol))
3811 (if c-strict-syntax-p
3812 (c-benign-error "No offset found for syntactic symbol %s" symbol))
3814 (if (vectorp offset)
3816 (or (and (numberp offset) offset)
3817 (and (symbolp offset) (symbol-value offset))
3821 (defun c-get-syntactic-indentation (langelems)
3822 "Apply `c-get-offset' to a list of langelem cells to get the total
3823 syntactic indentation. The anchor position, whose column is used as a
3824 base for all the collected offsets, is taken from the first element
3826 ;; Note that topmost-intro always has a relpos at bol, for
3827 ;; historical reasons. It's often used together with other symbols
3828 ;; that has more sane positions. Since we always use the first
3829 ;; found relpos, we rely on that these other symbols always precede
3830 ;; topmost-intro in the LANGELEMS list.
3831 (let ((indent 0) anchor)
3834 (let ((res (c-get-offset (car langelems))))
3836 (throw 'done (elt res 0))
3838 (let ((relpos (cdr (car langelems))))
3840 (setq anchor relpos))))
3841 (setq indent (+ indent res)
3842 langelems (cdr langelems)))))
3851 (cc-provide 'cc-engine)
3853 ;;; cc-engine.el ends here