[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/progmodes/cc-engine.el
From: |
Martin Stjernholm |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/progmodes/cc-engine.el |
Date: |
Sun, 21 Apr 2002 20:35:39 -0400 |
Index: emacs/lisp/progmodes/cc-engine.el
diff -c emacs/lisp/progmodes/cc-engine.el:1.21
emacs/lisp/progmodes/cc-engine.el:1.22
*** emacs/lisp/progmodes/cc-engine.el:1.21 Thu Apr 11 23:05:04 2002
--- emacs/lisp/progmodes/cc-engine.el Sun Apr 21 20:35:36 2002
***************
*** 25,36 ****
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
! ;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;;; Code:
(eval-when-compile
--- 25,46 ----
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
! ;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
+ ;; The functions which have docstring documentation can be considered
+ ;; part of an API which other packages can use in CC Mode buffers.
+ ;; Otoh, undocumented functions and functions with the documentation
+ ;; in comments are considered purely internal and can change semantics
+ ;; or even disappear in the future.
+ ;;
+ ;; (This policy applies to CC Mode as a whole, not just this file. It
+ ;; probably also applies to many other Emacs packages, but here it's
+ ;; clearly spelled out.)
+
;;; Code:
(eval-when-compile
***************
*** 49,56 ****
(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
! (defvar c-state-cache nil)
(defvar c-in-literal-cache t)
;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
--- 59,76 ----
(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
! (defun c-calculate-state (arg prevstate)
! ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
! ;; arg is nil or zero, toggle the state. If arg is negative, turn
! ;; the state off, and if arg is positive, turn the state on
! (if (or (not arg)
! (zerop (setq arg (prefix-numeric-value arg))))
! (not prevstate)
! (> arg 0)))
!
!
(defvar c-in-literal-cache t)
+ (defvar c-parsing-error nil)
;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
***************
*** 58,342 ****
;; the byte compiler.
(defvar c-maybe-labelp nil)
! ;; WARNING WARNING WARNING
! ;;
! ;; Be *exceptionally* careful about modifications to this function!
! ;; Much of CC Mode depends on this Doing The Right Thing. If you
! ;; break it you will be sorry. If you think you know how this works,
! ;; you probably don't. No human on Earth does! :-)
! ;;
! ;; WARNING WARNING WARNING
! (defun c-beginning-of-statement-1 (&optional lim)
! ;; move to the start of the current statement, or the previous
! ;; statement if already at the beginning of one.
! (let ((firstp t)
! (substmt-p t)
! donep c-in-literal-cache saved
! (last-begin (point)))
! ;; first check for bare semicolon
! (if (and (progn (c-backward-syntactic-ws lim)
! (eq (char-before) ?\;))
! (c-safe (progn (forward-char -1)
! (setq saved (point))
! t))
! (progn (c-backward-syntactic-ws lim)
! (memq (char-before) '(?\; ?{ ?:)))
! )
! (setq last-begin saved)
! (goto-char last-begin)
! (while (not donep)
! ;; stop at beginning of buffer
! (if (bobp) (setq donep t)
! ;; go backwards one balanced expression, but be careful of
! ;; unbalanced paren being reached
! (if (not (c-safe (progn (c-backward-sexp 1) t)))
! (progn
! (if firstp
! (backward-up-list 1)
! (goto-char last-begin))
! ;; skip over any unary operators, or other special
! ;; characters appearing at front of identifier
! (save-excursion
! (c-backward-syntactic-ws lim)
! (skip-chars-backward "-+!*&:.~@ \t\n")
! (if (eq (char-before) ?\()
! (setq last-begin (point))))
! (goto-char last-begin)
! (setq donep t)))
!
! (setq c-maybe-labelp nil)
! ;; see if we're in a literal. if not, then this bufpos may be
! ;; a candidate for stopping
! (cond
! ;; CASE 0: did we hit the error condition above?
! (donep)
! ;; CASE 1: are we in a literal?
! ((eq (c-in-literal lim) 'pound)
! (beginning-of-line))
! ;; CASE 2: some other kind of literal?
! ((c-in-literal lim))
! ;; CASE 3: are we looking at a conditional keyword?
! ((or (and c-conditional-key (looking-at c-conditional-key))
! (and (eq (char-after) ?\()
! (save-excursion
! (c-forward-sexp 1)
! (c-forward-syntactic-ws)
! (not (eq (char-after) ?\;)))
! (let ((here (point))
! (foundp (progn
! (c-backward-syntactic-ws lim)
! (forward-word -1)
! (and lim
! (<= lim (point))
! (not (c-in-literal lim))
! (not (eq (char-before) ?_))
! c-conditional-key
! (looking-at c-conditional-key)
! ))))
! ;; did we find a conditional?
! (if (not foundp)
! (goto-char here))
! foundp)))
! ;; are we in the middle of an else-if clause?
! (if (save-excursion
! (and (not substmt-p)
! (c-safe (progn (c-forward-sexp -1) t))
! (looking-at "\\<else\\>[ \t\n]+\\<if\\>")
! (not (c-in-literal lim))))
! (progn
! (c-forward-sexp -1)
! (c-backward-to-start-of-if lim)))
! ;; are we sitting at an else clause, that we are not a
! ;; substatement of?
! (if (and (not substmt-p)
! (looking-at "\\<else\\>[^_]"))
! (c-backward-to-start-of-if lim))
! ;; a finally or a series of catches?
! (if (not substmt-p)
! (while (looking-at "\\<\\(catch\\|finally\\)\\>[^_]")
! (c-safe (c-backward-sexp 2))
! (if (eq (char-after) ?\()
! (c-safe (c-backward-sexp)))))
! ;; are we sitting at the while of a do-while?
! (if (and (looking-at "\\<while\\>[^_]")
! (c-backward-to-start-of-do lim))
! (setq substmt-p nil))
! (setq last-begin (point)
! donep substmt-p))
! ;; CASE 4: are we looking at a label? (But we handle
! ;; switch labels later.)
! ((and (looking-at c-label-key)
! (not (looking-at "default\\>"))
! (not (and (c-major-mode-is 'pike-mode)
! (save-excursion
! ;; Not inside a Pike type declaration?
! (and (c-safe (backward-up-list 1) t)
! (eq (char-after) ?\()))))))
! ;; CASE 5: is this the first time we're checking?
! (firstp (setq firstp nil
! substmt-p (not (c-crosses-statement-barrier-p
! (point) last-begin))
! last-begin (point)))
! ;; CASE 6: have we crossed a statement barrier?
! ((save-excursion
! ;; Move over in-expression blocks before checking the
! ;; barrier
! (if (or (memq (char-after) '(?\( ?\[))
! (and (eq (char-after) ?{)
! (c-looking-at-inexpr-block lim)))
! (c-forward-sexp 1))
! (c-crosses-statement-barrier-p (point) last-begin))
! (setq donep t))
! ;; CASE 7: ignore labels
! ((and c-maybe-labelp
! (or (and c-access-key (looking-at c-access-key))
! ;; with switch labels, we have to go back further
! ;; to try to pick up the case or default
! ;; keyword. Potential bogosity alert: we assume
! ;; `case' or `default' is first thing on line
! (let ((here (point)))
! (beginning-of-line)
! (c-forward-syntactic-ws here)
! (if (looking-at c-switch-label-key)
! t
! (goto-char here)
! nil)))))
! ;; CASE 8: ObjC or Java method def
! ((and c-method-key
! (setq last-begin (c-in-method-def-p)))
! (setq donep t))
! ;; CASE 9: Normal token. At bob, we can end up at ws or a
! ;; comment, and last-begin shouldn't be updated then.
! ((not (looking-at "\\s \\|/[/*]"))
! (setq last-begin (point)))
! ))))
! (goto-char last-begin)
! ;; We always want to skip over the non-whitespace modifier
! ;; characters that can start a statement.
! (let ((lim (point)))
! (skip-chars-backward "-+!*&address@hidden \t\n" (c-point 'boi))
! (skip-chars-forward " \t\n" lim))))
!
! (defun c-end-of-statement-1 ()
! (condition-case nil
! (let (beg end found)
! (while (and (not (eobp))
(progn
! (setq beg (point))
! (c-forward-sexp 1)
! (setq end (point))
! (goto-char beg)
! (setq found nil)
! (while (and (not found)
! (re-search-forward "[;{}]" end t))
! (if (not (c-in-literal beg))
! (setq found t)))
! (not found)))
! (goto-char end))
! (re-search-backward "[;{}]")
! (forward-char 1))
! (error
! (let ((beg (point)))
! (c-safe (backward-up-list -1))
! (let ((end (point)))
! (goto-char beg)
! (search-forward ";" end 'move)))
! )))
-
(defun c-crosses-statement-barrier-p (from to)
! ;; Does buffer positions FROM to TO cross a C statement boundary?
! (let ((here (point))
! (lim from)
! crossedp)
! (condition-case ()
! (progn
! (goto-char from)
! (while (and (not crossedp)
(< (point) to))
! (skip-chars-forward "^;{}:" (1- to))
! (if (not (c-in-literal lim))
! (progn
! (if (memq (char-after) '(?\; ?{ ?}))
! (setq crossedp t)
! (if (eq (char-after) ?:)
! (setq c-maybe-labelp t))
! (forward-char 1))
! (setq lim (point)))
! (forward-char 1))))
! (error (setq crossedp nil)))
! (goto-char here)
! crossedp))
(defun c-beginning-of-macro (&optional lim)
! ;; Go to the beginning of a cpp macro definition. Leaves point at
! ;; the beginning of the macro and returns t if in a cpp macro
! ;; definition, otherwise returns nil and leaves point unchanged.
! ;; `lim' is currently ignored, but the interface requires it.
(let ((here (point)))
! (beginning-of-line)
! (while (eq (char-before (1- (point))) ?\\)
! (forward-line -1))
! (back-to-indentation)
! (if (and (<= (point) here)
! (eq (char-after) ?#))
! t
! (goto-char here)
! nil)))
! ;; Skipping of "syntactic whitespace", defined as lexical whitespace,
! ;; C and C++ style comments, and preprocessor directives. Search no
! ;; farther back or forward than optional LIM. If LIM is omitted,
! ;; `beginning-of-defun' is used for backward skipping, point-max is
! ;; used for forward skipping.
(defun c-forward-syntactic-ws (&optional lim)
! ;; Forward skip of syntactic whitespace for Emacs 19.
! (let* ((here (point-max))
! (hugenum (point-max)))
(while (/= here (point))
(setq here (point))
! (c-forward-comment hugenum)
! ;; skip preprocessor directives
! (when (and (eq (char-after) ?#)
! (= (c-point 'boi) (point)))
! (while (and (eq (char-before (c-point 'eol)) ?\\)
! (= (forward-line 1) 0)))
! (end-of-line))
! )
! (if lim (goto-char (min (point) lim)))))
(defun c-backward-syntactic-ws (&optional lim)
! ;; Backward skip over syntactic whitespace for Emacs 19.
! (let* ((here (point-min))
! (hugenum (- (point-max))))
(while (/= here (point))
(setq here (point))
! (c-forward-comment hugenum)
! (c-beginning-of-macro))
! (if lim (goto-char (max (point) lim)))))
!
!
! ;; Moving by tokens, where a token is defined as all symbols and
! ;; identifiers which aren't syntactic whitespace (note that "->" is
! ;; considered to be two tokens). Point is always either left at the
! ;; beginning of a token or not moved at all. COUNT specifies the
! ;; number of tokens to move; a negative COUNT moves in the opposite
! ;; direction. A COUNT of 0 moves to the next token beginning only if
! ;; not already at one. If BALANCED is true, move over balanced
! ;; parens, otherwise move into them. Also, if BALANCED is true, never
! ;; move out of an enclosing paren. LIM sets the limit for the
! ;; movement and defaults to the point limit. Returns the number of
! ;; tokens left to move (positive or negative). If BALANCED is true, a
! ;; move over a balanced paren counts as one. Note that if COUNT is 0
! ;; and no appropriate token beginning is found, 1 will be returned.
! ;; Thus, a return value of 0 guarantees that point is at the requested
! ;; position and a return value less (without signs) than COUNT
! ;; guarantees that point is at the beginning of some token.
(defun c-forward-token-1 (&optional count balanced lim)
(or count (setq count 1))
(if (< count 0)
(- (c-backward-token-1 (- count) balanced lim))
--- 78,734 ----
;; the byte compiler.
(defvar c-maybe-labelp nil)
! ;; Macros used internally in c-beginning-of-statement-1 for the
! ;; automaton actions.
! (defmacro c-bos-push-state ()
! '(setq stack (cons (cons state saved-pos)
! stack)))
! (defmacro c-bos-pop-state (&optional do-if-done)
! `(if (setq state (car (car stack))
! saved-pos (cdr (car stack))
! stack (cdr stack))
! t
! ,do-if-done
! (throw 'loop nil)))
! (defmacro c-bos-pop-state-and-retry ()
! '(throw 'loop (setq state (car (car stack))
! saved-pos (cdr (car stack))
! ;; Throw nil if stack is empty, else throw non-nil.
! stack (cdr stack))))
! (defmacro c-bos-save-pos ()
! '(setq saved-pos (vector pos tok ptok pptok)))
! (defmacro c-bos-restore-pos ()
! '(unless (eq (elt saved-pos 0) start)
! (setq pos (elt saved-pos 0)
! tok (elt saved-pos 1)
! ptok (elt saved-pos 2)
! pptok (elt saved-pos 3))
! (goto-char pos)
! (setq sym nil)))
! (defmacro c-bos-save-error-info (missing got)
! `(setq saved-pos (vector pos ,missing ,got)))
! (defmacro c-bos-report-error ()
! '(unless noerror
! (setq c-parsing-error
! (format "No matching `%s' found for `%s' on line %d"
! (elt saved-pos 1)
! (elt saved-pos 2)
! (1+ (count-lines (point-min)
! (c-point 'bol (elt saved-pos 0))))))))
!
! (defun c-beginning-of-statement-1 (&optional lim ignore-labels
! noerror comma-delim)
! "Move to the start of the current statement or declaration, or to
! the previous one if already at the beginning of one. Only
! statements/declarations on the same level are considered, i.e. don't
! move into or out of sexps (not even normal expression parentheses).
!
! Stop at statement continuations like \"else\", \"catch\", \"finally\"
! and the \"while\" in \"do ... while\" if the start point is within
! them. If starting at such a continuation, move to the corresponding
! statement start. If at the beginning of a statement, move to the
! closest containing statement if there is any. This might also stop at
! a continuation clause.
!
! Labels are treated as separate statements if IGNORE-LABELS is non-nil.
! The function is not overly intelligent in telling labels from other
! uses of colons; if used outside a statement context it might trip up
! on e.g. inherit colons, so IGNORE-LABELS should be used then. There
! should be no such mistakes in a statement context, however.
!
! Macros are ignored unless point is within one, in which case the
! content of the macro is treated as normal code. Aside from any normal
! statement starts found in it, stop at the first token of the content
! in the macro, i.e. the expression of an \"#if\" or the start of the
! definition in a \"#define\". Also stop at start of macros before
! leaving them.
!
! Return 'label if stopped at a label, 'same if stopped at the beginning
! of the current statement, 'up if stepped to a containing statement,
! 'previous if stepped to a preceding statement, 'beginning if stepped
! from a statement continuation clause to its start clause, or 'macro if
! stepped to a macro start. Note that 'same and not 'label is returned
! if stopped at the same label without crossing the colon character.
!
! LIM may be given to limit the search. If the search hits the limit,
! point will be left at the closest following token, or at the start
! position if that is less ('same is returned in this case).
! NOERROR turns off error logging to `c-parsing-error'.
!
! Normally only ';' is considered to delimit statements, but if
! COMMA-DELIM is non-nil then ',' is treated likewise."
!
! ;; The bulk of this function is a pushdown automaton that looks at
! ;; statement boundaries and the tokens in c-opt-block-stmt-key.
! ;;
! ;; Note: The position of a boundary is the following token.
! ;;
! ;; Begin with current token, stop when stack is empty and the
! ;; position has been moved.
! ;;
! ;; Common state:
! ;; "else": Push state, goto state `else':
! ;; boundary: Goto state `else-boundary':
! ;; "if": Pop state.
! ;; boundary: Error, pop state.
! ;; other: See common state.
! ;; other: Error, pop state, retry token.
! ;; "while": Push state, goto state `while':
! ;; boundary: Save position, goto state `while-boundary':
! ;; "do": Pop state.
! ;; boundary: Restore position if it's not at start, pop state.
! ;; other: See common state.
! ;; other: Pop state, retry token.
! ;; "catch" or "finally": Push state, goto state `catch':
! ;; boundary: Goto state `catch-boundary':
! ;; "try": Pop state.
! ;; "catch": Goto state `catch'.
! ;; boundary: Error, pop state.
! ;; other: See common state.
! ;; other: Error, pop state, retry token.
! ;; other: Do nothing special.
! ;;
! ;; In addition to the above there is some special handling of labels
! ;; and macros.
!
! (let ((case-fold-search nil)
! (start (point))
! macro-start
! (delims (if comma-delim '(?\; ?,) '(?\;)))
! (c-stmt-delim-chars (if comma-delim
! c-stmt-delim-chars-with-comma
! c-stmt-delim-chars))
! pos ; Current position.
! boundary-pos ; Position of last boundary.
! after-labels-pos ; Value of tok after first found colon.
! last-label-pos ; Value of tok after last found colon.
! sym ; Current symbol in the alphabet.
! state ; Current state in the automaton.
! saved-pos ; Current saved positions.
! stack ; Stack of conses (state . saved-pos).
! (cond-key (or c-opt-block-stmt-key
! "\\<\\>")) ; Matches nothing.
! (ret 'same)
! tok ptok pptok ; Pos of last three sexps or bounds.
! c-in-literal-cache c-maybe-labelp saved)
!
! (save-restriction
! (if lim (narrow-to-region lim (point-max)))
!
! (if (save-excursion
! (and (c-beginning-of-macro)
! (/= (point) start)))
! (setq macro-start (point)))
!
! ;; Try to skip over unary operator characters, to register
! ;; that we've moved.
! (while (progn
! (setq pos (point))
! (c-backward-syntactic-ws)
! (/= (skip-chars-backward "-+!*&address@hidden") 0)))
!
! ;; First check for bare semicolon. Later on we ignore the
! ;; boundaries for statements that doesn't contain any sexp.
! ;; The only thing that is affected is that the error checking
! ;; is a little less strict, and we really don't bother.
! (if (and (memq (char-before) delims)
! (progn (forward-char -1)
! (setq saved (point))
! (c-backward-syntactic-ws)
! (or (memq (char-before) delims)
! (memq (char-before) '(?: nil))
! (eq (char-syntax (char-before)) ?\())))
! (setq ret 'previous
! pos saved)
!
! ;; Begin at start and not pos to detect macros if we stand
! ;; directly after the #.
! (goto-char start)
! (if (looking-at "\\<\\|\\W")
! ;; Record this as the first token if not starting inside it.
! (setq tok start))
!
! (while
! (catch 'loop ;; Throw nil to break, non-nil to continue.
! (cond
! ;; Check for macro start.
! ((save-excursion
! (and macro-start
! (looking-at "[ \t]*[a-zA-Z0-9!]")
! (progn (skip-chars-backward " \t")
! (eq (char-before) ?#))
! (progn (setq saved (1- (point)))
! (beginning-of-line)
! (not (eq (char-before (1- (point))) ?\\)))
! (progn (skip-chars-forward " \t")
! (eq (point) saved))))
! (goto-char saved)
! (if (and (c-forward-to-cpp-define-body)
! (progn (c-forward-syntactic-ws start)
! (< (point) start)))
! ;; Stop at the first token in the content of the macro.
! (setq pos (point)
! ignore-labels t) ; Avoid the label check on exit.
! (setq pos saved
! ret 'macro
! ignore-labels t))
! (throw 'loop nil))
!
! ;; Do a round through the automaton if we found a
! ;; boundary or if looking at a statement keyword.
! ((or sym
! (and (looking-at cond-key)
! (setq sym (intern (match-string 1)))))
!
! (when (and (< pos start) (null stack))
! (throw 'loop nil))
!
! ;; The state handling. Continue in the common state for
! ;; unhandled cases.
! (or (cond
! ((eq state 'else)
! (if (eq sym 'boundary)
! (setq state 'else-boundary)
! (c-bos-report-error)
! (c-bos-pop-state-and-retry)))
!
! ((eq state 'else-boundary)
! (cond ((eq sym 'if)
! (c-bos-pop-state (setq ret 'beginning)))
! ((eq sym 'boundary)
! (c-bos-report-error)
! (c-bos-pop-state))))
!
! ((eq state 'while)
! (if (and (eq sym 'boundary)
! ;; Since this can cause backtracking we do a
! ;; little more careful analysis to avoid it:
! ;; If there's a label in front of the while
! ;; it can't be part of a do-while.
! (not after-labels-pos))
! (progn (c-bos-save-pos)
! (setq state 'while-boundary))
! (c-bos-pop-state-and-retry)))
!
! ((eq state 'while-boundary)
! (cond ((eq sym 'do)
! (c-bos-pop-state (setq ret 'beginning)))
! ((eq sym 'boundary)
! (c-bos-restore-pos)
! (c-bos-pop-state))))
!
! ((eq state 'catch)
! (if (eq sym 'boundary)
! (setq state 'catch-boundary)
! (c-bos-report-error)
! (c-bos-pop-state-and-retry)))
!
! ((eq state 'catch-boundary)
! (cond
! ((eq sym 'try)
! (c-bos-pop-state (setq ret 'beginning)))
! ((eq sym 'catch)
! (setq state 'catch))
! ((eq sym 'boundary)
! (c-bos-report-error)
! (c-bos-pop-state)))))
!
! ;; This is state common.
! (cond ((eq sym 'boundary)
! (if (< pos start)
! (c-bos-pop-state)
! (c-bos-push-state)))
! ((eq sym 'else)
! (c-bos-push-state)
! (c-bos-save-error-info 'if 'else)
! (setq state 'else))
! ((eq sym 'while)
! (when (or (not pptok)
! (memq (char-after pptok) delims))
! ;; Since this can cause backtracking we do a
! ;; little more careful analysis to avoid it: If
! ;; the while isn't followed by a semicolon it
! ;; can't be a do-while.
! (c-bos-push-state)
! (setq state 'while)))
! ((memq sym '(catch finally))
! (c-bos-push-state)
! (c-bos-save-error-info 'try sym)
! (setq state 'catch))))
!
! (when c-maybe-labelp
! ;; We're either past a statement boundary or at the
! ;; start of a statement, so throw away any label data
! ;; for the previous one.
! (setq after-labels-pos nil
! last-label-pos nil
! c-maybe-labelp nil))))
!
! ;; Step to next sexp, but not if we crossed a boundary, since
! ;; that doesn't consume an sexp.
! (if (eq sym 'boundary)
! (setq ret 'previous)
! (while
(progn
! (or (c-safe (goto-char (scan-sexps (point) -1)) t)
! (throw 'loop nil))
! (cond ((looking-at "\\\\$")
! ;; Step again if we hit a line continuation.
! t)
! (macro-start
! ;; If we started inside a macro then this
! ;; sexp is always interesting.
! nil)
! (t
! ;; Otherwise check that we didn't step
! ;; into a macro from the end.
! (let ((macro-start
! (save-excursion
! (and (c-beginning-of-macro)
! (point)))))
! (when macro-start
! (goto-char macro-start)
! t))))))
!
! ;; Check for statement boundary.
! (when (save-excursion
! (if (if (eq (char-after) ?{)
! (c-looking-at-inexpr-block lim nil)
! (eq (char-syntax (char-after)) ?\())
! ;; Need to move over parens and
! ;; in-expression blocks to get a good start
! ;; position for the boundary check.
! (c-forward-sexp 1))
! (setq boundary-pos (c-crosses-statement-barrier-p
! (point) pos)))
! (setq pptok ptok
! ptok tok
! tok boundary-pos
! sym 'boundary)
! (throw 'loop t)))
!
! (when (and (numberp c-maybe-labelp) (not ignore-labels))
! ;; c-crosses-statement-barrier-p has found a colon, so
! ;; we might be in a label now.
! (if (not after-labels-pos)
! (setq after-labels-pos tok))
! (setq last-label-pos tok
! c-maybe-labelp t))
!
! ;; ObjC method def?
! (when (and c-opt-method-key
! (setq saved (c-in-method-def-p)))
! (setq pos saved
! ignore-labels t) ; Avoid the label check on exit.
! (throw 'loop nil))
!
! (setq sym nil
! pptok ptok
! ptok tok
! tok (point)
! pos tok))) ; Not nil.
!
! ;; If the stack isn't empty there might be errors to report.
! (while stack
! (if (and (vectorp saved-pos) (eq (length saved-pos) 3))
! (c-bos-report-error))
! (setq saved-pos (cdr (car stack))
! stack (cdr stack)))
!
! (when (and (eq ret 'same)
! (not (memq sym '(boundary ignore nil))))
! ;; Need to investigate closer whether we've crossed
! ;; between a substatement and its containing statement.
! (if (setq saved (if (looking-at c-block-stmt-1-key)
! ptok
! pptok))
! (cond ((> start saved) (setq pos saved))
! ((= start saved) (setq ret 'up)))))
!
! (when (and c-maybe-labelp (not ignore-labels) after-labels-pos)
! ;; We're in a label. Maybe we should step to the statement
! ;; after it.
! (if (< after-labels-pos start)
! (setq pos after-labels-pos)
! (setq ret 'label)
! (if (< last-label-pos start)
! (setq pos last-label-pos)))))
!
! ;; Skip over the unary operators that can start the statement.
! (goto-char pos)
! (while (progn
! (c-backward-syntactic-ws)
! (/= (skip-chars-backward "-+!*&address@hidden") 0))
! (setq pos (point)))
! (goto-char pos)
! ret)))
(defun c-crosses-statement-barrier-p (from to)
! "Return non-nil if buffer positions FROM to TO cross one or more
! statement or declaration boundaries. The returned value is actually
! the position of the earliest boundary char.
!
! The variable `c-maybe-labelp' is set to the position of the first `:' that
! might start a label (i.e. not part of `::' and not preceded by `?'). If a
! single `?' is found, then `c-maybe-labelp' is cleared."
! (let ((skip-chars c-stmt-delim-chars)
! lit-range)
! (save-excursion
! (catch 'done
! (goto-char from)
! (while (progn (skip-chars-forward skip-chars to)
(< (point) to))
! (if (setq lit-range (c-literal-limits from))
! (goto-char (setq from (cdr lit-range)))
! (cond ((eq (char-after) ?:)
! (forward-char)
! (if (and (eq (char-after) ?:)
! (< (point) to))
! ;; Ignore scope operators.
! (forward-char)
! (setq c-maybe-labelp (1- (point)))))
! ((eq (char-after) ??)
! ;; A question mark. Can't be a label, so stop
! ;; looking for more : and ?.
! (setq c-maybe-labelp nil
! skip-chars (substring c-stmt-delim-chars 0 -2)))
! (t (throw 'done (point))))))
! nil))))
+ ;; This is a dynamically bound cache used together with
+ ;; c-query-macro-start and c-query-and-set-macro-start. It only works
+ ;; as long as point doesn't cross a macro boundary.
+ (defvar c-macro-start 'unknown)
+
+ (defsubst c-query-and-set-macro-start ()
+ (if (symbolp c-macro-start)
+ (setq c-macro-start (save-excursion
+ (and (c-beginning-of-macro)
+ (point))))
+ c-macro-start))
+
+ (defsubst c-query-macro-start ()
+ (if (symbolp c-macro-start)
+ (save-excursion
+ (and (c-beginning-of-macro)
+ (point)))
+ c-macro-start))
+
(defun c-beginning-of-macro (&optional lim)
! "Go to the beginning of a cpp macro definition.
! Leave point at the beginning of the macro and return t if in a cpp
! macro definition, otherwise return nil and leave point unchanged."
(let ((here (point)))
! (save-restriction
! (if lim (narrow-to-region lim (point-max)))
! (beginning-of-line)
! (while (eq (char-before (1- (point))) ?\\)
! (forward-line -1))
! (back-to-indentation)
! (if (and (<= (point) here)
! (looking-at "#[ \t]*[a-zA-Z0-9!]"))
! t
! (goto-char here)
! nil))))
!
! (defun c-end-of-macro ()
! "Go to the end of a cpp macro definition.
! More accurately, move point to the end of the closest following line
! that doesn't end with a line continuation backslash."
! (while (progn
! (end-of-line)
! (when (and (eq (char-before) ?\\)
! (not (eobp)))
! (forward-char)
! t))))
!
! (defun c-forward-comment (count)
! ;; Insulation from various idiosyncrasies in implementations of
! ;; `forward-comment'.
! ;;
! ;; Note: Some emacsen considers incorrectly that any line comment
! ;; ending with a backslash continues to the next line. I can't
! ;; think of any way to work around that in a reliable way without
! ;; changing the buffer, though. Suggestions welcome. ;) (No,
! ;; temporarily changing the syntax for backslash doesn't work since
! ;; we must treat escapes in string literals correctly.)
! ;;
! ;; Another note: When moving backwards over a block comment, there's
! ;; a bug in forward-comment that can make it stop at "/*" inside a
! ;; line comment. Haven't yet found a reasonably cheap way to kludge
! ;; around that one either. :\
! (let ((here (point)))
! (if (>= count 0)
! (when (forward-comment count)
! (if (eobp)
! ;; Some emacsen (e.g. XEmacs 21) return t when moving
! ;; forwards at eob.
! nil
! ;; Emacs includes the ending newline in a b-style (c++)
! ;; comment, but XEmacs doesn't. We depend on the Emacs
! ;; behavior (which also is symmetric).
! (if (and (eolp) (nth 7 (parse-partial-sexp here (point))))
! (condition-case nil (forward-char 1)))
! t))
! ;; When we got newline terminated comments,
! ;; forward-comment in all supported emacsen so far will
! ;; stop at eol of each line not ending with a comment when
! ;; moving backwards. The following corrects for it when
! ;; count is -1. The other common case, when count is
! ;; large and negative, works regardless. It's too much
! ;; work to correct for the rest of the cases.
! (skip-chars-backward " \t\n\r\f")
! (if (bobp)
! ;; Some emacsen return t when moving backwards at bob.
! nil
! (re-search-forward "[\n\r]" here t)
! (let* ((res (if (forward-comment count)
! (if (eolp) (forward-comment -1) t)))
! (savepos (point)))
! ;; XEmacs treats line continuations as whitespace (but only
! ;; in the backward direction).
! (while (and (progn (end-of-line) (< (point) here))
! (eq (char-before) ?\\))
! (setq res nil
! savepos (point))
! (forward-line))
! (goto-char savepos)
! res)))))
! (defun c-forward-comment-lc (count)
! ;; Like `c-forward-comment', but treat line continuations as
! ;; whitespace.
! (catch 'done
! (if (> count 0)
! (while (if (c-forward-comment 1)
! (progn
! (setq count (1- count))
! (> count 0))
! (if (looking-at "\\\\$")
! (progn
! (forward-char)
! t)
! (throw 'done nil))))
! (while (if (c-forward-comment -1)
! (progn
! (setq count (1+ count))
! (< count 0))
! (if (and (eolp) (eq (char-before) ?\\))
! (progn
! (backward-char)
! t)
! (throw 'done nil)))))
! t))
(defun c-forward-syntactic-ws (&optional lim)
! "Forward skip of syntactic whitespace.
! Syntactic whitespace is defined as whitespace characters, comments,
! and preprocessor directives. However if point starts inside a comment
! or preprocessor directive, the content of it is not treated as
! whitespace. LIM sets an upper limit of the forward movement, if
! specified."
! (let ((here (point-max)))
! (or lim (setq lim here))
(while (/= here (point))
+ ;; If forward-comment in at least XEmacs 21 is given a large
+ ;; positive value, it'll loop all the way through if it hits eob.
+ (while (c-forward-comment 5))
(setq here (point))
! (cond
! ;; Skip line continuations.
! ((looking-at "\\\\$")
! (forward-char))
! ;; Skip preprocessor directives.
! ((and (looking-at "#[ \t]*[a-zA-Z0-9!]")
! (progn (skip-chars-backward " \t")
! (bolp)))
! (end-of-line)
! (while (and (<= (point) lim)
! (eq (char-before) ?\\)
! (= (forward-line 1) 0))
! (end-of-line))
! (when (> (point) lim)
! ;; Don't move past the macro if that'd take us past the limit.
! (goto-char here)))
! ;; Skip in-comment line continuations (used for Pike refdoc).
! ((and c-opt-in-comment-lc (looking-at c-opt-in-comment-lc))
! (goto-char (match-end 0)))))
! (goto-char (min (point) lim))))
(defun c-backward-syntactic-ws (&optional lim)
! "Backward skip of syntactic whitespace.
! Syntactic whitespace is defined as whitespace characters, comments,
! and preprocessor directives. However if point starts inside a comment
! or preprocessor directive, the content of it is not treated as
! whitespace. LIM sets a lower limit of the backward movement, if
! specified."
! (let ((start-line (c-point 'bol))
! (here (point-min))
! (line-cont 'maybe)
! prev-pos)
! (or lim (setq lim here))
(while (/= here (point))
+ (setq prev-pos (point))
+ ;; If forward-comment in Emacs 19.34 is given a large negative
+ ;; value, it'll loop all the way through if it hits bob.
+ (while (c-forward-comment -5))
(setq here (point))
! (cond
! ((and (eolp)
! (eq (char-before) ?\\)
! (if (<= prev-pos (c-point 'eonl))
! t
! ;; Passed a line continuation, but not from the line we
! ;; started on.
! (forward-char)
! (setq line-cont nil)))
! (backward-char)
! (setq line-cont t))
! ((progn
! (when (eq line-cont 'maybe)
! (save-excursion
! (end-of-line)
! (setq line-cont (eq (char-before) ?\\))))
! (or line-cont
! (and (< (point) start-line)
! (c-beginning-of-macro))))
! (if (< (point) lim)
! ;; Don't move past the macro if we began inside it or at
! ;; the end of the same line, or if the move would take us
! ;; past the limit.
! (goto-char here))
! (setq line-cont nil))
! ;; Skip in-comment line continuations (used for Pike refdoc).
! ((and c-opt-in-comment-lc
! (save-excursion
! (and (c-safe (beginning-of-line)
! (backward-char 2)
! t)
! (looking-at c-opt-in-comment-lc)
! (eq (match-end 0) here))))
! (goto-char (match-beginning 0)))))
! (goto-char (max (point) lim))))
(defun c-forward-token-1 (&optional count balanced lim)
+ "Move forward by tokens.
+ A token is defined as all symbols and identifiers which aren't
+ syntactic whitespace \(note that e.g. \"->\" is considered to be two
+ tokens). Point is always either left at the beginning of a token or
+ not moved at all. COUNT specifies the number of tokens to move; a
+ negative COUNT moves in the opposite direction. A COUNT of 0 moves to
+ the next token beginning only if not already at one. If BALANCED is
+ true, move over balanced parens, otherwise move into them. Also, if
+ BALANCED is true, never move out of an enclosing paren. LIM sets the
+ limit for the movement and defaults to the point limit.
+
+ Return the number of tokens left to move \(positive or negative). If
+ BALANCED is true, a move over a balanced paren counts as one. Note
+ that if COUNT is 0 and no appropriate token beginning is found, 1 will
+ be returned. Thus, a return value of 0 guarantees that point is at
+ the requested position and a return value less \(without signs) than
+ COUNT guarantees that point is at the beginning of some token."
(or count (setq count 1))
(if (< count 0)
(- (c-backward-token-1 (- count) balanced lim))
***************
*** 371,377 ****
(if (memq (char-syntax (char-after)) jump-syntax)
(goto-char (scan-sexps (point) 1))
(forward-char))
! (c-forward-syntactic-ws lim)
(setq count (1- count)))
(error (goto-char last)))
(when (eobp)
--- 763,769 ----
(if (memq (char-syntax (char-after)) jump-syntax)
(goto-char (scan-sexps (point) 1))
(forward-char))
! (c-forward-syntactic-ws)
(setq count (1- count)))
(error (goto-char last)))
(when (eobp)
***************
*** 380,385 ****
--- 772,779 ----
count)))
(defun c-backward-token-1 (&optional count balanced lim)
+ "Move backward by tokens.
+ See `c-forward-token-1' for details."
(or count (setq count 1))
(if (< count 0)
(- (c-forward-token-1 (- count) balanced lim))
***************
*** 391,397 ****
(or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
(memq (char-syntax (or (char-before) ? )) '(?w ?_)))
(/= (point)
! (save-excursion (c-forward-syntactic-ws) (point)))
(eobp)))
;; If count is zero we should jump if in the middle of a
;; token or if there is whitespace between point and the
--- 785,793 ----
(or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
(memq (char-syntax (or (char-before) ? )) '(?w ?_)))
(/= (point)
! (save-excursion
! (c-forward-syntactic-ws (1+ lim))
! (point)))
(eobp)))
;; If count is zero we should jump if in the middle of a
;; token or if there is whitespace between point and the
***************
*** 406,412 ****
(while (progn
(setq last (point))
(> count 0))
! (c-backward-syntactic-ws lim)
(if (memq (char-syntax (char-before)) jump-syntax)
(goto-char (scan-sexps (point) -1))
(backward-char))
--- 802,808 ----
(while (progn
(setq last (point))
(> count 0))
! (c-backward-syntactic-ws)
(if (memq (char-syntax (char-before)) jump-syntax)
(goto-char (scan-sexps (point) -1))
(backward-char))
***************
*** 415,430 ****
(if (bobp) (goto-char last)))))
count)))
! ;; Return `c' if in a C-style comment, `c++' if in a C++ style
! ;; comment, `string' if in a string literal, `pound' if on a
! ;; preprocessor line, or nil if not in a comment at all. Optional LIM
! ;; is used as the backward limit of the search. If omitted, or nil,
! ;; `beginning-of-defun' is used."
!
! (defun c-in-literal (&optional lim)
! ;; Determine if point is in a C++ literal. we cache the last point
! ;; calculated if the cache is enabled
(if (and (vectorp c-in-literal-cache)
(= (point) (aref c-in-literal-cache 0)))
(aref c-in-literal-cache 1)
--- 811,903 ----
(if (bobp) (goto-char last)))))
count)))
+ (defun c-syntactic-re-search-forward (regexp &optional bound noerror count
+ paren-level)
+ ;; Like `re-search-forward', but only report matches that are found
+ ;; in syntactically significant text. I.e. matches that begins in
+ ;; comments, macros or string literals are ignored. The start point
+ ;; is assumed to be outside any comment, macro or string literal, or
+ ;; else the content of that region is taken as syntactically
+ ;; significant text. If PAREN-LEVEL is non-nil, an additional
+ ;; restriction is added to ignore matches in nested paren sexps, and
+ ;; the search will also not go outside the current paren sexp.
+ (or bound (setq bound (point-max)))
+ (or count (setq count 1))
+ (if paren-level (setq paren-level -1))
+ (let ((start (point))
+ (pos (point))
+ match-pos state)
+ (condition-case err
+ (while (and (> count 0)
+ (re-search-forward regexp bound noerror))
+ (setq match-pos (point)
+ state (parse-partial-sexp pos (match-beginning 0)
+ paren-level nil state)
+ pos (point))
+ (cond ((nth 3 state)
+ ;; Match inside a string. Skip to the end of it
+ ;; before continuing.
+ (let ((ender (make-string 1 (nth 3 state))))
+ (while (progn
+ (search-forward ender bound noerror)
+ (setq state (parse-partial-sexp pos (point)
+ nil nil state)
+ pos (point))
+ (nth 3 state)))))
+ ((nth 7 state)
+ ;; Match inside a line comment. Skip to eol. Use
+ ;; re-search-forward for it to get the right bound
+ ;; behavior.
+ (re-search-forward "[\n\r]" bound noerror))
+ ((nth 4 state)
+ ;; Match inside a block comment. Skip to the '*/'.
+ (re-search-forward "\\*/" bound noerror))
+ ((save-excursion (c-beginning-of-macro start))
+ ;; Match inside a macro. Skip to the end of it.
+ (c-end-of-macro))
+ ((and paren-level (/= (car state) 0))
+ (if (> (car state) 0)
+ ;; Match inside a nested paren sexp. Skip out of it.
+ (setq state (parse-partial-sexp pos bound 0 nil state)
+ pos (point))
+ ;; Have exited the current paren sexp. The
+ ;; parse-partial-sexp above has left us just after
+ ;; the closing paren in this case. Just make
+ ;; re-search-forward above fail in the appropriate
+ ;; way; we'll adjust the leave off point below if
+ ;; necessary.
+ (setq bound (point))))
+ (t
+ ;; A real match.
+ (setq count (1- count)))))
+ (error
+ (goto-char start)
+ (signal (car err) (cdr err))))
+ (if (= count 0)
+ (progn
+ (goto-char match-pos)
+ match-pos)
+ ;; Search failed. Set point as appropriate.
+ (cond ((eq noerror t)
+ (goto-char start))
+ (paren-level
+ (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1)
+ (backward-char)))
+ (t
+ (goto-char bound)))
+ nil)))
+
! (defun c-in-literal (&optional lim detect-cpp)
! "Return the type of literal point is in, if any.
! The return value is `c' if in a C-style comment, `c++' if in a C++
! style comment, `string' if in a string literal, `pound' if DETECT-CPP
! is non-nil and on a preprocessor line, or nil if somewhere else.
! Optional LIM is used as the backward limit of the search. If omitted,
! or nil, `c-beginning-of-defun' is used.
!
! The last point calculated is cached if the cache is enabled, i.e. if
! `c-in-literal-cache' is bound to a two element vector."
(if (and (vectorp c-in-literal-cache)
(= (point) (aref c-in-literal-cache 0)))
(aref c-in-literal-cache 1)
***************
*** 434,440 ****
(cond
((nth 3 state) 'string)
((nth 4 state) (if (nth 7 state) 'c++ 'c))
! ((c-beginning-of-macro lim) 'pound)
(t nil))))))
;; cache this result if the cache is enabled
(if (not c-in-literal-cache)
--- 907,913 ----
(cond
((nth 3 state) 'string)
((nth 4 state) (if (nth 7 state) 'c++ 'c))
! ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
(t nil))))))
;; cache this result if the cache is enabled
(if (not c-in-literal-cache)
***************
*** 443,472 ****
;; XEmacs has a built-in function that should make this much quicker.
;; I don't think we even need the cache, which makes our lives more
! ;; complicated anyway. In this case, lim is ignored.
! (defun c-fast-in-literal (&optional lim)
(let ((context (buffer-syntactic-context)))
(cond
((eq context 'string) 'string)
((eq context 'comment) 'c++)
((eq context 'block-comment) 'c)
! ((save-excursion (c-beginning-of-macro lim)) 'pound))))
(if (fboundp 'buffer-syntactic-context)
(defalias 'c-in-literal 'c-fast-in-literal))
(defun c-literal-limits (&optional lim near not-in-delimiter)
! ;; Returns a cons of the beginning and end positions of the comment
! ;; or string surrounding point (including both delimiters), or nil
! ;; if point isn't in one. If LIM is non-nil, it's used as the
! ;; "safe" position to start parsing from. If NEAR is non-nil, then
! ;; the limits of any literal next to point is returned. "Next to"
! ;; means there's only [ \t] between point and the literal. The
! ;; search for such a literal is done first in forward direction. If
! ;; NOT-IN-DELIMITER is non-nil, the case when point is inside a
! ;; starting delimiter won't be recognized. This only has effect for
! ;; comments, which have starting delimiters with more than one
! ;; character.
(save-excursion
(let* ((pos (point))
(lim (or lim (c-point 'bod)))
--- 916,945 ----
;; XEmacs has a built-in function that should make this much quicker.
;; I don't think we even need the cache, which makes our lives more
! ;; complicated anyway. In this case, lim is only used to detect
! ;; cpp directives.
! (defun c-fast-in-literal (&optional lim detect-cpp)
(let ((context (buffer-syntactic-context)))
(cond
((eq context 'string) 'string)
((eq context 'comment) 'c++)
((eq context 'block-comment) 'c)
! ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound))))
(if (fboundp 'buffer-syntactic-context)
(defalias 'c-in-literal 'c-fast-in-literal))
(defun c-literal-limits (&optional lim near not-in-delimiter)
! "Return a cons of the beginning and end positions of the comment or
! string surrounding point (including both delimiters), or nil if point
! isn't in one. If LIM is non-nil, it's used as the \"safe\" position
! to start parsing from. If NEAR is non-nil, then the limits of any
! literal next to point is returned. \"Next to\" means there's only [
! \t] between point and the literal. The search for such a literal is
! done first in forward direction. If NOT-IN-DELIMITER is non-nil, the
! case when point is inside a starting delimiter won't be recognized.
! This only has effect for comments, which have starting delimiters with
! more than one character."
(save-excursion
(let* ((pos (point))
(lim (or lim (c-point 'bod)))
***************
*** 586,597 ****
(defalias 'c-literal-limits 'c-literal-limits-fast))
(defun c-collect-line-comments (range)
! ;; If the argument is a cons of two buffer positions (such as
! ;; returned by c-literal-limits), and that range contains a C++
! ;; style line comment, then an extended range is returned that
! ;; contains all adjacent line comments (i.e. all comments that
! ;; starts in the same column with no empty lines or non-whitespace
! ;; characters between them). Otherwise the argument is returned.
(save-excursion
(condition-case nil
(if (and (consp range) (progn
--- 1059,1070 ----
(defalias 'c-literal-limits 'c-literal-limits-fast))
(defun c-collect-line-comments (range)
! "If the argument is a cons of two buffer positions (such as returned by
! `c-literal-limits'), and that range contains a C++ style line comment,
! then an extended range is returned that contains all adjacent line
! comments (i.e. all comments that starts in the same column with no
! empty lines or non-whitespace characters between them). Otherwise the
! argument is returned."
(save-excursion
(condition-case nil
(if (and (consp range) (progn
***************
*** 620,629 ****
(error range))))
(defun c-literal-type (range)
! ;; Convenience function that given the result of c-literal-limits,
! ;; returns nil or the type of literal that the range surrounds.
! ;; It's much faster than using c-in-literal and is intended to be
! ;; used when you need both the type of a literal and its limits.
(if (consp range)
(save-excursion
(goto-char (car range))
--- 1093,1102 ----
(error range))))
(defun c-literal-type (range)
! "Convenience function that given the result of `c-literal-limits',
! returns nil or the type of literal that the range surrounds. It's
! much faster than using `c-in-literal' and is intended to be used when
! you need both the type of a literal and its limits."
(if (consp range)
(save-excursion
(goto-char (car range))
***************
*** 635,849 ****
;; utilities for moving and querying around syntactic elements
! (defvar c-parsing-error nil)
(defun c-parse-state ()
! ;; Finds and records all open parens between some important point
! ;; earlier in the file and point.
;;
! ;; if there's a state cache, return it
! (if c-state-cache c-state-cache
! (let* (at-bob
! (pos (save-excursion
;; go back 2 bods, but ignore any bogus positions
! ;; returned by beginning-of-defun (i.e. open paren
! ;; in column zero)
(let ((cnt 2))
! (while (not (or at-bob (zerop cnt)))
! (goto-char (c-point 'bod))
! (if (and
! (eq (char-after) ?\{)
! ;; The following catches an obscure special
! ;; case where the brace is preceded by an
! ;; open paren. That can only legally occur
! ;; with blocks inside expressions and in
! ;; Pike special brace lists. Even so, this
! ;; test is still bogus then, but hopefully
! ;; good enough. (We don't want to use
! ;; up-list here since it might be slow.)
! (save-excursion
! (c-backward-syntactic-ws)
! (not (eq (char-before) ?\())))
! (setq cnt (1- cnt)))
! (if (bobp)
! (setq at-bob t))))
! (point)))
! (here (save-excursion
! ;;(skip-chars-forward " \t}")
! (point)))
! (last-bod here) (last-pos pos)
! placeholder state sexp-end)
! ;; cache last bod position
! (while (catch 'backup-bod
! (setq state nil)
! (while (and pos (< pos here))
! (setq last-pos pos)
! (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
! (<= pos here))
! (progn
! (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
! (if (and sexp-end
! (<= sexp-end here))
! ;; we want to record both the start and end
! ;; of this sexp, but we only want to record
! ;; the last-most of any of them before here
! (progn
! (if (eq (char-after (1- pos)) ?\{)
! (setq state (cons (cons (1- pos) sexp-end)
! (if (consp (car state))
! (cdr state)
! state))))
! (setq pos sexp-end))
! ;; we're contained in this sexp so put pos on
! ;; front of list
! (setq state (cons (1- pos) state))))
! ;; something bad happened. check to see if we
! ;; crossed an unbalanced close brace. if so, we
! ;; didn't really find the right `important bufpos'
! ;; so lets back up and try again
! (if (and (not pos) (not at-bob)
! (setq placeholder
! (c-safe (scan-lists last-pos 1 1)))
! ;;(char-after (1- placeholder))
! (<= placeholder here)
! (eq (char-after (1- placeholder)) ?\}))
! (while t
! (setq last-bod (c-safe (scan-lists last-pos -1 1)))
! (if (not last-bod)
! (save-excursion
! ;; bogus, but what can we do here?
! (goto-char placeholder)
! (beginning-of-line)
! (setq c-parsing-error
! (format "\
! Unbalanced close brace at line %d" (1+ (count-lines 1 (point)))))
! (throw 'backup-bod nil))
! (setq at-bob (= last-bod (point-min))
! pos last-bod)
! (if (= (char-after last-bod) ?\{)
! (throw 'backup-bod t)))
! )) ;end-if
! )) ;end-while
! nil))
! state)))
!
! (defun c-whack-state (bufpos state)
! ;; whack off any state information that appears on STATE which lies
! ;; after the bounds of BUFPOS.
! (let (newstate car)
! (while state
! (setq car (car state)
! state (cdr state))
! (if (consp car)
! ;; just check the car, because in a balanced brace
! ;; expression, it must be impossible for the corresponding
! ;; close brace to be before point, but the open brace to be
! ;; after.
! (if (<= bufpos (car car))
nil ; whack it off
! ;; its possible that the open brace is before bufpos, but
! ;; the close brace is after. In that case, convert this
! ;; to a non-cons element.
! (if (<= bufpos (cdr car))
! (setq newstate (append newstate (list (car car))))
! ;; we know that both the open and close braces are
! ;; before bufpos, so we also know that everything else
! ;; on state is before bufpos, so we can glom up the
! ;; whole thing and exit.
! (setq newstate (append newstate (list car) state)
! state nil)))
! (if (<= bufpos car)
! nil ; whack it off
! ;; it's before bufpos, so everything else should too
! (setq newstate (append newstate (list car) state)
! state nil))))
! newstate))
!
! (defun c-hack-state (bufpos which state)
! ;; Using BUFPOS buffer position, and WHICH (must be 'open or
! ;; 'close), hack the c-parse-state STATE and return the results.
! (if (eq which 'open)
! (let ((car (car state)))
! (if (or (null car)
! (consp car)
! (/= bufpos car))
! (cons bufpos state)
! state))
! (if (not (eq which 'close))
! (error "c-hack-state, bad argument: %s" which))
! ;; 'close brace
! (let ((car (car state))
! (cdr (cdr state)))
! (if (consp car)
! (setq car (car cdr)
! cdr (cdr cdr)))
! ;; TBD: is this test relevant???
! (if (consp car)
! state ;on error, don't change
! ;; watch out for balanced expr already on cdr of list
! (cons (cons car bufpos)
! (if (consp (car cdr))
! (cdr cdr) cdr))
! ))))
!
! (defun c-adjust-state (from to shift state)
! ;; Adjust all points in state that lie in the region FROM..TO by
! ;; SHIFT amount.
! (mapcar
! (function
! (lambda (e)
! (if (consp e)
! (let ((car (car e))
! (cdr (cdr e)))
! (if (and (<= from car) (< car to))
! (setcar e (+ shift car)))
! (if (and (<= from cdr) (< cdr to))
! (setcdr e (+ shift cdr))))
! (if (and (<= from e) (< e to))
! (setq e (+ shift e))))
! e))
! state))
(defun c-beginning-of-inheritance-list (&optional lim)
;; Go to the first non-whitespace after the colon that starts a
;; multiple inheritance introduction. Optional LIM is the farthest
;; back we should search.
! (let* ((lim (or lim (c-point 'bod)))
! (placeholder (progn
! (back-to-indentation)
! (point)))
! (chr (char-after)))
! (c-backward-syntactic-ws lim)
! (while (and (> (point) lim)
! (or (eq chr ?,)
! (memq (char-before) '(?, ?:)))
! (progn
! (beginning-of-line)
! (setq placeholder (point))
! (skip-chars-forward " \t")
! (setq chr (char-after))
! (not (looking-at c-class-key))
! ))
! (c-backward-syntactic-ws lim))
! (goto-char placeholder)
! (skip-chars-forward "^:" (c-point 'eol))))
(defun c-in-method-def-p ()
;; Return nil if we aren't in a method definition, otherwise the
;; position of the initial [+-].
(save-excursion
(beginning-of-line)
! (and c-method-key
! (looking-at c-method-key)
(point))
))
(defun c-at-toplevel-p ()
"Return a determination as to whether point is at the `top-level'.
Being at the top-level means that point is either outside any
! enclosing block (such function definition), or inside a class
! definition, but outside any method blocks.
If point is not at the top-level (e.g. it is inside a method
definition), then nil is returned. Otherwise, if point is at a
--- 1108,1408 ----
;; utilities for moving and querying around syntactic elements
!
! (defvar c-state-cache nil)
! (make-variable-buffer-local 'c-state-cache)
! ;; The state cache used by `c-parse-state' to cut down the amount of
! ;; searching. It's the result from some earlier `c-parse-state' call.
! ;; The use of the cached info is more effective if the next
! ;; `c-parse-state' call is on a line close by the one the cached state
! ;; was made at; the cache can actually slow down a little if the
! ;; cached state was made very far back in the buffer. The cache is
! ;; most effective if `c-parse-state' is used on each line while moving
! ;; forward.
!
! (defvar c-state-cache-start nil)
! ;; This (point-min) when `c-state-cache' was calculated, to detect
! ;; that the start point hasn't changed due to narrowing.
(defun c-parse-state ()
! ;; Finds and records all noteworthy parens between some good point
! ;; earlier in the file and point. That good point is at least the
! ;; beginning of the top-level construct we are in, or the beginning
! ;; of the preceding top-level construct if we aren't in one.
;;
! ;; The returned value is a list of the noteworthy parens with the
! ;; last one first. If an element in the list is an integer, it's
! ;; the position of an open paren which has not been closed before
! ;; point. If an element is a cons, it gives the position of a
! ;; closed brace paren pair; the car is the start paren position and
! ;; the cdr is the position following the closing paren. Only the
! ;; last closed brace paren pair before each open paren is recorded,
! ;; and thus the state never contains two cons elements in
! ;; succession.
! (save-restriction
! (let* ((here (point))
! (c-macro-start (c-query-macro-start))
! (in-macro-start (or c-macro-start (point)))
! old-state last-pos pairs pos)
! ;; Somewhat ugly use of c-check-state-cache to get rid of the
! ;; part of the state cache that is after point. Can't use
! ;; c-whack-state-after for the same reasons as in that function.
! (c-check-state-cache (point) nil nil)
! ;; Get the latest position we know are directly inside the
! ;; closest containing paren of the cached state.
! (setq last-pos (and c-state-cache
! (if (consp (car c-state-cache))
! (cdr (car c-state-cache))
! (1+ (car c-state-cache)))))
! ;; Check if the found last-pos is in a macro. If it is, and
! ;; we're not in the same macro, we must discard everything on
! ;; c-state-cache that is inside the macro before using it.
! (when last-pos
! (save-excursion
! (goto-char last-pos)
! (when (and (c-beginning-of-macro)
! (/= (point) in-macro-start))
! (c-check-state-cache (point) nil nil)
! ;; Set last-pos again, just like above.
! (setq last-pos (and c-state-cache
! (if (consp (car c-state-cache))
! (cdr (car c-state-cache))
! (1+ (car c-state-cache))))))))
! (setq pos
! ;; Find the start position for the forward search. (Can't
! ;; search in the backward direction since point might be
! ;; in some kind of literal.)
! (or (when last-pos
! ;; There's a cached state with a containing paren. Pop
! ;; off the stale containing sexps from it by going
! ;; forward out of parens as far as possible.
! (narrow-to-region (point-min) here)
! (let (placeholder pair-beg)
! (while (and c-state-cache
! (setq placeholder
! (c-up-list-forward last-pos)))
! (setq last-pos placeholder)
! (if (consp (car c-state-cache))
! (setq pair-beg (car-safe (cdr c-state-cache))
! c-state-cache (cdr-safe (cdr c-state-cache)))
! (setq pair-beg (car c-state-cache)
! c-state-cache (cdr c-state-cache))))
! (when (and pair-beg (eq (char-after pair-beg) ?{))
! ;; The last paren pair we moved out from was a brace
! ;; pair. Modify the state to record this as a closed
! ;; pair now.
! (if (consp (car-safe c-state-cache))
! (setq c-state-cache (cdr c-state-cache)))
! (setq c-state-cache (cons (cons pair-beg last-pos)
! c-state-cache))))
! ;; Check if the preceding balanced paren is within a
! ;; macro; it should be ignored if we're outside the
! ;; macro. There's no need to check any further upwards;
! ;; if the macro contains an unbalanced opening paren then
! ;; we're smoked anyway.
! (when (and (<= (point) in-macro-start)
! (consp (car c-state-cache)))
! (save-excursion
! (goto-char (car (car c-state-cache)))
! (when (c-beginning-of-macro)
! (setq here (point)
! c-state-cache (cdr c-state-cache)))))
! (when c-state-cache
! (setq old-state c-state-cache)
! last-pos))
! (save-excursion
;; go back 2 bods, but ignore any bogus positions
! ;; returned by beginning-of-defun (i.e. open paren in
! ;; column zero)
! (goto-char here)
(let ((cnt 2))
! (while (not (or (bobp) (zerop cnt)))
! (c-beginning-of-defun-1)
! (if (eq (char-after) ?\{)
! (setq cnt (1- cnt)))))
! (point))))
! (narrow-to-region (point-min) here)
! (while pos
! ;; Find the balanced brace pairs.
! (setq pairs nil)
! (while (and (setq last-pos (c-down-list-forward pos))
! (setq pos (c-up-list-forward last-pos)))
! (if (eq (char-before last-pos) ?{)
! (setq pairs (cons (cons last-pos pos) pairs))))
! ;; Should ignore any pairs that are in a macro, providing
! ;; we're not in the same one.
! (when (and pairs (< (car (car pairs)) in-macro-start))
! (while (and (save-excursion
! (goto-char (car (car pairs)))
! (c-beginning-of-macro))
! (setq pairs (cdr pairs)))))
! ;; Record the last brace pair.
! (when pairs
! (if (and (eq c-state-cache old-state)
! (consp (car-safe c-state-cache)))
! ;; There's a closed pair on the cached state but we've
! ;; found a later one, so remove it.
! (setq c-state-cache (cdr c-state-cache)))
! (setq pairs (car pairs))
! (setcar pairs (1- (car pairs)))
! (setq c-state-cache (cons pairs c-state-cache)))
! (if last-pos
! ;; Prepare to loop, but record the open paren only if it's
! ;; outside a macro or within the same macro as point.
! (progn
! (setq pos last-pos)
! (if (or (>= last-pos in-macro-start)
! (save-excursion
! (goto-char last-pos)
! (not (c-beginning-of-macro))))
! (setq c-state-cache (cons (1- pos) c-state-cache))))
! (if (setq last-pos (c-up-list-forward pos))
! ;; Found a close paren without a corresponding opening
! ;; one. Maybe we didn't go back far enough, so try to
! ;; scan backward for the start paren and then start over.
! (progn
! (setq pos (c-up-list-backward pos)
! c-state-cache nil)
! (unless pos
! (setq pos last-pos
! c-parsing-error
! (format "Unbalanced close paren at line %d"
! (1+ (count-lines (point-min)
! (c-point 'bol last-pos)))))))
! (setq pos nil))))
! c-state-cache)))
!
! ;; Debug tool to catch cache inconsistencies.
! (defvar c-debug-parse-state nil)
! (unless (fboundp 'c-real-parse-state)
! (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
! (cc-bytecomp-defun c-real-parse-state)
! (defun c-debug-parse-state ()
! (let ((res1 (c-real-parse-state)) res2)
! (let ((c-state-cache nil))
! (setq res2 (c-real-parse-state)))
! (unless (equal res1 res2)
! (error "c-parse-state inconsistency: using cache: %s, from scratch: %s"
! res1 res2))
! res1))
! (defun c-toggle-parse-state-debug (&optional arg)
! (interactive "P")
! (setq c-debug-parse-state (c-calculate-state arg c-debug-parse-state))
! (fset 'c-parse-state (symbol-function (if c-debug-parse-state
! 'c-debug-parse-state
! 'c-real-parse-state)))
! (c-keep-region-active))
!
! (defun c-check-state-cache (beg end old-length)
! ;; Used on `after-change-functions' to adjust `c-state-cache'.
! ;; Prefer speed to finesse here, since there will be many more calls
! ;; to this function than times `c-state-cache' is used.
! ;;
! ;; This is much like `c-whack-state-after', but it never changes a
! ;; paren pair element into an open paren element. Doing that would
! ;; mean that the new open paren wouldn't have the required preceding
! ;; paren pair element.
! (if (not (eq c-state-cache-start (point-min)))
! (setq c-state-cache-start (point-min)
! c-state-cache nil)
! (while (and c-state-cache
! (let ((elem (car c-state-cache)))
! (if (consp elem)
! (or (<= beg (car elem))
! (< beg (cdr elem)))
! (<= beg elem))))
! (setq c-state-cache (cdr c-state-cache)))))
!
! (defun c-whack-state-before (bufpos paren-state)
! ;; Whack off any state information from PAREN-STATE which lies
! ;; before BUFPOS. Not destructive on PAREN-STATE.
! (let* ((newstate (list nil))
! (ptr newstate)
! car)
! (while paren-state
! (setq car (car paren-state)
! paren-state (cdr paren-state))
! (if (< (if (consp car) (car car) car) bufpos)
! (setq paren-state nil)
! (setcdr ptr (list car))
! (setq ptr (cdr ptr))))
! (cdr newstate)))
!
! (defun c-whack-state-after (bufpos paren-state)
! ;; Whack off any state information from PAREN-STATE which lies at or
! ;; after BUFPOS. Not destructive on PAREN-STATE.
! (catch 'done
! (while paren-state
! (let ((car (car paren-state)))
! (if (consp car)
! ;; just check the car, because in a balanced brace
! ;; expression, it must be impossible for the corresponding
! ;; close brace to be before point, but the open brace to
! ;; be after.
! (if (<= bufpos (car car))
! nil ; whack it off
! (if (< bufpos (cdr car))
! ;; its possible that the open brace is before
! ;; bufpos, but the close brace is after. In that
! ;; case, convert this to a non-cons element. The
! ;; rest of the state is before bufpos, so we're
! ;; done.
! (throw 'done (cons (car car) (cdr paren-state)))
! ;; we know that both the open and close braces are
! ;; before bufpos, so we also know that everything else
! ;; on state is before bufpos.
! (throw 'done paren-state)))
! (if (<= bufpos car)
nil ; whack it off
! ;; it's before bufpos, so everything else should too.
! (throw 'done paren-state)))
! (setq paren-state (cdr paren-state)))
! nil)))
(defun c-beginning-of-inheritance-list (&optional lim)
;; Go to the first non-whitespace after the colon that starts a
;; multiple inheritance introduction. Optional LIM is the farthest
;; back we should search.
! (let* ((lim (or lim (c-point 'bod))))
! (c-with-syntax-table c++-template-syntax-table
! (c-backward-token-1 0 t lim)
! (while (and (looking-at "[_a-zA-Z<,]")
! (= (c-backward-token-1 1 t lim) 0)))
! (skip-chars-forward "^:"))))
(defun c-in-method-def-p ()
;; Return nil if we aren't in a method definition, otherwise the
;; position of the initial [+-].
(save-excursion
(beginning-of-line)
! (and c-opt-method-key
! (looking-at c-opt-method-key)
(point))
))
+ ;; Contributed by Kevin Ryde <address@hidden>.
+ (defun c-in-gcc-asm-p ()
+ ;; Return non-nil if point is within a gcc \"asm\" block.
+ ;;
+ ;; This should be called with point inside an argument list.
+ ;;
+ ;; Only one level of enclosing parentheses is considered, so for
+ ;; instance `nil' is returned when in a function call within an asm
+ ;; operand.
+
+ (and c-opt-asm-stmt-key
+ (save-excursion
+ (beginning-of-line)
+ (backward-up-list 1)
+ (c-beginning-of-statement-1 (point-min) nil t)
+ (looking-at c-opt-asm-stmt-key))))
+
(defun c-at-toplevel-p ()
"Return a determination as to whether point is at the `top-level'.
Being at the top-level means that point is either outside any
! enclosing block (such function definition), or inside a class,
! namespace or extern definition, but outside any method blocks.
If point is not at the top-level (e.g. it is inside a method
definition), then nil is returned. Otherwise, if point is at a
***************
*** 852,876 ****
buffer position of the start of the class declaration, and the first
element is the buffer position of the enclosing class's opening
brace."
! (let ((state (c-parse-state)))
! (or (not (c-most-enclosing-brace state))
! (c-search-uplist-for-classkey state))))
! (defun c-just-after-func-arglist-p (&optional containing)
;; Return t if we are between a function's argument list closing
;; paren and its opening brace. Note that the list close brace
;; could be followed by a "const" specifier or a member init hanging
;; colon. Optional CONTAINING is position of containing s-exp open
! ;; brace. If not supplied, point is used as search start.
(save-excursion
! (c-backward-syntactic-ws)
(let ((checkpoint (or containing (point))))
(goto-char checkpoint)
;; could be looking at const specifier
(if (and (eq (char-before) ?t)
(forward-word -1)
! (looking-at "\\<const\\>"))
! (c-backward-syntactic-ws)
;; otherwise, we could be looking at a hanging member init
;; colon
(goto-char checkpoint)
--- 1411,1452 ----
buffer position of the start of the class declaration, and the first
element is the buffer position of the enclosing class's opening
brace."
! (let ((paren-state (c-parse-state)))
! (or (not (c-most-enclosing-brace paren-state))
! (c-search-uplist-for-classkey paren-state))))
!
! (defun c-forward-to-cpp-define-body ()
! ;; Assuming point is at the "#" that introduces a preprocessor
! ;; directive, it's moved forward to the start of the definition body
! ;; if it's a "#define". Non-nil is returned in this case, in all
! ;; other cases nil is returned and point isn't moved.
! (when (and (looking-at
! (concat "#[ \t]*"
! "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
! "\\([ \t]\\|\\\\\n\\)*"))
! (not (= (match-end 0) (c-point 'eol))))
! (goto-char (match-end 0))))
! (defun c-just-after-func-arglist-p (&optional containing lim)
;; Return t if we are between a function's argument list closing
;; paren and its opening brace. Note that the list close brace
;; could be followed by a "const" specifier or a member init hanging
;; colon. Optional CONTAINING is position of containing s-exp open
! ;; brace. If not supplied, point is used as search start. LIM is
! ;; used as bound for some backward buffer searches; the search might
! ;; continue past it.
! ;;
! ;; Note: This test is easily fooled. It only works reasonably well
! ;; in the situations where `c-guess-basic-syntax' uses it.
(save-excursion
! (c-backward-syntactic-ws lim)
(let ((checkpoint (or containing (point))))
(goto-char checkpoint)
;; could be looking at const specifier
(if (and (eq (char-before) ?t)
(forward-word -1)
! (looking-at "\\<const\\>[^_]"))
! (c-backward-syntactic-ws lim)
;; otherwise, we could be looking at a hanging member init
;; colon
(goto-char checkpoint)
***************
*** 882,903 ****
(if (eq (char-before) ?\))
(c-backward-sexp 2)
(c-backward-sexp 1))
! (c-backward-syntactic-ws))
(if (and (eq (char-before) ?:)
(progn
(forward-char -1)
! (c-backward-syntactic-ws)
! (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
nil
(goto-char checkpoint))
)
(and (eq (char-before) ?\))
! ;; check if we are looking at a method def
! (or (not c-method-key)
(progn
(c-forward-sexp -1)
(forward-char -1)
! (c-backward-syntactic-ws)
(not (or (memq (char-before) '(?- ?+))
;; or a class category
(progn
--- 1458,1487 ----
(if (eq (char-before) ?\))
(c-backward-sexp 2)
(c-backward-sexp 1))
! (c-backward-syntactic-ws lim))
(if (and (eq (char-before) ?:)
(progn
(forward-char -1)
! (c-backward-syntactic-ws lim)
! (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)")))
nil
(goto-char checkpoint))
)
+ (setq checkpoint (point))
(and (eq (char-before) ?\))
! ;; Check that it isn't a cpp expression, e.g. the
! ;; expression of an #if directive or the "function header"
! ;; of a #define.
! (or (not (c-beginning-of-macro))
! (and (c-forward-to-cpp-define-body)
! (< (point) checkpoint)))
! ;; check if we are looking at an ObjC method def
! (or (not c-opt-method-key)
(progn
+ (goto-char checkpoint)
(c-forward-sexp -1)
(forward-char -1)
! (c-backward-syntactic-ws lim)
(not (or (memq (char-before) '(?- ?+))
;; or a class category
(progn
***************
*** 906,1023 ****
)))))
)))
! ;; defuns to look backwards for things
! (defun c-backward-to-start-of-do (&optional lim)
! ;; Move to the start of the last "unbalanced" do expression.
! ;; Optional LIM is the farthest back to search. If none is found,
! ;; nil is returned and point is left unchanged, otherwise t is returned.
! (let ((do-level 1)
! (case-fold-search nil)
! (lim (or lim (c-point 'bod)))
! (here (point))
! foundp)
! (while (not (zerop do-level))
! ;; we protect this call because trying to execute this when the
! ;; while is not associated with a do will throw an error
! (condition-case nil
! (progn
! (c-backward-sexp 1)
! (cond
! ;; break infloop for illegal C code
! ((bobp) (setq do-level 0))
! ((memq (c-in-literal lim) '(c c++)))
! ((looking-at "while\\b[^_]")
! (setq do-level (1+ do-level)))
! ((looking-at "do\\b[^_]")
! (if (zerop (setq do-level (1- do-level)))
! (setq foundp t)))
! ((<= (point) lim)
! (setq do-level 0)
! (goto-char lim))))
! (error
! (goto-char lim)
! (setq do-level 0))))
! (if (not foundp)
! (goto-char here))
! foundp))
!
! (defun c-backward-to-start-of-if (&optional lim)
! ;; Move to the start of the last "unbalanced" if and return t. If
! ;; none is found, and we are looking at an if clause, nil is
! ;; returned.
! (let ((if-level 1)
! (here (c-point 'bol))
! (case-fold-search nil)
! (lim (or (and lim (>= (point) lim) lim)
! (c-point 'bod)))
! (at-if (looking-at "if\\b[^_]")))
! (catch 'orphan-if
! (while (and (not (bobp))
! (not (zerop if-level)))
! (c-backward-syntactic-ws)
! (condition-case nil
! (c-backward-sexp 1)
! (error
! (unless at-if
! (goto-char here)
! (c-beginning-of-statement-1)
! (setq c-parsing-error
! (format "No matching `if' found for `else' on line %d"
! (1+ (count-lines (point-min) here))))
! (throw 'orphan-if nil))))
! (cond
! ((looking-at "else\\b[^_]")
! (setq if-level (1+ if-level)))
! ((looking-at "if\\b[^_]")
! ;; check for else if... skip over
! (let ((here (point)))
! (c-safe (c-forward-sexp -1))
! (if (looking-at "\\<else\\>[ \t]+\\<if\\>[^_]")
! nil
! (setq if-level (1- if-level))
! (goto-char here))))
! ((< (point) lim)
! (setq if-level 0)
! (goto-char lim))
! ))
! t)))
(defun c-skip-conditional ()
;; skip forward over conditional at point, including any predicate
;; statements in parentheses. No error checking is performed.
(c-forward-sexp (cond
;; else if()
! ((looking-at "\\<else\\>[ \t]+\\<if\\>\\([^_]\\|$\\)") 3)
;; do, else, try, finally
! ((looking-at
! "\\<\\(do\\|else\\|try\\|finally\\)\\>\\([^_]\\|$\\)")
1)
;; for, if, while, switch, catch, synchronized, foreach
(t 2))))
! (defun c-beginning-of-closest-statement (&optional lim)
! ;; Go back to the closest preceding statement start.
(let ((start (point))
! (label-re (concat c-label-key "\\|"
! c-switch-label-key))
! stmtbeg)
! (if c-access-key
! (setq label-re (concat label-re "\\|" c-access-key)))
! (c-beginning-of-statement-1 lim)
! (while (and (when (<= (point) start)
! (setq stmtbeg (point)))
! (cond
! ((looking-at label-re)
! ;; Skip a label.
! (goto-char (match-end 0))
! t)
! ((looking-at c-conditional-key)
! ;; Skip a conditional statement.
! (c-safe (c-skip-conditional) t))
! (t nil)))
! (c-forward-syntactic-ws start))
! (if stmtbeg
! (goto-char stmtbeg))))
(defun c-beginning-of-member-init-list (&optional limit)
;; Goes to the beginning of a member init list (i.e. just after the
--- 1490,1723 ----
)))))
)))
! (defun c-in-knr-argdecl (&optional lim)
! ;; Return the position of the first argument declaration if point is
! ;; inside a K&R style argument declaration list, nil otherwise.
! ;; `c-recognize-knr-p' is not checked. If LIM is non-nil, it's a
! ;; position that bounds the backward search for the argument list.
! ;;
! ;; Note: A declaration level context is assumed; the test can return
! ;; false positives for statements and #define headers. This test is
! ;; even more easily fooled than `c-just-after-func-arglist-p'.
! (save-excursion
! (save-restriction
! ;; Go back to the closest preceding normal parenthesis sexp. We
! ;; take that as the argument list in the function header. Then
! ;; check that it's followed by some symbol before the next ';'
! ;; or '{'. If it does, it's the header of the K&R argdecl we're
! ;; in.
! (if lim (narrow-to-region lim (point)))
! (let (paren-end)
! (and (c-safe (setq paren-end (c-down-list-backward (point))))
! (eq (char-after paren-end) ?\))
! (progn
! (goto-char (1+ paren-end))
! (c-forward-syntactic-ws)
! (looking-at "\\w\\|\\s_"))
! (c-safe (c-up-list-backward paren-end))
! (point))))))
(defun c-skip-conditional ()
;; skip forward over conditional at point, including any predicate
;; statements in parentheses. No error checking is performed.
(c-forward-sexp (cond
;; else if()
! ((looking-at (concat "\\<else"
! "\\([ \t\n]\\|\\\\\n\\)+"
! "if\\>\\([^_]\\|$\\)"))
! 3)
;; do, else, try, finally
! ((looking-at (concat "\\<\\("
! "do\\|else\\|try\\|finally"
! "\\)\\>\\([^_]\\|$\\)"))
1)
;; for, if, while, switch, catch, synchronized, foreach
(t 2))))
! (defun c-after-conditional (&optional lim)
! ;; If looking at the token after a conditional then return the
! ;; position of its start, otherwise return nil.
! (save-excursion
! (and (= (c-backward-token-1 1 t lim) 0)
! (or (looking-at c-block-stmt-1-key)
! (and (eq (char-after) ?\()
! (= (c-backward-token-1 1 t lim) 0)
! (looking-at c-block-stmt-2-key)))
! (point))))
!
! (defsubst c-backward-to-block-anchor (&optional lim)
! ;; Assuming point is at a brace that opens a statement block of some
! ;; kind, move to the proper anchor point for that block. It might
! ;; need to be adjusted further by c-add-stmt-syntax, but the
! ;; position at return is suitable as start position for that
! ;; function.
! (unless (= (point) (c-point 'boi))
! (let ((start (c-after-conditional lim)))
! (if start
! (goto-char start)))))
!
! (defun c-backward-to-decl-anchor (&optional lim)
! ;; Assuming point is at a brace that opens the block of a top level
! ;; declaration of some kind, move to the proper anchor point for
! ;; that block.
! (unless (= (point) (c-point 'boi))
! ;; What we have below is actually an extremely stripped variant of
! ;; c-beginning-of-statement-1.
! (let ((pos (point)))
! ;; Switch syntax table to avoid stopping at line continuations.
! (save-restriction
! (if lim (narrow-to-region lim (point-max)))
! (while (and (progn
! (c-backward-syntactic-ws)
! (c-safe (goto-char (scan-sexps (point) -1)) t))
! (not (c-crosses-statement-barrier-p (point) pos)))
! (setq pos (point)))
! (goto-char pos)))))
!
! (defsubst c-search-decl-header-end ()
! ;; Search forward for the end of the "header" of the current
! ;; declaration. That's the position where the definition body
! ;; starts, or the first variable initializer, or the ending
! ;; semicolon. I.e. search forward for the closest following
! ;; (syntactically relevant) '{', '=' or ';' token. Point is left
! ;; _after_ the first found token, or at point-max if none is found.
! (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
! c++-template-syntax-table
! (syntax-table))
! (while (and (c-syntactic-re-search-forward "[;{=]" nil 'move 1 t)
! ;; In Pike it can be an operator identifier containing
! ;; '='.
! (c-major-mode-is 'pike-mode)
! (eq (char-before) ?=)
! (c-on-identifier)))))
!
! (defun c-beginning-of-decl-1 (&optional lim)
! ;; Go to the beginning of the current declaration, or the beginning
! ;; of the previous one if already at the start of it. Point won't
! ;; be moved out of any surrounding paren. Return a cons cell on the
! ;; form (MOVE . KNR-POS). MOVE is like the return value from
! ;; `c-beginning-of-statement-1'. If point skipped over some K&R
! ;; style argument declarations (and they are to be recognized) then
! ;; KNR-POS is set to the start of the first such argument
! ;; declaration, otherwise KNR-POS is nil. If LIM is non-nil, it's a
! ;; position that bounds the backward search.
! ;;
! ;; NB: Cases where the declaration continues after the block, as in
! ;; "struct foo { ... } bar;", are currently recognized as two
! ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case.
! (catch 'return
! (let* ((start (point))
! (last-stmt-start (point))
! (move (c-beginning-of-statement-1 lim nil t)))
!
! (while (and (/= last-stmt-start (point))
! (save-excursion
! (c-backward-syntactic-ws lim)
! (not (memq (char-before) '(?\; ?} ?: nil)))))
! ;; `c-beginning-of-statement-1' stops at a block start, but we
! ;; want to continue if the block doesn't begin a top level
! ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob.
! (setq last-stmt-start (point)
! move (c-beginning-of-statement-1 lim nil t)))
!
! (when c-recognize-knr-p
! (let ((fallback-pos (point)) knr-argdecl-start)
! ;; Handle K&R argdecls. Back up after the "statement" jumped
! ;; over by `c-beginning-of-statement-1', unless it was the
! ;; function body, in which case we're sitting on the opening
! ;; brace now. Then test if we're in a K&R argdecl region and
! ;; that we started at the other side of the first argdecl in
! ;; it.
! (unless (eq (char-after) ?{)
! (goto-char last-stmt-start))
! (if (and (setq knr-argdecl-start (c-in-knr-argdecl lim))
! (< knr-argdecl-start start)
! (progn
! (goto-char knr-argdecl-start)
! (not (eq (c-beginning-of-statement-1 lim nil t) 'macro))))
! (throw 'return
! (cons (if (eq (char-after fallback-pos) ?{)
! 'previous
! 'same)
! knr-argdecl-start))
! (goto-char fallback-pos))))
!
! ;; `c-beginning-of-statement-1' counts each brace block as a
! ;; separate statement, so the result will be 'previous if we've
! ;; moved over any. If they were brace list initializers we might
! ;; not have moved over a declaration boundary though, so change it
! ;; to 'same if we've moved past a '=' before '{', but not ';'.
! ;; (This ought to be integrated into `c-beginning-of-statement-1',
! ;; so we avoid this extra pass which potentially can search over a
! ;; large amount of text.)
! (if (and (eq move 'previous)
! (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
! c++-template-syntax-table
! (syntax-table))
! (save-excursion
! (and (c-syntactic-re-search-forward "[;={]" start t 1 t)
! (eq (char-before) ?=)
! (c-syntactic-re-search-forward "[;{]" start t 1 t)
! (eq (char-before) ?{)
! (c-safe (goto-char (c-up-list-forward (point))) t)
! (not (c-syntactic-re-search-forward ";" start t 1 t))))))
! (cons 'same nil)
! (cons move nil)))))
!
! (defun c-end-of-decl-1 ()
! ;; Assuming point is at the start of a declaration (as detected by
! ;; e.g. `c-beginning-of-decl-1'), go to the end of it. Unlike
! ;; `c-beginning-of-decl-1', this function handles the case when a
! ;; block is followed by identifiers in e.g. struct declarations in C
! ;; or C++. If a proper end was found then t is returned, otherwise
! ;; point is moved as far as possible within the current sexp and nil
! ;; is returned. This function doesn't handle macros; use
! ;; `c-end-of-macro' instead in those cases.
(let ((start (point))
! (decl-syntax-table (if (c-major-mode-is 'c++-mode)
! c++-template-syntax-table
! (syntax-table))))
! (catch 'return
! (c-search-decl-header-end)
!
! (when (and c-recognize-knr-p
! (eq (char-before) ?\;)
! (c-in-knr-argdecl start))
! ;; Stopped at the ';' in a K&R argdecl section which is
! ;; detected using the same criteria as in
! ;; `c-beginning-of-decl-1'. Move to the following block
! ;; start.
! (c-syntactic-re-search-forward "{" nil 'move 1 t))
!
! (when (eq (char-before) ?{)
! ;; Encountered a block in the declaration. Jump over it.
! (condition-case nil
! (goto-char (c-up-list-forward (point)))
! (goto-char (point-max))
! (throw 'return nil))
! (if (or (not c-opt-block-decls-with-vars-key)
! (save-excursion
! (c-with-syntax-table decl-syntax-table
! (let ((lim (point)))
! (goto-char start)
! (not (and (c-syntactic-re-search-forward
! (concat "[;=\(\[{]\\|\\<\\("
! c-opt-block-decls-with-vars-key
! "\\)")
! lim t 1 t)
! (match-beginning 1)
! (not (eq (char-before) ?_))))))))
! ;; The declaration doesn't have any of the
! ;; `c-opt-block-decls-with-vars' keywords in the
! ;; beginning, so it ends here at the end of the block.
! (throw 'return t)))
!
! (c-with-syntax-table decl-syntax-table
! (while (progn
! (if (eq (char-before) ?\;)
! (throw 'return t))
! (c-syntactic-re-search-forward ";" nil 'move 1 t))))
! nil)))
(defun c-beginning-of-member-init-list (&optional limit)
;; Goes to the beginning of a member init list (i.e. just after the
***************
*** 1055,1115 ****
(and (< limit (point))
(eq (char-before) ?:)))
! (defun c-skip-case-statement-forward (state &optional lim)
! ;; skip forward over case/default bodies, with optional maximal
! ;; limit. if no next case body is found, nil is returned and point
! ;; is not moved
! (let ((lim (or lim (point-max)))
! (here (point))
! donep foundp bufpos
! (safepos (point))
! (balanced (car state)))
! ;; search until we've passed the limit, or we've found our match
! (while (and (< (point) lim)
! (not donep))
! (setq safepos (point))
! ;; see if we can find a case statement, not in a literal
! (if (and (re-search-forward c-switch-label-key lim 'move)
! (setq bufpos (match-beginning 0))
! (not (c-in-literal safepos))
! (/= bufpos here))
! ;; if we crossed into a balanced sexp, we know the case is
! ;; not part of our switch statement, so just bound over the
! ;; sexp and keep looking.
! (if (and (consp balanced)
! (> bufpos (car balanced))
! (< bufpos (cdr balanced)))
! (goto-char (cdr balanced))
! (goto-char bufpos)
! (setq donep t
! foundp t))))
! (if (not foundp)
! (goto-char here))
! foundp))
!
! (defun c-search-uplist-for-classkey (brace-state)
;; search for the containing class, returning a 2 element vector if
;; found. aref 0 contains the bufpos of the boi of the class key
;; line, and aref 1 contains the bufpos of the open brace.
! (if (null brace-state)
! ;; no brace-state means we cannot be inside a class
nil
! (let ((carcache (car brace-state))
search-start search-end)
(if (consp carcache)
;; a cons cell in the first element means that there is some
;; balanced sexp before the current bufpos. this we can
;; ignore. the nth 1 and nth 2 elements define for us the
;; search boundaries
! (setq search-start (nth 2 brace-state)
! search-end (nth 1 brace-state))
;; if the car was not a cons cell then nth 0 and nth 1 define
;; for us the search boundaries
! (setq search-start (nth 1 brace-state)
! search-end (nth 0 brace-state)))
! ;; search-end cannot be a cons cell
! (and (consp search-end)
! (error "consp search-end: %s" search-end))
;; if search-end is nil, or if the search-end character isn't an
;; open brace, we are definitely not in a class
(if (or (not search-end)
--- 1755,1780 ----
(and (< limit (point))
(eq (char-before) ?:)))
! (defun c-search-uplist-for-classkey (paren-state)
;; search for the containing class, returning a 2 element vector if
;; found. aref 0 contains the bufpos of the boi of the class key
;; line, and aref 1 contains the bufpos of the open brace.
! (if (null paren-state)
! ;; no paren-state means we cannot be inside a class
nil
! (let ((carcache (car paren-state))
search-start search-end)
(if (consp carcache)
;; a cons cell in the first element means that there is some
;; balanced sexp before the current bufpos. this we can
;; ignore. the nth 1 and nth 2 elements define for us the
;; search boundaries
! (setq search-start (nth 2 paren-state)
! search-end (nth 1 paren-state))
;; if the car was not a cons cell then nth 0 and nth 1 define
;; for us the search boundaries
! (setq search-start (nth 1 paren-state)
! search-end (nth 0 paren-state)))
;; if search-end is nil, or if the search-end character isn't an
;; open brace, we are definitely not in a class
(if (or (not search-end)
***************
*** 1132,1153 ****
(save-excursion
(save-restriction
(goto-char search-start)
! (let ((search-key (concat c-class-key "\\|" c-extra-toplevel-key))
! foundp class match-end)
! (if c-inexpr-class-key
! (setq search-key (concat search-key "\\|"
! c-inexpr-class-key)))
(while (and (not foundp)
(progn
! (c-forward-syntactic-ws)
(> search-end (point)))
! (re-search-forward search-key search-end t))
(setq class (match-beginning 0)
match-end (match-end 0))
(if (c-in-literal search-start)
! nil ; its in a comment or string, ignore
! (goto-char class)
! (skip-chars-forward " \t\n")
(setq foundp (vector (c-point 'boi) search-end))
(cond
;; check for embedded keywords
--- 1797,1814 ----
(save-excursion
(save-restriction
(goto-char search-start)
! (let (foundp class match-end)
(while (and (not foundp)
(progn
! (c-forward-syntactic-ws search-end)
(> search-end (point)))
! (re-search-forward c-decl-block-key search-end t))
(setq class (match-beginning 0)
match-end (match-end 0))
+ (goto-char class)
(if (c-in-literal search-start)
! (goto-char match-end) ; its in a comment or string, ignore
! (c-skip-ws-forward)
(setq foundp (vector (c-point 'boi) search-end))
(cond
;; check for embedded keywords
***************
*** 1157,1171 ****
(goto-char match-end)
(setq foundp nil))
;; make sure we're really looking at the start of a
! ;; class definition, and not a forward decl, return
! ;; arg, template arg list, or an ObjC or Java method.
! ((and c-method-key
! (re-search-forward c-method-key search-end t)
(not (c-in-literal class)))
(setq foundp nil))
;; Check if this is an anonymous inner class.
! ((and c-inexpr-class-key
! (looking-at c-inexpr-class-key))
(while (and (= (c-forward-token-1 1 t) 0)
(looking-at "(\\|\\w\\|\\s_\\|\\.")))
(if (eq (point) search-end)
--- 1818,1831 ----
(goto-char match-end)
(setq foundp nil))
;; make sure we're really looking at the start of a
! ;; class definition, and not an ObjC method.
! ((and c-opt-method-key
! (re-search-forward c-opt-method-key search-end t)
(not (c-in-literal class)))
(setq foundp nil))
;; Check if this is an anonymous inner class.
! ((and c-opt-inexpr-class-key
! (looking-at c-opt-inexpr-class-key))
(while (and (= (c-forward-token-1 1 t) 0)
(looking-at "(\\|\\w\\|\\s_\\|\\.")))
(if (eq (point) search-end)
***************
*** 1198,1204 ****
foundp))
)))))
! (defun c-inside-bracelist-p (containing-sexp brace-state)
;; return the buffer position of the beginning of the brace list
;; statement if we're inside a brace list, otherwise return nil.
;; CONTAINING-SEXP is the buffer pos of the innermost containing
--- 1858,1864 ----
foundp))
)))))
! (defun c-inside-bracelist-p (containing-sexp paren-state)
;; return the buffer position of the beginning of the brace list
;; statement if we're inside a brace list, otherwise return nil.
;; CONTAINING-SEXP is the buffer pos of the innermost containing
***************
*** 1215,1224 ****
(goto-char containing-sexp)
(c-forward-sexp -1)
(let (bracepos)
! (if (and (or (looking-at "enum[\t\n ]+")
(progn (c-forward-sexp -1)
! (looking-at "enum[\t\n ]+")))
! (setq bracepos (c-safe (scan-lists (point) 1 -1)))
(not (c-crosses-statement-barrier-p (point)
(- bracepos 2))))
(point)))))
--- 1875,1884 ----
(goto-char containing-sexp)
(c-forward-sexp -1)
(let (bracepos)
! (if (and (or (looking-at "enum\\>[^_]")
(progn (c-forward-sexp -1)
! (looking-at "enum\\>[^_]")))
! (setq bracepos (c-down-list-forward (point)))
(not (c-crosses-statement-barrier-p (point)
(- bracepos 2))))
(point)))))
***************
*** 1228,1251 ****
;; Pike can have class definitions anywhere, so we must
;; check for the class key here.
(and (c-major-mode-is 'pike-mode)
! (concat c-class-key "\\|" c-extra-toplevel-key)))
! bufpos lim braceassignp)
(while (and (not bufpos)
containing-sexp)
! (if (consp containing-sexp)
! (setq containing-sexp (car brace-state)
! brace-state (cdr brace-state))
(goto-char containing-sexp)
! (if (c-looking-at-inexpr-block)
! ;; We're in an in-expression block of some kind. Do
! ;; not check nesting.
(setq containing-sexp nil)
;; see if the open brace is preceded by = or [...] in
;; this statement, but watch out for operator=
! (setq lim (if (consp (car brace-state))
! (cdr (car brace-state))
! (car brace-state))
! braceassignp 'dontknow)
(c-backward-token-1 1 t lim)
;; Checks to do only on the first sexp before the brace.
(when (and (c-major-mode-is 'java-mode)
--- 1888,1915 ----
;; Pike can have class definitions anywhere, so we must
;; check for the class key here.
(and (c-major-mode-is 'pike-mode)
! c-decl-block-key))
! bufpos braceassignp lim next-containing)
(while (and (not bufpos)
containing-sexp)
! (when paren-state
! (if (consp (car paren-state))
! (setq lim (cdr (car paren-state))
! paren-state (cdr paren-state))
! (setq lim (car paren-state)))
! (when paren-state
! (setq next-containing (car paren-state)
! paren-state (cdr paren-state))))
(goto-char containing-sexp)
! (if (c-looking-at-inexpr-block next-containing next-containing)
! ;; We're in an in-expression block of some kind. Do not
! ;; check nesting. We deliberately set the limit to the
! ;; containing sexp, so that c-looking-at-inexpr-block
! ;; doesn't check for an identifier before it.
(setq containing-sexp nil)
;; see if the open brace is preceded by = or [...] in
;; this statement, but watch out for operator=
! (setq braceassignp 'dontknow)
(c-backward-token-1 1 t lim)
;; Checks to do only on the first sexp before the brace.
(when (and (c-major-mode-is 'java-mode)
***************
*** 1280,1286 ****
(setq braceassignp
(cond
;; Check for operator =
! ((looking-at "operator\\>") nil)
;; Check for `<opchar>= in Pike.
((and (c-major-mode-is 'pike-mode)
(or (eq (char-after) ?`)
--- 1944,1950 ----
(setq braceassignp
(cond
;; Check for operator =
! ((looking-at "operator\\>[^_]") nil)
;; Check for `<opchar>= in Pike.
((and (c-major-mode-is 'pike-mode)
(or (eq (char-after) ?`)
***************
*** 1293,1309 ****
((looking-at "\\s.") 'maybe)
;; make sure we're not in a C++ template
;; argument assignment
! ((and (c-major-mode-is 'c++-mode)
! (save-excursion
! (let ((here (point))
! (pos< (progn
! (skip-chars-backward "^<>")
! (point))))
! (and (eq (char-before) ?<)
! (not
(c-crosses-statement-barrier-p
! pos< here))
! (not (c-in-literal))
! ))))
nil)
(t t))))))
(if (and (eq braceassignp 'dontknow)
--- 1957,1974 ----
((looking-at "\\s.") 'maybe)
;; make sure we're not in a C++ template
;; argument assignment
! ((and
! (c-major-mode-is 'c++-mode)
! (save-excursion
! (let ((here (point))
! (pos< (progn
! (skip-chars-backward "^<>")
! (point))))
! (and (eq (char-before) ?<)
! (not (c-crosses-statement-barrier-p
! pos< here))
! (not (c-in-literal))
! ))))
nil)
(t t))))))
(if (and (eq braceassignp 'dontknow)
***************
*** 1313,1327 ****
(if (eq (char-after) ?\;)
;; Brace lists can't contain a semicolon, so we're done.
(setq containing-sexp nil)
! ;; lets see if we're nested. find the most nested
! ;; containing brace
! (setq containing-sexp (car brace-state)
! brace-state (cdr brace-state)))
;; we've hit the beginning of the aggregate list
(c-beginning-of-statement-1
! (c-most-enclosing-brace brace-state))
(setq bufpos (point))))
! ))
bufpos))
))
--- 1978,1992 ----
(if (eq (char-after) ?\;)
;; Brace lists can't contain a semicolon, so we're done.
(setq containing-sexp nil)
! ;; Go up one level.
! (setq containing-sexp next-containing
! lim nil
! next-containing nil))
;; we've hit the beginning of the aggregate list
(c-beginning-of-statement-1
! (c-most-enclosing-brace paren-state))
(setq bufpos (point))))
! )
bufpos))
))
***************
*** 1375,1456 ****
(cons (list beg) type)))))
(error nil))))
! (defun c-looking-at-bos ()
! ;; Returns nil if inside a statement or declaration.
(save-excursion
! (c-backward-syntactic-ws)
(or (bobp)
! (memq (char-before) '(?\; ?}))
(and (eq (char-before) ?{)
(not (and c-special-brace-lists
(progn (backward-char)
(c-looking-at-special-brace-list))))))))
! (defun c-looking-at-inexpr-block (&optional lim)
;; Returns non-nil if we're looking at the beginning of a block
;; inside an expression. The value returned is actually a cons of
;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
;; position of the beginning of the construct. LIM limits the
! ;; backward search.
(save-excursion
! (or lim (setq lim (point-min)))
! (let ((block-follows (eq (char-after) ?{)))
! ;; Look at the character after point only as a last resort when
! ;; we can't disambiguate.
! (if (and block-follows
! (progn (c-backward-syntactic-ws) (> (point) lim))
! (eq (char-before) ?\()
! (not (and c-special-brace-lists
! (c-looking-at-special-brace-list))))
! (cons 'inexpr-statement (point))
! (let (res)
! (while (and (not res)
! (= (c-backward-token-1 1 t lim) 0)
! (>= (point) lim)
! (looking-at "(\\|\\w\\|\\s_\\|\\."))
! (setq res
! (cond ((and block-follows
! c-inexpr-class-key
! (looking-at c-inexpr-class-key)
! (or (not (looking-at c-class-key))
! (let ((prev (point)))
! (while (and (= (c-backward-token-1 1 t lim)
! 0)
! (>= (point) lim)
! (eq (char-syntax (char-after))
! ?w))
! (setq prev (point)))
! (goto-char prev)
! (not (c-looking-at-bos)))))
! (cons 'inexpr-class (point)))
! ((and c-inexpr-block-key
! (looking-at c-inexpr-block-key))
! (cons 'inexpr-statement (point)))
! ((and c-lambda-key
! (looking-at c-lambda-key))
! (cons 'inlambda (point))))))
! res)))))
! (defun c-looking-at-inexpr-block-backward (&optional lim)
;; Returns non-nil if we're looking at the end of an in-expression
;; block, otherwise the same as `c-looking-at-inexpr-block'.
(save-excursion
! (let ((lim (or lim (c-point 'bod))))
! (c-safe
! (c-backward-syntactic-ws lim)
! (if (eq (char-before) ?}) ; Recognize only a block currently.
! (progn
! (c-forward-sexp -1)
! (if (>= (point) lim)
! (c-looking-at-inexpr-block lim))))))))
(defun c-on-identifier ()
! ;; Returns non-nil if we're on or directly after an identifier.
(if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_))
(memq (char-syntax (or (char-before) ? )) '(?w ?_)))
(save-excursion
(skip-syntax-backward "w_")
! (not (looking-at c-keywords)))
(if (c-major-mode-is 'pike-mode)
;; Handle the `<operator> syntax in Pike.
(save-excursion
--- 2040,2165 ----
(cons (list beg) type)))))
(error nil))))
! (defun c-looking-at-bos (&optional lim)
! ;; Return non-nil if between two statements or declarations, assuming
! ;; point is not inside a literal or comment.
(save-excursion
! (c-backward-syntactic-ws lim)
(or (bobp)
! ;; Return t if at the start inside some parenthesis expression
! ;; too, to catch macros that have statements as arguments.
! (memq (char-before) '(?\; ?} ?\())
(and (eq (char-before) ?{)
(not (and c-special-brace-lists
(progn (backward-char)
(c-looking-at-special-brace-list))))))))
! (defun c-looking-at-inexpr-block (lim containing-sexp)
;; Returns non-nil if we're looking at the beginning of a block
;; inside an expression. The value returned is actually a cons of
;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
;; position of the beginning of the construct. LIM limits the
! ;; backward search. CONTAINING-SEXP is the start position of the
! ;; closest containing list. If it's nil, the containing paren isn't
! ;; used to decide whether we're inside an expression or not. If
! ;; both LIM and CONTAINING-SEXP is used, LIM needs to be farther
! ;; back.
(save-excursion
! (let ((res 'maybe) passed-bracket
! (closest-lim (or containing-sexp lim (point-min)))
! ;; Look at the character after point only as a last resort
! ;; when we can't disambiguate.
! (block-follows (and (eq (char-after) ?{) (point))))
! (while (and (eq res 'maybe)
! (progn (c-backward-syntactic-ws)
! (> (point) closest-lim))
! (not (bobp))
! (progn (backward-char)
! (looking-at "[\]\).]\\|\\w\\|\\s_"))
! (progn (forward-char)
! (goto-char (scan-sexps (point) -1))))
! (setq res
! (cond
! ((and block-follows
! c-opt-inexpr-class-key
! (looking-at c-opt-inexpr-class-key))
! (and (not passed-bracket)
! (or (not (looking-at c-class-key))
! ;; If the class definition is at the start of
! ;; a statement, we don't consider it an
! ;; in-expression class.
! (let ((prev (point)))
! (while (and
! (= (c-backward-token-1 1 nil closest-lim) 0)
! (eq (char-syntax (char-after)) ?w))
! (setq prev (point)))
! (goto-char prev)
! (not (c-looking-at-bos)))
! ;; Also, in Pike we treat it as an
! ;; in-expression class if it's used in an
! ;; object clone expression.
! (save-excursion
! (and (c-major-mode-is 'pike-mode)
! (progn (goto-char block-follows)
! (= (c-forward-token-1 1 t) 0))
! (eq (char-after) ?\())))
! (cons 'inexpr-class (point))))
! ((and c-opt-inexpr-block-key
! (looking-at c-opt-inexpr-block-key))
! (cons 'inexpr-statement (point)))
! ((and c-opt-lambda-key
! (looking-at c-opt-lambda-key))
! (cons 'inlambda (point)))
! ((and c-opt-block-stmt-key
! (looking-at c-opt-block-stmt-key))
! nil)
! (t
! (if (eq (char-after) ?\[)
! (setq passed-bracket t))
! 'maybe))))
! (if (eq res 'maybe)
! (when (and block-follows
! containing-sexp
! (eq (char-after containing-sexp) ?\())
! (goto-char containing-sexp)
! (if (or (save-excursion
! (c-backward-syntactic-ws lim)
! (and (> (point) (or lim (point-min)))
! (c-on-identifier)))
! (and c-special-brace-lists
! (c-looking-at-special-brace-list)))
! nil
! (cons 'inexpr-statement (point))))
! res))))
! (defun c-looking-at-inexpr-block-backward (paren-state)
;; Returns non-nil if we're looking at the end of an in-expression
;; block, otherwise the same as `c-looking-at-inexpr-block'.
+ ;; PAREN-STATE is the paren state relevant at the current position.
(save-excursion
! ;; We currently only recognize a block.
! (let ((here (point))
! (elem (car-safe paren-state))
! containing-sexp)
! (when (and (consp elem)
! (progn (goto-char (cdr elem))
! (c-forward-syntactic-ws here)
! (= (point) here)))
! (goto-char (car elem))
! (if (setq paren-state (cdr paren-state))
! (setq containing-sexp (car-safe paren-state)))
! (c-looking-at-inexpr-block (c-safe-position containing-sexp
! paren-state)
! containing-sexp)))))
(defun c-on-identifier ()
! "Return non-nil if we're on or directly after an identifier.
! Keywords are recognized and not considered identifiers."
(if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_))
(memq (char-syntax (or (char-before) ? )) '(?w ?_)))
(save-excursion
(skip-syntax-backward "w_")
! (not (looking-at c-keywords-regexp)))
(if (c-major-mode-is 'pike-mode)
;; Handle the `<operator> syntax in Pike.
(save-excursion
***************
*** 1467,1515 ****
(looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
! (defun c-most-enclosing-brace (state)
! ;; return the bufpos of the most enclosing brace that hasn't been
! ;; narrowed out by any enclosing class, or nil if none was found
(let (enclosingp)
! (while (and state (not enclosingp))
! (setq enclosingp (car state)
! state (cdr state))
! (if (consp enclosingp)
(setq enclosingp nil)
! (if (> (point-min) enclosingp)
(setq enclosingp nil))
! (setq state nil)))
enclosingp))
! (defun c-least-enclosing-brace (state)
! ;; return the bufpos of the least (highest) enclosing brace that
! ;; hasn't been narrowed out by any enclosing class, or nil if none
! ;; was found.
! (c-most-enclosing-brace (nreverse state)))
!
! (defun c-safe-position (bufpos state)
! ;; return the closest known safe position higher up than point
! (let ((safepos nil))
! (while state
! (setq safepos
! (if (consp (car state))
! (cdr (car state))
! (car state)))
! (if (< safepos bufpos)
! (setq state nil)
! (setq state (cdr state))))
! safepos))
!
! (defun c-narrow-out-enclosing-class (state lim)
! ;; narrow the buffer so that the enclosing class is hidden
! (setq state (c-whack-state (point) state))
(let (inclass-p)
! (and state
! (setq inclass-p (c-search-uplist-for-classkey state))
(narrow-to-region
(progn
(goto-char (1+ (aref inclass-p 1)))
! (skip-chars-forward " \t\n" lim)
;; if point is now left of the class opening brace, we're
;; hosed, so try a different tact
(if (<= (point) (aref inclass-p 1))
--- 2176,2248 ----
(looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
! (defun c-most-enclosing-brace (paren-state &optional bufpos)
! ;; Return the bufpos of the innermost enclosing brace before bufpos
! ;; that hasn't been narrowed out, or nil if none was found.
(let (enclosingp)
! (or bufpos (setq bufpos 134217727))
! (while paren-state
! (setq enclosingp (car paren-state)
! paren-state (cdr paren-state))
! (if (or (consp enclosingp)
! (>= enclosingp bufpos))
(setq enclosingp nil)
! (if (< enclosingp (point-min))
(setq enclosingp nil))
! (setq paren-state nil)))
enclosingp))
! (defun c-least-enclosing-brace (paren-state &optional bufpos)
! ;; Return the bufpos of the outermost enclosing brace before bufpos
! ;; that hasn't been narrowed out, or nil if none was found.
! (let (pos elem)
! (or bufpos (setq bufpos 134217727))
! (while paren-state
! (setq elem (car paren-state)
! paren-state (cdr paren-state))
! (unless (or (consp elem)
! (>= elem bufpos))
! (if (>= elem (point-min))
! (setq pos elem))))
! pos))
!
! (defun c-safe-position (bufpos paren-state)
! ;; Return the closest known safe position higher up than BUFPOS, or
! ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is
! ;; nil, which is useful to find the closest limit before a given
! ;; limit that might be nil.
! (when bufpos
! (let ((c-macro-start (c-query-macro-start)) safepos)
! (if (and c-macro-start
! (< c-macro-start bufpos))
! ;; Make sure bufpos is outside the macro we might be in.
! (setq bufpos c-macro-start))
! (catch 'done
! (while paren-state
! (setq safepos
! (if (consp (car paren-state))
! (cdr (car paren-state))
! (car paren-state)))
! (if (< safepos bufpos)
! (throw 'done safepos)
! (setq paren-state (cdr paren-state))))
! (if (eq c-macro-start bufpos)
! ;; Backed up bufpos to the macro start and got outside the
! ;; state. We know the macro is at the top level in this case,
! ;; so we can use the macro start as the safe position.
! c-macro-start)))))
!
! (defun c-narrow-out-enclosing-class (paren-state lim)
! ;; Narrow the buffer so that the enclosing class is hidden. Uses
! ;; and returns the value from c-search-uplist-for-classkey.
! (setq paren-state (c-whack-state-after (point) paren-state))
(let (inclass-p)
! (and paren-state
! (setq inclass-p (c-search-uplist-for-classkey paren-state))
(narrow-to-region
(progn
(goto-char (1+ (aref inclass-p 1)))
! (c-skip-ws-forward lim)
;; if point is now left of the class opening brace, we're
;; hosed, so try a different tact
(if (<= (point) (aref inclass-p 1))
***************
*** 1525,1548 ****
inclass-p))
! ;; This function implements the main decision tree for determining the
! ;; syntactic analysis of the current line of code. Yes, it's huge and
! ;; bloated!
(defun c-guess-basic-syntax ()
(save-excursion
(save-restriction
(beginning-of-line)
(let* ((indent-point (point))
(case-fold-search nil)
! (fullstate (c-parse-state))
! (state fullstate)
literal containing-sexp char-before-ip char-after-ip lim
! syntax placeholder c-in-literal-cache inswitch-p
tmpsymbol keyword injava-inher special-brace-list
;; narrow out any enclosing class or extern "C" block
! (inclass-p (c-narrow-out-enclosing-class state indent-point))
! inenclosing-p)
;; check for meta top-level enclosing constructs, possible
;; extern language definitions, possibly (in C++) namespace
;; definitions.
--- 2258,2562 ----
inclass-p))
! ;; c-guess-basic-syntax implements the main decision tree for
! ;; determining the syntactic analysis of the current line of code.
! ;; Yes, it's huge and bloated!
!
! ;; It's useful to break out some parts of the decision tree to
! ;; separate functions, which are all collected below. Use dynamic
! ;; binding to propagate back the syntax results from them.
! (defvar syntax)
! (defvar syntactic-relpos)
!
! (defun c-add-stmt-syntax (syntax-symbol
! stop-at-boi-only
! containing-sexp
! paren-state
! &optional at-block-start)
! ;; Do the generic processing to anchor the given syntax symbol on
! ;; the preceding statement: Skip over any labels and containing
! ;; statements on the same line, and then search backward until we
! ;; find a statement or block start that begins at boi without a
! ;; label or comment.
! ;;
! ;; Point is assumed to be at the prospective anchor point for the
! ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to
! ;; skip past block opens and containing statement. All the added
! ;; syntax elements will get the same anchor point.
! ;;
! ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the
! ;; line if another statement precedes the current one on this line.
! ;;
! ;; If AT-BLOCK-START is non-nil, point is taken to be at the
! ;; beginning of a block or brace list, which then might be nested
! ;; inside an expression. If AT-BLOCK-START is nil, this is found
! ;; out by checking whether the character at point is "{" or not.
! (if (= (point) (c-point 'boi))
! ;; This is by far the most common case, so let's give it special
! ;; treatment.
! (c-add-syntax syntax-symbol (point))
!
! (let* ((savepos (point))
! (syms (list syntax-symbol))
! (syms-tail syms)
! (boi (c-point 'boi))
! (prev-paren (if at-block-start ?{ (char-after)))
! step-type step-tmp at-comment add-inexpr-stmt)
!
! ;; Begin by skipping any labels and containing statements that
! ;; are on the same line.
! (while (and (/= (point) boi)
! (if (memq (setq step-tmp
! (c-beginning-of-statement-1 boi nil t))
! '(up label))
! t
! (goto-char savepos)
! nil)
! (/= (point) savepos))
! (setq savepos (point)
! step-type step-tmp))
!
! ;; Skip over any comments that stands between the statement and
! ;; boi. If stop-at-boi-only is nil and we're not at boi after
! ;; this, then we're done.
! (while (and (/= (setq savepos (point)) boi)
! (c-forward-comment -1))
! (setq at-comment t
! boi (c-point 'boi)))
! (goto-char savepos)
!
! (when (or stop-at-boi-only
! (= (point) boi))
! (catch 'done
! ;; Loop if we have to back out of the containing block.
! (while
! (progn
! ;; Loop if we have to back up another statement.
! (while
! (progn
! ;; Always start by skipping over any comments that
! ;; stands between the statement and boi.
! (while (and (/= (setq savepos (point)) boi)
! (c-forward-comment -1))
! (setq at-comment t
! boi (c-point 'boi)))
! (goto-char savepos)
! (and (or at-comment
! (eq step-type 'label)
! (/= savepos boi))
! (progn
! ;; Current position not good enough; skip
! ;; backward another statement.
! (setq stop-at-boi-only t
! step-type (c-beginning-of-statement-1
! containing-sexp))
! ;; Record this a substatement if we skipped
! ;; up one level, but not if we're still on
! ;; the same line. This so e.g. a sequence
! ;; of "else if" clauses won't indent deeper
! ;; and deeper.
! (when (and (eq step-type 'up)
! (< (point) boi))
! (setcdr syms-tail (list 'substatement))
! (setq syms-tail (cdr syms-tail)))
! (setq boi (c-point 'boi))
! (/= (point) savepos))))
! (setq savepos (point)
! at-comment nil))
! (setq at-comment nil)
!
! (when (and (eq step-type 'same)
! containing-sexp)
! (goto-char containing-sexp)
! (setq paren-state (c-whack-state-after containing-sexp
! paren-state)
! containing-sexp (c-most-enclosing-brace paren-state))
!
! (when (and (prog1
! (eq prev-paren ?{)
! (setq prev-paren (char-after)))
! (eq prev-paren ?\())
! (c-backward-syntactic-ws containing-sexp)
! (when (c-on-identifier)
! ;; Arrived at a function arglist start. Exit with
! ;; the position of the first argument inside it.
! (goto-char savepos)
! (throw 'done t))
! ;; We're in an in-expression statement. Remember
! ;; this. We'll iterate below, but won't add any
! ;; syntax element.
! (setq add-inexpr-stmt t))
!
! (setq savepos (point)
! boi (c-point 'boi)
! step-type (c-beginning-of-statement-1 containing-sexp))
!
! (let ((at-bod (and (eq step-type 'same)
! (/= savepos (point))
! (eq prev-paren ?{))))
! (when (= savepos boi)
! ;; If the open brace was at boi, we're always
! ;; done. The c-beginning-of-statement-1 call
! ;; above is necessary anyway, to decide the type
! ;; of block-intro to add.
! (goto-char savepos)
! (setq savepos nil))
!
! (when (eq prev-paren ?{)
! (setcdr syms-tail (list (if at-bod
! 'defun-block-intro
! 'statement-block-intro)))
! (setq syms-tail (cdr syms-tail)))
!
! (when (and (not at-bod) savepos)
! ;; Loop if the brace wasn't at boi, and we didn't
! ;; arrive at a defun block.
! (if (eq step-type 'same)
! ;; Avoid backing up another sexp if the point
! ;; we're at now is found to be good enough in
! ;; the loop above.
! (setq step-type nil))
! (setq stop-at-boi-only t
! boi (c-point 'boi)))))
! ))))
!
! (while syms
! (c-add-syntax (car syms) (point))
! (setq syms (cdr syms)))
! (if add-inexpr-stmt
! (c-add-syntax 'inexpr-statement))
! )))
!
! (defun c-add-class-syntax (symbol classkey paren-state)
! ;; The inclass and class-close syntactic symbols are added in
! ;; several places and some work is needed to fix everything.
! ;; Therefore it's collected here.
! (save-restriction
! (widen)
! (let (inexpr anchor containing-sexp)
! (goto-char (aref classkey 1))
! (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
! (c-add-syntax symbol (setq anchor (point)))
! (c-add-syntax symbol (setq anchor (aref classkey 0)))
! (if (and c-opt-inexpr-class-key
! (setq containing-sexp (c-most-enclosing-brace paren-state
! (point))
! inexpr (cdr (c-looking-at-inexpr-block
! (c-safe-position containing-sexp
! paren-state)
! containing-sexp)))
! (/= inexpr (c-point 'boi inexpr)))
! (c-add-syntax 'inexpr-class)))
! anchor)))
!
! (defun c-guess-continued-construct (indent-point
! char-after-ip
! beg-of-same-or-containing-stmt
! containing-sexp
! paren-state)
! ;; This function contains the decision tree reached through both
! ;; cases 18 and 10. It's a continued statement or top level
! ;; construct of some kind.
! (let (special-brace-list)
! (goto-char indent-point)
! (skip-chars-forward " \t")
! (cond
! ;; (CASE A removed.)
! ;; CASE B: open braces for class or brace-lists
! ((setq special-brace-list
! (or (and c-special-brace-lists
! (c-looking-at-special-brace-list))
! (eq char-after-ip ?{)))
! (cond
! ;; CASE B.1: class-open
! ((save-excursion
! (goto-char indent-point)
! (skip-chars-forward " \t{")
! (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
! (and decl
! (setq beg-of-same-or-containing-stmt (aref decl 0)))
! ))
! (c-add-syntax 'class-open beg-of-same-or-containing-stmt))
! ;; CASE B.2: brace-list-open
! ((or (consp special-brace-list)
! (save-excursion
! (goto-char beg-of-same-or-containing-stmt)
! (looking-at "enum\\>[^_]"))
! (save-excursion
! (goto-char indent-point)
! (while (and (> (point) beg-of-same-or-containing-stmt)
! (= (c-backward-token-1 1 t) 0)
! (/= (char-after) ?=)))
! (eq (char-after) ?=)))
! ;; The most semantically accurate symbol here is
! ;; brace-list-open, but we report it simply as a statement-cont.
! ;; The reason is that one normally adjusts brace-list-open for
! ;; brace lists as top-level constructs, and brace lists inside
! ;; statements is a completely different context.
! (c-beginning-of-statement-1 containing-sexp)
! (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state))
! ;; CASE B.3: The body of a function declared inside a normal
! ;; block. Can occur e.g. in Pike and when using gcc
! ;; extensions. Might also trigger it with some macros followed
! ;; by blocks, and this gives sane indentation then too.
! ;; C.f. cases 16F and 17G.
! ((progn
! (goto-char indent-point)
! (and (not (c-looking-at-bos))
! (eq (c-beginning-of-statement-1 containing-sexp nil nil t)
! 'same)))
! (c-add-stmt-syntax 'defun-open t containing-sexp paren-state))
! ;; CASE B.4: Continued statement with block open.
! (t
! (goto-char beg-of-same-or-containing-stmt)
! (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state)
! (c-add-syntax 'block-open))
! ))
! ;; CASE C: iostream insertion or extraction operator
! ((and (looking-at "<<\\|>>")
! (save-excursion
! (goto-char beg-of-same-or-containing-stmt)
! (while (and (re-search-forward "<<\\|>>" indent-point 'move)
! (c-in-literal beg-of-same-or-containing-stmt)))
! ;; if we ended up at indent-point, then the first streamop is on a
! ;; separate line. Indent the line like a statement-cont instead
! (when (/= (point) indent-point)
! (c-add-syntax 'stream-op (c-point 'boi))
! t))))
! ;; CASE D: continued statement.
! (t
! (c-beginning-of-statement-1 containing-sexp)
! (c-add-stmt-syntax 'statement-cont nil containing-sexp paren-state))
! )))
(defun c-guess-basic-syntax ()
+ "Return the syntactic context of the current line."
(save-excursion
(save-restriction
(beginning-of-line)
(let* ((indent-point (point))
(case-fold-search nil)
! (paren-state (c-parse-state))
literal containing-sexp char-before-ip char-after-ip lim
! syntax placeholder c-in-literal-cache step-type
tmpsymbol keyword injava-inher special-brace-list
;; narrow out any enclosing class or extern "C" block
! (inclass-p (c-narrow-out-enclosing-class paren-state
! indent-point))
! ;; c-state-cache is shadowed here. That means we must
! ;; not do any changes during the execution of this
! ;; function, since c-check-state-cache then would change
! ;; this local variable and leave a bogus value in the
! ;; global one.
! (c-state-cache (if inclass-p
! (c-whack-state-before (point-min) paren-state)
! paren-state))
! (c-state-cache-start (point-min))
! inenclosing-p macro-start in-macro-expr
! ;; There's always at most one syntactic element which got
! ;; a relpos. It's stored in syntactic-relpos.
! syntactic-relpos
! (c-stmt-delim-chars c-stmt-delim-chars))
;; check for meta top-level enclosing constructs, possible
;; extern language definitions, possibly (in C++) namespace
;; definitions.
***************
*** 1552,1558 ****
(if (and inclass-p
(progn
(goto-char (aref inclass-p 0))
! (looking-at (concat c-extra-toplevel-key "[^_]"))))
(let ((enclosing (match-string 1)))
(cond
((string-equal enclosing "extern")
--- 2566,2572 ----
(if (and inclass-p
(progn
(goto-char (aref inclass-p 0))
! (looking-at c-other-decl-block-key)))
(let ((enclosing (match-string 1)))
(cond
((string-equal enclosing "extern")
***************
*** 1560,1604 ****
((string-equal enclosing "namespace")
(setq inenclosing-p 'namespace))
)))))
! ;; get the buffer position of the most nested opening brace,
! ;; if there is one, and it hasn't been narrowed out
! (save-excursion
! (goto-char indent-point)
! (skip-chars-forward " \t}")
! (skip-chars-backward " \t")
! (while (and state
! (not containing-sexp))
! (setq containing-sexp (car state)
! state (cdr state))
! (if (consp containing-sexp)
! ;; if cdr == point, then containing sexp is the brace
! ;; that opens the sexp we close
! (if (= (cdr containing-sexp) (point))
! (setq containing-sexp (car containing-sexp))
! ;; otherwise, ignore this element
! (setq containing-sexp nil))
! ;; ignore the bufpos if its been narrowed out by the
! ;; containing class or does not contain the indent point
! (if (or (<= containing-sexp (point-min))
! (>= containing-sexp indent-point))
! (setq containing-sexp nil)))))
!
! ;; set the limit on the farthest back we need to search
! (setq lim (or containing-sexp
! (if (consp (car fullstate))
! (cdr (car fullstate))
! nil)
! (point-min)))
;; cache char before and after indent point, and move point to
;; the most likely position to perform the majority of tests
(goto-char indent-point)
- (skip-chars-forward " \t")
- (setq char-after-ip (char-after))
(c-backward-syntactic-ws lim)
(setq char-before-ip (char-before))
(goto-char indent-point)
(skip-chars-forward " \t")
;; are we in a literal?
(setq literal (c-in-literal lim))
--- 2574,2635 ----
((string-equal enclosing "namespace")
(setq inenclosing-p 'namespace))
)))))
!
! ;; Init some position variables:
! ;;
! ;; containing-sexp is the open paren of the closest
! ;; surrounding sexp or nil if there is none that hasn't been
! ;; narrowed out.
! ;;
! ;; lim is the position after the closest preceding brace sexp
! ;; (nested sexps are ignored), or the position after
! ;; containing-sexp if there is none, or (point-min) if
! ;; containing-sexp is nil.
! ;;
! ;; c-state-cache is the state from c-parse-state at
! ;; indent-point, without any parens outside the region
! ;; narrowed by c-narrow-out-enclosing-class.
! ;;
! ;; paren-state is the state from c-parse-state outside
! ;; containing-sexp, or at indent-point if containing-sexp is
! ;; nil. paren-state is not limited to the narrowed region, as
! ;; opposed to c-state-cache.
! (if c-state-cache
! (progn
! (setq containing-sexp (car paren-state)
! paren-state (cdr paren-state))
! (if (consp containing-sexp)
! (progn
! (setq lim (cdr containing-sexp))
! (if (cdr c-state-cache)
! ;; Ignore balanced paren. The next entry
! ;; can't be another one.
! (setq containing-sexp (car (cdr c-state-cache))
! paren-state (cdr paren-state))
! ;; If there is no surrounding open paren then
! ;; put the last balanced pair back on paren-state.
! (setq paren-state (cons containing-sexp paren-state)
! containing-sexp nil)))
! (setq lim (1+ containing-sexp))))
! (setq lim (point-min)))
!
! ;; If we're in a parenthesis list then ',' delimits the
! ;; "statements" rather than being an operator (with the
! ;; exception of the "for" clause). This difference is
! ;; typically only noticeable when statements are used in macro
! ;; arglists.
! (when (and containing-sexp
! (eq (char-after containing-sexp) ?\())
! (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
;; cache char before and after indent point, and move point to
;; the most likely position to perform the majority of tests
(goto-char indent-point)
(c-backward-syntactic-ws lim)
(setq char-before-ip (char-before))
(goto-char indent-point)
(skip-chars-forward " \t")
+ (setq char-after-ip (char-after))
;; are we in a literal?
(setq literal (c-in-literal lim))
***************
*** 1606,1626 ****
;; now figure out syntactic qualities of the current line
(cond
;; CASE 1: in a string.
! ((memq literal '(string))
(c-add-syntax 'string (c-point 'bopl)))
;; CASE 2: in a C or C++ style comment.
((memq literal '(c c++))
(c-add-syntax literal (car (c-literal-limits lim))))
;; CASE 3: in a cpp preprocessor macro continuation.
! ((and (eq literal 'pound)
! (/= (save-excursion
! (c-beginning-of-macro lim)
! (setq placeholder (point)))
! (c-point 'boi)))
! (c-add-syntax 'cpp-macro-cont placeholder))
! ;; CASE 4: In-expression statement.
! ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key)
! (setq placeholder (c-looking-at-inexpr-block)))
(setq tmpsymbol (assq (car placeholder)
'((inexpr-class . class-open)
(inexpr-statement . block-open))))
--- 2637,2778 ----
;; now figure out syntactic qualities of the current line
(cond
;; CASE 1: in a string.
! ((eq literal 'string)
(c-add-syntax 'string (c-point 'bopl)))
;; CASE 2: in a C or C++ style comment.
((memq literal '(c c++))
(c-add-syntax literal (car (c-literal-limits lim))))
;; CASE 3: in a cpp preprocessor macro continuation.
! ((and (save-excursion
! (when (c-beginning-of-macro)
! (setq macro-start (point))))
! (/= macro-start (c-point 'boi))
! (progn
! (setq tmpsymbol 'cpp-macro-cont)
! (or (not c-syntactic-indentation-in-macros)
! (save-excursion
! (goto-char macro-start)
! ;; If at the beginning of the body of a #define
! ;; directive then analyze as cpp-define-intro
! ;; only. Go on with the syntactic analysis
! ;; otherwise. in-macro-expr is set if we're in a
! ;; cpp expression, i.e. before the #define body
! ;; or anywhere in a non-#define directive.
! (if (c-forward-to-cpp-define-body)
! (let ((indent-boi (c-point 'boi indent-point)))
! (setq in-macro-expr (> (point) indent-boi)
! tmpsymbol 'cpp-define-intro)
! (= (point) indent-boi))
! (setq in-macro-expr t)
! nil)))))
! (c-add-syntax tmpsymbol macro-start)
! (setq macro-start nil))
! ;; CASE 11: an else clause?
! ((looking-at "else\\>[^_]")
! (c-beginning-of-statement-1 containing-sexp)
! (c-add-stmt-syntax 'else-clause t containing-sexp paren-state))
! ;; CASE 12: while closure of a do/while construct?
! ((and (looking-at "while\\>[^_]")
! (save-excursion
! (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
! 'beginning)
! (setq placeholder (point)))))
! (goto-char placeholder)
! (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state))
! ;; CASE 13: A catch or finally clause? This case is simpler
! ;; than if-else and do-while, because a block is required
! ;; after every try, catch and finally.
! ((save-excursion
! (and (cond ((c-major-mode-is 'c++-mode)
! (looking-at "catch\\>[^_]"))
! ((c-major-mode-is 'java-mode)
! (looking-at "\\(catch\\|finally\\)\\>[^_]")))
! (and (c-safe (c-backward-syntactic-ws)
! (c-backward-sexp)
! t)
! (eq (char-after) ?{)
! (c-safe (c-backward-syntactic-ws)
! (c-backward-sexp)
! t)
! (if (eq (char-after) ?\()
! (c-safe (c-backward-sexp) t)
! t))
! (looking-at "\\(try\\|catch\\)\\>[^_]")
! (setq placeholder (point))))
! (goto-char placeholder)
! (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state))
! ;; CASE 18: A substatement we can recognize by keyword.
! ((save-excursion
! (and c-opt-block-stmt-key
! (not (eq char-before-ip ?\;))
! (not (memq char-after-ip '(?\) ?\] ?,)))
! (or (not (eq char-before-ip ?}))
! (c-looking-at-inexpr-block-backward c-state-cache))
! (> (point)
! (progn
! ;; Ought to cache the result from the
! ;; c-beginning-of-statement-1 calls here.
! (setq placeholder (point))
! (while (eq (setq step-type
! (c-beginning-of-statement-1 lim))
! 'label))
! (if (eq step-type 'previous)
! (goto-char placeholder)
! (setq placeholder (point))
! (if (and (eq step-type 'same)
! (not (looking-at c-opt-block-stmt-key)))
! ;; Step up to the containing statement if we
! ;; stayed in the same one.
! (let (step)
! (while (eq
! (setq step
! (c-beginning-of-statement-1 lim))
! 'label))
! (if (eq step 'up)
! (setq placeholder (point))
! ;; There was no containing statement afterall.
! (goto-char placeholder)))))
! placeholder))
! (if (looking-at c-block-stmt-2-key)
! ;; Require a parenthesis after these keywords.
! ;; Necessary to catch e.g. synchronized in Java,
! ;; which can be used both as statement and
! ;; modifier.
! (and (= (c-forward-token-1 1 nil) 0)
! (eq (char-after) ?\())
! (looking-at c-opt-block-stmt-key))))
! (if (eq step-type 'up)
! ;; CASE 18A: Simple substatement.
! (progn
! (goto-char placeholder)
! (cond
! ((eq char-after-ip ?{)
! (c-add-stmt-syntax 'substatement-open nil
! containing-sexp paren-state))
! ((save-excursion
! (goto-char indent-point)
! (back-to-indentation)
! (looking-at c-label-key))
! (c-add-stmt-syntax 'substatement-label nil
! containing-sexp paren-state))
! (t
! (c-add-stmt-syntax 'substatement nil
! containing-sexp paren-state))))
! ;; CASE 18B: Some other substatement. This is shared
! ;; with case 10.
! (c-guess-continued-construct indent-point
! char-after-ip
! placeholder
! lim
! paren-state)))
! ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
! ;; 17E.
! ((and (or c-opt-inexpr-class-key
! c-opt-inexpr-block-key
! c-opt-lambda-key)
! (setq placeholder (c-looking-at-inexpr-block
! (c-safe-position containing-sexp paren-state)
! containing-sexp)))
(setq tmpsymbol (assq (car placeholder)
'((inexpr-class . class-open)
(inexpr-statement . block-open))))
***************
*** 1635,1641 ****
'lambda-intro-cont)))
(goto-char (cdr placeholder))
(back-to-indentation)
! (c-add-syntax tmpsymbol (point))
(unless (eq (point) (cdr placeholder))
(c-add-syntax (car placeholder))))
;; CASE 5: Line is at top level.
--- 2787,2795 ----
'lambda-intro-cont)))
(goto-char (cdr placeholder))
(back-to-indentation)
! (c-add-stmt-syntax tmpsymbol t
! (c-most-enclosing-brace c-state-cache (point))
! (c-whack-state-after (point) paren-state))
(unless (eq (point) (cdr placeholder))
(c-add-syntax (car placeholder))))
;; CASE 5: Line is at top level.
***************
*** 1653,1659 ****
(goto-char indent-point)
(skip-chars-forward " \t")
(and (c-safe (progn (c-backward-sexp 2) t))
! (looking-at (concat c-extra-toplevel-key "[^_]"))
(setq keyword (match-string 1)
placeholder (point))
(or (and (string-equal keyword "namespace")
--- 2807,2813 ----
(goto-char indent-point)
(skip-chars-forward " \t")
(and (c-safe (progn (c-backward-sexp 2) t))
! (looking-at c-other-decl-block-key)
(setq keyword (match-string 1)
placeholder (point))
(or (and (string-equal keyword "namespace")
***************
*** 1671,1695 ****
((save-excursion
(goto-char indent-point)
(skip-chars-forward " \t{")
! ;; TBD: watch out! there could be a bogus
! ;; c-state-cache in place when we get here. we have
! ;; to go through much chicanery to ignore the cache.
! ;; But of course, there may not be! BLECH! BOGUS!
! (let ((decl
! (let ((c-state-cache nil))
! (c-search-uplist-for-classkey (c-parse-state))
! )))
(and decl
(setq placeholder (aref decl 0)))
))
(c-add-syntax 'class-open placeholder))
;; CASE 5A.3: brace list open
((save-excursion
! (c-beginning-of-statement-1 lim)
! ;; c-b-o-s could have left us at point-min
! (and (bobp)
! (c-forward-syntactic-ws indent-point))
! (if (looking-at "typedef[^_]")
(progn (c-forward-sexp 1)
(c-forward-syntactic-ws indent-point)))
(setq placeholder (c-point 'boi))
--- 2825,2839 ----
((save-excursion
(goto-char indent-point)
(skip-chars-forward " \t{")
! (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
(and decl
(setq placeholder (aref decl 0)))
))
(c-add-syntax 'class-open placeholder))
;; CASE 5A.3: brace list open
((save-excursion
! (c-beginning-of-statement-1 lim t)
! (if (looking-at "typedef\\>[^_]")
(progn (c-forward-sexp 1)
(c-forward-syntactic-ws indent-point)))
(setq placeholder (c-point 'boi))
***************
*** 1704,1710 ****
(looking-at "new\\>[^_]"))
(setq tmpsymbol 'topmost-intro-cont)))
(eq (char-after) ?=))
! (looking-at "enum[ \t\n]+"))
(save-excursion
(while (and (< (point) indent-point)
(= (c-forward-token-1 1 t) 0)
--- 2848,2854 ----
(looking-at "new\\>[^_]"))
(setq tmpsymbol 'topmost-intro-cont)))
(eq (char-after) ?=))
! (looking-at "enum\\>[^_]"))
(save-excursion
(while (and (< (point) indent-point)
(= (c-forward-token-1 1 t) 0)
***************
*** 1723,1744 ****
;; case 10B.2.
(progn
(c-beginning-of-statement-1 lim)
- (c-forward-syntactic-ws)
(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
(c-add-syntax 'brace-list-open placeholder)))
;; CASE 5A.4: inline defun open
((and inclass-p (not inenclosing-p))
(c-add-syntax 'inline-open)
! (c-add-class-syntax 'inclass inclass-p))
;; CASE 5A.5: ordinary defun open
(t
(goto-char placeholder)
! (if inclass-p
(c-add-syntax 'defun-open (c-point 'boi))
(c-add-syntax 'defun-open (c-point 'bol)))
)))
;; CASE 5B: first K&R arg decl or member init
! ((c-just-after-func-arglist-p)
(cond
;; CASE 5B.1: a member init
((or (eq char-before-ip ?:)
--- 2867,2888 ----
;; case 10B.2.
(progn
(c-beginning-of-statement-1 lim)
(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
(c-add-syntax 'brace-list-open placeholder)))
;; CASE 5A.4: inline defun open
((and inclass-p (not inenclosing-p))
(c-add-syntax 'inline-open)
! (c-add-class-syntax 'inclass inclass-p paren-state))
;; CASE 5A.5: ordinary defun open
(t
(goto-char placeholder)
! (if (or inclass-p macro-start)
(c-add-syntax 'defun-open (c-point 'boi))
+ ;; Bogus to use bol here, but it's the legacy.
(c-add-syntax 'defun-open (c-point 'bol)))
)))
;; CASE 5B: first K&R arg decl or member init
! ((c-just-after-func-arglist-p nil lim)
(cond
;; CASE 5B.1: a member init
((or (eq char-before-ip ?:)
***************
*** 1769,1776 ****
)
;; CASE 5B.2: K&R arg decl intro
(c-recognize-knr-p
(c-add-syntax 'knr-argdecl-intro (c-point 'boi))
! (if inclass-p (c-add-class-syntax 'inclass inclass-p)))
;; CASE 5B.3: Inside a member init list.
((c-beginning-of-member-init-list lim)
(c-forward-syntactic-ws)
--- 2913,2922 ----
)
;; CASE 5B.2: K&R arg decl intro
(c-recognize-knr-p
+ (c-beginning-of-statement-1 lim)
(c-add-syntax 'knr-argdecl-intro (c-point 'boi))
! (if inclass-p
! (c-add-class-syntax 'inclass inclass-p paren-state)))
;; CASE 5B.3: Inside a member init list.
((c-beginning-of-member-init-list lim)
(c-forward-syntactic-ws)
***************
*** 1783,1794 ****
)))
;; CASE 5C: inheritance line. could be first inheritance
;; line, or continuation of a multiple inheritance
! ((or (and c-baseclass-key
(progn
(when (eq char-after-ip ?,)
(skip-chars-forward " \t")
(forward-char))
! (looking-at c-baseclass-key)))
(and (or (eq char-before-ip ?:)
;; watch out for scope operator
(save-excursion
--- 2929,2940 ----
)))
;; CASE 5C: inheritance line. could be first inheritance
;; line, or continuation of a multiple inheritance
! ((or (and (c-major-mode-is 'c++-mode)
(progn
(when (eq char-after-ip ?,)
(skip-chars-forward " \t")
(forward-char))
! (looking-at c-opt-decl-spec-key)))
(and (or (eq char-before-ip ?:)
;; watch out for scope operator
(save-excursion
***************
*** 1812,1818 ****
cont done)
(save-excursion
(while (not done)
! (cond ((looking-at c-Java-special-key)
(setq injava-inher (cons cont (point))
done t))
((or (not (c-safe (c-forward-sexp -1) t))
--- 2958,2964 ----
cont done)
(save-excursion
(while (not done)
! (cond ((looking-at c-opt-decl-spec-key)
(setq injava-inher (cons cont (point))
done t))
((or (not (c-safe (c-forward-sexp -1) t))
***************
*** 1827,1847 ****
(cond
;; CASE 5C.1: non-hanging colon on an inher intro
((eq char-after-ip ?:)
! (c-backward-syntactic-ws lim)
(c-add-syntax 'inher-intro (c-point 'boi))
;; don't add inclass symbol since relative point already
;; contains any class offset
)
;; CASE 5C.2: hanging colon on an inher intro
((eq char-before-ip ?:)
(c-add-syntax 'inher-intro (c-point 'boi))
! (if inclass-p (c-add-class-syntax 'inclass inclass-p)))
;; CASE 5C.3: in a Java implements/extends
(injava-inher
(let ((where (cdr injava-inher))
(cont (car injava-inher)))
(goto-char where)
! (cond ((looking-at "throws[ \t\n]")
(c-add-syntax 'func-decl-cont
(progn (c-beginning-of-statement-1 lim)
(c-point 'boi))))
--- 2973,2995 ----
(cond
;; CASE 5C.1: non-hanging colon on an inher intro
((eq char-after-ip ?:)
! (c-beginning-of-statement-1 lim)
(c-add-syntax 'inher-intro (c-point 'boi))
;; don't add inclass symbol since relative point already
;; contains any class offset
)
;; CASE 5C.2: hanging colon on an inher intro
((eq char-before-ip ?:)
+ (c-beginning-of-statement-1 lim)
(c-add-syntax 'inher-intro (c-point 'boi))
! (if inclass-p
! (c-add-class-syntax 'inclass inclass-p paren-state)))
;; CASE 5C.3: in a Java implements/extends
(injava-inher
(let ((where (cdr injava-inher))
(cont (car injava-inher)))
(goto-char where)
! (cond ((looking-at "throws\\>[^_]")
(c-add-syntax 'func-decl-cont
(progn (c-beginning-of-statement-1 lim)
(c-point 'boi))))
***************
*** 1858,1873 ****
;; don't add inclass symbol since relative point already
;; contains any class offset
)))
! ;; CASE 5D: this could be a top-level compound statement, a
;; member init list continuation, or a template argument
;; list continuation.
((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
c++-template-syntax-table
(syntax-table))
(save-excursion
(while (and (= (c-backward-token-1 1 t lim) 0)
! (not (looking-at "[;{<,]"))))
! (eq (char-after) ?,)))
(goto-char indent-point)
(c-beginning-of-member-init-list lim)
(cond
--- 3006,3026 ----
;; don't add inclass symbol since relative point already
;; contains any class offset
)))
! ;; CASE 5D: this could be a top-level initialization, a
;; member init list continuation, or a template argument
;; list continuation.
((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
c++-template-syntax-table
(syntax-table))
(save-excursion
+ ;; Note: We use the fact that lim is always after any
+ ;; preceding brace sexp.
(while (and (= (c-backward-token-1 1 t lim) 0)
! (not (looking-at "[;<,=]"))))
! (or (memq (char-after) '(?, ?=))
! (and (c-major-mode-is 'c++-mode)
! (= (c-backward-token-1 1 nil lim) 0)
! (eq (char-after) ?<)))))
(goto-char indent-point)
(c-beginning-of-member-init-list lim)
(cond
***************
*** 1886,1894 ****
(parse-partial-sexp (point) placeholder)))
0)
(and
! (if c-access-key (not (looking-at c-access-key)) t)
(not (looking-at c-class-key))
! (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
)))
(goto-char placeholder)
(c-forward-syntactic-ws)
--- 3039,3049 ----
(parse-partial-sexp (point) placeholder)))
0)
(and
! (if c-opt-access-key
! (not (looking-at c-opt-access-key)) t)
(not (looking-at c-class-key))
! (if c-opt-bitfield-key
! (not (looking-at c-opt-bitfield-key)) t))
)))
(goto-char placeholder)
(c-forward-syntactic-ws)
***************
*** 1902,1944 ****
(eq (char-after) ?:))
(skip-chars-forward " \t:")
(c-add-syntax 'member-init-cont (point)))
! ;; CASE 5D.3: perhaps a multiple inheritance line?
! ((save-excursion
! (c-beginning-of-statement-1 lim)
! (setq placeholder (point))
! (looking-at c-inher-key))
! (goto-char placeholder)
! (c-add-syntax 'inher-cont (c-point 'boi)))
! ;; CASE 5D.4: perhaps a template list continuation?
! ((save-excursion
! (goto-char indent-point)
! (skip-chars-backward "^<" lim)
! ;; not sure if this is the right test, but it should
! ;; be fast and mostly accurate.
! (setq placeholder (point))
! (and (eq (char-before) ?<)
! (not (c-in-literal lim))))
;; we can probably indent it just like an arglist-cont
(goto-char placeholder)
! (c-beginning-of-statement-1 lim)
(c-add-syntax 'template-args-cont (c-point 'boi)))
! ;; CASE 5D.5: perhaps a top-level statement-cont
(t
! (c-beginning-of-statement-1 lim)
! ;; skip over any access-specifiers
! (and inclass-p c-access-key
! (while (looking-at c-access-key)
! (forward-line 1)))
! ;; skip over comments, whitespace
! (c-forward-syntactic-ws indent-point)
! (c-add-syntax 'statement-cont (c-point 'boi)))
))
;; CASE 5E: we are looking at a access specifier
((and inclass-p
! c-access-key
! (looking-at c-access-key))
! (c-add-syntax 'access-label (c-point 'bonl))
! (c-add-class-syntax 'inclass inclass-p))
;; CASE 5F: extern-lang-close or namespace-close?
((and inenclosing-p
(eq char-after-ip ?}))
--- 3057,3117 ----
(eq (char-after) ?:))
(skip-chars-forward " \t:")
(c-add-syntax 'member-init-cont (point)))
! ;; CASE 5D.3: perhaps a template list continuation?
! ((and (c-major-mode-is 'c++-mode)
! (save-excursion
! (save-restriction
! (c-with-syntax-table c++-template-syntax-table
! (goto-char indent-point)
! (setq placeholder (c-up-list-backward (point)))
! (and placeholder
! (eq (char-after placeholder) ?<))))))
;; we can probably indent it just like an arglist-cont
(goto-char placeholder)
! (c-beginning-of-statement-1 lim t)
(c-add-syntax 'template-args-cont (c-point 'boi)))
! ;; CASE 5D.4: perhaps a multiple inheritance line?
! ((and (c-major-mode-is 'c++-mode)
! (save-excursion
! (c-beginning-of-statement-1 lim)
! (setq placeholder (point))
! (if (looking-at "static\\>[^_]")
! (c-forward-token-1 1 nil indent-point))
! (and (looking-at c-class-key)
! (= (c-forward-token-1 2 nil indent-point) 0)
! (if (eq (char-after) ?<)
! (c-with-syntax-table c++-template-syntax-table
! (= (c-forward-token-1 1 t indent-point) 0))
! t)
! (eq (char-after) ?:))))
! (goto-char placeholder)
! (c-add-syntax 'inher-cont (c-point 'boi)))
! ;; CASE 5D.5: Continuation of the "expression part" of a
! ;; top level construct.
(t
! (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
! 'same)
! (save-excursion
! (c-backward-syntactic-ws)
! (eq (char-before) ?}))))
! (c-add-stmt-syntax
! (if (eq char-before-ip ?,)
! ;; A preceding comma at the top level means that a
! ;; new variable declaration starts here. Use
! ;; topmost-intro-cont for it, for consistency with
! ;; the first variable declaration. C.f. case 5N.
! 'topmost-intro-cont
! 'statement-cont)
! nil containing-sexp paren-state))
))
;; CASE 5E: we are looking at a access specifier
((and inclass-p
! c-opt-access-key
! (looking-at c-opt-access-key))
! (setq placeholder (c-add-class-syntax 'inclass inclass-p
! paren-state))
! ;; Append access-label with the same anchor point as inclass gets.
! (nconc syntax (list (cons 'access-label placeholder))))
;; CASE 5F: extern-lang-close or namespace-close?
((and inenclosing-p
(eq char-after-ip ?}))
***************
*** 1957,2022 ****
(and (c-safe (progn (c-backward-sexp 1) t))
(= (point) (aref inclass-p 1))
))))
! (c-add-class-syntax 'class-close inclass-p))
;; CASE 5H: we could be looking at subsequent knr-argdecls
((and c-recognize-knr-p
! ;; here we essentially use the hack that is used in
! ;; Emacs' c-mode.el to limit how far back we should
! ;; look. The assumption is made that argdecls are
! ;; indented at least one space and that function
! ;; headers are not indented.
! (let ((limit (save-excursion
! (re-search-backward "^[^ \^L\t\n#]" nil 'move)
! (point))))
! (save-excursion
! (c-backward-syntactic-ws limit)
! (setq placeholder (point))
! (while (and (memq (char-before) '(?\; ?,))
! (> (point) limit))
! (beginning-of-line)
! (setq placeholder (point))
! (c-backward-syntactic-ws limit))
! (and (eq (char-before) ?\))
! (or (not c-method-key)
! (progn
! (c-forward-sexp -1)
! (forward-char -1)
! (c-backward-syntactic-ws)
! (not (or (memq (char-before) '(?- ?+))
! ;; or a class category
! (progn
! (c-forward-sexp -2)
! (looking-at c-class-key))
! )))))
! ))
(save-excursion
! (c-beginning-of-statement-1)
! (not (looking-at "typedef[ \t\n]+"))))
(goto-char placeholder)
! (c-add-syntax 'knr-argdecl (c-point 'boi)))
;; CASE 5I: ObjC method definition.
! ((and c-method-key
! (looking-at c-method-key))
(c-add-syntax 'objc-method-intro (c-point 'boi)))
! ;; CASE 5J: we are at the topmost level, make sure we skip
! ;; back past any access specifiers
((progn
(c-backward-syntactic-ws lim)
(while (and inclass-p
! c-access-key
(not (bobp))
(save-excursion
(c-safe (progn (c-backward-sexp 1) t))
! (looking-at c-access-key)))
(c-backward-sexp 1)
(c-backward-syntactic-ws lim))
(or (bobp)
! (memq (char-before) '(?\; ?\}))))
;; real beginning-of-line could be narrowed out due to
;; enclosure in a class block
(save-restriction
(widen)
(c-add-syntax 'topmost-intro (c-point 'bol))
(if inclass-p
(progn
(goto-char (aref inclass-p 1))
--- 3130,3201 ----
(and (c-safe (progn (c-backward-sexp 1) t))
(= (point) (aref inclass-p 1))
))))
! (c-add-class-syntax 'class-close inclass-p paren-state))
;; CASE 5H: we could be looking at subsequent knr-argdecls
((and c-recognize-knr-p
! (not (eq char-before-ip ?}))
(save-excursion
! (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
! (and placeholder
! ;; Do an extra check to avoid tripping up on
! ;; statements that occur in invalid contexts
! ;; (e.g. in macro bodies where we don't really
! ;; know the context of what we're looking at).
! (not (and c-opt-block-stmt-key
! (looking-at c-opt-block-stmt-key)))))
! (< placeholder indent-point))
(goto-char placeholder)
! (c-add-syntax 'knr-argdecl (point)))
;; CASE 5I: ObjC method definition.
! ((and c-opt-method-key
! (looking-at c-opt-method-key))
! (c-beginning-of-statement-1 lim)
(c-add-syntax 'objc-method-intro (c-point 'boi)))
! ;; CASE 5N: At a variable declaration that follows a class
! ;; definition or some other block declaration that doesn't
! ;; end at the closing '}'. C.f. case 5D.5.
((progn
(c-backward-syntactic-ws lim)
+ (and (eq (char-before) ?})
+ (save-excursion
+ (let ((start (point)))
+ (if paren-state
+ ;; Speed up the backward search a bit.
+ (goto-char (car (car paren-state))))
+ (c-beginning-of-decl-1 containing-sexp)
+ (setq placeholder (point))
+ (if (= start (point))
+ ;; The '}' is unbalanced.
+ nil
+ (c-end-of-decl-1)
+ (> (point) indent-point))))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'topmost-intro-cont nil
+ containing-sexp paren-state))
+ ;; CASE 5J: we are at the topmost level, make
+ ;; sure we skip back past any access specifiers
+ ((progn
(while (and inclass-p
! c-opt-access-key
(not (bobp))
(save-excursion
(c-safe (progn (c-backward-sexp 1) t))
! (looking-at c-opt-access-key)))
(c-backward-sexp 1)
(c-backward-syntactic-ws lim))
(or (bobp)
! (memq (char-before) '(?\; ?}))
! (and (c-major-mode-is 'objc-mode)
! (progn
! (c-beginning-of-statement-1 lim)
! (eq (char-after) ?@)))))
;; real beginning-of-line could be narrowed out due to
;; enclosure in a class block
(save-restriction
(widen)
(c-add-syntax 'topmost-intro (c-point 'bol))
+ ;; Using bol instead of boi above is highly bogus, and
+ ;; it makes our lives hard to remain compatible. :P
(if inclass-p
(progn
(goto-char (aref inclass-p 1))
***************
*** 2027,2055 ****
(c-add-syntax 'inextern-lang (c-point 'boi)))
((eq inenclosing-p 'namespace)
(c-add-syntax 'innamespace (c-point 'boi)))
! (t (c-add-class-syntax 'inclass inclass-p)))
))
))
! ;; CASE 5K: we are at an ObjC or Java method definition
;; continuation line.
! ((and c-method-key
(progn
(c-beginning-of-statement-1 lim)
(beginning-of-line)
! (looking-at c-method-key)))
(c-add-syntax 'objc-method-args-cont (point)))
;; CASE 5L: we are at the first argument of a template
;; arglist that begins on the previous line.
((eq (char-before) ?<)
! (c-beginning-of-statement-1 lim)
! (c-forward-syntactic-ws)
(c-add-syntax 'template-args-cont (c-point 'boi)))
;; CASE 5M: we are at a topmost continuation line
(t
! (c-beginning-of-statement-1 lim)
! (c-forward-syntactic-ws)
(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
! )) ; end CASE 5
;; (CASE 6 has been removed.)
;; CASE 7: line is an expression, not a statement. Most
;; likely we are either in a function prototype or a function
--- 3206,3237 ----
(c-add-syntax 'inextern-lang (c-point 'boi)))
((eq inenclosing-p 'namespace)
(c-add-syntax 'innamespace (c-point 'boi)))
! (t (c-add-class-syntax 'inclass inclass-p paren-state)))
))
+ (when (and c-syntactic-indentation-in-macros
+ macro-start
+ (/= macro-start (c-point 'boi indent-point)))
+ (c-add-syntax 'cpp-define-intro)
+ (setq macro-start nil))
))
! ;; CASE 5K: we are at an ObjC method definition
;; continuation line.
! ((and c-opt-method-key
(progn
(c-beginning-of-statement-1 lim)
(beginning-of-line)
! (looking-at c-opt-method-key)))
(c-add-syntax 'objc-method-args-cont (point)))
;; CASE 5L: we are at the first argument of a template
;; arglist that begins on the previous line.
((eq (char-before) ?<)
! (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
(c-add-syntax 'template-args-cont (c-point 'boi)))
;; CASE 5M: we are at a topmost continuation line
(t
! (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
! ))
;; (CASE 6 has been removed.)
;; CASE 7: line is an expression, not a statement. Most
;; likely we are either in a function prototype or a function
***************
*** 2059,2072 ****
(goto-char containing-sexp)
(c-looking-at-special-brace-list)))
(eq (char-after containing-sexp) ?{)))
- (c-backward-syntactic-ws containing-sexp)
(cond
;; CASE 7A: we are looking at the arglist closing paren
! ((and (or (c-major-mode-is 'pike-mode)
! ;; Don't check this in Pike since it allows a
! ;; comma after the last arg.
! (not (eq char-before-ip ?,)))
! (memq char-after-ip '(?\) ?\])))
(goto-char containing-sexp)
(setq placeholder (c-point 'boi))
(when (and (c-safe (backward-up-list 1) t)
--- 3241,3249 ----
(goto-char containing-sexp)
(c-looking-at-special-brace-list)))
(eq (char-after containing-sexp) ?{)))
(cond
;; CASE 7A: we are looking at the arglist closing paren
! ((memq char-after-ip '(?\) ?\]))
(goto-char containing-sexp)
(setq placeholder (c-point 'boi))
(when (and (c-safe (backward-up-list 1) t)
***************
*** 2076,2093 ****
(setq placeholder (point)))
(c-add-syntax 'arglist-close placeholder))
;; CASE 7B: Looking at the opening brace of an
! ;; in-expression block or brace list.
! ((eq char-after-ip ?{)
! (goto-char indent-point)
! (setq placeholder (c-point 'boi))
! (goto-char containing-sexp)
! (if (c-inside-bracelist-p placeholder
! (cons containing-sexp state))
! (progn
! (c-add-syntax 'brace-list-open (c-point 'boi))
! (c-add-syntax 'inexpr-class))
! (c-add-syntax 'block-open (c-point 'boi))
! (c-add-syntax 'inexpr-statement)))
;; CASE 7C: we are looking at the first argument in an empty
;; argument list. Use arglist-close if we're actually
;; looking at a close paren or bracket.
--- 3253,3283 ----
(setq placeholder (point)))
(c-add-syntax 'arglist-close placeholder))
;; CASE 7B: Looking at the opening brace of an
! ;; in-expression block or brace list. C.f. cases 4, 16A
! ;; and 17E.
! ((and (eq char-after-ip ?{)
! (progn
! (setq placeholder (c-inside-bracelist-p (point)
! c-state-cache))
! (if placeholder
! (setq tmpsymbol '(brace-list-open . inexpr-class))
! (setq tmpsymbol '(block-open . inexpr-statement)
! placeholder
! (cdr-safe (c-looking-at-inexpr-block
! (c-safe-position containing-sexp
! paren-state)
! containing-sexp)))
! ;; placeholder is nil if it's a block directly in
! ;; a function arglist. That makes us skip out of
! ;; this case.
! )))
! (goto-char placeholder)
! (back-to-indentation)
! (c-add-stmt-syntax (car tmpsymbol) t
! (c-most-enclosing-brace paren-state (point))
! (c-whack-state-after (point) paren-state))
! (if (/= (point) placeholder)
! (c-add-syntax (cdr tmpsymbol))))
;; CASE 7C: we are looking at the first argument in an empty
;; argument list. Use arglist-close if we're actually
;; looking at a close paren or bracket.
***************
*** 2102,2124 ****
(c-add-syntax 'arglist-intro placeholder))
;; CASE 7D: we are inside a conditional test clause. treat
;; these things as statements
! ((save-excursion
(goto-char containing-sexp)
(and (c-safe (progn (c-forward-sexp -1) t))
(looking-at "\\<for\\>[^_]")))
(goto-char (1+ containing-sexp))
(c-forward-syntactic-ws indent-point)
- (c-beginning-of-statement-1 containing-sexp)
(if (eq char-before-ip ?\;)
(c-add-syntax 'statement (point))
(c-add-syntax 'statement-cont (point))
))
! ;; CASE 7E: maybe a continued method call. This is the case
! ;; when we are inside a [] bracketed exp, and what precede
! ;; the opening bracket is not an identifier.
! ((and c-method-key
(eq (char-after containing-sexp) ?\[)
! (save-excursion
(goto-char (1- containing-sexp))
(c-backward-syntactic-ws (c-point 'bod))
(if (not (looking-at c-symbol-key))
--- 3292,3313 ----
(c-add-syntax 'arglist-intro placeholder))
;; CASE 7D: we are inside a conditional test clause. treat
;; these things as statements
! ((progn
(goto-char containing-sexp)
(and (c-safe (progn (c-forward-sexp -1) t))
(looking-at "\\<for\\>[^_]")))
(goto-char (1+ containing-sexp))
(c-forward-syntactic-ws indent-point)
(if (eq char-before-ip ?\;)
(c-add-syntax 'statement (point))
(c-add-syntax 'statement-cont (point))
))
! ;; CASE 7E: maybe a continued ObjC method call. This is the
! ;; case when we are inside a [] bracketed exp, and what
! ;; precede the opening bracket is not an identifier.
! ((and c-opt-method-key
(eq (char-after containing-sexp) ?\[)
! (progn
(goto-char (1- containing-sexp))
(c-backward-syntactic-ws (c-point 'bod))
(if (not (looking-at c-symbol-key))
***************
*** 2129,2138 ****
;; opening paren. This case includes multi-line
;; mathematical paren groupings, but we could be on a
;; for-list continuation line
! ((save-excursion
(goto-char (1+ containing-sexp))
(skip-chars-forward " \t")
! (not (eolp)))
(goto-char containing-sexp)
(setq placeholder (c-point 'boi))
(when (and (c-safe (backward-up-list 1) t)
--- 3318,3328 ----
;; opening paren. This case includes multi-line
;; mathematical paren groupings, but we could be on a
;; for-list continuation line
! ((progn
(goto-char (1+ containing-sexp))
(skip-chars-forward " \t")
! (and (not (eolp))
! (not (looking-at "\\\\$"))))
(goto-char containing-sexp)
(setq placeholder (c-point 'boi))
(when (and (c-safe (backward-up-list 1) t)
***************
*** 2143,2159 ****
(c-add-syntax 'arglist-cont-nonempty placeholder))
;; CASE 7G: we are looking at just a normal arglist
;; continuation line
! (t (c-beginning-of-statement-1 containing-sexp)
! (forward-char 1)
! (c-forward-syntactic-ws indent-point)
(c-add-syntax 'arglist-cont (c-point 'boi)))
))
;; CASE 8: func-local multi-inheritance line
! ((and c-baseclass-key
(save-excursion
(goto-char indent-point)
(skip-chars-forward " \t")
! (looking-at c-baseclass-key)))
(goto-char indent-point)
(skip-chars-forward " \t")
(cond
--- 3333,3347 ----
(c-add-syntax 'arglist-cont-nonempty placeholder))
;; CASE 7G: we are looking at just a normal arglist
;; continuation line
! (t (c-forward-syntactic-ws indent-point)
(c-add-syntax 'arglist-cont (c-point 'boi)))
))
;; CASE 8: func-local multi-inheritance line
! ((and (c-major-mode-is 'c++-mode)
(save-excursion
(goto-char indent-point)
(skip-chars-forward " \t")
! (looking-at c-opt-decl-spec-key)))
(goto-char indent-point)
(skip-chars-forward " \t")
(cond
***************
*** 2175,2181 ****
(save-excursion
(goto-char containing-sexp)
(c-looking-at-special-brace-list)))
! (c-inside-bracelist-p containing-sexp state)))
(cond
;; CASE 9A: In the middle of a special brace list opener.
((and (consp special-brace-list)
--- 3363,3369 ----
(save-excursion
(goto-char containing-sexp)
(c-looking-at-special-brace-list)))
! (c-inside-bracelist-p containing-sexp paren-state)))
(cond
;; CASE 9A: In the middle of a special brace list opener.
((and (consp special-brace-list)
***************
*** 2189,2197 ****
(assoc 'statement-cont
(setq placeholder (c-guess-basic-syntax))))
(setq syntax placeholder)
! (c-beginning-of-statement-1 lim)
(c-forward-token-1 0)
! (if (looking-at "typedef\\>") (c-forward-token-1 1))
(c-add-syntax 'brace-list-open (c-point 'boi))))
;; CASE 9B: brace-list-close brace
((if (consp special-brace-list)
--- 3377,3386 ----
(assoc 'statement-cont
(setq placeholder (c-guess-basic-syntax))))
(setq syntax placeholder)
! (c-beginning-of-statement-1
! (c-safe-position (1- containing-sexp) paren-state))
(c-forward-token-1 0)
! (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1))
(c-add-syntax 'brace-list-open (c-point 'boi))))
;; CASE 9B: brace-list-close brace
((if (consp special-brace-list)
***************
*** 2211,2221 ****
(eq (1+ (point)) (cdr (car special-brace-list)))))))
;; Normal brace list check.
(and (eq char-after-ip ?})
! (c-safe (progn (forward-char 1)
! (c-backward-sexp 1)
t))
(= (point) containing-sexp)))
! (c-add-syntax 'brace-list-close (c-point 'boi)))
(t
;; Prepare for the rest of the cases below by going to the
;; token following the opening brace
--- 3400,3414 ----
(eq (1+ (point)) (cdr (car special-brace-list)))))))
;; Normal brace list check.
(and (eq char-after-ip ?})
! (c-safe (progn (goto-char (c-up-list-backward (point)))
t))
(= (point) containing-sexp)))
! (if (eq (point) (c-point 'boi))
! (c-add-syntax 'brace-list-close (point))
! (setq lim (c-most-enclosing-brace c-state-cache (point)))
! (c-beginning-of-statement-1 lim)
! (c-add-stmt-syntax 'brace-list-close t lim
! (c-whack-state-after (point) paren-state) t)))
(t
;; Prepare for the rest of the cases below by going to the
;; token following the opening brace
***************
*** 2228,2240 ****
(let ((start (point)))
(c-forward-syntactic-ws indent-point)
(goto-char (max start (c-point 'bol))))
! (skip-chars-forward " \t\n\r" indent-point)
(cond
;; CASE 9C: we're looking at the first line in a brace-list
((= (point) indent-point)
! (goto-char containing-sexp)
! (c-add-syntax 'brace-list-intro (c-point 'boi))
! ) ; end CASE 9C
;; CASE 9D: this is just a later brace-list-entry or
;; brace-entry-open
(t (if (or (eq char-after-ip ?{)
--- 3421,3440 ----
(let ((start (point)))
(c-forward-syntactic-ws indent-point)
(goto-char (max start (c-point 'bol))))
! (c-skip-ws-forward indent-point)
(cond
;; CASE 9C: we're looking at the first line in a brace-list
((= (point) indent-point)
! (if (consp special-brace-list)
! (goto-char (car (car special-brace-list)))
! (goto-char containing-sexp))
! (if (eq (point) (c-point 'boi))
! (c-add-syntax 'brace-list-intro (point))
! (setq lim (c-most-enclosing-brace c-state-cache (point)))
! (c-beginning-of-statement-1 lim)
! (c-add-stmt-syntax 'brace-list-intro t lim
! (c-whack-state-after (point) paren-state)
! t)))
;; CASE 9D: this is just a later brace-list-entry or
;; brace-entry-open
(t (if (or (eq char-after-ip ?{)
***************
*** 2245,2428 ****
(c-looking-at-special-brace-list (point)))))
(c-add-syntax 'brace-entry-open (point))
(c-add-syntax 'brace-list-entry (point))
! )) ; end CASE 9D
! )))) ; end CASE 9
! ;; CASE 10: A continued statement
((and (not (memq char-before-ip '(?\; ?:)))
(or (not (eq char-before-ip ?}))
! (c-looking-at-inexpr-block-backward containing-sexp))
(> (point)
(save-excursion
(c-beginning-of-statement-1 containing-sexp)
- (c-forward-syntactic-ws)
(setq placeholder (point))))
(/= placeholder containing-sexp))
! (goto-char indent-point)
! (skip-chars-forward " \t")
! (let ((after-cond-placeholder
! (save-excursion
! (goto-char placeholder)
! (if (and c-conditional-key (looking-at c-conditional-key))
! (progn
! (c-safe (c-skip-conditional))
! (c-forward-syntactic-ws)
! (if (eq (char-after) ?\;)
! (progn
! (forward-char 1)
! (c-forward-syntactic-ws)))
! (point))
! nil))))
! (cond
! ;; CASE 10A: substatement
! ((and after-cond-placeholder
! (>= after-cond-placeholder indent-point))
! (goto-char placeholder)
! (if (eq char-after-ip ?{)
! (c-add-syntax 'substatement-open (c-point 'boi))
! (c-add-syntax 'substatement (c-point 'boi))))
! ;; CASE 10B: open braces for class or brace-lists
! ((setq special-brace-list
! (or (and c-special-brace-lists
! (c-looking-at-special-brace-list))
! (eq char-after-ip ?{)))
! (cond
! ;; CASE 10B.1: class-open
! ((save-excursion
! (goto-char indent-point)
! (skip-chars-forward " \t{")
! (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
! (and decl
! (setq placeholder (aref decl 0)))
! ))
! (c-add-syntax 'class-open placeholder))
! ;; CASE 10B.2: brace-list-open
! ((or (consp special-brace-list)
! (save-excursion
! (goto-char placeholder)
! (looking-at "\\<enum\\>"))
! (save-excursion
! (goto-char indent-point)
! (while (and (> (point) placeholder)
! (= (c-backward-token-1 1 t) 0)
! (/= (char-after) ?=)))
! (eq (char-after) ?=)))
! ;; The most semantically accurate symbol here is
! ;; brace-list-open, but we report it simply as a
! ;; statement-cont. The reason is that one normally
! ;; adjusts brace-list-open for brace lists as
! ;; top-level constructs, and brace lists inside
! ;; statements is a completely different context.
! (goto-char indent-point)
! (c-beginning-of-closest-statement)
! (c-add-syntax 'statement-cont (c-point 'boi)))
! ;; CASE 10B.3: The body of a function declared inside a
! ;; normal block. This can only occur in Pike.
! ((and (c-major-mode-is 'pike-mode)
! (progn
! (goto-char indent-point)
! (not (c-looking-at-bos))))
! (c-beginning-of-closest-statement)
! (c-add-syntax 'defun-open (c-point 'boi)))
! ;; CASE 10B.4: catch-all for unknown construct.
! (t
! ;; Can and should I add an extensibility hook here?
! ;; Something like c-recognize-hook so support for
! ;; unknown constructs could be added. It's probably a
! ;; losing proposition, so I dunno.
! (goto-char placeholder)
! (c-add-syntax 'statement-cont (c-point 'boi))
! (c-add-syntax 'block-open))
! ))
! ;; CASE 10C: iostream insertion or extraction operator
! ((looking-at "<<\\|>>")
! (goto-char placeholder)
! (and after-cond-placeholder
! (goto-char after-cond-placeholder))
! (while (and (re-search-forward "<<\\|>>" indent-point 'move)
! (c-in-literal placeholder)))
! ;; if we ended up at indent-point, then the first
! ;; streamop is on a separate line. Indent the line like
! ;; a statement-cont instead
! (if (/= (point) indent-point)
! (c-add-syntax 'stream-op (c-point 'boi))
! (c-backward-syntactic-ws lim)
! (c-add-syntax 'statement-cont (c-point 'boi))))
! ;; CASE 10D: continued statement. find the accurate
! ;; beginning of statement or substatement
! (t
! (c-beginning-of-statement-1 after-cond-placeholder)
! ;; KLUDGE ALERT! c-beginning-of-statement-1 can leave
! ;; us before the lim we're passing in. It should be
! ;; fixed, but I'm worried about side-effects at this
! ;; late date. Fix for v5.
! (goto-char (or (and after-cond-placeholder
! (max after-cond-placeholder (point)))
! (point)))
! (c-add-syntax 'statement-cont (point)))
! )))
! ;; CASE 11: an else clause?
! ((looking-at "\\<else\\>[^_]")
! (c-backward-to-start-of-if containing-sexp)
! (c-add-syntax 'else-clause (c-point 'boi)))
! ;; CASE 12: Statement. But what kind? Lets see if its a
! ;; while closure of a do/while construct
! ((progn
! (goto-char indent-point)
! (skip-chars-forward " \t")
! (and (looking-at "while\\b[^_]")
! (save-excursion
! (c-backward-to-start-of-do containing-sexp)
! (setq placeholder (point))
! (looking-at "do\\b[^_]"))
! ))
! (goto-char placeholder)
! (c-add-syntax 'do-while-closure (c-point 'boi)))
! ;; CASE 13: A catch or finally clause? This case is simpler
! ;; than if-else and do-while, because a block is required
! ;; after every try, catch and finally.
! ((save-excursion
! (and (cond ((c-major-mode-is 'c++-mode)
! (looking-at "\\<catch\\>[^_]"))
! ((c-major-mode-is 'java-mode)
! (looking-at "\\<\\(catch\\|finally\\)\\>[^_]")))
! (c-safe (c-backward-sexp) t)
! (eq (char-after) ?{)
! (c-safe (c-backward-sexp) t)
! (if (eq (char-after) ?\()
! (c-safe (c-backward-sexp) t)
! t)
! (looking-at "\\<\\(try\\|catch\\)\\>[^_]")
! (setq placeholder (c-point 'boi))))
! (c-add-syntax 'catch-clause placeholder))
;; CASE 14: A case or default label
! ((looking-at c-switch-label-key)
(goto-char containing-sexp)
! ;; check for hanging braces
! (if (/= (point) (c-point 'boi))
! (c-forward-sexp -1))
! (c-add-syntax 'case-label (c-point 'boi)))
;; CASE 15: any other label
((looking-at c-label-key)
(goto-char containing-sexp)
! ;; check for hanging braces
! (if (/= (point) (c-point 'boi))
! (c-forward-sexp -1))
! (c-add-syntax 'label (c-point 'boi)))
;; CASE 16: block close brace, possibly closing the defun or
;; the class
((eq char-after-ip ?})
! (let* ((lim (c-safe-position containing-sexp fullstate))
! (relpos (save-excursion
! (goto-char containing-sexp)
! (if (/= (point) (c-point 'boi))
! (c-beginning-of-statement-1 lim))
! (c-point 'boi))))
(cond
;; CASE 16A: closing a lambda defun or an in-expression
! ;; block?
! ((save-excursion
! (goto-char containing-sexp)
! (setq placeholder (c-looking-at-inexpr-block)))
(setq tmpsymbol (if (eq (car placeholder) 'inlambda)
'inline-close
'block-close))
--- 3445,3507 ----
(c-looking-at-special-brace-list (point)))))
(c-add-syntax 'brace-entry-open (point))
(c-add-syntax 'brace-list-entry (point))
! ))
! ))))
! ;; CASE 10: A continued statement or top level construct.
((and (not (memq char-before-ip '(?\; ?:)))
(or (not (eq char-before-ip ?}))
! (c-looking-at-inexpr-block-backward c-state-cache))
(> (point)
(save-excursion
(c-beginning-of-statement-1 containing-sexp)
(setq placeholder (point))))
(/= placeholder containing-sexp))
! ;; This is shared with case 18.
! (c-guess-continued-construct indent-point
! char-after-ip
! placeholder
! containing-sexp
! paren-state))
;; CASE 14: A case or default label
! ((looking-at c-label-kwds-regexp)
(goto-char containing-sexp)
! (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
! (c-backward-to-block-anchor lim)
! (c-add-stmt-syntax 'case-label t lim paren-state))
;; CASE 15: any other label
((looking-at c-label-key)
(goto-char containing-sexp)
! (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
! (save-excursion
! (setq tmpsymbol
! (if (and (eq (c-beginning-of-statement-1 lim) 'up)
! (looking-at "switch\\>[^_]"))
! ;; If the surrounding statement is a switch then
! ;; let's analyze all labels as switch labels, so
! ;; that they get lined up consistently.
! 'case-label
! 'label)))
! (c-backward-to-block-anchor lim)
! (c-add-stmt-syntax tmpsymbol t lim paren-state))
;; CASE 16: block close brace, possibly closing the defun or
;; the class
((eq char-after-ip ?})
! ;; From here on we have the next containing sexp in lim.
! (setq lim (c-most-enclosing-brace paren-state))
! (goto-char containing-sexp)
(cond
+ ;; CASE 16E: Closing a statement block? This catches
+ ;; cases where it's preceded by a statement keyword,
+ ;; which works even when used in an "invalid" context,
+ ;; e.g. a macro argument.
+ ((c-after-conditional)
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'block-close t lim paren-state))
;; CASE 16A: closing a lambda defun or an in-expression
! ;; block? C.f. cases 4, 7B and 17E.
! ((setq placeholder (c-looking-at-inexpr-block
! (c-safe-position containing-sexp paren-state)
! nil))
(setq tmpsymbol (if (eq (car placeholder) 'inlambda)
'inline-close
'block-close))
***************
*** 2432,2463 ****
(c-add-syntax tmpsymbol (point))
(goto-char (cdr placeholder))
(back-to-indentation)
! (c-add-syntax tmpsymbol (point))
(if (/= (point) (cdr placeholder))
(c-add-syntax (car placeholder)))))
;; CASE 16B: does this close an inline or a function in
;; an extern block or namespace?
! ((progn
! (goto-char containing-sexp)
! (setq placeholder (c-search-uplist-for-classkey state)))
! (goto-char (aref placeholder 0))
! (if (looking-at (concat c-extra-toplevel-key "[^_]"))
! (c-add-syntax 'defun-close relpos)
! (c-add-syntax 'inline-close relpos)))
;; CASE 16C: if there an enclosing brace that hasn't
;; been narrowed out by a class, then this is a
! ;; block-close
! ((and (not inenclosing-p)
! (c-most-enclosing-brace state)
! (or (not (c-major-mode-is 'pike-mode))
! ;; In Pike it can be a defun-close of a
! ;; function declared in a statement block. Let
! ;; it through to be handled below.
! (or (c-looking-at-bos)
! (progn
! (c-beginning-of-statement-1)
! (looking-at c-conditional-key)))))
! (c-add-syntax 'block-close relpos))
;; CASE 16D: find out whether we're closing a top-level
;; class or a defun
(t
--- 3511,3566 ----
(c-add-syntax tmpsymbol (point))
(goto-char (cdr placeholder))
(back-to-indentation)
! (c-add-stmt-syntax tmpsymbol t
! (c-most-enclosing-brace paren-state (point))
! (c-whack-state-after (point) paren-state))
(if (/= (point) (cdr placeholder))
(c-add-syntax (car placeholder)))))
;; CASE 16B: does this close an inline or a function in
;; an extern block or namespace?
! ((setq placeholder (c-search-uplist-for-classkey paren-state))
! (c-backward-to-decl-anchor lim)
! (back-to-indentation)
! (if (save-excursion
! (goto-char (aref placeholder 0))
! (looking-at c-other-decl-block-key))
! (c-add-syntax 'defun-close (point))
! (c-add-syntax 'inline-close (point))))
! ;; CASE 16F: Can be a defun-close of a function declared
! ;; in a statement block, e.g. in Pike or when using gcc
! ;; extensions. Might also trigger it with some macros
! ;; followed by blocks, and this gives sane indentation
! ;; then too. Let it through to be handled below.
! ;; C.f. cases B.3 and 17G.
! ((and (not inenclosing-p)
! lim
! (save-excursion
! (and (not (c-looking-at-bos))
! (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
! (setq placeholder (point)))))
! (back-to-indentation)
! (if (/= (point) containing-sexp)
! (goto-char placeholder))
! (c-add-stmt-syntax 'defun-close t lim paren-state))
;; CASE 16C: if there an enclosing brace that hasn't
;; been narrowed out by a class, then this is a
! ;; block-close. C.f. case 17H.
! ((and (not inenclosing-p) lim)
! ;; If the block is preceded by a case/switch label on
! ;; the same line, we anchor at the first preceding label
! ;; at boi. The default handling in c-add-stmt-syntax is
! ;; really fixes it better, but we do like this to keep
! ;; the indentation compatible with version 5.28 and
! ;; earlier.
! (while (and (/= (setq placeholder (point)) (c-point 'boi))
! (eq (c-beginning-of-statement-1 lim) 'label)))
! (goto-char placeholder)
! (if (looking-at c-label-kwds-regexp)
! (c-add-syntax 'block-close (point))
! (goto-char containing-sexp)
! ;; c-backward-to-block-anchor not necessary here; those
! ;; situations are handled in case 16E above.
! (c-add-stmt-syntax 'block-close t lim paren-state)))
;; CASE 16D: find out whether we're closing a top-level
;; class or a defun
(t
***************
*** 2465,2668 ****
(narrow-to-region (point-min) indent-point)
(let ((decl (c-search-uplist-for-classkey (c-parse-state))))
(if decl
! (c-add-class-syntax 'class-close decl)
! (c-add-syntax 'defun-close relpos)))))
! )))
! ;; CASE 17: statement catchall
(t
! ;; we know its a statement, but we need to find out if it is
! ;; the first statement in a block
! (goto-char containing-sexp)
! (forward-char 1)
! (c-forward-syntactic-ws indent-point)
! ;; now skip forward past any case/default clauses we might find.
! (while (or (c-skip-case-statement-forward fullstate indent-point)
! (and (looking-at c-switch-label-key)
! (not inswitch-p)))
! (setq inswitch-p t))
! ;; we want to ignore non-case labels when skipping forward
! (while (and (looking-at c-label-key)
! (goto-char (match-end 0)))
! (c-forward-syntactic-ws indent-point))
(cond
- ;; CASE 17A: we are inside a case/default clause inside a
- ;; switch statement. find out if we are at the statement
- ;; just after the case/default label.
- ((and inswitch-p
- (progn
- (goto-char indent-point)
- (c-beginning-of-statement-1 containing-sexp)
- (setq placeholder (point))
- (beginning-of-line)
- (when (re-search-forward c-switch-label-key
- (max placeholder (c-point 'eol)) t)
- (setq placeholder (match-beginning 0)))))
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (if (eq (char-after) ?{)
- (c-add-syntax 'statement-case-open placeholder)
- (c-add-syntax 'statement-case-intro placeholder)))
;; CASE 17B: continued statement
! ((eq char-before-ip ?,)
! (goto-char indent-point)
! (c-beginning-of-closest-statement)
! (c-add-syntax 'statement-cont (c-point 'boi)))
! ;; CASE 17C: a question/colon construct? But make sure
! ;; what came before was not a label, and what comes after
! ;; is not a globally scoped function call!
! ((or (and (memq char-before-ip '(?: ??))
! (save-excursion
! (goto-char indent-point)
! (c-backward-syntactic-ws lim)
! (back-to-indentation)
! (not (looking-at c-label-key))))
! (and (memq char-after-ip '(?: ??))
! (save-excursion
! (goto-char indent-point)
! (skip-chars-forward " \t")
! ;; watch out for scope operator
! (not (looking-at "::")))))
! (goto-char indent-point)
! (c-beginning-of-closest-statement)
! (c-add-syntax 'statement-cont (c-point 'boi)))
;; CASE 17D: any old statement
! ((< (point) indent-point)
! (let ((safepos (c-most-enclosing-brace fullstate))
! relpos done)
! (goto-char indent-point)
! (c-beginning-of-statement-1 safepos)
! ;; It is possible we're on the brace that opens a nested
! ;; function.
! (if (and (eq (char-after) ?{)
! (save-excursion
! (c-backward-syntactic-ws safepos)
! (not (eq (char-before) ?\;))))
! (c-beginning-of-statement-1 safepos))
! (if (and inswitch-p
! (looking-at c-switch-label-key))
! (progn
! (goto-char (match-end 0))
! (c-forward-syntactic-ws)))
! (setq relpos (c-point 'boi))
! (while (and (not done)
! (<= safepos (point))
! (/= relpos (point)))
! (c-beginning-of-statement-1 safepos)
! (if (= relpos (c-point 'boi))
! (setq done t))
! (setq relpos (c-point 'boi)))
! (c-add-syntax 'statement relpos)
! (if (eq char-after-ip ?{)
! (c-add-syntax 'block-open))))
! ;; CASE 17E: first statement in an in-expression block
! ((setq placeholder
! (save-excursion
! (goto-char containing-sexp)
! (c-looking-at-inexpr-block)))
! (goto-char containing-sexp)
(back-to-indentation)
! (let ((block-intro (if (eq (car placeholder) 'inlambda)
! 'defun-block-intro
! 'statement-block-intro)))
! (if (= containing-sexp (point))
! (c-add-syntax block-intro (point))
! (goto-char (cdr placeholder))
! (back-to-indentation)
! (c-add-syntax block-intro (point))
! (if (/= (point) (cdr placeholder))
! (c-add-syntax (car placeholder)))))
(if (eq char-after-ip ?{)
(c-add-syntax 'block-open)))
;; CASE 17F: first statement in an inline, or first
;; statement in a top-level defun. we can tell this is it
;; if there are no enclosing braces that haven't been
! ;; narrowed out by a class (i.e. don't use bod here!)
((save-excursion
(save-restriction
(widen)
! (goto-char containing-sexp)
! (c-narrow-out-enclosing-class state containing-sexp)
! (not (c-most-enclosing-brace state))))
! (goto-char containing-sexp)
! ;; if not at boi, then defun-opening braces are hung on
! ;; right side, so we need a different relpos
! (if (/= (point) (c-point 'boi))
! (progn
! (c-backward-syntactic-ws)
! (c-safe (c-forward-sexp (if (eq (char-before) ?\))
! -1 -2)))
! ;; looking at a Java throws clause following a
! ;; method's parameter list
! (c-beginning-of-statement-1)
! ))
! (c-add-syntax 'defun-block-intro (c-point 'boi)))
;; CASE 17G: First statement in a function declared inside
! ;; a normal block. This can only occur in Pike.
! ((and (c-major-mode-is 'pike-mode)
! (progn
! (goto-char containing-sexp)
! (and (not (c-looking-at-bos))
! (progn
! (c-beginning-of-statement-1)
! (not (looking-at c-conditional-key))))))
! (c-add-syntax 'defun-block-intro (c-point 'boi)))
! ;; CASE 17H: first statement in a block
! (t (goto-char containing-sexp)
! (if (/= (point) (c-point 'boi))
! (c-beginning-of-statement-1
! (if (= (point) lim)
! (c-safe-position (point) state) lim)))
! (c-add-syntax 'statement-block-intro (c-point 'boi))
! (if (eq char-after-ip ?{)
! (c-add-syntax 'block-open)))
))
)
;; now we need to look at any modifiers
(goto-char indent-point)
(skip-chars-forward " \t")
! (cond
! ;; are we looking at a comment only line?
! ((and (looking-at c-comment-start-regexp)
! (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
(c-add-syntax 'comment-intro))
! ;; we might want to give additional offset to friends (in C++).
! ((and (c-major-mode-is 'c++-mode)
! (looking-at c-C++-friend-key))
(c-add-syntax 'friend))
! ;; Start of a preprocessor directive?
! ((and (eq literal 'pound)
! (= (save-excursion
! (c-beginning-of-macro lim)
! (setq placeholder (point)))
! (c-point 'boi))
! (not (and (c-major-mode-is 'pike-mode)
! (eq (char-after (1+ placeholder)) ?\"))))
! (c-add-syntax 'cpp-macro)))
;; return the syntax
syntax))))
(defun c-echo-parsing-error (&optional quiet)
! (when (and c-parsing-error (not quiet))
! (message "%s" c-parsing-error)
! (ding))
c-parsing-error)
- (defun c-shift-line-indentation (shift-amt)
- (let ((pos (- (point-max) (point)))
- (col (current-indentation)))
- (if (zerop shift-amt)
- nil
- (delete-region (c-point 'bol) (c-point 'boi))
- (beginning-of-line)
- (indent-to (+ col shift-amt)))
- (if (< (point) (c-point 'boi))
- (back-to-indentation)
- ;; If initial point was within line's indentation, position after
- ;; the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos))))))
-
(defun c-evaluate-offset (offset langelem symbol)
;; offset can be a number, a function, a variable, a list, or one of
;; the symbols + or -
--- 3568,3749 ----
(narrow-to-region (point-min) indent-point)
(let ((decl (c-search-uplist-for-classkey (c-parse-state))))
(if decl
! (c-add-class-syntax 'class-close decl paren-state)
! (goto-char containing-sexp)
! (c-backward-to-decl-anchor lim)
! (back-to-indentation)
! (c-add-syntax 'defun-close (point)))))
! )))
! ;; CASE 17: Statement or defun catchall.
(t
! (goto-char indent-point)
! ;; Back up statements until we find one that starts at boi.
! (while (let* ((prev-point (point))
! (last-step-type (c-beginning-of-statement-1
! containing-sexp)))
! (if (= (point) prev-point)
! (progn
! (setq step-type (or step-type last-step-type))
! nil)
! (setq step-type last-step-type)
! (/= (point) (c-point 'boi)))))
(cond
;; CASE 17B: continued statement
! ((and (eq step-type 'same)
! (/= (point) indent-point))
! (c-add-stmt-syntax 'statement-cont nil
! containing-sexp paren-state))
! ;; CASE 17A: After a case/default label?
! ((progn
! (while (and (eq step-type 'label)
! (not (looking-at c-label-kwds-regexp)))
! (setq step-type
! (c-beginning-of-statement-1 containing-sexp)))
! (eq step-type 'label))
! (c-add-stmt-syntax (if (eq char-after-ip ?{)
! 'statement-case-open
! 'statement-case-intro)
! t containing-sexp paren-state))
;; CASE 17D: any old statement
! ((progn
! (while (eq step-type 'label)
! (setq step-type
! (c-beginning-of-statement-1 containing-sexp)))
! (eq step-type 'previous))
! (c-add-stmt-syntax 'statement t containing-sexp paren-state)
! (if (eq char-after-ip ?{)
! (c-add-syntax 'block-open)))
! ;; CASE 17I: Inside a substatement block.
! ((progn
! ;; The following tests are all based on containing-sexp.
! (goto-char containing-sexp)
! ;; From here on we have the next containing sexp in lim.
! (setq lim (c-most-enclosing-brace paren-state containing-sexp))
! (c-after-conditional))
! (c-backward-to-block-anchor lim)
! (c-add-stmt-syntax 'statement-block-intro t lim paren-state)
! (if (eq char-after-ip ?{)
! (c-add-syntax 'block-open)))
! ;; CASE 17E: first statement in an in-expression block.
! ;; C.f. cases 4, 7B and 16A.
! ((setq placeholder (c-looking-at-inexpr-block
! (c-safe-position containing-sexp paren-state)
! nil))
! (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
! 'defun-block-intro
! 'statement-block-intro))
(back-to-indentation)
! (if (= containing-sexp (point))
! (c-add-syntax tmpsymbol (point))
! (goto-char (cdr placeholder))
! (back-to-indentation)
! (c-add-stmt-syntax tmpsymbol t
! (c-most-enclosing-brace c-state-cache (point))
! (c-whack-state-after (point) paren-state))
! (if (/= (point) (cdr placeholder))
! (c-add-syntax (car placeholder))))
(if (eq char-after-ip ?{)
(c-add-syntax 'block-open)))
;; CASE 17F: first statement in an inline, or first
;; statement in a top-level defun. we can tell this is it
;; if there are no enclosing braces that haven't been
! ;; narrowed out by a class (i.e. don't use bod here).
! ;; However, we first check for statements that we can
! ;; recognize by keywords. That increases the robustness in
! ;; cases where statements are used on the top level,
! ;; e.g. in macro definitions.
((save-excursion
(save-restriction
(widen)
! (c-narrow-out-enclosing-class paren-state containing-sexp)
! (not (c-most-enclosing-brace paren-state))))
! (c-backward-to-decl-anchor lim)
! (back-to-indentation)
! (c-add-syntax 'defun-block-intro (point)))
;; CASE 17G: First statement in a function declared inside
! ;; a normal block. This can occur in Pike and with
! ;; e.g. the gcc extensions. Might also trigger it with
! ;; some macros followed by blocks, and this gives sane
! ;; indentation then too. C.f. cases B.3 and 16F.
! ((save-excursion
! (and (not (c-looking-at-bos))
! (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
! (setq placeholder (point))))
! (back-to-indentation)
! (if (/= (point) containing-sexp)
! (goto-char placeholder))
! (c-add-stmt-syntax 'defun-block-intro t lim paren-state))
! ;; CASE 17H: First statement in a block. C.f. case 16C.
! (t
! ;; If the block is preceded by a case/switch label on the
! ;; same line, we anchor at the first preceding label at
! ;; boi. The default handling in c-add-stmt-syntax is
! ;; really fixes it better, but we do like this to keep the
! ;; indentation compatible with version 5.28 and earlier.
! (while (and (/= (setq placeholder (point)) (c-point 'boi))
! (eq (c-beginning-of-statement-1 lim) 'label)))
! (goto-char placeholder)
! (if (looking-at c-label-kwds-regexp)
! (c-add-syntax 'statement-block-intro (point))
! (goto-char containing-sexp)
! ;; c-backward-to-block-anchor not necessary here; those
! ;; situations are handled in case 17I above.
! (c-add-stmt-syntax 'statement-block-intro t lim paren-state))
! (if (eq char-after-ip ?{)
! (c-add-syntax 'block-open)))
))
)
;; now we need to look at any modifiers
(goto-char indent-point)
(skip-chars-forward " \t")
! ;; are we looking at a comment only line?
! (when (and (looking-at c-comment-start-regexp)
! (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
(c-add-syntax 'comment-intro))
! ;; we might want to give additional offset to friends (in C++).
! (when (and c-opt-friend-key
! (looking-at c-opt-friend-key))
(c-add-syntax 'friend))
! ;; Start of or a continuation of a preprocessor directive?
! (if (and macro-start
! (eq macro-start (c-point 'boi))
! (not (and (c-major-mode-is 'pike-mode)
! (eq (char-after (1+ macro-start)) ?\"))))
! (c-add-syntax 'cpp-macro)
! (when (and c-syntactic-indentation-in-macros macro-start)
! (if in-macro-expr
! (when (or (< syntactic-relpos macro-start)
! (not (or (assq 'arglist-intro syntax)
! (assq 'arglist-cont syntax)
! (assq 'arglist-cont-nonempty syntax)
! (assq 'arglist-close syntax))))
! ;; If inside a cpp expression, i.e. anywhere in a
! ;; cpp directive except a #define body, we only let
! ;; through the syntactic analysis that is internal
! ;; in the expression. That means the arglist
! ;; elements, if they are anchored inside the cpp
! ;; expression.
! (setq syntax `((cpp-macro-cont . ,macro-start))))
! (when (and (eq macro-start syntactic-relpos)
! (not (assq 'cpp-define-intro syntax))
! (save-excursion
! (goto-char macro-start)
! (or (not (c-forward-to-cpp-define-body))
! (<= (point) (c-point 'boi indent-point)))))
! ;; Inside a #define body and the syntactic analysis is
! ;; anchored on the start of the #define. In this case
! ;; we add cpp-define-intro to get the extra
! ;; indentation of the #define body.
! (c-add-syntax 'cpp-define-intro)))))
;; return the syntax
syntax))))
(defun c-echo-parsing-error (&optional quiet)
! (when (and c-report-syntactic-errors c-parsing-error (not quiet))
! (c-benign-error "%s" c-parsing-error))
c-parsing-error)
(defun c-evaluate-offset (offset langelem symbol)
;; offset can be a number, a function, a variable, a list, or one of
;; the symbols + or -
***************
*** 2683,2795 ****
(while (and (not done) offset)
(setq done (c-evaluate-offset (car offset) langelem symbol)
offset (cdr offset)))
! (if (not done)
! (if c-strict-syntax-p
! (error "No offset found for syntactic symbol %s" symbol))
! done)))
(t (symbol-value offset))
))
(defun c-get-offset (langelem)
! ;; Get offset from LANGELEM which is a cons cell of the form:
! ;; (SYMBOL . RELPOS). The symbol is matched against
! ;; c-offsets-alist and the offset found there is either returned,
! ;; or added to the indentation at RELPOS. If RELPOS is nil, then
! ;; the offset is simply returned.
(let* ((symbol (car langelem))
- (relpos (cdr langelem))
(match (assq symbol c-offsets-alist))
(offset (cdr-safe match)))
! (if (not match)
! (if c-strict-syntax-p
! (error "No offset found for syntactic symbol %s" symbol)
! (setq offset 0
! relpos 0))
! (setq offset (c-evaluate-offset offset langelem symbol)))
(if (vectorp offset)
offset
! (+ (if (and relpos
! (< relpos (c-point 'bol)))
! (save-excursion
! (goto-char relpos)
! (current-column))
! 0)
! (or (and (numberp offset) offset)
! (and (symbolp offset) (symbol-value offset))
! 0)))
))
(defun c-get-syntactic-indentation (langelems)
! ;; Apply c-get-offset to a list of langelem cells to get the total
! ;; syntactic indentation. Special treatment is needed for vectors
! ;; containing absolute columns.
! (let ((indent 0))
(catch 'done
(while langelems
(let ((res (c-get-offset (car langelems))))
(if (vectorp res)
(throw 'done (elt res 0))
(setq indent (+ indent res)
langelems (cdr langelems)))))
! indent)))
!
! (defun c-indent-line (&optional syntax quiet)
! ;; Indent the current line according to the syntactic context, if
! ;; c-syntactic-indentation is non-nil. Optional SYNTAX is the
! ;; syntactic information for the current line. Be silent about
! ;; syntactic errors if the optional argument QUIET is non-nil.
! ;; Returns the amount of indentation change (in columns).
! (let (shift-amt)
! (if c-syntactic-indentation
! (setq c-parsing-error
! (or (let* ((c-parsing-error nil)
! (c-syntactic-context (or syntax
! c-syntactic-context
! (c-guess-basic-syntax)))
! (indent (c-get-syntactic-indentation
c-syntactic-context)))
! (and (not (c-echo-parsing-error quiet))
! c-echo-syntactic-information-p
! (message "syntax: %s, indent: %d"
! c-syntactic-context indent))
! (setq shift-amt (- indent (current-indentation)))
! (c-shift-line-indentation shift-amt)
! (run-hooks 'c-special-indent-hook)
! c-parsing-error)
! c-parsing-error))
! (let ((indent 0))
! (save-excursion
! (while (and (= (forward-line -1) 0)
! (if (looking-at "\\s-*$")
! t
! (back-to-indentation)
! (setq indent (current-indentation))
! nil))))
! (setq shift-amt (- indent (current-indentation)))
! (c-shift-line-indentation shift-amt)))
! shift-amt))
!
! (defun c-show-syntactic-information (arg)
! "Show syntactic information for current line.
! With universal argument, inserts the analysis as a comment on that line."
! (interactive "P")
! (let ((syntax (c-guess-basic-syntax)))
! (if (not (consp arg))
! (message "syntactic analysis: %s" syntax)
! (indent-for-comment)
! (insert (format "%s" syntax))
! ))
! (c-keep-region-active))
!
! (defun c-syntactic-information-on-region (from to)
! "Inserts a comment with the syntactic analysis on every line in the region."
! (interactive "*r")
! (save-excursion
! (save-restriction
! (narrow-to-region from to)
! (goto-char (point-min))
! (while (not (eobp))
! (c-show-syntactic-information '(0))
! (forward-line)))))
(cc-provide 'cc-engine)
--- 3764,3822 ----
(while (and (not done) offset)
(setq done (c-evaluate-offset (car offset) langelem symbol)
offset (cdr offset)))
! (if (and c-strict-syntax-p (not done))
! (c-benign-error "No offset found for syntactic symbol %s" symbol))
! done))
(t (symbol-value offset))
))
(defun c-get-offset (langelem)
! "Get offset from LANGELEM which is a cons cell of the form:
! \(SYMBOL . RELPOS). The symbol is matched against `c-offsets-alist'
! and the offset found there is returned."
(let* ((symbol (car langelem))
(match (assq symbol c-offsets-alist))
(offset (cdr-safe match)))
! (if match
! (setq offset (c-evaluate-offset offset langelem symbol))
! (if c-strict-syntax-p
! (c-benign-error "No offset found for syntactic symbol %s" symbol))
! (setq offset 0))
(if (vectorp offset)
offset
! (or (and (numberp offset) offset)
! (and (symbolp offset) (symbol-value offset))
! 0))
))
(defun c-get-syntactic-indentation (langelems)
! "Apply `c-get-offset' to a list of langelem cells to get the total
! syntactic indentation. The anchor position, whose column is used as a
! base for all the collected offsets, is taken from the first element
! with a relpos."
! ;; Note that topmost-intro always has a relpos at bol, for
! ;; historical reasons. It's often used together with other symbols
! ;; that has more sane positions. Since we always use the first
! ;; found relpos, we rely on that these other symbols always precede
! ;; topmost-intro in the LANGELEMS list.
! (let ((indent 0) anchor)
(catch 'done
(while langelems
(let ((res (c-get-offset (car langelems))))
(if (vectorp res)
(throw 'done (elt res 0))
+ (unless anchor
+ (let ((relpos (cdr (car langelems))))
+ (if relpos
+ (setq anchor relpos))))
(setq indent (+ indent res)
langelems (cdr langelems)))))
! (+ indent
! (if anchor
! (save-excursion
! (goto-char anchor)
! (current-column))
! 0)))))
(cc-provide 'cc-engine)