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 a 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!]")
646 (skip-chars-backward " \t")
649 (while (and (<= (point) lim
)
650 (eq (char-before) ?
\\)
651 (= (forward-line 1) 0))
653 (when (> (point) lim
)
654 ;; Don't move past the macro if that'd take us past the limit.
656 ;; Skip in-comment line continuations (used for Pike refdoc).
657 ((and c-opt-in-comment-lc
(looking-at c-opt-in-comment-lc
))
658 (goto-char (match-end 0)))))
659 (goto-char (min (point) lim
))))
661 (defun c-backward-syntactic-ws (&optional lim
)
662 "Backward skip of syntactic whitespace.
663 Syntactic whitespace is defined as whitespace characters, comments,
664 and preprocessor directives. However if point starts inside a comment
665 or preprocessor directive, the content of it is not treated as
666 whitespace. LIM sets a lower limit of the backward movement, if
668 (let ((start-line (c-point 'bol
))
672 (or lim
(setq lim here
))
673 (while (/= here
(point))
674 (setq prev-pos
(point))
675 ;; If forward-comment in Emacs 19.34 is given a large negative
676 ;; value, it'll loop all the way through if it hits bob.
677 (while (c-forward-comment -
5))
681 (eq (char-before) ?
\\)
682 (if (<= prev-pos
(c-point 'eonl
))
684 ;; Passed a line continuation, but not from the line we
687 (setq line-cont nil
)))
691 (when (eq line-cont
'maybe
)
694 (setq line-cont
(eq (char-before) ?
\\))))
696 (and (< (point) start-line
)
697 (c-beginning-of-macro))))
699 ;; Don't move past the macro if we began inside it or at
700 ;; the end of the same line, or if the move would take us
703 (setq line-cont nil
))
704 ;; Skip in-comment line continuations (used for Pike refdoc).
705 ((and c-opt-in-comment-lc
707 (and (c-safe (beginning-of-line)
710 (looking-at c-opt-in-comment-lc
)
711 (eq (match-end 0) here
))))
712 (goto-char (match-beginning 0)))))
713 (goto-char (max (point) lim
))))
715 (defun c-forward-token-1 (&optional count balanced lim
)
716 "Move forward by tokens.
717 A token is defined as all symbols and identifiers which aren't
718 syntactic whitespace \(note that e.g. \"->\" is considered to be two
719 tokens). Point is always either left at the beginning of a token or
720 not moved at all. COUNT specifies the number of tokens to move; a
721 negative COUNT moves in the opposite direction. A COUNT of 0 moves to
722 the next token beginning only if not already at one. If BALANCED is
723 true, move over balanced parens, otherwise move into them. Also, if
724 BALANCED is true, never move out of an enclosing paren. LIM sets the
725 limit for the movement and defaults to the point limit.
727 Return the number of tokens left to move \(positive or negative). If
728 BALANCED is true, a move over a balanced paren counts as one. Note
729 that if COUNT is 0 and no appropriate token beginning is found, 1 will
730 be returned. Thus, a return value of 0 guarantees that point is at
731 the requested position and a return value less \(without signs) than
732 COUNT guarantees that point is at the beginning of some token."
733 (or count
(setq count
1))
735 (- (c-backward-token-1 (- count
) balanced lim
))
736 (let ((jump-syntax (if balanced
737 '(?w ?_ ?\
( ?\
) ?
\" ?
\\ ?
/ ?$ ?
')
738 '(?w ?_ ?
\" ?
\\ ?
/ ?
')))
742 (if lim
(narrow-to-region (point-min) lim
))
744 (progn (c-forward-syntactic-ws) (point)))
745 ;; Skip whitespace. Count this as a move if we did in fact
746 ;; move and aren't out of bounds.
748 (setq count
(max (1- count
) 0))))
750 (or (and (memq (char-syntax (or (char-after) ?
)) '(?w ?_
))
751 (memq (char-syntax (or (char-before) ?
)) '(?w ?_
)))
753 ;; If count is zero we should jump if in the middle of a
754 ;; token or if there is whitespace between point and the
755 ;; following token beginning.
759 ;; Avoid having the limit tests inside the loop.
764 (if (memq (char-syntax (char-after)) jump-syntax
)
765 (goto-char (scan-sexps (point) 1))
767 (c-forward-syntactic-ws)
768 (setq count
(1- count
)))
769 (error (goto-char last
)))
772 (setq count
(1+ count
)))))
775 (defun c-backward-token-1 (&optional count balanced lim
)
776 "Move backward by tokens.
777 See `c-forward-token-1' for details."
778 (or count
(setq count
1))
780 (- (c-forward-token-1 (- count
) balanced lim
))
781 (let ((jump-syntax (if balanced
782 '(?w ?_ ?\
( ?\
) ?
\" ?
\\ ?
/ ?$ ?
')
783 '(?w ?_ ?
\" ?
\\ ?
/ ?
')))
786 (or (and (memq (char-syntax (or (char-after) ?
)) '(?w ?_
))
787 (memq (char-syntax (or (char-before) ?
)) '(?w ?_
)))
790 (c-forward-syntactic-ws (1+ lim
))
793 ;; If count is zero we should jump if in the middle of a
794 ;; token or if there is whitespace between point and the
795 ;; following token beginning.
798 (if lim
(narrow-to-region lim
(point-max)))
801 ;; Avoid having the limit tests inside the loop.
806 (c-backward-syntactic-ws)
807 (if (memq (char-syntax (char-before)) jump-syntax
)
808 (goto-char (scan-sexps (point) -
1))
810 (setq count
(1- count
)))
811 (error (goto-char last
)))
812 (if (bobp) (goto-char last
)))))
815 (defun c-syntactic-re-search-forward (regexp &optional bound noerror count
817 ;; Like `re-search-forward', but only report matches that are found
818 ;; in syntactically significant text. I.e. matches that begins in
819 ;; comments, macros or string literals are ignored. The start point
820 ;; is assumed to be outside any comment, macro or string literal, or
821 ;; else the content of that region is taken as syntactically
822 ;; significant text. If PAREN-LEVEL is non-nil, an additional
823 ;; restriction is added to ignore matches in nested paren sexps, and
824 ;; the search will also not go outside the current paren sexp.
825 (or bound
(setq bound
(point-max)))
826 (or count
(setq count
1))
827 (if paren-level
(setq paren-level -
1))
828 (let ((start (point))
832 (while (and (> count
0)
833 (re-search-forward regexp bound noerror
))
834 (setq match-pos
(point)
835 state
(parse-partial-sexp pos
(match-beginning 0)
836 paren-level nil state
)
839 ;; Match inside a string. Skip to the end of it
840 ;; before continuing.
841 (let ((ender (make-string 1 (nth 3 state
))))
843 (search-forward ender bound noerror
)
844 (setq state
(parse-partial-sexp pos
(point)
849 ;; Match inside a line comment. Skip to eol. Use
850 ;; re-search-forward for it to get the right bound
852 (re-search-forward "[\n\r]" bound noerror
))
854 ;; Match inside a block comment. Skip to the '*/'.
855 (re-search-forward "\\*/" bound noerror
))
856 ((save-excursion (c-beginning-of-macro start
))
857 ;; Match inside a macro. Skip to the end of it.
859 ((and paren-level
(/= (car state
) 0))
860 (if (> (car state
) 0)
861 ;; Match inside a nested paren sexp. Skip out of it.
862 (setq state
(parse-partial-sexp pos bound
0 nil state
)
864 ;; Have exited the current paren sexp. The
865 ;; parse-partial-sexp above has left us just after
866 ;; the closing paren in this case. Just make
867 ;; re-search-forward above fail in the appropriate
868 ;; way; we'll adjust the leave off point below if
870 (setq bound
(point))))
873 (setq count
(1- count
)))))
876 (signal (car err
) (cdr err
))))
879 (goto-char match-pos
)
881 ;; Search failed. Set point as appropriate.
882 (cond ((eq noerror t
)
885 (if (eq (car (parse-partial-sexp pos bound -
1 nil state
)) -
1)
892 (defun c-in-literal (&optional lim detect-cpp
)
893 "Return the type of literal point is in, if any.
894 The return value is `c' if in a C-style comment, `c++' if in a C++
895 style comment, `string' if in a string literal, `pound' if DETECT-CPP
896 is non-nil and on a preprocessor line, or nil if somewhere else.
897 Optional LIM is used as the backward limit of the search. If omitted,
898 or nil, `c-beginning-of-defun' is used.
900 The last point calculated is cached if the cache is enabled, i.e. if
901 `c-in-literal-cache' is bound to a two element vector."
902 (if (and (vectorp c-in-literal-cache
)
903 (= (point) (aref c-in-literal-cache
0)))
904 (aref c-in-literal-cache
1)
905 (let ((rtn (save-excursion
906 (let* ((lim (or lim
(c-point 'bod
)))
907 (state (parse-partial-sexp lim
(point))))
909 ((nth 3 state
) 'string
)
910 ((nth 4 state
) (if (nth 7 state
) 'c
++ 'c
))
911 ((and detect-cpp
(c-beginning-of-macro lim
)) 'pound
)
913 ;; cache this result if the cache is enabled
914 (if (not c-in-literal-cache
)
915 (setq c-in-literal-cache
(vector (point) rtn
)))
918 ;; XEmacs has a built-in function that should make this much quicker.
919 ;; I don't think we even need the cache, which makes our lives more
920 ;; complicated anyway. In this case, lim is only used to detect
922 (defun c-fast-in-literal (&optional lim detect-cpp
)
923 (let ((context (buffer-syntactic-context)))
925 ((eq context
'string
) 'string
)
926 ((eq context
'comment
) 'c
++)
927 ((eq context
'block-comment
) 'c
)
928 ((and detect-cpp
(save-excursion (c-beginning-of-macro lim
))) 'pound
))))
930 (if (fboundp 'buffer-syntactic-context
)
931 (defalias 'c-in-literal
'c-fast-in-literal
))
933 (defun c-literal-limits (&optional lim near not-in-delimiter
)
934 "Return a cons of the beginning and end positions of the comment or
935 string surrounding point (including both delimiters), or nil if point
936 isn't in one. If LIM is non-nil, it's used as the \"safe\" position
937 to start parsing from. If NEAR is non-nil, then the limits of any
938 literal next to point is returned. \"Next to\" means there's only [
939 \t] between point and the literal. The search for such a literal is
940 done first in forward direction. If NOT-IN-DELIMITER is non-nil, the
941 case when point is inside a starting delimiter won't be recognized.
942 This only has effect for comments, which have starting delimiters with
943 more than one character."
946 (lim (or lim
(c-point 'bod
)))
947 (state (parse-partial-sexp lim
(point))))
949 ;; String. Search backward for the start.
951 (search-backward (make-string 1 (nth 3 state
)))
952 (setq state
(parse-partial-sexp lim
(point))))
953 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
956 ;; Line comment. Search from bol for the comment starter.
958 (setq state
(parse-partial-sexp lim
(point))
960 (while (not (nth 7 state
))
961 (search-forward "//") ; Should never fail.
962 (setq state
(parse-partial-sexp
963 lim
(point) nil nil state
)
966 (cons (point) (progn (c-forward-comment 1) (point))))
968 ;; Block comment. Search backward for the comment starter.
970 (search-backward "/*") ; Should never fail.
971 (setq state
(parse-partial-sexp lim
(point))))
972 (cons (point) (progn (c-forward-comment 1) (point))))
973 ((and (not not-in-delimiter
)
975 (eq (char-before) ?
/)
977 ;; We're standing in a comment starter.
979 (cons (point) (progn (c-forward-comment 1) (point))))
982 ;; Search forward for a literal.
983 (skip-chars-forward " \t")
985 ((eq (char-syntax (or (char-after) ?\
)) ?
\") ; String.
986 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
988 ((looking-at "/[/*]") ; Line or block comment.
989 (cons (point) (progn (c-forward-comment 1) (point))))
992 (skip-chars-backward " \t")
993 (let ((end (point)) beg
)
995 ((eq (char-syntax (or (char-before) ?\
)) ?
\") ; String.
996 (setq beg
(c-safe (c-backward-sexp 1) (point))))
997 ((and (c-safe (forward-char -
2) t
)
999 ;; Block comment. Due to the nature of line
1000 ;; comments, they will always be covered by the
1001 ;; normal case above.
1003 (c-forward-comment -
1)
1004 ;; If LIM is bogus, beg will be bogus.
1005 (setq beg
(point))))
1006 (if beg
(cons beg end
))))))
1009 (defun c-literal-limits-fast (&optional lim near not-in-delimiter
)
1010 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
1011 ;; returns the pos of the comment start.
1013 (let* ((pos (point))
1014 (lim (or lim
(c-point 'bod
)))
1015 (state (parse-partial-sexp lim
(point))))
1016 (cond ((nth 3 state
) ; String.
1017 (goto-char (nth 8 state
))
1018 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
1020 ((nth 4 state
) ; Comment.
1021 (goto-char (nth 8 state
))
1022 (cons (point) (progn (c-forward-comment 1) (point))))
1023 ((and (not not-in-delimiter
)
1025 (eq (char-before) ?
/)
1026 (looking-at "[/*]"))
1027 ;; We're standing in a comment starter.
1029 (cons (point) (progn (c-forward-comment 1) (point))))
1032 ;; Search forward for a literal.
1033 (skip-chars-forward " \t")
1035 ((eq (char-syntax (or (char-after) ?\
)) ?
\") ; String.
1036 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
1038 ((looking-at "/[/*]") ; Line or block comment.
1039 (cons (point) (progn (c-forward-comment 1) (point))))
1042 (skip-chars-backward " \t")
1043 (let ((end (point)) beg
)
1045 ((eq (char-syntax (or (char-before) ?\
)) ?
\") ; String.
1046 (setq beg
(c-safe (c-backward-sexp 1) (point))))
1047 ((and (c-safe (forward-char -
2) t
)
1049 ;; Block comment. Due to the nature of line
1050 ;; comments, they will always be covered by the
1051 ;; normal case above.
1053 (c-forward-comment -
1)
1054 ;; If LIM is bogus, beg will be bogus.
1055 (setq beg
(point))))
1056 (if beg
(cons beg end
))))))
1059 (if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8))
1060 (defalias 'c-literal-limits
'c-literal-limits-fast
))
1062 (defun c-collect-line-comments (range)
1063 "If the argument is a cons of two buffer positions (such as returned by
1064 `c-literal-limits'), and that range contains a C++ style line comment,
1065 then an extended range is returned that contains all adjacent line
1066 comments (i.e. all comments that starts in the same column with no
1067 empty lines or non-whitespace characters between them). Otherwise the
1068 argument is returned."
1071 (if (and (consp range
) (progn
1072 (goto-char (car range
))
1074 (let ((col (current-column))
1076 (bopl (c-point 'bopl
))
1078 ;; Got to take care in the backward direction to handle
1079 ;; comments which are preceded by code.
1080 (while (and (c-forward-comment -
1)
1083 (= col
(current-column)))
1085 bopl
(c-point 'bopl
)))
1087 (while (and (progn (skip-chars-forward " \t")
1089 (= col
(current-column))
1090 (prog1 (zerop (forward-line 1))
1091 (setq end
(point)))))
1096 (defun c-literal-type (range)
1097 "Convenience function that given the result of `c-literal-limits',
1098 returns nil or the type of literal that the range surrounds. It's
1099 much faster than using `c-in-literal' and is intended to be used when
1100 you need both the type of a literal and its limits."
1103 (goto-char (car range
))
1104 (cond ((eq (char-syntax (or (char-after) ?\
)) ?
\") 'string
)
1105 ((looking-at "//") 'c
++)
1106 (t 'c
))) ; Assuming the range is valid.
1111 ;; utilities for moving and querying around syntactic elements
1113 (defvar c-state-cache nil
)
1114 (make-variable-buffer-local 'c-state-cache
)
1115 ;; The state cache used by `c-parse-state' to cut down the amount of
1116 ;; searching. It's the result from some earlier `c-parse-state' call.
1117 ;; The use of the cached info is more effective if the next
1118 ;; `c-parse-state' call is on a line close by the one the cached state
1119 ;; was made at; the cache can actually slow down a little if the
1120 ;; cached state was made very far back in the buffer. The cache is
1121 ;; most effective if `c-parse-state' is used on each line while moving
1124 (defvar c-state-cache-start nil
)
1125 ;; This (point-min) when `c-state-cache' was calculated, to detect
1126 ;; that the start point hasn't changed due to narrowing.
1128 (defun c-parse-state ()
1129 ;; Finds and records all noteworthy parens between some good point
1130 ;; earlier in the file and point. That good point is at least the
1131 ;; beginning of the top-level construct we are in, or the beginning
1132 ;; of the preceding top-level construct if we aren't in one.
1134 ;; The returned value is a list of the noteworthy parens with the
1135 ;; last one first. If an element in the list is an integer, it's
1136 ;; the position of an open paren which has not been closed before
1137 ;; point. If an element is a cons, it gives the position of a
1138 ;; closed brace paren pair; the car is the start paren position and
1139 ;; the cdr is the position following the closing paren. Only the
1140 ;; last closed brace paren pair before each open paren is recorded,
1141 ;; and thus the state never contains two cons elements in
1144 (let* ((here (point))
1145 (c-macro-start (c-query-macro-start))
1146 (in-macro-start (or c-macro-start
(point)))
1147 old-state last-pos pairs pos
)
1148 ;; Somewhat ugly use of c-check-state-cache to get rid of the
1149 ;; part of the state cache that is after point. Can't use
1150 ;; c-whack-state-after for the same reasons as in that function.
1151 (c-check-state-cache (point) nil nil
)
1152 ;; Get the latest position we know are directly inside the
1153 ;; closest containing paren of the cached state.
1154 (setq last-pos
(and c-state-cache
1155 (if (consp (car c-state-cache
))
1156 (cdr (car c-state-cache
))
1157 (1+ (car c-state-cache
)))))
1158 ;; Check if the found last-pos is in a macro. If it is, and
1159 ;; we're not in the same macro, we must discard everything on
1160 ;; c-state-cache that is inside the macro before using it.
1163 (goto-char last-pos
)
1164 (when (and (c-beginning-of-macro)
1165 (/= (point) in-macro-start
))
1166 (c-check-state-cache (point) nil nil
)
1167 ;; Set last-pos again, just like above.
1168 (setq last-pos
(and c-state-cache
1169 (if (consp (car c-state-cache
))
1170 (cdr (car c-state-cache
))
1171 (1+ (car c-state-cache
))))))))
1173 ;; Find the start position for the forward search. (Can't
1174 ;; search in the backward direction since point might be
1175 ;; in some kind of literal.)
1177 ;; There's a cached state with a containing paren. Pop
1178 ;; off the stale containing sexps from it by going
1179 ;; forward out of parens as far as possible.
1180 (narrow-to-region (point-min) here
)
1181 (let (placeholder pair-beg
)
1182 (while (and c-state-cache
1184 (c-up-list-forward last-pos
)))
1185 (setq last-pos placeholder
)
1186 (if (consp (car c-state-cache
))
1187 (setq pair-beg
(car-safe (cdr c-state-cache
))
1188 c-state-cache
(cdr-safe (cdr c-state-cache
)))
1189 (setq pair-beg
(car c-state-cache
)
1190 c-state-cache
(cdr c-state-cache
))))
1191 (when (and pair-beg
(eq (char-after pair-beg
) ?
{))
1192 ;; The last paren pair we moved out from was a brace
1193 ;; pair. Modify the state to record this as a closed
1195 (if (consp (car-safe c-state-cache
))
1196 (setq c-state-cache
(cdr c-state-cache
)))
1197 (setq c-state-cache
(cons (cons pair-beg last-pos
)
1199 ;; Check if the preceding balanced paren is within a
1200 ;; macro; it should be ignored if we're outside the
1201 ;; macro. There's no need to check any further upwards;
1202 ;; if the macro contains an unbalanced opening paren then
1203 ;; we're smoked anyway.
1204 (when (and (<= (point) in-macro-start
)
1205 (consp (car c-state-cache
)))
1207 (goto-char (car (car c-state-cache
)))
1208 (when (c-beginning-of-macro)
1210 c-state-cache
(cdr c-state-cache
)))))
1212 (setq old-state c-state-cache
)
1215 ;; go back 2 bods, but ignore any bogus positions
1216 ;; returned by beginning-of-defun (i.e. open paren in
1220 (while (not (or (bobp) (zerop cnt
)))
1221 (c-beginning-of-defun-1)
1222 (if (eq (char-after) ?\
{)
1223 (setq cnt
(1- cnt
)))))
1225 (narrow-to-region (point-min) here
)
1227 ;; Find the balanced brace pairs.
1229 (while (and (setq last-pos
(c-down-list-forward pos
))
1230 (setq pos
(c-up-list-forward last-pos
)))
1231 (if (eq (char-before last-pos
) ?
{)
1232 (setq pairs
(cons (cons last-pos pos
) pairs
))))
1233 ;; Should ignore any pairs that are in a macro, providing
1234 ;; we're not in the same one.
1235 (when (and pairs
(< (car (car pairs
)) in-macro-start
))
1236 (while (and (save-excursion
1237 (goto-char (car (car pairs
)))
1238 (c-beginning-of-macro))
1239 (setq pairs
(cdr pairs
)))))
1240 ;; Record the last brace pair.
1242 (if (and (eq c-state-cache old-state
)
1243 (consp (car-safe c-state-cache
)))
1244 ;; There's a closed pair on the cached state but we've
1245 ;; found a later one, so remove it.
1246 (setq c-state-cache
(cdr c-state-cache
)))
1247 (setq pairs
(car pairs
))
1248 (setcar pairs
(1- (car pairs
)))
1249 (when (consp (car-safe c-state-cache
))
1250 ;; There could already be a cons first in `c-state-cache'
1251 ;; if we've jumped over an unbalanced open paren in a
1253 (setq c-state-cache
(cdr c-state-cache
)))
1254 (setq c-state-cache
(cons pairs c-state-cache
)))
1256 ;; Prepare to loop, but record the open paren only if it's
1257 ;; outside a macro or within the same macro as point.
1260 (if (or (>= last-pos in-macro-start
)
1262 (goto-char last-pos
)
1263 (not (c-beginning-of-macro))))
1264 (setq c-state-cache
(cons (1- pos
) c-state-cache
))))
1265 (if (setq last-pos
(c-up-list-forward pos
))
1266 ;; Found a close paren without a corresponding opening
1267 ;; one. Maybe we didn't go back far enough, so try to
1268 ;; scan backward for the start paren and then start over.
1270 (setq pos
(c-up-list-backward pos
)
1275 (format "Unbalanced close paren at line %d"
1276 (1+ (count-lines (point-min)
1277 (c-point 'bol last-pos
)))))))
1281 ;; Debug tool to catch cache inconsistencies.
1282 (defvar c-debug-parse-state nil
)
1283 (unless (fboundp 'c-real-parse-state
)
1284 (fset 'c-real-parse-state
(symbol-function 'c-parse-state
)))
1285 (cc-bytecomp-defun c-real-parse-state)
1286 (defun c-debug-parse-state ()
1287 (let ((res1 (c-real-parse-state)) res2
)
1288 (let ((c-state-cache nil
))
1289 (setq res2
(c-real-parse-state)))
1290 (unless (equal res1 res2
)
1291 (error "c-parse-state inconsistency: using cache: %s, from scratch: %s"
1294 (defun c-toggle-parse-state-debug (&optional arg
)
1296 (setq c-debug-parse-state
(c-calculate-state arg c-debug-parse-state
))
1297 (fset 'c-parse-state
(symbol-function (if c-debug-parse-state
1298 'c-debug-parse-state
1299 'c-real-parse-state
)))
1300 (c-keep-region-active))
1302 (defun c-check-state-cache (beg end old-length
)
1303 ;; Used on `after-change-functions' to adjust `c-state-cache'.
1304 ;; Prefer speed to finesse here, since there will be many more calls
1305 ;; to this function than times `c-state-cache' is used.
1307 ;; This is much like `c-whack-state-after', but it never changes a
1308 ;; paren pair element into an open paren element. Doing that would
1309 ;; mean that the new open paren wouldn't have the required preceding
1310 ;; paren pair element.
1311 (if (not (eq c-state-cache-start
(point-min)))
1312 (setq c-state-cache-start
(point-min)
1314 (while (and c-state-cache
1315 (let ((elem (car c-state-cache
)))
1317 (or (<= beg
(car elem
))
1320 (setq c-state-cache
(cdr c-state-cache
)))))
1322 (defun c-whack-state-before (bufpos paren-state
)
1323 ;; Whack off any state information from PAREN-STATE which lies
1324 ;; before BUFPOS. Not destructive on PAREN-STATE.
1325 (let* ((newstate (list nil
))
1329 (setq car
(car paren-state
)
1330 paren-state
(cdr paren-state
))
1331 (if (< (if (consp car
) (car car
) car
) bufpos
)
1332 (setq paren-state nil
)
1333 (setcdr ptr
(list car
))
1334 (setq ptr
(cdr ptr
))))
1337 (defun c-whack-state-after (bufpos paren-state
)
1338 ;; Whack off any state information from PAREN-STATE which lies at or
1339 ;; after BUFPOS. Not destructive on PAREN-STATE.
1342 (let ((car (car paren-state
)))
1344 ;; just check the car, because in a balanced brace
1345 ;; expression, it must be impossible for the corresponding
1346 ;; close brace to be before point, but the open brace to
1348 (if (<= bufpos
(car car
))
1350 (if (< bufpos
(cdr car
))
1351 ;; its possible that the open brace is before
1352 ;; bufpos, but the close brace is after. In that
1353 ;; case, convert this to a non-cons element. The
1354 ;; rest of the state is before bufpos, so we're
1356 (throw 'done
(cons (car car
) (cdr paren-state
)))
1357 ;; we know that both the open and close braces are
1358 ;; before bufpos, so we also know that everything else
1359 ;; on state is before bufpos.
1360 (throw 'done paren-state
)))
1363 ;; it's before bufpos, so everything else should too.
1364 (throw 'done paren-state
)))
1365 (setq paren-state
(cdr paren-state
)))
1369 (defun c-beginning-of-inheritance-list (&optional lim
)
1370 ;; Go to the first non-whitespace after the colon that starts a
1371 ;; multiple inheritance introduction. Optional LIM is the farthest
1372 ;; back we should search.
1373 (let* ((lim (or lim
(c-point 'bod
))))
1374 (c-with-syntax-table c
++-template-syntax-table
1375 (c-backward-token-1 0 t lim
)
1376 (while (and (looking-at "[_a-zA-Z<,]")
1377 (= (c-backward-token-1 1 t lim
) 0)))
1378 (skip-chars-forward "^:"))))
1380 (defun c-in-method-def-p ()
1381 ;; Return nil if we aren't in a method definition, otherwise the
1382 ;; position of the initial [+-].
1385 (and c-opt-method-key
1386 (looking-at c-opt-method-key
)
1390 ;; Contributed by Kevin Ryde <user42@zip.com.au>.
1391 (defun c-in-gcc-asm-p ()
1392 ;; Return non-nil if point is within a gcc \"asm\" block.
1394 ;; This should be called with point inside an argument list.
1396 ;; Only one level of enclosing parentheses is considered, so for
1397 ;; instance `nil' is returned when in a function call within an asm
1400 (and c-opt-asm-stmt-key
1403 (backward-up-list 1)
1404 (c-beginning-of-statement-1 (point-min) nil t
)
1405 (looking-at c-opt-asm-stmt-key
))))
1407 (defun c-at-toplevel-p ()
1408 "Return a determination as to whether point is at the `top-level'.
1409 Being at the top-level means that point is either outside any
1410 enclosing block (such function definition), or inside a class,
1411 namespace or extern definition, but outside any method blocks.
1413 If point is not at the top-level (e.g. it is inside a method
1414 definition), then nil is returned. Otherwise, if point is at a
1415 top-level not enclosed within a class definition, t is returned.
1416 Otherwise, a 2-vector is returned where the zeroth element is the
1417 buffer position of the start of the class declaration, and the first
1418 element is the buffer position of the enclosing class's opening
1420 (let ((paren-state (c-parse-state)))
1421 (or (not (c-most-enclosing-brace paren-state
))
1422 (c-search-uplist-for-classkey paren-state
))))
1424 (defun c-forward-to-cpp-define-body ()
1425 ;; Assuming point is at the "#" that introduces a preprocessor
1426 ;; directive, it's moved forward to the start of the definition body
1427 ;; if it's a "#define". Non-nil is returned in this case, in all
1428 ;; other cases nil is returned and point isn't moved.
1429 (when (and (looking-at
1431 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
1432 "\\([ \t]\\|\\\\\n\\)*"))
1433 (not (= (match-end 0) (c-point 'eol
))))
1434 (goto-char (match-end 0))))
1436 (defun c-just-after-func-arglist-p (&optional containing lim
)
1437 ;; Return t if we are between a function's argument list closing
1438 ;; paren and its opening brace. Note that the list close brace
1439 ;; could be followed by a "const" specifier or a member init hanging
1440 ;; colon. Optional CONTAINING is position of containing s-exp open
1441 ;; brace. If not supplied, point is used as search start. LIM is
1442 ;; used as bound for some backward buffer searches; the search might
1443 ;; continue past it.
1445 ;; Note: This test is easily fooled. It only works reasonably well
1446 ;; in the situations where `c-guess-basic-syntax' uses it.
1448 (c-backward-syntactic-ws lim
)
1449 (let ((checkpoint (or containing
(point))))
1450 (goto-char checkpoint
)
1451 ;; could be looking at const specifier
1452 (if (and (eq (char-before) ?t
)
1454 (looking-at "\\<const\\>[^_]"))
1455 (c-backward-syntactic-ws lim
)
1456 ;; otherwise, we could be looking at a hanging member init
1458 (goto-char checkpoint
)
1459 (while (eq (char-before) ?
,)
1460 ;; this will catch member inits with multiple
1463 (c-backward-syntactic-ws (c-point 'bol
))
1464 (if (eq (char-before) ?\
))
1466 (c-backward-sexp 1))
1467 (c-backward-syntactic-ws lim
))
1468 (if (and (eq (char-before) ?
:)
1471 (c-backward-syntactic-ws lim
)
1472 (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)")))
1474 (goto-char checkpoint
))
1476 (setq checkpoint
(point))
1477 (and (eq (char-before) ?\
))
1478 ;; Check that it isn't a cpp expression, e.g. the
1479 ;; expression of an #if directive or the "function header"
1481 (or (not (c-beginning-of-macro))
1482 (and (c-forward-to-cpp-define-body)
1483 (< (point) checkpoint
)))
1484 ;; check if we are looking at an ObjC method def
1485 (or (not c-opt-method-key
)
1487 (goto-char checkpoint
)
1490 (c-backward-syntactic-ws lim
)
1491 (not (or (memq (char-before) '(?- ?
+))
1492 ;; or a class category
1495 (looking-at c-class-key
))
1499 (defun c-in-knr-argdecl (&optional lim
)
1500 ;; Return the position of the first argument declaration if point is
1501 ;; inside a K&R style argument declaration list, nil otherwise.
1502 ;; `c-recognize-knr-p' is not checked. If LIM is non-nil, it's a
1503 ;; position that bounds the backward search for the argument list.
1505 ;; Note: A declaration level context is assumed; the test can return
1506 ;; false positives for statements and #define headers. This test is
1507 ;; even more easily fooled than `c-just-after-func-arglist-p'.
1510 ;; Go back to the closest preceding normal parenthesis sexp. We
1511 ;; take that as the argument list in the function header. Then
1512 ;; check that it's followed by some symbol before the next ';'
1513 ;; or '{'. If it does, it's the header of the K&R argdecl we're
1515 (if lim
(narrow-to-region lim
(point)))
1517 (and (c-safe (setq paren-end
(c-down-list-backward (point))))
1518 (eq (char-after paren-end
) ?\
))
1520 (goto-char (1+ paren-end
))
1521 (c-forward-syntactic-ws)
1522 (looking-at "\\w\\|\\s_"))
1523 (c-safe (c-up-list-backward paren-end
))
1526 (defun c-skip-conditional ()
1527 ;; skip forward over conditional at point, including any predicate
1528 ;; statements in parentheses. No error checking is performed.
1529 (c-forward-sexp (cond
1531 ((looking-at (concat "\\<else"
1532 "\\([ \t\n]\\|\\\\\n\\)+"
1533 "if\\>\\([^_]\\|$\\)"))
1535 ;; do, else, try, finally
1536 ((looking-at (concat "\\<\\("
1537 "do\\|else\\|try\\|finally"
1538 "\\)\\>\\([^_]\\|$\\)"))
1540 ;; for, if, while, switch, catch, synchronized, foreach
1543 (defun c-after-conditional (&optional lim
)
1544 ;; If looking at the token after a conditional then return the
1545 ;; position of its start, otherwise return nil.
1547 (and (= (c-backward-token-1 1 t lim
) 0)
1548 (or (looking-at c-block-stmt-1-key
)
1549 (and (eq (char-after) ?\
()
1550 (= (c-backward-token-1 1 t lim
) 0)
1551 (looking-at c-block-stmt-2-key
)))
1554 (defsubst c-backward-to-block-anchor
(&optional lim
)
1555 ;; Assuming point is at a brace that opens a statement block of some
1556 ;; kind, move to the proper anchor point for that block. It might
1557 ;; need to be adjusted further by c-add-stmt-syntax, but the
1558 ;; position at return is suitable as start position for that
1560 (unless (= (point) (c-point 'boi
))
1561 (let ((start (c-after-conditional lim
)))
1563 (goto-char start
)))))
1565 (defun c-backward-to-decl-anchor (&optional lim
)
1566 ;; Assuming point is at a brace that opens the block of a top level
1567 ;; declaration of some kind, move to the proper anchor point for
1569 (unless (= (point) (c-point 'boi
))
1570 ;; What we have below is actually an extremely stripped variant of
1571 ;; c-beginning-of-statement-1.
1572 (let ((pos (point)))
1573 ;; Switch syntax table to avoid stopping at line continuations.
1575 (if lim
(narrow-to-region lim
(point-max)))
1577 (c-backward-syntactic-ws)
1578 (c-safe (goto-char (scan-sexps (point) -
1)) t
))
1579 (not (c-crosses-statement-barrier-p (point) pos
)))
1583 (defsubst c-search-decl-header-end
()
1584 ;; Search forward for the end of the "header" of the current
1585 ;; declaration. That's the position where the definition body
1586 ;; starts, or the first variable initializer, or the ending
1587 ;; semicolon. I.e. search forward for the closest following
1588 ;; (syntactically relevant) '{', '=' or ';' token. Point is left
1589 ;; _after_ the first found token, or at point-max if none is found.
1590 (c-with-syntax-table (if (c-major-mode-is 'c
++-mode
)
1591 c
++-template-syntax-table
1593 (while (and (c-syntactic-re-search-forward "[;{=]" nil
'move
1 t
)
1594 ;; In Pike it can be an operator identifier containing
1596 (c-major-mode-is 'pike-mode
)
1597 (eq (char-before) ?
=)
1598 (c-on-identifier)))))
1600 (defun c-beginning-of-decl-1 (&optional lim
)
1601 ;; Go to the beginning of the current declaration, or the beginning
1602 ;; of the previous one if already at the start of it. Point won't
1603 ;; be moved out of any surrounding paren. Return a cons cell on the
1604 ;; form (MOVE . KNR-POS). MOVE is like the return value from
1605 ;; `c-beginning-of-statement-1'. If point skipped over some K&R
1606 ;; style argument declarations (and they are to be recognized) then
1607 ;; KNR-POS is set to the start of the first such argument
1608 ;; declaration, otherwise KNR-POS is nil. If LIM is non-nil, it's a
1609 ;; position that bounds the backward search.
1611 ;; NB: Cases where the declaration continues after the block, as in
1612 ;; "struct foo { ... } bar;", are currently recognized as two
1613 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case.
1615 (let* ((start (point))
1616 (last-stmt-start (point))
1617 (move (c-beginning-of-statement-1 lim t t
)))
1619 (while (and (/= last-stmt-start
(point))
1621 (c-backward-syntactic-ws lim
)
1622 (not (memq (char-before) '(?\
; ?} ?: nil)))))
1623 ;; `c-beginning-of-statement-1' stops at a block start, but we
1624 ;; want to continue if the block doesn't begin a top level
1625 ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob.
1626 (setq last-stmt-start
(point)
1627 move
(c-beginning-of-statement-1 lim t t
)))
1629 (when c-recognize-knr-p
1630 (let ((fallback-pos (point)) knr-argdecl-start
)
1631 ;; Handle K&R argdecls. Back up after the "statement" jumped
1632 ;; over by `c-beginning-of-statement-1', unless it was the
1633 ;; function body, in which case we're sitting on the opening
1634 ;; brace now. Then test if we're in a K&R argdecl region and
1635 ;; that we started at the other side of the first argdecl in
1637 (unless (eq (char-after) ?
{)
1638 (goto-char last-stmt-start
))
1639 (if (and (setq knr-argdecl-start
(c-in-knr-argdecl lim
))
1640 (< knr-argdecl-start start
)
1642 (goto-char knr-argdecl-start
)
1643 (not (eq (c-beginning-of-statement-1 lim t t
) 'macro
))))
1645 (cons (if (eq (char-after fallback-pos
) ?
{)
1649 (goto-char fallback-pos
))))
1651 (when c-opt-access-key
1652 ;; Might have ended up before a protection label. This should
1653 ;; perhaps be checked before `c-recognize-knr-p' to be really
1654 ;; accurate, but we know that no language has both.
1655 (while (looking-at c-opt-access-key
)
1656 (goto-char (match-end 0))
1657 (c-forward-syntactic-ws)
1658 (when (>= (point) start
)
1660 (throw 'return
(cons 'same nil
)))))
1662 ;; `c-beginning-of-statement-1' counts each brace block as a
1663 ;; separate statement, so the result will be 'previous if we've
1664 ;; moved over any. If they were brace list initializers we might
1665 ;; not have moved over a declaration boundary though, so change it
1666 ;; to 'same if we've moved past a '=' before '{', but not ';'.
1667 ;; (This ought to be integrated into `c-beginning-of-statement-1',
1668 ;; so we avoid this extra pass which potentially can search over a
1669 ;; large amount of text.)
1670 (if (and (eq move
'previous
)
1671 (c-with-syntax-table (if (c-major-mode-is 'c
++-mode
)
1672 c
++-template-syntax-table
1675 (and (c-syntactic-re-search-forward "[;={]" start t
1 t
)
1676 (eq (char-before) ?
=)
1677 (c-syntactic-re-search-forward "[;{]" start t
1 t
)
1678 (eq (char-before) ?
{)
1679 (c-safe (goto-char (c-up-list-forward (point))) t
)
1680 (not (c-syntactic-re-search-forward ";" start t
1 t
))))))
1684 (defun c-end-of-decl-1 ()
1685 ;; Assuming point is at the start of a declaration (as detected by
1686 ;; e.g. `c-beginning-of-decl-1'), go to the end of it. Unlike
1687 ;; `c-beginning-of-decl-1', this function handles the case when a
1688 ;; block is followed by identifiers in e.g. struct declarations in C
1689 ;; or C++. If a proper end was found then t is returned, otherwise
1690 ;; point is moved as far as possible within the current sexp and nil
1691 ;; is returned. This function doesn't handle macros; use
1692 ;; `c-end-of-macro' instead in those cases.
1693 (let ((start (point))
1694 (decl-syntax-table (if (c-major-mode-is 'c
++-mode
)
1695 c
++-template-syntax-table
1698 (c-search-decl-header-end)
1700 (when (and c-recognize-knr-p
1701 (eq (char-before) ?\
;)
1702 (c-in-knr-argdecl start
))
1703 ;; Stopped at the ';' in a K&R argdecl section which is
1704 ;; detected using the same criteria as in
1705 ;; `c-beginning-of-decl-1'. Move to the following block
1707 (c-syntactic-re-search-forward "{" nil
'move
1 t
))
1709 (when (eq (char-before) ?
{)
1710 ;; Encountered a block in the declaration. Jump over it.
1712 (goto-char (c-up-list-forward (point)))
1713 (goto-char (point-max))
1714 (throw 'return nil
))
1715 (if (or (not c-opt-block-decls-with-vars-key
)
1717 (c-with-syntax-table decl-syntax-table
1718 (let ((lim (point)))
1721 ;; Check for `c-opt-block-decls-with-vars-key'
1722 ;; before the first paren.
1723 (c-syntactic-re-search-forward
1724 (concat "[;=\(\[{]\\|\\<\\("
1725 c-opt-block-decls-with-vars-key
1729 (not (eq (char-before) ?_
))
1730 ;; Check that the first following paren is the block.
1731 (c-syntactic-re-search-forward "[;=\(\[{]" lim t
1 t
)
1732 (eq (char-before) ?
{)))))))
1733 ;; The declaration doesn't have any of the
1734 ;; `c-opt-block-decls-with-vars' keywords in the
1735 ;; beginning, so it ends here at the end of the block.
1738 (c-with-syntax-table decl-syntax-table
1740 (if (eq (char-before) ?\
;)
1742 (c-syntactic-re-search-forward ";" nil
'move
1 t
))))
1745 (defun c-beginning-of-member-init-list (&optional limit
)
1746 ;; Goes to the beginning of a member init list (i.e. just after the
1747 ;; ':') if inside one. Returns t in that case, nil otherwise.
1749 (setq limit
(point-min)))
1750 (skip-chars-forward " \t")
1751 (if (eq (char-after) ?
,)
1753 (c-backward-syntactic-ws limit
))
1754 (while (and (< limit
(point))
1755 (eq (char-before) ?
,))
1756 ;; this will catch member inits with multiple
1759 (c-backward-syntactic-ws limit
)
1760 (if (eq (char-before) ?\
))
1761 (c-backward-sexp 1))
1762 (c-backward-syntactic-ws limit
)
1763 ;; Skip over any template arg to the class.
1764 (if (eq (char-before) ?
>)
1765 (c-with-syntax-table c
++-template-syntax-table
1766 (c-backward-sexp 1)))
1768 (c-backward-syntactic-ws limit
)
1769 ;; Skip backwards over a fully::qualified::name.
1770 (while (and (eq (char-before) ?
:)
1773 (eq (char-before) ?
:)))
1775 (c-backward-sexp 1))
1776 ;; now continue checking
1777 (c-backward-syntactic-ws limit
))
1778 (and (< limit
(point))
1779 (eq (char-before) ?
:)))
1781 (defun c-search-uplist-for-classkey (paren-state)
1782 ;; search for the containing class, returning a 2 element vector if
1783 ;; found. aref 0 contains the bufpos of the boi of the class key
1784 ;; line, and aref 1 contains the bufpos of the open brace.
1785 (if (null paren-state
)
1786 ;; no paren-state means we cannot be inside a class
1788 (let ((carcache (car paren-state
))
1789 search-start search-end
)
1790 (if (consp carcache
)
1791 ;; a cons cell in the first element means that there is some
1792 ;; balanced sexp before the current bufpos. this we can
1793 ;; ignore. the nth 1 and nth 2 elements define for us the
1794 ;; search boundaries
1795 (setq search-start
(nth 2 paren-state
)
1796 search-end
(nth 1 paren-state
))
1797 ;; if the car was not a cons cell then nth 0 and nth 1 define
1798 ;; for us the search boundaries
1799 (setq search-start
(nth 1 paren-state
)
1800 search-end
(nth 0 paren-state
)))
1801 ;; if search-end is nil, or if the search-end character isn't an
1802 ;; open brace, we are definitely not in a class
1803 (when (consp search-end
)
1804 (setq search-end
(car search-end
)))
1805 (unless (or (not search-end
)
1806 (< search-end
(point-min))
1807 (not (eq (char-after search-end
) ?
{)))
1808 ;; now, we need to look more closely at search-start. if
1809 ;; search-start is nil, then our start boundary is really
1811 (if (not search-start
)
1812 (setq search-start
(point-min))
1813 ;; if search-start is a cons cell, then we can start
1814 ;; searching from the end of the balanced sexp just ahead of
1816 (if (consp search-start
)
1817 (setq search-start
(cdr search-start
))))
1818 ;; now we can do a quick regexp search from search-start to
1819 ;; search-end and see if we can find a class key. watch for
1820 ;; class like strings in literals
1823 (goto-char search-start
)
1824 (let (foundp class match-end
)
1825 (while (and (not foundp
)
1827 (c-forward-syntactic-ws search-end
)
1828 (> search-end
(point)))
1829 (re-search-forward c-decl-block-key search-end t
))
1830 (setq class
(match-beginning 0)
1831 match-end
(match-end 0))
1833 (if (c-in-literal search-start
)
1834 (goto-char match-end
) ; its in a comment or string, ignore
1836 (setq foundp
(vector (c-point 'boi
) search-end
))
1838 ;; check for embedded keywords
1839 ((let ((char (char-after (1- class
))))
1841 (memq (char-syntax char
) '(?w ?_
))))
1842 (goto-char match-end
)
1844 ;; make sure we're really looking at the start of a
1845 ;; class definition, and not an ObjC method.
1846 ((and c-opt-method-key
1847 (re-search-forward c-opt-method-key search-end t
)
1848 (not (c-in-literal class
)))
1850 ;; Check if this is an anonymous inner class.
1851 ((and c-opt-inexpr-class-key
1852 (looking-at c-opt-inexpr-class-key
))
1853 (while (and (= (c-forward-token-1 1 t
) 0)
1854 (looking-at "(\\|\\w\\|\\s_\\|\\.")))
1855 (if (eq (point) search-end
)
1856 ;; We're done. Just trap this case in the cond.
1858 ;; False alarm; all conditions aren't satisfied.
1860 ;; Its impossible to define a regexp for this, and
1861 ;; nearly so to do it programmatically.
1863 ;; ; picks up forward decls
1864 ;; = picks up init lists
1865 ;; ) picks up return types
1866 ;; > picks up templates, but remember that we can
1867 ;; inherit from templates!
1868 ((let ((skipchars "^;=)"))
1869 ;; try to see if we found the `class' keyword
1870 ;; inside a template arg list
1872 (skip-chars-backward "^<>" search-start
)
1873 (if (eq (char-before) ?
<)
1874 (setq skipchars
(concat skipchars
">"))))
1876 (skip-chars-forward skipchars search-end
)
1877 (c-in-literal class
))
1879 (/= (point) search-end
))
1885 (defun c-inside-bracelist-p (containing-sexp paren-state
)
1886 ;; return the buffer position of the beginning of the brace list
1887 ;; statement if we're inside a brace list, otherwise return nil.
1888 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
1889 ;; paren. BRACE-STATE is the remainder of the state of enclosing
1892 ;; N.B.: This algorithm can potentially get confused by cpp macros
1893 ;; places in inconvenient locations. Its a trade-off we make for
1896 ;; this will pick up enum lists
1899 (goto-char containing-sexp
)
1902 (if (and (or (looking-at "enum\\>[^_]")
1903 (progn (c-forward-sexp -
1)
1904 (looking-at "enum\\>[^_]")))
1905 (setq bracepos
(c-down-list-forward (point)))
1906 (not (c-crosses-statement-barrier-p (point)
1909 ;; this will pick up array/aggregate init lists, even if they are nested.
1912 ;; Pike can have class definitions anywhere, so we must
1913 ;; check for the class key here.
1914 (and (c-major-mode-is 'pike-mode
)
1916 bufpos braceassignp lim next-containing
)
1917 (while (and (not bufpos
)
1920 (if (consp (car paren-state
))
1921 (setq lim
(cdr (car paren-state
))
1922 paren-state
(cdr paren-state
))
1923 (setq lim
(car paren-state
)))
1925 (setq next-containing
(car paren-state
)
1926 paren-state
(cdr paren-state
))))
1927 (goto-char containing-sexp
)
1928 (if (c-looking-at-inexpr-block next-containing next-containing
)
1929 ;; We're in an in-expression block of some kind. Do not
1930 ;; check nesting. We deliberately set the limit to the
1931 ;; containing sexp, so that c-looking-at-inexpr-block
1932 ;; doesn't check for an identifier before it.
1933 (setq containing-sexp nil
)
1934 ;; see if the open brace is preceded by = or [...] in
1935 ;; this statement, but watch out for operator=
1936 (setq braceassignp
'dontknow
)
1937 (c-backward-token-1 1 t lim
)
1938 ;; Checks to do only on the first sexp before the brace.
1939 (when (and (c-major-mode-is 'java-mode
)
1940 (eq (char-after) ?\
[))
1941 ;; In Java, an initialization brace list may follow
1942 ;; directly after "new Foo[]", so check for a "new"
1944 (while (eq braceassignp
'dontknow
)
1946 (cond ((/= (c-backward-token-1 1 t lim
) 0) nil
)
1947 ((looking-at "new\\>[^_]") t
)
1948 ((looking-at "\\sw\\|\\s_\\|[.[]")
1949 ;; Carry on looking if this is an
1950 ;; identifier (may contain "." in Java)
1951 ;; or another "[]" sexp.
1954 ;; Checks to do on all sexps before the brace, up to the
1955 ;; beginning of the statement.
1956 (while (eq braceassignp
'dontknow
)
1957 (cond ((eq (char-after) ?\
;)
1958 (setq braceassignp nil
))
1960 (looking-at class-key
))
1961 (setq braceassignp nil
))
1962 ((eq (char-after) ?
=)
1963 ;; We've seen a =, but must check earlier tokens so
1964 ;; that it isn't something that should be ignored.
1965 (setq braceassignp
'maybe
)
1966 (while (and (eq braceassignp
'maybe
)
1967 (zerop (c-backward-token-1 1 t lim
)))
1970 ;; Check for operator =
1971 ((looking-at "operator\\>[^_]") nil
)
1972 ;; Check for `<opchar>= in Pike.
1973 ((and (c-major-mode-is 'pike-mode
)
1974 (or (eq (char-after) ?
`)
1975 ;; Special case for Pikes
1976 ;; `[]=, since '[' is not in
1977 ;; the punctuation class.
1978 (and (eq (char-after) ?\
[)
1979 (eq (char-before) ?
`))))
1981 ((looking-at "\\s.") 'maybe
)
1982 ;; make sure we're not in a C++ template
1983 ;; argument assignment
1985 (c-major-mode-is 'c
++-mode
)
1987 (let ((here (point))
1989 (skip-chars-backward "^<>")
1991 (and (eq (char-before) ?
<)
1992 (not (c-crosses-statement-barrier-p
1994 (not (c-in-literal))
1998 (if (and (eq braceassignp
'dontknow
)
1999 (/= (c-backward-token-1 1 t lim
) 0))
2000 (setq braceassignp nil
)))
2001 (if (not braceassignp
)
2002 (if (eq (char-after) ?\
;)
2003 ;; Brace lists can't contain a semicolon, so we're done.
2004 (setq containing-sexp nil
)
2006 (setq containing-sexp next-containing
2008 next-containing nil
))
2009 ;; we've hit the beginning of the aggregate list
2010 (c-beginning-of-statement-1
2011 (c-most-enclosing-brace paren-state
))
2012 (setq bufpos
(point))))
2017 (defun c-looking-at-special-brace-list (&optional lim
)
2018 ;; If we're looking at the start of a pike-style list, ie `({Â })',
2019 ;; `([Â ])', `(<Â >)' etc, a cons of a cons of its starting and ending
2020 ;; positions and its entry in c-special-brace-lists is returned, nil
2021 ;; otherwise. The ending position is nil if the list is still open.
2022 ;; LIM is the limit for forward search. The point may either be at
2023 ;; the `(' or at the following paren character. Tries to check the
2024 ;; matching closer, but assumes it's correct if no balanced paren is
2025 ;; found (i.e. the case `({ ... } ... )' is detected as _not_ being
2026 ;; a special brace list).
2027 (if c-special-brace-lists
2032 (c-forward-syntactic-ws)
2033 (if (eq (char-after) ?\
()
2036 (c-forward-syntactic-ws)
2037 (setq type
(assq (char-after) c-special-brace-lists
)))
2038 (if (setq type
(assq (char-after) c-special-brace-lists
))
2040 (c-backward-syntactic-ws)
2042 (setq beg
(if (eq (char-after) ?\
()
2046 (if (and (c-safe (goto-char beg
)
2049 (= (char-before) ?\
)))
2050 (c-safe (goto-char beg
)
2053 ;; Kludges needed to handle inner
2054 ;; chars both with and without
2056 (or (/= (char-syntax (char-before)) ?\
))
2057 (= (char-before) (cdr type
)))))
2058 (if (or (/= (char-syntax (char-before)) ?\
))
2060 (c-forward-syntactic-ws)
2063 (cons (cons beg end
) type
))
2064 (cons (list beg
) type
)))))
2067 (defun c-looking-at-bos (&optional lim
)
2068 ;; Return non-nil if between two statements or declarations, assuming
2069 ;; point is not inside a literal or comment.
2071 (c-backward-syntactic-ws lim
)
2073 ;; Return t if at the start inside some parenthesis expression
2074 ;; too, to catch macros that have statements as arguments.
2075 (memq (char-before) '(?\
; ?} ?\())
2076 (and (eq (char-before) ?
{)
2077 (not (and c-special-brace-lists
2078 (progn (backward-char)
2079 (c-looking-at-special-brace-list))))))))
2081 (defun c-looking-at-inexpr-block (lim containing-sexp
)
2082 ;; Returns non-nil if we're looking at the beginning of a block
2083 ;; inside an expression. The value returned is actually a cons of
2084 ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
2085 ;; position of the beginning of the construct. LIM limits the
2086 ;; backward search. CONTAINING-SEXP is the start position of the
2087 ;; closest containing list. If it's nil, the containing paren isn't
2088 ;; used to decide whether we're inside an expression or not. If
2089 ;; both LIM and CONTAINING-SEXP is used, LIM needs to be farther
2092 (let ((res 'maybe
) passed-bracket
2093 (closest-lim (or containing-sexp lim
(point-min)))
2094 ;; Look at the character after point only as a last resort
2095 ;; when we can't disambiguate.
2096 (block-follows (and (eq (char-after) ?
{) (point))))
2097 (while (and (eq res
'maybe
)
2098 (progn (c-backward-syntactic-ws)
2099 (> (point) closest-lim
))
2101 (progn (backward-char)
2102 (looking-at "[\]\).]\\|\\w\\|\\s_"))
2103 (progn (forward-char)
2104 (goto-char (scan-sexps (point) -
1))))
2108 c-opt-inexpr-class-key
2109 (looking-at c-opt-inexpr-class-key
))
2110 (and (not passed-bracket
)
2111 (or (not (looking-at c-class-key
))
2112 ;; If the class definition is at the start of
2113 ;; a statement, we don't consider it an
2114 ;; in-expression class.
2115 (let ((prev (point)))
2117 (= (c-backward-token-1 1 nil closest-lim
) 0)
2118 (eq (char-syntax (char-after)) ?w
))
2119 (setq prev
(point)))
2121 (not (c-looking-at-bos)))
2122 ;; Also, in Pike we treat it as an
2123 ;; in-expression class if it's used in an
2124 ;; object clone expression.
2126 (and (c-major-mode-is 'pike-mode
)
2127 (progn (goto-char block-follows
)
2128 (= (c-forward-token-1 1 t
) 0))
2129 (eq (char-after) ?\
())))
2130 (cons 'inexpr-class
(point))))
2131 ((and c-opt-inexpr-block-key
2132 (looking-at c-opt-inexpr-block-key
))
2133 (cons 'inexpr-statement
(point)))
2134 ((and c-opt-lambda-key
2135 (looking-at c-opt-lambda-key
))
2136 (cons 'inlambda
(point)))
2137 ((and c-opt-block-stmt-key
2138 (looking-at c-opt-block-stmt-key
))
2141 (if (eq (char-after) ?\
[)
2142 (setq passed-bracket t
))
2145 (when (and block-follows
2147 (eq (char-after containing-sexp
) ?\
())
2148 (goto-char containing-sexp
)
2149 (if (or (save-excursion
2150 (c-backward-syntactic-ws lim
)
2151 (and (> (point) (or lim
(point-min)))
2153 (and c-special-brace-lists
2154 (c-looking-at-special-brace-list)))
2156 (cons 'inexpr-statement
(point))))
2159 (defun c-looking-at-inexpr-block-backward (paren-state)
2160 ;; Returns non-nil if we're looking at the end of an in-expression
2161 ;; block, otherwise the same as `c-looking-at-inexpr-block'.
2162 ;; PAREN-STATE is the paren state relevant at the current position.
2164 ;; We currently only recognize a block.
2165 (let ((here (point))
2166 (elem (car-safe paren-state
))
2168 (when (and (consp elem
)
2169 (progn (goto-char (cdr elem
))
2170 (c-forward-syntactic-ws here
)
2172 (goto-char (car elem
))
2173 (if (setq paren-state
(cdr paren-state
))
2174 (setq containing-sexp
(car-safe paren-state
)))
2175 (c-looking-at-inexpr-block (c-safe-position containing-sexp
2177 containing-sexp
)))))
2179 (defun c-on-identifier ()
2180 "Return non-nil if we're on or directly after an identifier.
2181 Keywords are recognized and not considered identifiers."
2182 (if (or (memq (char-syntax (or (char-after) ?
)) '(?w ?_
))
2183 (memq (char-syntax (or (char-before) ?
)) '(?w ?_
)))
2185 (skip-syntax-backward "w_")
2186 (not (looking-at c-keywords-regexp
)))
2187 (if (c-major-mode-is 'pike-mode
)
2188 ;; Handle the `<operator> syntax in Pike.
2190 (if (eq (char-after) ?\
`) (forward-char))
2191 (skip-chars-backward "!%&*+\\-/<=>^|~")
2192 (let ((pos (point)))
2193 (cond ((memq (char-before) '(?\
) ?\
]))
2194 (c-safe (backward-char 2)))
2195 ((memq (char-before) '(?\
( ?\
[))
2196 (c-safe (backward-char 1))))
2197 (if (not (looking-at "()\\|\\[]"))
2199 (and (eq (char-before) ?\
`)
2200 (looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
2203 (defun c-most-enclosing-brace (paren-state &optional bufpos
)
2204 ;; Return the bufpos of the innermost enclosing brace before bufpos
2205 ;; that hasn't been narrowed out, or nil if none was found.
2207 (or bufpos
(setq bufpos
134217727))
2209 (setq enclosingp
(car paren-state
)
2210 paren-state
(cdr paren-state
))
2211 (if (or (consp enclosingp
)
2212 (>= enclosingp bufpos
))
2213 (setq enclosingp nil
)
2214 (if (< enclosingp
(point-min))
2215 (setq enclosingp nil
))
2216 (setq paren-state nil
)))
2219 (defun c-least-enclosing-brace (paren-state &optional bufpos
)
2220 ;; Return the bufpos of the outermost enclosing brace before bufpos
2221 ;; that hasn't been narrowed out, or nil if none was found.
2223 (or bufpos
(setq bufpos
134217727))
2225 (setq elem
(car paren-state
)
2226 paren-state
(cdr paren-state
))
2227 (unless (or (consp elem
)
2229 (if (>= elem
(point-min))
2233 (defun c-safe-position (bufpos paren-state
)
2234 ;; Return the closest known safe position higher up than BUFPOS, or
2235 ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is
2236 ;; nil, which is useful to find the closest limit before a given
2237 ;; limit that might be nil.
2239 (let ((c-macro-start (c-query-macro-start)) safepos
)
2240 (if (and c-macro-start
2241 (< c-macro-start bufpos
))
2242 ;; Make sure bufpos is outside the macro we might be in.
2243 (setq bufpos c-macro-start
))
2247 (if (consp (car paren-state
))
2248 (cdr (car paren-state
))
2250 (if (< safepos bufpos
)
2251 (throw 'done safepos
)
2252 (setq paren-state
(cdr paren-state
))))
2253 (if (eq c-macro-start bufpos
)
2254 ;; Backed up bufpos to the macro start and got outside the
2255 ;; state. We know the macro is at the top level in this case,
2256 ;; so we can use the macro start as the safe position.
2259 (defun c-narrow-out-enclosing-class (paren-state lim
)
2260 ;; Narrow the buffer so that the enclosing class is hidden. Uses
2261 ;; and returns the value from c-search-uplist-for-classkey.
2262 (setq paren-state
(c-whack-state-after (point) paren-state
))
2265 (setq inclass-p
(c-search-uplist-for-classkey paren-state
))
2268 (goto-char (1+ (aref inclass-p
1)))
2269 (c-skip-ws-forward lim
)
2270 ;; if point is now left of the class opening brace, we're
2271 ;; hosed, so try a different tact
2272 (if (<= (point) (aref inclass-p
1))
2274 (goto-char (1+ (aref inclass-p
1)))
2275 (c-forward-syntactic-ws lim
)))
2277 ;; end point is the end of the current line
2281 ;; return the class vector
2285 ;; c-guess-basic-syntax implements the main decision tree for
2286 ;; determining the syntactic analysis of the current line of code.
2287 ;; Yes, it's huge and bloated!
2289 ;; It's useful to break out some parts of the decision tree to
2290 ;; separate functions, which are all collected below. Use dynamic
2291 ;; binding to propagate back the syntax results from them.
2293 (defvar syntactic-relpos
)
2295 (defun c-add-stmt-syntax (syntax-symbol
2299 &optional at-block-start
)
2300 ;; Do the generic processing to anchor the given syntax symbol on
2301 ;; the preceding statement: Skip over any labels and containing
2302 ;; statements on the same line, and then search backward until we
2303 ;; find a statement or block start that begins at boi without a
2304 ;; label or comment.
2306 ;; Point is assumed to be at the prospective anchor point for the
2307 ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to
2308 ;; skip past block opens and containing statement. All the added
2309 ;; syntax elements will get the same anchor point.
2311 ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the
2312 ;; line if another statement precedes the current one on this line.
2314 ;; If AT-BLOCK-START is non-nil, point is taken to be at the
2315 ;; beginning of a block or brace list, which then might be nested
2316 ;; inside an expression. If AT-BLOCK-START is nil, this is found
2317 ;; out by checking whether the character at point is "{" or not.
2318 (if (= (point) (c-point 'boi
))
2319 ;; This is by far the most common case, so let's give it special
2321 (c-add-syntax syntax-symbol
(point))
2323 (let* ((savepos (point))
2324 (syms (list syntax-symbol
))
2326 (boi (c-point 'boi
))
2327 (prev-paren (if at-block-start ?
{ (char-after)))
2328 step-type step-tmp at-comment add-inexpr-stmt
)
2330 ;; Begin by skipping any labels and containing statements that
2331 ;; are on the same line.
2332 (while (and (/= (point) boi
)
2333 (if (memq (setq step-tmp
2334 (c-beginning-of-statement-1 boi nil t
))
2339 (/= (point) savepos
))
2340 (setq savepos
(point)
2341 step-type step-tmp
))
2344 ;; Loop if we have to back out of the containing block.
2347 ;; Loop if we have to back up another statement.
2351 ;; Always start by skipping over any comments that
2352 ;; stands between the statement and boi.
2353 (while (and (/= (setq savepos
(point)) boi
)
2354 (c-forward-comment -
1))
2356 boi
(c-point 'boi
)))
2361 (eq step-type
'label
)
2365 ;; Current position might not be good enough;
2366 ;; skip backward another statement.
2367 (setq step-type
(c-beginning-of-statement-1
2370 (if (and (not stop-at-boi-only
)
2372 (memq step-type
'(up previous
)))
2373 ;; If stop-at-boi-only is nil, we shouldn't
2374 ;; back up over previous or containing
2375 ;; statements to try to reach boi, so go
2376 ;; back to the last position and exit.
2380 (if (and (not stop-at-boi-only
)
2381 (memq step-type
'(up previous beginning
)))
2382 ;; If we've moved into another statement
2383 ;; then we should no longer try to stop
2385 (setq stop-at-boi-only t
))
2387 ;; Record this a substatement if we skipped up
2388 ;; one level, but not if we're still on the
2389 ;; same line. This so e.g. a sequence of "else
2390 ;; if" clauses won't indent deeper and deeper.
2391 (when (and (eq step-type
'up
)
2393 (setcdr syms-tail
(list 'substatement
))
2394 (setq syms-tail
(cdr syms-tail
)))
2396 (setq boi
(c-point 'boi
))
2397 (/= (point) savepos
)))))
2399 (setq savepos
(point)
2401 (setq at-comment nil
)
2403 (when (and (eq step-type
'same
)
2405 (goto-char containing-sexp
)
2406 (setq paren-state
(c-whack-state-after containing-sexp
2408 containing-sexp
(c-most-enclosing-brace paren-state
))
2411 (when (eq (setq prev-paren
(char-after)) ?\
()
2412 (c-backward-syntactic-ws containing-sexp
)
2413 (when (c-on-identifier)
2414 ;; Arrived at a function arglist start. Exit with
2415 ;; the position of the first argument inside it.
2418 ;; We're in an in-expression statement. Remember
2419 ;; this. We'll iterate below, but won't add any
2421 (setq add-inexpr-stmt t
))
2423 (setq savepos
(point)
2425 step-type
(c-beginning-of-statement-1 containing-sexp
))
2427 (let ((at-bod (and (eq step-type
'same
)
2428 (/= savepos
(point))
2429 (eq prev-paren ?
{))))
2430 (when (= savepos boi
)
2431 ;; If the open brace was at boi, we're always
2432 ;; done. The c-beginning-of-statement-1 call
2433 ;; above is necessary anyway, to decide the type
2434 ;; of block-intro to add.
2438 (when (eq prev-paren ?
{)
2439 (setcdr syms-tail
(list (if at-bod
2441 'statement-block-intro
)))
2442 (setq syms-tail
(cdr syms-tail
)))
2444 (when (and (not at-bod
) savepos
)
2445 ;; Loop if the brace wasn't at boi, and we didn't
2446 ;; arrive at a defun block.
2447 (if (eq step-type
'same
)
2448 ;; Avoid backing up another sexp if the point
2449 ;; we're at now is found to be good enough in
2451 (setq step-type nil
))
2452 (if (and (not stop-at-boi-only
)
2453 (memq step-type
'(up previous beginning
)))
2454 (setq stop-at-boi-only t
))
2455 (setq boi
(c-point 'boi
)))))
2459 (c-add-syntax (car syms
) (point))
2460 (setq syms
(cdr syms
)))
2462 (c-add-syntax 'inexpr-statement
))
2465 (defun c-add-class-syntax (symbol classkey paren-state
)
2466 ;; The inclass and class-close syntactic symbols are added in
2467 ;; several places and some work is needed to fix everything.
2468 ;; Therefore it's collected here.
2471 (let (inexpr anchor containing-sexp
)
2472 (goto-char (aref classkey
1))
2473 (if (and (eq symbol
'inclass
) (= (point) (c-point 'boi
)))
2474 (c-add-syntax symbol
(setq anchor
(point)))
2475 (c-add-syntax symbol
(setq anchor
(aref classkey
0)))
2476 (if (and c-opt-inexpr-class-key
2477 (setq containing-sexp
(c-most-enclosing-brace paren-state
2479 inexpr
(cdr (c-looking-at-inexpr-block
2480 (c-safe-position containing-sexp
2483 (/= inexpr
(c-point 'boi inexpr
)))
2484 (c-add-syntax 'inexpr-class
)))
2487 (defun c-guess-continued-construct (indent-point
2489 beg-of-same-or-containing-stmt
2492 ;; This function contains the decision tree reached through both
2493 ;; cases 18 and 10. It's a continued statement or top level
2494 ;; construct of some kind.
2495 (let (special-brace-list)
2496 (goto-char indent-point
)
2497 (skip-chars-forward " \t")
2499 ;; (CASE A removed.)
2500 ;; CASE B: open braces for class or brace-lists
2501 ((setq special-brace-list
2502 (or (and c-special-brace-lists
2503 (c-looking-at-special-brace-list))
2504 (eq char-after-ip ?
{)))
2506 ;; CASE B.1: class-open
2508 (goto-char indent-point
)
2509 (skip-chars-forward " \t{")
2510 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
2512 (setq beg-of-same-or-containing-stmt
(aref decl
0)))
2514 (c-add-syntax 'class-open beg-of-same-or-containing-stmt
))
2515 ;; CASE B.2: brace-list-open
2516 ((or (consp special-brace-list
)
2518 (goto-char beg-of-same-or-containing-stmt
)
2519 (looking-at "enum\\>[^_]"))
2521 (goto-char indent-point
)
2522 (while (and (> (point) beg-of-same-or-containing-stmt
)
2523 (= (c-backward-token-1 1 t
) 0)
2524 (/= (char-after) ?
=)))
2525 (eq (char-after) ?
=)))
2526 ;; The most semantically accurate symbol here is
2527 ;; brace-list-open, but we report it simply as a statement-cont.
2528 ;; The reason is that one normally adjusts brace-list-open for
2529 ;; brace lists as top-level constructs, and brace lists inside
2530 ;; statements is a completely different context.
2531 (c-beginning-of-statement-1 containing-sexp
)
2532 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state
))
2533 ;; CASE B.3: The body of a function declared inside a normal
2534 ;; block. Can occur e.g. in Pike and when using gcc
2535 ;; extensions. Might also trigger it with some macros followed
2536 ;; by blocks, and this gives sane indentation then too.
2537 ;; C.f. cases 16F and 17G.
2539 (goto-char indent-point
)
2540 (and (not (c-looking-at-bos))
2541 (eq (c-beginning-of-statement-1 containing-sexp nil nil t
)
2543 (c-add-stmt-syntax 'defun-open t containing-sexp paren-state
))
2544 ;; CASE B.4: Continued statement with block open.
2546 (goto-char beg-of-same-or-containing-stmt
)
2547 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state
)
2548 (c-add-syntax 'block-open
))
2550 ;; CASE C: iostream insertion or extraction operator
2551 ((and (looking-at "<<\\|>>")
2553 (goto-char beg-of-same-or-containing-stmt
)
2554 (while (and (re-search-forward "<<\\|>>" indent-point
'move
)
2555 (c-in-literal beg-of-same-or-containing-stmt
)))
2556 ;; if we ended up at indent-point, then the first streamop is on a
2557 ;; separate line. Indent the line like a statement-cont instead
2558 (when (/= (point) indent-point
)
2559 (c-add-syntax 'stream-op
(c-point 'boi
))
2561 ;; CASE D: continued statement.
2563 (c-beginning-of-statement-1 containing-sexp
)
2564 (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state
))
2567 (defun c-guess-basic-syntax ()
2568 "Return the syntactic context of the current line."
2572 (let* ((indent-point (point))
2573 (case-fold-search nil
)
2574 (paren-state (c-parse-state))
2575 literal containing-sexp char-before-ip char-after-ip lim
2576 syntax placeholder c-in-literal-cache step-type
2577 tmpsymbol keyword injava-inher special-brace-list
2578 ;; narrow out any enclosing class or extern "C" block
2579 (inclass-p (c-narrow-out-enclosing-class paren-state
2581 ;; c-state-cache is shadowed here. That means we must
2582 ;; not do any changes during the execution of this
2583 ;; function, since c-check-state-cache then would change
2584 ;; this local variable and leave a bogus value in the
2586 (c-state-cache (if inclass-p
2587 (c-whack-state-before (point-min) paren-state
)
2589 (c-state-cache-start (point-min))
2590 inenclosing-p macro-start in-macro-expr
2591 ;; There's always at most one syntactic element which got
2592 ;; a relpos. It's stored in syntactic-relpos.
2594 (c-stmt-delim-chars c-stmt-delim-chars
))
2595 ;; check for meta top-level enclosing constructs, possible
2596 ;; extern language definitions, possibly (in C++) namespace
2603 (goto-char (aref inclass-p
0))
2604 (looking-at c-other-decl-block-key
)))
2605 (let ((enclosing (match-string 1)))
2607 ((string-equal enclosing
"extern")
2608 (setq inenclosing-p
'extern
))
2609 ((string-equal enclosing
"namespace")
2610 (setq inenclosing-p
'namespace
))
2613 ;; Init some position variables:
2615 ;; containing-sexp is the open paren of the closest
2616 ;; surrounding sexp or nil if there is none that hasn't been
2619 ;; lim is the position after the closest preceding brace sexp
2620 ;; (nested sexps are ignored), or the position after
2621 ;; containing-sexp if there is none, or (point-min) if
2622 ;; containing-sexp is nil.
2624 ;; c-state-cache is the state from c-parse-state at
2625 ;; indent-point, without any parens outside the region
2626 ;; narrowed by c-narrow-out-enclosing-class.
2628 ;; paren-state is the state from c-parse-state outside
2629 ;; containing-sexp, or at indent-point if containing-sexp is
2630 ;; nil. paren-state is not limited to the narrowed region, as
2631 ;; opposed to c-state-cache.
2634 (setq containing-sexp
(car paren-state
)
2635 paren-state
(cdr paren-state
))
2636 (if (consp containing-sexp
)
2638 (setq lim
(cdr containing-sexp
))
2639 (if (cdr c-state-cache
)
2640 ;; Ignore balanced paren. The next entry
2641 ;; can't be another one.
2642 (setq containing-sexp
(car (cdr c-state-cache
))
2643 paren-state
(cdr paren-state
))
2644 ;; If there is no surrounding open paren then
2645 ;; put the last balanced pair back on paren-state.
2646 (setq paren-state
(cons containing-sexp paren-state
)
2647 containing-sexp nil
)))
2648 (setq lim
(1+ containing-sexp
))))
2649 (setq lim
(point-min)))
2651 ;; If we're in a parenthesis list then ',' delimits the
2652 ;; "statements" rather than being an operator (with the
2653 ;; exception of the "for" clause). This difference is
2654 ;; typically only noticeable when statements are used in macro
2656 (when (and containing-sexp
2657 (eq (char-after containing-sexp
) ?\
())
2658 (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma
))
2660 ;; cache char before and after indent point, and move point to
2661 ;; the most likely position to perform the majority of tests
2662 (goto-char indent-point
)
2663 (c-backward-syntactic-ws lim
)
2664 (setq char-before-ip
(char-before))
2665 (goto-char indent-point
)
2666 (skip-chars-forward " \t")
2667 (setq char-after-ip
(char-after))
2669 ;; are we in a literal?
2670 (setq literal
(c-in-literal lim
))
2672 ;; now figure out syntactic qualities of the current line
2674 ;; CASE 1: in a string.
2675 ((eq literal
'string
)
2676 (c-add-syntax 'string
(c-point 'bopl
)))
2677 ;; CASE 2: in a C or C++ style comment.
2678 ((memq literal
'(c c
++))
2679 (c-add-syntax literal
(car (c-literal-limits lim
))))
2680 ;; CASE 3: in a cpp preprocessor macro continuation.
2681 ((and (save-excursion
2682 (when (c-beginning-of-macro)
2683 (setq macro-start
(point))))
2684 (/= macro-start
(c-point 'boi
))
2686 (setq tmpsymbol
'cpp-macro-cont
)
2687 (or (not c-syntactic-indentation-in-macros
)
2689 (goto-char macro-start
)
2690 ;; If at the beginning of the body of a #define
2691 ;; directive then analyze as cpp-define-intro
2692 ;; only. Go on with the syntactic analysis
2693 ;; otherwise. in-macro-expr is set if we're in a
2694 ;; cpp expression, i.e. before the #define body
2695 ;; or anywhere in a non-#define directive.
2696 (if (c-forward-to-cpp-define-body)
2697 (let ((indent-boi (c-point 'boi indent-point
)))
2698 (setq in-macro-expr
(> (point) indent-boi
)
2699 tmpsymbol
'cpp-define-intro
)
2700 (= (point) indent-boi
))
2701 (setq in-macro-expr t
)
2703 (c-add-syntax tmpsymbol macro-start
)
2704 (setq macro-start nil
))
2705 ;; CASE 11: an else clause?
2706 ((looking-at "else\\>[^_]")
2707 (c-beginning-of-statement-1 containing-sexp
)
2708 (c-add-stmt-syntax 'else-clause t containing-sexp paren-state
))
2709 ;; CASE 12: while closure of a do/while construct?
2710 ((and (looking-at "while\\>[^_]")
2712 (prog1 (eq (c-beginning-of-statement-1 containing-sexp
)
2714 (setq placeholder
(point)))))
2715 (goto-char placeholder
)
2716 (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state
))
2717 ;; CASE 13: A catch or finally clause? This case is simpler
2718 ;; than if-else and do-while, because a block is required
2719 ;; after every try, catch and finally.
2721 (and (cond ((c-major-mode-is 'c
++-mode
)
2722 (looking-at "catch\\>[^_]"))
2723 ((c-major-mode-is 'java-mode
)
2724 (looking-at "\\(catch\\|finally\\)\\>[^_]")))
2725 (and (c-safe (c-backward-syntactic-ws)
2728 (eq (char-after) ?
{)
2729 (c-safe (c-backward-syntactic-ws)
2732 (if (eq (char-after) ?\
()
2733 (c-safe (c-backward-sexp) t
)
2735 (looking-at "\\(try\\|catch\\)\\>[^_]")
2736 (setq placeholder
(point))))
2737 (goto-char placeholder
)
2738 (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state
))
2739 ;; CASE 18: A substatement we can recognize by keyword.
2741 (and c-opt-block-stmt-key
2742 (not (eq char-before-ip ?\
;))
2743 (not (memq char-after-ip
'(?\
) ?\
] ?
,)))
2744 (or (not (eq char-before-ip ?
}))
2745 (c-looking-at-inexpr-block-backward c-state-cache
))
2748 ;; Ought to cache the result from the
2749 ;; c-beginning-of-statement-1 calls here.
2750 (setq placeholder
(point))
2751 (while (eq (setq step-type
2752 (c-beginning-of-statement-1 lim
))
2754 (if (eq step-type
'previous
)
2755 (goto-char placeholder
)
2756 (setq placeholder
(point))
2757 (if (and (eq step-type
'same
)
2758 (not (looking-at c-opt-block-stmt-key
)))
2759 ;; Step up to the containing statement if we
2760 ;; stayed in the same one.
2764 (c-beginning-of-statement-1 lim
))
2767 (setq placeholder
(point))
2768 ;; There was no containing statement afterall.
2769 (goto-char placeholder
)))))
2771 (if (looking-at c-block-stmt-2-key
)
2772 ;; Require a parenthesis after these keywords.
2773 ;; Necessary to catch e.g. synchronized in Java,
2774 ;; which can be used both as statement and
2776 (and (= (c-forward-token-1 1 nil
) 0)
2777 (eq (char-after) ?\
())
2778 (looking-at c-opt-block-stmt-key
))))
2779 (if (eq step-type
'up
)
2780 ;; CASE 18A: Simple substatement.
2782 (goto-char placeholder
)
2784 ((eq char-after-ip ?
{)
2785 (c-add-stmt-syntax 'substatement-open nil
2786 containing-sexp paren-state
))
2788 (goto-char indent-point
)
2789 (back-to-indentation)
2790 (looking-at c-label-key
))
2791 (c-add-stmt-syntax 'substatement-label nil
2792 containing-sexp paren-state
))
2794 (c-add-stmt-syntax 'substatement nil
2795 containing-sexp paren-state
))))
2796 ;; CASE 18B: Some other substatement. This is shared
2798 (c-guess-continued-construct indent-point
2803 ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
2805 ((and (or c-opt-inexpr-class-key
2806 c-opt-inexpr-block-key
2808 (setq placeholder
(c-looking-at-inexpr-block
2809 (c-safe-position containing-sexp paren-state
)
2811 (setq tmpsymbol
(assq (car placeholder
)
2812 '((inexpr-class . class-open
)
2813 (inexpr-statement . block-open
))))
2815 ;; It's a statement block or an anonymous class.
2816 (setq tmpsymbol
(cdr tmpsymbol
))
2817 ;; It's a Pike lambda. Check whether we are between the
2818 ;; lambda keyword and the argument list or at the defun
2820 (setq tmpsymbol
(if (eq char-after-ip ?
{)
2822 'lambda-intro-cont
)))
2823 (goto-char (cdr placeholder
))
2824 (back-to-indentation)
2825 (c-add-stmt-syntax tmpsymbol t
2826 (c-most-enclosing-brace c-state-cache
(point))
2827 (c-whack-state-after (point) paren-state
))
2828 (unless (eq (point) (cdr placeholder
))
2829 (c-add-syntax (car placeholder
))))
2830 ;; CASE 5: Line is at top level.
2831 ((null containing-sexp
)
2833 ;; CASE 5A: we are looking at a defun, brace list, class,
2834 ;; or inline-inclass method opening brace
2835 ((setq special-brace-list
2836 (or (and c-special-brace-lists
2837 (c-looking-at-special-brace-list))
2838 (eq char-after-ip ?
{)))
2840 ;; CASE 5A.1: extern language or namespace construct
2842 (goto-char indent-point
)
2843 (skip-chars-forward " \t")
2844 (and (c-safe (progn (c-backward-sexp 2) t
))
2845 (looking-at c-other-decl-block-key
)
2846 (setq keyword
(match-string 1)
2847 placeholder
(point))
2848 (or (and (string-equal keyword
"namespace")
2849 (setq tmpsymbol
'namespace-open
))
2850 (and (string-equal keyword
"extern")
2853 (c-forward-syntactic-ws)
2854 (eq (char-after) ?
\"))
2855 (setq tmpsymbol
'extern-lang-open
)))
2857 (goto-char placeholder
)
2858 (c-add-syntax tmpsymbol
(c-point 'boi
)))
2859 ;; CASE 5A.2: we are looking at a class opening brace
2861 (goto-char indent-point
)
2862 (skip-chars-forward " \t{")
2863 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
2865 (setq placeholder
(aref decl
0)))
2867 (c-add-syntax 'class-open placeholder
))
2868 ;; CASE 5A.3: brace list open
2870 (c-beginning-of-statement-1 lim t
)
2871 (if (looking-at "typedef\\>[^_]")
2872 (progn (c-forward-sexp 1)
2873 (c-forward-syntactic-ws indent-point
)))
2874 (setq placeholder
(c-point 'boi
))
2875 (or (consp special-brace-list
)
2876 (and (or (save-excursion
2877 (goto-char indent-point
)
2878 (setq tmpsymbol nil
)
2879 (while (and (> (point) placeholder
)
2880 (= (c-backward-token-1 1 t
) 0)
2881 (/= (char-after) ?
=))
2882 (if (and (not tmpsymbol
)
2883 (looking-at "new\\>[^_]"))
2884 (setq tmpsymbol
'topmost-intro-cont
)))
2885 (eq (char-after) ?
=))
2886 (looking-at "enum\\>[^_]"))
2888 (while (and (< (point) indent-point
)
2889 (= (c-forward-token-1 1 t
) 0)
2890 (not (memq (char-after) '(?\
; ?\()))))
2891 (not (memq (char-after) '(?\
; ?\()))
2893 (if (and (c-major-mode-is 'java-mode
)
2894 (eq tmpsymbol
'topmost-intro-cont
))
2895 ;; We're in Java and have found that the open brace
2896 ;; belongs to a "new Foo[]" initialization list,
2897 ;; which means the brace list is part of an
2898 ;; expression and not a top level definition. We
2899 ;; therefore treat it as any topmost continuation
2900 ;; even though the semantically correct symbol still
2901 ;; is brace-list-open, on the same grounds as in
2904 (c-beginning-of-statement-1 lim
)
2905 (c-add-syntax 'topmost-intro-cont
(c-point 'boi
)))
2906 (c-add-syntax 'brace-list-open placeholder
)))
2907 ;; CASE 5A.4: inline defun open
2908 ((and inclass-p
(not inenclosing-p
))
2909 (c-add-syntax 'inline-open
)
2910 (c-add-class-syntax 'inclass inclass-p paren-state
))
2911 ;; CASE 5A.5: ordinary defun open
2913 (goto-char placeholder
)
2914 (if (or inclass-p macro-start
)
2915 (c-add-syntax 'defun-open
(c-point 'boi
))
2916 ;; Bogus to use bol here, but it's the legacy.
2917 (c-add-syntax 'defun-open
(c-point 'bol
)))
2919 ;; CASE 5B: first K&R arg decl or member init
2920 ((c-just-after-func-arglist-p nil lim
)
2922 ;; CASE 5B.1: a member init
2923 ((or (eq char-before-ip ?
:)
2924 (eq char-after-ip ?
:))
2925 ;; this line should be indented relative to the beginning
2926 ;; of indentation for the topmost-intro line that contains
2927 ;; the prototype's open paren
2928 ;; TBD: is the following redundant?
2929 (if (eq char-before-ip ?
:)
2931 (c-backward-syntactic-ws lim
)
2932 ;; TBD: is the preceding redundant?
2933 (if (eq (char-before) ?
:)
2934 (progn (forward-char -
1)
2935 (c-backward-syntactic-ws lim
)))
2936 (if (eq (char-before) ?\
))
2937 (c-backward-sexp 1))
2938 (setq placeholder
(point))
2940 (and (c-safe (c-backward-sexp 1) t
)
2941 (looking-at "throw[^_]")
2942 (c-safe (c-backward-sexp 1) t
)
2943 (setq placeholder
(point))))
2944 (goto-char placeholder
)
2945 (c-add-syntax 'member-init-intro
(c-point 'boi
))
2946 ;; we don't need to add any class offset since this
2947 ;; should be relative to the ctor's indentation
2949 ;; CASE 5B.2: K&R arg decl intro
2951 (c-beginning-of-statement-1 lim
)
2952 (c-add-syntax 'knr-argdecl-intro
(c-point 'boi
))
2954 (c-add-class-syntax 'inclass inclass-p paren-state
)))
2955 ;; CASE 5B.3: Inside a member init list.
2956 ((c-beginning-of-member-init-list lim
)
2957 (c-forward-syntactic-ws)
2958 (c-add-syntax 'member-init-cont
(point)))
2959 ;; CASE 5B.4: Nether region after a C++ or Java func
2960 ;; decl, which could include a `throws' declaration.
2962 (c-beginning-of-statement-1 lim
)
2963 (c-add-syntax 'func-decl-cont
(c-point 'boi
))
2965 ;; CASE 5C: inheritance line. could be first inheritance
2966 ;; line, or continuation of a multiple inheritance
2967 ((or (and (c-major-mode-is 'c
++-mode
)
2969 (when (eq char-after-ip ?
,)
2970 (skip-chars-forward " \t")
2972 (looking-at c-opt-decl-spec-key
)))
2973 (and (or (eq char-before-ip ?
:)
2974 ;; watch out for scope operator
2976 (and (eq char-after-ip ?
:)
2977 (c-safe (progn (forward-char 1) t
))
2978 (not (eq (char-after) ?
:))
2981 (c-backward-syntactic-ws lim
)
2982 (if (eq char-before-ip ?
:)
2985 (c-backward-syntactic-ws lim
)))
2986 (back-to-indentation)
2987 (looking-at c-class-key
)))
2989 (and (c-major-mode-is 'java-mode
)
2990 (let ((fence (save-excursion
2991 (c-beginning-of-statement-1 lim
)
2996 (cond ((looking-at c-opt-decl-spec-key
)
2997 (setq injava-inher
(cons cont
(point))
2999 ((or (not (c-safe (c-forward-sexp -
1) t
))
3005 (not (c-crosses-statement-barrier-p (cdr injava-inher
)
3009 ;; CASE 5C.1: non-hanging colon on an inher intro
3010 ((eq char-after-ip ?
:)
3011 (c-beginning-of-statement-1 lim
)
3012 (c-add-syntax 'inher-intro
(c-point 'boi
))
3013 ;; don't add inclass symbol since relative point already
3014 ;; contains any class offset
3016 ;; CASE 5C.2: hanging colon on an inher intro
3017 ((eq char-before-ip ?
:)
3018 (c-beginning-of-statement-1 lim
)
3019 (c-add-syntax 'inher-intro
(c-point 'boi
))
3021 (c-add-class-syntax 'inclass inclass-p paren-state
)))
3022 ;; CASE 5C.3: in a Java implements/extends
3024 (let ((where (cdr injava-inher
))
3025 (cont (car injava-inher
)))
3027 (cond ((looking-at "throws\\>[^_]")
3028 (c-add-syntax 'func-decl-cont
3029 (progn (c-beginning-of-statement-1 lim
)
3031 (cont (c-add-syntax 'inher-cont where
))
3032 (t (c-add-syntax 'inher-intro
3033 (progn (goto-char (cdr injava-inher
))
3034 (c-beginning-of-statement-1 lim
)
3037 ;; CASE 5C.4: a continued inheritance line
3039 (c-beginning-of-inheritance-list lim
)
3040 (c-add-syntax 'inher-cont
(point))
3041 ;; don't add inclass symbol since relative point already
3042 ;; contains any class offset
3044 ;; CASE 5D: this could be a top-level initialization, a
3045 ;; member init list continuation, or a template argument
3046 ;; list continuation.
3047 ((c-with-syntax-table (if (c-major-mode-is 'c
++-mode
)
3048 c
++-template-syntax-table
3051 ;; Note: We use the fact that lim is always after any
3052 ;; preceding brace sexp.
3053 (while (and (= (c-backward-token-1 1 t lim
) 0)
3054 (not (looking-at "[;<,=]"))))
3055 (or (memq (char-after) '(?
, ?
=))
3056 (and (c-major-mode-is 'c
++-mode
)
3057 (= (c-backward-token-1 1 nil lim
) 0)
3058 (eq (char-after) ?
<)))))
3059 (goto-char indent-point
)
3060 (c-beginning-of-member-init-list lim
)
3062 ;; CASE 5D.1: hanging member init colon, but watch out
3063 ;; for bogus matches on access specifiers inside classes.
3064 ((and (save-excursion
3065 (setq placeholder
(point))
3066 (c-backward-token-1 1 t lim
)
3067 (and (eq (char-after) ?
:)
3068 (not (eq (char-before) ?
:))))
3070 (goto-char placeholder
)
3071 (back-to-indentation)
3073 (/= (car (save-excursion
3074 (parse-partial-sexp (point) placeholder
)))
3077 (if c-opt-access-key
3078 (not (looking-at c-opt-access-key
)) t
)
3079 (not (looking-at c-class-key
))
3080 (if c-opt-bitfield-key
3081 (not (looking-at c-opt-bitfield-key
)) t
))
3083 (goto-char placeholder
)
3084 (c-forward-syntactic-ws)
3085 (c-add-syntax 'member-init-cont
(point))
3086 ;; we do not need to add class offset since relative
3087 ;; point is the member init above us
3089 ;; CASE 5D.2: non-hanging member init colon
3091 (c-forward-syntactic-ws indent-point
)
3092 (eq (char-after) ?
:))
3093 (skip-chars-forward " \t:")
3094 (c-add-syntax 'member-init-cont
(point)))
3095 ;; CASE 5D.3: perhaps a template list continuation?
3096 ((and (c-major-mode-is 'c
++-mode
)
3099 (c-with-syntax-table c
++-template-syntax-table
3100 (goto-char indent-point
)
3101 (setq placeholder
(c-up-list-backward (point)))
3103 (eq (char-after placeholder
) ?
<))))))
3104 ;; we can probably indent it just like an arglist-cont
3105 (goto-char placeholder
)
3106 (c-beginning-of-statement-1 lim t
)
3107 (c-add-syntax 'template-args-cont
(c-point 'boi
)))
3108 ;; CASE 5D.4: perhaps a multiple inheritance line?
3109 ((and (c-major-mode-is 'c
++-mode
)
3111 (c-beginning-of-statement-1 lim
)
3112 (setq placeholder
(point))
3113 (if (looking-at "static\\>[^_]")
3114 (c-forward-token-1 1 nil indent-point
))
3115 (and (looking-at c-class-key
)
3116 (= (c-forward-token-1 2 nil indent-point
) 0)
3117 (if (eq (char-after) ?
<)
3118 (c-with-syntax-table c
++-template-syntax-table
3119 (= (c-forward-token-1 1 t indent-point
) 0))
3121 (eq (char-after) ?
:))))
3122 (goto-char placeholder
)
3123 (c-add-syntax 'inher-cont
(c-point 'boi
)))
3124 ;; CASE 5D.5: Continuation of the "expression part" of a
3125 ;; top level construct.
3127 (while (and (eq (car (c-beginning-of-decl-1 containing-sexp
))
3130 (c-backward-syntactic-ws)
3131 (eq (char-before) ?
}))))
3133 (if (eq char-before-ip ?
,)
3134 ;; A preceding comma at the top level means that a
3135 ;; new variable declaration starts here. Use
3136 ;; topmost-intro-cont for it, for consistency with
3137 ;; the first variable declaration. C.f. case 5N.
3140 nil containing-sexp paren-state
))
3142 ;; CASE 5E: we are looking at a access specifier
3145 (looking-at c-opt-access-key
))
3146 (setq placeholder
(c-add-class-syntax 'inclass inclass-p
3148 ;; Append access-label with the same anchor point as inclass gets.
3149 (nconc syntax
(list (cons 'access-label placeholder
))))
3150 ;; CASE 5F: extern-lang-close or namespace-close?
3152 (eq char-after-ip ?
}))
3153 (setq tmpsymbol
(if (eq inenclosing-p
'extern
)
3156 (c-add-syntax tmpsymbol
(aref inclass-p
0)))
3157 ;; CASE 5G: we are looking at the brace which closes the
3158 ;; enclosing nested class decl
3160 (eq char-after-ip ?
})
3165 (and (c-safe (progn (c-backward-sexp 1) t
))
3166 (= (point) (aref inclass-p
1))
3168 (c-add-class-syntax 'class-close inclass-p paren-state
))
3169 ;; CASE 5H: we could be looking at subsequent knr-argdecls
3170 ((and c-recognize-knr-p
3171 (not (eq char-before-ip ?
}))
3173 (setq placeholder
(cdr (c-beginning-of-decl-1 lim
)))
3175 ;; Do an extra check to avoid tripping up on
3176 ;; statements that occur in invalid contexts
3177 ;; (e.g. in macro bodies where we don't really
3178 ;; know the context of what we're looking at).
3179 (not (and c-opt-block-stmt-key
3180 (looking-at c-opt-block-stmt-key
)))))
3181 (< placeholder indent-point
))
3182 (goto-char placeholder
)
3183 (c-add-syntax 'knr-argdecl
(point)))
3184 ;; CASE 5I: ObjC method definition.
3185 ((and c-opt-method-key
3186 (looking-at c-opt-method-key
))
3187 (c-beginning-of-statement-1 lim
)
3188 (c-add-syntax 'objc-method-intro
(c-point 'boi
)))
3189 ;; CASE 5N: At a variable declaration that follows a class
3190 ;; definition or some other block declaration that doesn't
3191 ;; end at the closing '}'. C.f. case 5D.5.
3193 (c-backward-syntactic-ws lim
)
3194 (and (eq (char-before) ?
})
3196 (let ((start (point)))
3198 ;; Speed up the backward search a bit.
3199 (goto-char (car (car paren-state
))))
3200 (c-beginning-of-decl-1 containing-sexp
)
3201 (setq placeholder
(point))
3202 (if (= start
(point))
3203 ;; The '}' is unbalanced.
3206 (> (point) indent-point
))))))
3207 (goto-char placeholder
)
3208 (c-add-stmt-syntax 'topmost-intro-cont nil
3209 containing-sexp paren-state
))
3210 ;; CASE 5J: we are at the topmost level, make
3211 ;; sure we skip back past any access specifiers
3213 (while (and inclass-p
3217 (c-safe (progn (c-backward-sexp 1) t
))
3218 (looking-at c-opt-access-key
)))
3220 (c-backward-syntactic-ws lim
))
3222 (memq (char-before) '(?\
; ?}))
3223 (and (c-major-mode-is 'objc-mode
)
3225 (c-beginning-of-statement-1 lim
)
3226 (eq (char-after) ?
@)))))
3227 ;; real beginning-of-line could be narrowed out due to
3228 ;; enclosure in a class block
3231 (c-add-syntax 'topmost-intro
(c-point 'bol
))
3232 ;; Using bol instead of boi above is highly bogus, and
3233 ;; it makes our lives hard to remain compatible. :P
3236 (goto-char (aref inclass-p
1))
3237 (or (= (point) (c-point 'boi
))
3238 (goto-char (aref inclass-p
0)))
3240 ((eq inenclosing-p
'extern
)
3241 (c-add-syntax 'inextern-lang
(c-point 'boi
)))
3242 ((eq inenclosing-p
'namespace
)
3243 (c-add-syntax 'innamespace
(c-point 'boi
)))
3244 (t (c-add-class-syntax 'inclass inclass-p paren-state
)))
3246 (when (and c-syntactic-indentation-in-macros
3248 (/= macro-start
(c-point 'boi indent-point
)))
3249 (c-add-syntax 'cpp-define-intro
)
3250 (setq macro-start nil
))
3252 ;; CASE 5K: we are at an ObjC method definition
3253 ;; continuation line.
3254 ((and c-opt-method-key
3256 (c-beginning-of-statement-1 lim
)
3258 (looking-at c-opt-method-key
)))
3259 (c-add-syntax 'objc-method-args-cont
(point)))
3260 ;; CASE 5L: we are at the first argument of a template
3261 ;; arglist that begins on the previous line.
3262 ((eq (char-before) ?
<)
3263 (c-beginning-of-statement-1 (c-safe-position (point) paren-state
))
3264 (c-add-syntax 'template-args-cont
(c-point 'boi
)))
3265 ;; CASE 5M: we are at a topmost continuation line
3267 (c-beginning-of-statement-1 (c-safe-position (point) paren-state
))
3268 (c-add-syntax 'topmost-intro-cont
(c-point 'boi
)))
3270 ;; (CASE 6 has been removed.)
3271 ;; CASE 7: line is an expression, not a statement. Most
3272 ;; likely we are either in a function prototype or a function
3273 ;; call argument list
3274 ((not (or (and c-special-brace-lists
3276 (goto-char containing-sexp
)
3277 (c-looking-at-special-brace-list)))
3278 (eq (char-after containing-sexp
) ?
{)))
3280 ;; CASE 7A: we are looking at the arglist closing paren
3281 ((memq char-after-ip
'(?\
) ?\
]))
3282 (goto-char containing-sexp
)
3283 (setq placeholder
(c-point 'boi
))
3284 (when (and (c-safe (backward-up-list 1) t
)
3285 (> (point) placeholder
))
3287 (skip-chars-forward " \t")
3288 (setq placeholder
(point)))
3289 (c-add-syntax 'arglist-close placeholder
))
3290 ;; CASE 7B: Looking at the opening brace of an
3291 ;; in-expression block or brace list. C.f. cases 4, 16A
3293 ((and (eq char-after-ip ?
{)
3295 (setq placeholder
(c-inside-bracelist-p (point)
3298 (setq tmpsymbol
'(brace-list-open . inexpr-class
))
3299 (setq tmpsymbol
'(block-open . inexpr-statement
)
3301 (cdr-safe (c-looking-at-inexpr-block
3302 (c-safe-position containing-sexp
3305 ;; placeholder is nil if it's a block directly in
3306 ;; a function arglist. That makes us skip out of
3309 (goto-char placeholder
)
3310 (back-to-indentation)
3311 (c-add-stmt-syntax (car tmpsymbol
) t
3312 (c-most-enclosing-brace paren-state
(point))
3313 (c-whack-state-after (point) paren-state
))
3314 (if (/= (point) placeholder
)
3315 (c-add-syntax (cdr tmpsymbol
))))
3316 ;; CASE 7C: we are looking at the first argument in an empty
3317 ;; argument list. Use arglist-close if we're actually
3318 ;; looking at a close paren or bracket.
3319 ((memq char-before-ip
'(?\
( ?\
[))
3320 (goto-char containing-sexp
)
3321 (setq placeholder
(c-point 'boi
))
3322 (when (and (c-safe (backward-up-list 1) t
)
3323 (> (point) placeholder
))
3325 (skip-chars-forward " \t")
3326 (setq placeholder
(point)))
3327 (c-add-syntax 'arglist-intro placeholder
))
3328 ;; CASE 7D: we are inside a conditional test clause. treat
3329 ;; these things as statements
3331 (goto-char containing-sexp
)
3332 (and (c-safe (progn (c-forward-sexp -
1) t
))
3333 (looking-at "\\<for\\>[^_]")))
3334 (goto-char (1+ containing-sexp
))
3335 (c-forward-syntactic-ws indent-point
)
3336 (if (eq char-before-ip ?\
;)
3337 (c-add-syntax 'statement
(point))
3338 (c-add-syntax 'statement-cont
(point))
3340 ;; CASE 7E: maybe a continued ObjC method call. This is the
3341 ;; case when we are inside a [] bracketed exp, and what
3342 ;; precede the opening bracket is not an identifier.
3343 ((and c-opt-method-key
3344 (eq (char-after containing-sexp
) ?\
[)
3346 (goto-char (1- containing-sexp
))
3347 (c-backward-syntactic-ws (c-point 'bod
))
3348 (if (not (looking-at c-symbol-key
))
3349 (c-add-syntax 'objc-method-call-cont containing-sexp
))
3351 ;; CASE 7F: we are looking at an arglist continuation line,
3352 ;; but the preceding argument is on the same line as the
3353 ;; opening paren. This case includes multi-line
3354 ;; mathematical paren groupings, but we could be on a
3355 ;; for-list continuation line
3357 (goto-char (1+ containing-sexp
))
3358 (skip-chars-forward " \t")
3360 (not (looking-at "\\\\$"))))
3361 (goto-char containing-sexp
)
3362 (setq placeholder
(c-point 'boi
))
3363 (when (and (c-safe (backward-up-list 1) t
)
3364 (> (point) placeholder
))
3366 (skip-chars-forward " \t")
3367 (setq placeholder
(point)))
3368 (c-add-syntax 'arglist-cont-nonempty placeholder
))
3369 ;; CASE 7G: we are looking at just a normal arglist
3370 ;; continuation line
3371 (t (c-forward-syntactic-ws indent-point
)
3372 (c-add-syntax 'arglist-cont
(c-point 'boi
)))
3374 ;; CASE 8: func-local multi-inheritance line
3375 ((and (c-major-mode-is 'c
++-mode
)
3377 (goto-char indent-point
)
3378 (skip-chars-forward " \t")
3379 (looking-at c-opt-decl-spec-key
)))
3380 (goto-char indent-point
)
3381 (skip-chars-forward " \t")
3383 ;; CASE 8A: non-hanging colon on an inher intro
3384 ((eq char-after-ip ?
:)
3385 (c-backward-syntactic-ws lim
)
3386 (c-add-syntax 'inher-intro
(c-point 'boi
)))
3387 ;; CASE 8B: hanging colon on an inher intro
3388 ((eq char-before-ip ?
:)
3389 (c-add-syntax 'inher-intro
(c-point 'boi
)))
3390 ;; CASE 8C: a continued inheritance line
3392 (c-beginning-of-inheritance-list lim
)
3393 (c-add-syntax 'inher-cont
(point))
3395 ;; CASE 9: we are inside a brace-list
3396 ((setq special-brace-list
3397 (or (and c-special-brace-lists
3399 (goto-char containing-sexp
)
3400 (c-looking-at-special-brace-list)))
3401 (c-inside-bracelist-p containing-sexp paren-state
)))
3403 ;; CASE 9A: In the middle of a special brace list opener.
3404 ((and (consp special-brace-list
)
3406 (goto-char containing-sexp
)
3407 (eq (char-after) ?\
())
3408 (eq char-after-ip
(car (cdr special-brace-list
))))
3409 (goto-char (car (car special-brace-list
)))
3410 (skip-chars-backward " \t")
3412 (assoc 'statement-cont
3413 (setq placeholder
(c-guess-basic-syntax))))
3414 (setq syntax placeholder
)
3415 (c-beginning-of-statement-1
3416 (c-safe-position (1- containing-sexp
) paren-state
))
3417 (c-forward-token-1 0)
3418 (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1))
3419 (c-add-syntax 'brace-list-open
(c-point 'boi
))))
3420 ;; CASE 9B: brace-list-close brace
3421 ((if (consp special-brace-list
)
3422 ;; Check special brace list closer.
3424 (goto-char (car (car special-brace-list
)))
3426 (goto-char indent-point
)
3427 (back-to-indentation)
3429 ;; We were between the special close char and the `)'.
3430 (and (eq (char-after) ?\
))
3431 (eq (1+ (point)) (cdr (car special-brace-list
))))
3432 ;; We were before the special close char.
3433 (and (eq (char-after) (cdr (cdr special-brace-list
)))
3434 (= (c-forward-token-1) 0)
3435 (eq (1+ (point)) (cdr (car special-brace-list
)))))))
3436 ;; Normal brace list check.
3437 (and (eq char-after-ip ?
})
3438 (c-safe (progn (goto-char (c-up-list-backward (point)))
3440 (= (point) containing-sexp
)))
3441 (if (eq (point) (c-point 'boi
))
3442 (c-add-syntax 'brace-list-close
(point))
3443 (setq lim
(c-most-enclosing-brace c-state-cache
(point)))
3444 (c-beginning-of-statement-1 lim
)
3445 (c-add-stmt-syntax 'brace-list-close t lim
3446 (c-whack-state-after (point) paren-state
)
3449 ;; Prepare for the rest of the cases below by going to the
3450 ;; token following the opening brace
3451 (if (consp special-brace-list
)
3453 (goto-char (car (car special-brace-list
)))
3454 (c-forward-token-1 1 nil indent-point
))
3455 (goto-char containing-sexp
))
3457 (let ((start (point)))
3458 (c-forward-syntactic-ws indent-point
)
3459 (goto-char (max start
(c-point 'bol
))))
3460 (c-skip-ws-forward indent-point
)
3462 ;; CASE 9C: we're looking at the first line in a brace-list
3463 ((= (point) indent-point
)
3464 (if (consp special-brace-list
)
3465 (goto-char (car (car special-brace-list
)))
3466 (goto-char containing-sexp
))
3467 (if (eq (point) (c-point 'boi
))
3468 (c-add-syntax 'brace-list-intro
(point))
3469 (setq lim
(c-most-enclosing-brace c-state-cache
(point)))
3470 (c-beginning-of-statement-1 lim
)
3471 (c-add-stmt-syntax 'brace-list-intro t lim
3472 (c-whack-state-after (point) paren-state
)
3474 ;; CASE 9D: this is just a later brace-list-entry or
3476 (t (if (or (eq char-after-ip ?
{)
3477 (and c-special-brace-lists
3479 (goto-char indent-point
)
3480 (c-forward-syntactic-ws (c-point 'eol
))
3481 (c-looking-at-special-brace-list (point)))))
3482 (c-add-syntax 'brace-entry-open
(point))
3483 (c-add-syntax 'brace-list-entry
(point))
3486 ;; CASE 10: A continued statement or top level construct.
3487 ((and (not (memq char-before-ip
'(?\
; ?:)))
3488 (or (not (eq char-before-ip ?
}))
3489 (c-looking-at-inexpr-block-backward c-state-cache
))
3492 (c-beginning-of-statement-1 containing-sexp
)
3493 (setq placeholder
(point))))
3494 (/= placeholder containing-sexp
))
3495 ;; This is shared with case 18.
3496 (c-guess-continued-construct indent-point
3501 ;; CASE 14: A case or default label
3502 ((looking-at c-label-kwds-regexp
)
3503 (goto-char containing-sexp
)
3504 (setq lim
(c-most-enclosing-brace c-state-cache containing-sexp
))
3505 (c-backward-to-block-anchor lim
)
3506 (c-add-stmt-syntax 'case-label t lim paren-state
))
3507 ;; CASE 15: any other label
3508 ((looking-at c-label-key
)
3509 (goto-char containing-sexp
)
3510 (setq lim
(c-most-enclosing-brace c-state-cache containing-sexp
))
3513 (if (and (eq (c-beginning-of-statement-1 lim
) 'up
)
3514 (looking-at "switch\\>[^_]"))
3515 ;; If the surrounding statement is a switch then
3516 ;; let's analyze all labels as switch labels, so
3517 ;; that they get lined up consistently.
3520 (c-backward-to-block-anchor lim
)
3521 (c-add-stmt-syntax tmpsymbol t lim paren-state
))
3522 ;; CASE 16: block close brace, possibly closing the defun or
3524 ((eq char-after-ip ?
})
3525 ;; From here on we have the next containing sexp in lim.
3526 (setq lim
(c-most-enclosing-brace paren-state
))
3527 (goto-char containing-sexp
)
3529 ;; CASE 16E: Closing a statement block? This catches
3530 ;; cases where it's preceded by a statement keyword,
3531 ;; which works even when used in an "invalid" context,
3532 ;; e.g. a macro argument.
3533 ((c-after-conditional)
3534 (c-backward-to-block-anchor lim
)
3535 (c-add-stmt-syntax 'block-close t lim paren-state
))
3536 ;; CASE 16A: closing a lambda defun or an in-expression
3537 ;; block? C.f. cases 4, 7B and 17E.
3538 ((setq placeholder
(c-looking-at-inexpr-block
3539 (c-safe-position containing-sexp paren-state
)
3541 (setq tmpsymbol
(if (eq (car placeholder
) 'inlambda
)
3544 (goto-char containing-sexp
)
3545 (back-to-indentation)
3546 (if (= containing-sexp
(point))
3547 (c-add-syntax tmpsymbol
(point))
3548 (goto-char (cdr placeholder
))
3549 (back-to-indentation)
3550 (c-add-stmt-syntax tmpsymbol t
3551 (c-most-enclosing-brace paren-state
(point))
3552 (c-whack-state-after (point) paren-state
))
3553 (if (/= (point) (cdr placeholder
))
3554 (c-add-syntax (car placeholder
)))))
3555 ;; CASE 16B: does this close an inline or a function in
3556 ;; an extern block or namespace?
3557 ((setq placeholder
(c-search-uplist-for-classkey paren-state
))
3558 (c-backward-to-decl-anchor lim
)
3559 (back-to-indentation)
3561 (goto-char (aref placeholder
0))
3562 (looking-at c-other-decl-block-key
))
3563 (c-add-syntax 'defun-close
(point))
3564 (c-add-syntax 'inline-close
(point))))
3565 ;; CASE 16F: Can be a defun-close of a function declared
3566 ;; in a statement block, e.g. in Pike or when using gcc
3567 ;; extensions. Might also trigger it with some macros
3568 ;; followed by blocks, and this gives sane indentation
3569 ;; then too. Let it through to be handled below.
3570 ;; C.f. cases B.3 and 17G.
3571 ((and (not inenclosing-p
)
3574 (and (not (c-looking-at-bos))
3575 (eq (c-beginning-of-statement-1 lim nil nil t
) 'same
)
3576 (setq placeholder
(point)))))
3577 (back-to-indentation)
3578 (if (/= (point) containing-sexp
)
3579 (goto-char placeholder
))
3580 (c-add-stmt-syntax 'defun-close t lim paren-state
))
3581 ;; CASE 16C: if there an enclosing brace that hasn't
3582 ;; been narrowed out by a class, then this is a
3583 ;; block-close. C.f. case 17H.
3584 ((and (not inenclosing-p
) lim
)
3585 ;; If the block is preceded by a case/switch label on
3586 ;; the same line, we anchor at the first preceding label
3587 ;; at boi. The default handling in c-add-stmt-syntax is
3588 ;; really fixes it better, but we do like this to keep
3589 ;; the indentation compatible with version 5.28 and
3591 (while (and (/= (setq placeholder
(point)) (c-point 'boi
))
3592 (eq (c-beginning-of-statement-1 lim
) 'label
)))
3593 (goto-char placeholder
)
3594 (if (looking-at c-label-kwds-regexp
)
3595 (c-add-syntax 'block-close
(point))
3596 (goto-char containing-sexp
)
3597 ;; c-backward-to-block-anchor not necessary here; those
3598 ;; situations are handled in case 16E above.
3599 (c-add-stmt-syntax 'block-close t lim paren-state
)))
3600 ;; CASE 16D: find out whether we're closing a top-level
3604 (narrow-to-region (point-min) indent-point
)
3605 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
3607 (c-add-class-syntax 'class-close decl paren-state
)
3608 (goto-char containing-sexp
)
3609 (c-backward-to-decl-anchor lim
)
3610 (back-to-indentation)
3611 (c-add-syntax 'defun-close
(point)))))
3613 ;; CASE 17: Statement or defun catchall.
3615 (goto-char indent-point
)
3616 ;; Back up statements until we find one that starts at boi.
3617 (while (let* ((prev-point (point))
3618 (last-step-type (c-beginning-of-statement-1
3620 (if (= (point) prev-point
)
3622 (setq step-type
(or step-type last-step-type
))
3624 (setq step-type last-step-type
)
3625 (/= (point) (c-point 'boi
)))))
3627 ;; CASE 17B: continued statement
3628 ((and (eq step-type
'same
)
3629 (/= (point) indent-point
))
3630 (c-add-stmt-syntax 'statement-cont nil
3631 containing-sexp paren-state
))
3632 ;; CASE 17A: After a case/default label?
3634 (while (and (eq step-type
'label
)
3635 (not (looking-at c-label-kwds-regexp
)))
3637 (c-beginning-of-statement-1 containing-sexp
)))
3638 (eq step-type
'label
))
3639 (c-add-stmt-syntax (if (eq char-after-ip ?
{)
3640 'statement-case-open
3641 'statement-case-intro
)
3642 t containing-sexp paren-state
))
3643 ;; CASE 17D: any old statement
3645 (while (eq step-type
'label
)
3647 (c-beginning-of-statement-1 containing-sexp
)))
3648 (eq step-type
'previous
))
3649 (c-add-stmt-syntax 'statement t containing-sexp paren-state
)
3650 (if (eq char-after-ip ?
{)
3651 (c-add-syntax 'block-open
)))
3652 ;; CASE 17I: Inside a substatement block.
3654 ;; The following tests are all based on containing-sexp.
3655 (goto-char containing-sexp
)
3656 ;; From here on we have the next containing sexp in lim.
3657 (setq lim
(c-most-enclosing-brace paren-state containing-sexp
))
3658 (c-after-conditional))
3659 (c-backward-to-block-anchor lim
)
3660 (c-add-stmt-syntax 'statement-block-intro t lim paren-state
)
3661 (if (eq char-after-ip ?
{)
3662 (c-add-syntax 'block-open
)))
3663 ;; CASE 17E: first statement in an in-expression block.
3664 ;; C.f. cases 4, 7B and 16A.
3665 ((setq placeholder
(c-looking-at-inexpr-block
3666 (c-safe-position containing-sexp paren-state
)
3668 (setq tmpsymbol
(if (eq (car placeholder
) 'inlambda
)
3670 'statement-block-intro
))
3671 (back-to-indentation)
3672 (if (= containing-sexp
(point))
3673 (c-add-syntax tmpsymbol
(point))
3674 (goto-char (cdr placeholder
))
3675 (back-to-indentation)
3676 (c-add-stmt-syntax tmpsymbol t
3677 (c-most-enclosing-brace c-state-cache
(point))
3678 (c-whack-state-after (point) paren-state
))
3679 (if (/= (point) (cdr placeholder
))
3680 (c-add-syntax (car placeholder
))))
3681 (if (eq char-after-ip ?
{)
3682 (c-add-syntax 'block-open
)))
3683 ;; CASE 17F: first statement in an inline, or first
3684 ;; statement in a top-level defun. we can tell this is it
3685 ;; if there are no enclosing braces that haven't been
3686 ;; narrowed out by a class (i.e. don't use bod here).
3687 ;; However, we first check for statements that we can
3688 ;; recognize by keywords. That increases the robustness in
3689 ;; cases where statements are used on the top level,
3690 ;; e.g. in macro definitions.
3694 (c-narrow-out-enclosing-class paren-state containing-sexp
)
3695 (not (c-most-enclosing-brace paren-state
))))
3696 (c-backward-to-decl-anchor lim
)
3697 (back-to-indentation)
3698 (c-add-syntax 'defun-block-intro
(point)))
3699 ;; CASE 17G: First statement in a function declared inside
3700 ;; a normal block. This can occur in Pike and with
3701 ;; e.g. the gcc extensions. Might also trigger it with
3702 ;; some macros followed by blocks, and this gives sane
3703 ;; indentation then too. C.f. cases B.3 and 16F.
3705 (and (not (c-looking-at-bos))
3706 (eq (c-beginning-of-statement-1 lim nil nil t
) 'same
)
3707 (setq placeholder
(point))))
3708 (back-to-indentation)
3709 (if (/= (point) containing-sexp
)
3710 (goto-char placeholder
))
3711 (c-add-stmt-syntax 'defun-block-intro t lim paren-state
))
3712 ;; CASE 17H: First statement in a block. C.f. case 16C.
3714 ;; If the block is preceded by a case/switch label on the
3715 ;; same line, we anchor at the first preceding label at
3716 ;; boi. The default handling in c-add-stmt-syntax is
3717 ;; really fixes it better, but we do like this to keep the
3718 ;; indentation compatible with version 5.28 and earlier.
3719 (while (and (/= (setq placeholder
(point)) (c-point 'boi
))
3720 (eq (c-beginning-of-statement-1 lim
) 'label
)))
3721 (goto-char placeholder
)
3722 (if (looking-at c-label-kwds-regexp
)
3723 (c-add-syntax 'statement-block-intro
(point))
3724 (goto-char containing-sexp
)
3725 ;; c-backward-to-block-anchor not necessary here; those
3726 ;; situations are handled in case 17I above.
3727 (c-add-stmt-syntax 'statement-block-intro t lim paren-state
))
3728 (if (eq char-after-ip ?
{)
3729 (c-add-syntax 'block-open
)))
3732 ;; now we need to look at any modifiers
3733 (goto-char indent-point
)
3734 (skip-chars-forward " \t")
3735 ;; are we looking at a comment only line?
3736 (when (and (looking-at c-comment-start-regexp
)
3737 (/= (c-forward-token-1 0 nil
(c-point 'eol
)) 0))
3738 (c-add-syntax 'comment-intro
))
3739 ;; we might want to give additional offset to friends (in C++).
3740 (when (and c-opt-friend-key
3741 (looking-at c-opt-friend-key
))
3742 (c-add-syntax 'friend
))
3743 ;; Start of or a continuation of a preprocessor directive?
3744 (if (and macro-start
3745 (eq macro-start
(c-point 'boi
))
3746 (not (and (c-major-mode-is 'pike-mode
)
3747 (eq (char-after (1+ macro-start
)) ?
\"))))
3748 (c-add-syntax 'cpp-macro
)
3749 (when (and c-syntactic-indentation-in-macros macro-start
)
3751 (when (or (< syntactic-relpos macro-start
)
3752 (not (or (assq 'arglist-intro syntax
)
3753 (assq 'arglist-cont syntax
)
3754 (assq 'arglist-cont-nonempty syntax
)
3755 (assq 'arglist-close syntax
))))
3756 ;; If inside a cpp expression, i.e. anywhere in a
3757 ;; cpp directive except a #define body, we only let
3758 ;; through the syntactic analysis that is internal
3759 ;; in the expression. That means the arglist
3760 ;; elements, if they are anchored inside the cpp
3762 (setq syntax
`((cpp-macro-cont .
,macro-start
))))
3763 (when (and (eq macro-start syntactic-relpos
)
3764 (not (assq 'cpp-define-intro syntax
))
3766 (goto-char macro-start
)
3767 (or (not (c-forward-to-cpp-define-body))
3768 (<= (point) (c-point 'boi indent-point
)))))
3769 ;; Inside a #define body and the syntactic analysis is
3770 ;; anchored on the start of the #define. In this case
3771 ;; we add cpp-define-intro to get the extra
3772 ;; indentation of the #define body.
3773 (c-add-syntax 'cpp-define-intro
)))))
3774 ;; return the syntax
3778 (defun c-echo-parsing-error (&optional quiet
)
3779 (when (and c-report-syntactic-errors c-parsing-error
(not quiet
))
3780 (c-benign-error "%s" c-parsing-error
))
3783 (defun c-evaluate-offset (offset langelem symbol
)
3784 ;; offset can be a number, a function, a variable, a list, or one of
3785 ;; the symbols + or -
3787 ((eq offset
'+) c-basic-offset
)
3788 ((eq offset
'-
) (- c-basic-offset
))
3789 ((eq offset
'++) (* 2 c-basic-offset
))
3790 ((eq offset
'--
) (* 2 (- c-basic-offset
)))
3791 ((eq offset
'*) (/ c-basic-offset
2))
3792 ((eq offset
'/) (/ (- c-basic-offset
) 2))
3793 ((numberp offset
) offset
)
3794 ((functionp offset
) (c-evaluate-offset
3795 (funcall offset langelem
) langelem symbol
))
3796 ((vectorp offset
) offset
)
3800 (while (and (not done
) offset
)
3801 (setq done
(c-evaluate-offset (car offset
) langelem symbol
)
3802 offset
(cdr offset
)))
3803 (if (and c-strict-syntax-p
(not done
))
3804 (c-benign-error "No offset found for syntactic symbol %s" symbol
))
3806 (t (symbol-value offset
))
3809 (defun c-get-offset (langelem)
3810 "Get offset from LANGELEM which is a cons cell of the form:
3811 \(SYMBOL . RELPOS). The symbol is matched against `c-offsets-alist'
3812 and the offset found there is returned."
3813 (let* ((symbol (car langelem
))
3814 (match (assq symbol c-offsets-alist
))
3815 (offset (cdr-safe match
)))
3817 (setq offset
(c-evaluate-offset offset langelem symbol
))
3818 (if c-strict-syntax-p
3819 (c-benign-error "No offset found for syntactic symbol %s" symbol
))
3821 (if (vectorp offset
)
3823 (or (and (numberp offset
) offset
)
3824 (and (symbolp offset
) (symbol-value offset
))
3828 (defun c-get-syntactic-indentation (langelems)
3829 "Apply `c-get-offset' to a list of langelem cells to get the total
3830 syntactic indentation. The anchor position, whose column is used as a
3831 base for all the collected offsets, is taken from the first element
3833 ;; Note that topmost-intro always has a relpos at bol, for
3834 ;; historical reasons. It's often used together with other symbols
3835 ;; that has more sane positions. Since we always use the first
3836 ;; found relpos, we rely on that these other symbols always precede
3837 ;; topmost-intro in the LANGELEMS list.
3838 (let ((indent 0) anchor
)
3841 (let ((res (c-get-offset (car langelems
))))
3843 (throw 'done
(elt res
0))
3845 (let ((relpos (cdr (car langelems
))))
3847 (setq anchor relpos
))))
3848 (setq indent
(+ indent res
)
3849 langelems
(cdr langelems
)))))
3858 (cc-provide 'cc-engine
)
3860 ;;; cc-engine.el ends here