Function: c-get-fontification-context

c-get-fontification-context is a byte-compiled function defined in cc-fonts.el.gz.

Signature

(c-get-fontification-context MATCH-POS NOT-FRONT-DECL &optional TOPLEV)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-fonts.el.gz
(defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
  ;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS.
  ;; NOT-FRONT-DECL is non-nil when a declaration later in the buffer than
  ;; MATCH-POS has already been parsed.  TOPLEV is non-nil when MATCH-POS is
  ;; known to be at "top level", i.e. outside any braces, or directly inside a
  ;; namespace, class, etc.
  ;;
  ;; CONTEXT is the fontification context of MATCH-POS, and is one of the
  ;; following:
  ;; 'decl     In a comma-separated declaration context (typically
  ;;           inside a function declaration arglist).
  ;; '<>       In an angle bracket arglist.
  ;; 'arglist  Some other type of arglist.
  ;; 'generic  In a C11 _Generic construct.
  ;; 'top      Some other context and point is at the top-level (either
  ;;           outside any braces or directly inside a class or namespace,
  ;;           etc.)
  ;; nil       Some other context or unknown context.  Includes
  ;;           within the parens of an if, for, ... construct.
  ;; 'not-decl Definitely not in a declaration.
  ;;
  ;; RESTRICTED-<>-ARGLISTS is non-nil when a scan of template/generic
  ;; arguments lists (i.e. lists enclosed by <...>) is more strict about what
  ;; characters it allows within the list.
  (let ((type (and (> match-pos (point-min))
		   (c-get-char-property (1- match-pos) 'c-type)))
	id-pos)
    (cond
     ;; Are we just after something like "(foo((bar))" ?
     ((and (eq (char-before match-pos) ?\))
	   (c-go-list-backward match-pos)
	   (progn
	     (c-backward-syntactic-ws)
	     (and (setq id-pos (c-on-identifier))
		  (goto-char id-pos)
		  (progn
		    (c-backward-syntactic-ws)
		    (eq (char-before) ?\()))))
      (c-get-fontification-context (point) not-front-decl toplev))
     ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
      (cons (and toplev 'top) nil))
     ;; A control flow expression or a decltype
     ((and (eq (char-before match-pos) ?\()
	   (save-excursion
	     (goto-char match-pos)
	     (backward-char)
	     (c-backward-token-2)
	     (cond
	      ((looking-at c-paren-stmt-key)
	       ;; Allow comma separated <> arglists in for statements.
	       (cons nil nil))
	      ((or (looking-at c-block-stmt-2-key)
		   (looking-at c-block-stmt-1-2-key)
		   (looking-at c-typeof-key))
	       (cons nil t))
	      (t nil)))))
     ;; Near BOB.
     ((<= match-pos (point-min))
      (cons 'arglist t))
     ;; Got a cached hit in a declaration arglist.
     ((eq type 'c-decl-arg-start)
      (cons 'decl nil))
     ;; We're inside (probably) a brace list.
     ((eq type 'c-not-decl)
      (cons 'not-decl nil))
     ;; Inside a C++11 lambda function arglist.
     ((and (c-major-mode-is 'c++-mode)
	   (eq (char-before match-pos) ?\()
	   (save-excursion
	     (goto-char match-pos)
	     (c-backward-token-2)
	     (and
	      (c-safe (goto-char (scan-sexps (point) -1)))
	      (c-looking-at-c++-lambda-capture-list))))
      (c-put-char-property (1- match-pos) 'c-type
			   'c-decl-arg-start)
      (cons 'decl nil))
     ;; We're inside a brace list.
     ((and (eq (char-before match-pos) ?{)
	   (c-inside-bracelist-p (1- match-pos)
				 (cdr (c-parse-state))
				 nil))
      (c-put-char-property (1- match-pos) 'c-type
			   'c-not-decl)
      (cons 'not-decl nil))
     ;; We're inside an "ordinary" open brace.
     ((eq (char-before match-pos) ?{)
      (cons (and toplev 'top) nil))
     ;; Inside an angle bracket arglist.
     ((or (eq type 'c-<>-arg-sep)
	  (eq (char-before match-pos) ?<))
      (cons '<> nil))
     ;; Got a cached hit in some other type of arglist.
     (type
      (cons 'arglist t))
     ;; We're at a C++ uniform initialization.
     ((and (c-major-mode-is 'c++-mode)
	   (eq (char-before match-pos) ?\()
	   (save-excursion
	     (goto-char match-pos)
	     (and
	      (zerop (c-backward-token-2 2))
	      (looking-at c-identifier-start)
	      (c-got-face-at (point)
			     '(font-lock-variable-name-face)))))
      (cons 'not-decl nil))
     ((and not-front-decl
	   ;; The point is within the range of a previously
	   ;; encountered type decl expression, so the arglist
	   ;; is probably one that contains declarations.
	   ;; However, if `c-recognize-paren-inits' is set it
	   ;; might also be an initializer arglist.
	   (or (not c-recognize-paren-inits)
	       (save-excursion
		 (goto-char match-pos)
		 (not (c-back-over-member-initializers)))))
      ;; The result of this check is cached with a char
      ;; property on the match token, so that we can look
      ;; it up again when refontifying single lines in a
      ;; multiline declaration.
      (c-put-char-property (1- match-pos)
			   'c-type 'c-decl-arg-start)
      (cons 'decl nil))
     ;; Got (an) open paren(s) preceded by an arith operator.
     ((and (eq (char-before match-pos) ?\()
	   (save-excursion
	     (goto-char match-pos)
	     (while
		 (and (zerop (c-backward-token-2))
		      (eq (char-after) ?\()))
	     (looking-at c-arithmetic-op-regexp)))
      (cons nil nil))
     ;; In a C++ member initialization list.
     ((and (eq (char-before match-pos) ?,)
	   (c-major-mode-is 'c++-mode)
	   (save-excursion
	     (goto-char match-pos)
	     (c-back-over-member-initializers)))
      (c-put-char-property (1- match-pos) 'c-type 'c-not-decl)
      (cons 'not-decl nil))
     ;; In a C11 _Generic construct.
     ((and c-generic-key
	   (eq (char-before match-pos) ?,)
	   (save-excursion
	     (and (c-go-up-list-backward match-pos
					 (max (- (point) 2000) (point-min)))
		  (zerop (c-backward-token-2))
		  (looking-at c-generic-key))))
      (cons 'generic nil))
     ;; At start of a declaration inside a declaration paren.
     ((save-excursion
	(goto-char match-pos)
	(and (memq (char-before match-pos) '(?\( ?\,))
	     (c-go-up-list-backward match-pos
					; c-determine-limit is too slow, here.
				    (max (- (point) 2000) (point-min)))
	     (eq (char-after) ?\()
	     (let ((type (c-get-char-property (point) 'c-type)))
	       (or (memq type '(c-decl-arg-start c-decl-type-start))
		   (progn
		     (c-backward-syntactic-ws)
		     (cond
		      ((and toplev
			    (eq (char-before) ?\)))
		       (save-excursion
			 (and (c-go-list-backward nil (max (- (point) 2000)
							   (point-min)))
			      (eq (char-after) ?\()
			      (progn (c-backward-syntactic-ws)
				     (c-back-over-compound-identifier)))))
		      ((save-excursion
			 (and
			  (c-back-over-compound-identifier)
			  (progn
			    (c-backward-syntactic-ws)
			    (or (bobp)
				(progn
				  (setq type (c-get-char-property (1- (point))
								  'c-type))
				  (memq type '(c-decl-arg-start
					       c-decl-type-start))))))))
		      ((and (zerop (c-backward-token-2))
			    (looking-at c-fun-name-substitute-key)
			    (not (eq (char-after (match-end 0)) ?_))))))))))
      ;; Cache the result of this test for next time around.
      (c-put-char-property (1- match-pos) 'c-type 'c-decl-arg-start)
      (cons 'decl nil))
     (t (cons 'arglist t)))))