Function: c-forward-keyword-clause

c-forward-keyword-clause is a byte-compiled function defined in cc-engine.el.gz.

Signature

(c-forward-keyword-clause MATCH &optional STOP-AT-END)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-forward-keyword-clause (match &optional stop-at-end)
  ;; Submatch MATCH in the current match data is assumed to surround a
  ;; token.  If it's a keyword, move over it and any immediately
  ;; following clauses associated with it, stopping either at the start
  ;; of the next token, or (when STOP-AT-END is non-nil) at the end
  ;; of the clause.  t is returned in that case, otherwise the point
  ;; stays and nil is returned.  The kind of clauses that are
  ;; recognized are those specified by `c-type-list-kwds',
  ;; `c-ref-list-kwds', `c-colon-type-list-kwds',
  ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds',
  ;; `c-<>-arglist-kwds', and `c-protection-kwds'.
  ;;
  ;; This function records identifier ranges on
  ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
  ;; `c-record-type-identifiers' is non-nil.
  ;;
  ;; Note that for `c-colon-type-list-kwds', which doesn't necessary
  ;; apply directly after the keyword, the type list is moved over
  ;; only when there is no unaccounted token before it (i.e. a token
  ;; that isn't moved over due to some other keyword list).  The
  ;; identifier ranges in the list are still recorded if that should
  ;; be done, though.
  ;;
  ;; This function might do hidden buffer changes.

  (let ((kwd-sym (c-keyword-sym (match-string match))) safe-pos pos
	;; The call to `c-forward-<>-arglist' below is made after
	;; `c-<>-sexp-kwds' keywords, so we're certain they actually
	;; are angle bracket arglists and `c-restricted-<>-arglists'
	;; should therefore be nil.
	(c-parse-and-markup-<>-arglists t)
	c-restricted-<>-arglists)

    (when kwd-sym
      (goto-char (match-end match))
      (setq safe-pos (point))
      (c-forward-syntactic-ws)

      (cond
       ((and (c-keyword-member kwd-sym 'c-type-list-kwds)
	     (c-forward-keyword-prefixed-id type t))
	;; There's a type directly after a keyword in `c-type-list-kwds'.
	(setq safe-pos (point))
	(c-forward-syntactic-ws)
	(c-forward-id-comma-list type t t))

       ((and (c-keyword-member kwd-sym 'c-ref-list-kwds)
	     (c-forward-keyword-prefixed-id ref t))
	;; There's a name directly after a keyword in `c-ref-list-kwds'.
	(setq safe-pos (point))
	(c-forward-syntactic-ws)
	(c-forward-id-comma-list ref t t))

       ((and (c-keyword-member kwd-sym 'c-paren-any-kwds)
	     (eq (char-after) ?\())
	;; There's an open paren after a keyword in `c-paren-any-kwds'.

	(forward-char)
	(when (and (setq pos (c-up-list-forward))
		   (eq (char-before pos) ?\)))
	  (when (and c-record-type-identifiers
		     (c-keyword-member kwd-sym 'c-paren-type-kwds))
	    ;; Use `c-forward-type' on every identifier we can find
	    ;; inside the paren, to record the types.
	    (while (c-syntactic-re-search-forward c-symbol-start pos t)
	      (goto-char (match-beginning 0))
	      (unless (c-forward-type)
		(looking-at c-symbol-key) ; Always matches.
		(goto-char (match-end 0)))))

	  (goto-char pos)
	  (setq safe-pos (point)))
	  (c-forward-syntactic-ws))

       ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds)
	     (eq (char-after) ?<)
	     (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds)))
	(setq safe-pos (point))
	(c-forward-syntactic-ws))

       ((and (c-keyword-member kwd-sym 'c-nonsymbol-sexp-kwds)
	     (not (looking-at c-symbol-start))
	     (c-safe (c-forward-sexp) t))
	(setq safe-pos (point))
	(c-forward-syntactic-ws))

       ((and (c-keyword-member kwd-sym 'c-protection-kwds)
	     (or (null c-post-protection-token)
		 (and (looking-at c-post-protection-token)
		      (save-excursion
			(goto-char (match-end 0))
			(not (c-end-of-current-token))))))
	(if c-post-protection-token
	    (goto-char (match-end 0)))
	(setq safe-pos (point))
	(c-forward-syntactic-ws)))

      (when (c-keyword-member kwd-sym 'c-colon-type-list-kwds)
	(if (eq (char-after) ?:)
	    ;; If we are at the colon already, we move over the type
	    ;; list after it.
	    (progn
	      (forward-char)
	      (c-forward-syntactic-ws)
	      (when (c-forward-keyword-prefixed-id type t)
		(setq safe-pos (point))
		(c-forward-syntactic-ws)
		(c-forward-id-comma-list type t t)))
	  ;; Not at the colon, so stop here.  But the identifier
	  ;; ranges in the type list later on should still be
	  ;; recorded.
	  (and c-record-type-identifiers
	       (progn
		 ;; If a keyword matched both one of the types above and
		 ;; this one, we move forward to the colon following the
		 ;; clause matched above.
		 (goto-char safe-pos)
		 (c-forward-syntactic-ws)
		 (c-forward-over-colon-type-list))
	       (progn
		 (c-forward-syntactic-ws)
		 (c-forward-keyword-prefixed-id type t))
	       ;; There's a type after the `c-colon-type-list-re' match
	       ;; after a keyword in `c-colon-type-list-kwds'.
	       (c-forward-id-comma-list type nil))))

      (goto-char safe-pos)
      (unless stop-at-end
	(c-forward-syntactic-ws))
      t)))