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-fun-name-substitute-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)
		 ;; Have we a requires with a parenthesis list?
		 (when (save-excursion
			 (and (zerop (c-backward-token-2 1 nil lim))
			      (looking-at c-fun-name-substitute-key)))
		   (setq braceassignp nil))
		 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.
      )))