Function: c-looking-at-or-maybe-in-bracelist
c-looking-at-or-maybe-in-bracelist is a byte-compiled function defined
in cc-engine.el.gz.
Signature
(c-looking-at-or-maybe-in-bracelist &optional CONTAINING-SEXP LIM)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim)
;; Point is at an open brace. If this starts a brace list, return a list
;; whose car is the buffer position of the start of the construct which
;; introduces the list, and whose cdr is the symbol `in-paren' if the brace
;; is directly enclosed in a parenthesis form (i.e. an arglist), t if we
;; have parsed a keyword matching `c-opt-inexpr-brace-list-key' (e.g. Java's
;; "new"), nil otherwise. Otherwise, if point might be inside an enclosing
;; brace list, return t. If point is definitely neither at nor in a brace
;; list, return nil.
;;
;; CONTAINING-SEXP is the position of the brace/paren/bracket enclosing
;; POINT, or nil if there is no such position, or we do not know it. LIM is
;; a backward search limit.
;;
;; The determination of whether the brace starts a brace list is mainly by
;; the context of the brace, not by its contents. In exceptional
;; circumstances (e.g. "struct A {" in C++ Mode), the contents are examined,
;; too.
;;
;; Here, "brace list" does not include the body of an enum.
(save-excursion
(let ((start (point))
(braceassignp 'dontknow)
inexpr-brace-list bufpos macro-start res pos after-type-id-pos
pos2 in-paren parens-before-brace
paren-state paren-pos)
(setq res
(or (progn (c-backward-syntactic-ws)
(c-back-over-compound-identifier))
(c-backward-token-2 1 t lim)))
;; Checks to do only on the first sexp before the brace.
;; Have we a C++ initialization, without an "="?
(if (and (c-major-mode-is 'c++-mode)
(cond
((and (or (not (memq res '(t 0)))
(eq (char-after) ?,))
(setq paren-state (c-parse-state))
(setq paren-pos (c-pull-open-brace paren-state))
(eq (char-after paren-pos) ?\())
(goto-char paren-pos)
(setq braceassignp 'c++-noassign
in-paren 'in-paren))
((looking-at c-pre-brace-non-bracelist-key)
(setq braceassignp nil))
((looking-at c-return-key))
((and (looking-at c-symbol-start)
(not (looking-at c-keywords-regexp)))
(if (save-excursion
(and (zerop (c-backward-token-2 1 t lim))
(looking-at c-pre-id-bracelist-key)))
(setq braceassignp 'c++-noassign)
(setq after-type-id-pos (point))))
((eq (char-after) ?\()
(setq parens-before-brace t)
nil)
(t nil))
(save-excursion
(cond
((or (not (memq res '(t 0)))
(eq (char-after) ?,))
(and (setq paren-state (c-parse-state))
(setq paren-pos (c-pull-open-brace paren-state))
(eq (char-after paren-pos) ?\()
(setq in-paren 'in-paren)
(goto-char paren-pos)))
((looking-at c-pre-brace-non-bracelist-key))
((looking-at c-return-key))
((and (looking-at c-symbol-start)
(not (looking-at c-keywords-regexp))
(save-excursion
(and (zerop (c-backward-token-2 1 t lim))
(looking-at c-pre-id-bracelist-key)))))
(t (setq after-type-id-pos (point))
nil))))
(setq braceassignp 'c++-noassign))
(when (and c-opt-inexpr-brace-list-key
(eq (char-after) ?\[))
;; In Java, an initialization brace list may follow
;; directly after "new Foo[]", so check for a "new"
;; earlier.
(while (eq braceassignp 'dontknow)
(setq braceassignp
(cond ((/= (c-backward-token-2 1 t lim) 0) nil)
((looking-at c-opt-inexpr-brace-list-key)
(setq inexpr-brace-list t)
t)
((looking-at "\\sw\\|\\s_\\|[.[]")
;; Carry on looking if this is an
;; identifier (may contain "." in Java)
;; or another "[]" sexp.
'dontknow)
(t nil)))))
(setq pos (point))
(cond
((not braceassignp)
nil)
((and after-type-id-pos
(goto-char after-type-id-pos)
(setq res (c-back-over-member-initializers))
(goto-char res)
(eq (car (c-beginning-of-decl-1 lim)) 'same))
(cons (point) nil)) ; Return value.
((and after-type-id-pos
(progn
(c-backward-syntactic-ws)
(eq (char-before) ?\()))
;; Single identifier between '(' and '{'. We have a bracelist.
(cons after-type-id-pos 'in-paren))
;; Are we at the parens of a C++ lambda expression?
((and parens-before-brace
(save-excursion
(and
(zerop (c-backward-token-2 1 t lim))
(c-looking-at-c++-lambda-capture-list))))
nil) ; a lambda expression isn't a brace list.
(t
(goto-char pos)
(when (eq braceassignp 'dontknow)
(let* ((cache-entry (and containing-sexp
(c-laomib-get-cache containing-sexp)))
(lim2 (or (cadr cache-entry) lim))
sub-bassign-p)
(if cache-entry
(cond
((<= (point) (cadr cache-entry))
;; We're inside the region we've already scanned over, so
;; just go to that scan's end position.
(goto-char (nth 2 cache-entry))
(setq braceassignp (nth 3 cache-entry)))
((> (point) (cadr cache-entry))
;; We're beyond the previous scan region, so just scan as
;; far as the end of that region.
(setq sub-bassign-p (c-laomib-loop lim2))
(if (<= (point) (cadr cache-entry))
(progn
(c-laomib-put-cache containing-sexp
start (nth 2 cache-entry)
(nth 3 cache-entry) ;; sub-bassign-p
)
(setq braceassignp (nth 3 cache-entry))
(goto-char (nth 2 cache-entry)))
(setq braceassignp sub-bassign-p)))
(t))
(setq braceassignp (c-laomib-loop lim))
(when lim
(c-laomib-put-cache lim start (point) braceassignp)))))
(cond
(braceassignp
;; We've hit the beginning of the aggregate list.
(setq pos2 (point))
(cons
(if (eq (c-beginning-of-statement-1 containing-sexp) 'same)
(point)
pos2)
(or in-paren inexpr-brace-list)))
((and after-type-id-pos
(save-excursion
(when (eq (char-after) ?\;)
(c-forward-over-token-and-ws t))
(setq bufpos (point))
(when (looking-at c-opt-<>-sexp-key)
(c-forward-over-token-and-ws)
(when (and (eq (char-after) ?<)
(c-get-char-property (point) 'syntax-table))
(c-go-list-forward nil after-type-id-pos)
(c-forward-syntactic-ws)))
(if (and (not (eq (point) after-type-id-pos))
(or (not (looking-at c-class-key))
(save-excursion
(goto-char (match-end 1))
(c-forward-syntactic-ws)
(not (eq (point) after-type-id-pos)))))
(progn
(setq res
(c-forward-decl-or-cast-1 (c-point 'bosws)
nil nil))
(and (consp res)
(cond
((eq (car res) after-type-id-pos))
((> (car res) after-type-id-pos) nil)
(t
(catch 'find-decl
(save-excursion
(goto-char (car res))
(c-do-declarators
(point-max) t nil nil
(lambda (id-start _id-end _tok _not-top _func _init)
(cond
((> id-start after-type-id-pos)
(throw 'find-decl nil))
((eq id-start after-type-id-pos)
(throw 'find-decl t)))))
nil))))))
(save-excursion
(goto-char start)
(not (c-looking-at-statement-block))))))
(cons bufpos (or in-paren inexpr-brace-list)))
((or (eq (char-after) ?\;)
;; Brace lists can't contain a semicolon, so we're done.
(save-excursion
(c-backward-syntactic-ws)
(eq (char-before) ?}))
;; They also can't contain a bare }, which is probably the end
;; of a function.
)
nil)
((and (setq macro-start (point))
(c-forward-to-cpp-define-body)
(eq (point) start))
;; We've a macro whose expansion starts with the '{'.
;; Heuristically, if we have a ';' in it we've not got a
;; brace list, otherwise we have.
(let ((macro-end (progn (c-end-of-macro) (point))))
(goto-char start)
(forward-char)
(if (and (c-syntactic-re-search-forward "[;,]" macro-end t t)
(eq (char-before) ?\;))
nil
(cons macro-start nil)))) ; (2016-08-30): Lazy! We have no
; languages where
; `c-opt-inexpr-brace-list-key' is
; non-nil and we have macros.
(t t)))) ;; The caller can go up one level.
)))