;;; cc-fonts.el --- font lock support for CC Mode
-;; Copyright (C) 2002-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2002-2016 Free Software Foundation, Inc.
;; Authors: 2003- Alan Mackenzie
;; 2002- Martin Stjernholm
(let* ((re (c-make-keywords-re nil
(c-lang-const c-cpp-include-directives)))
(re-depth (regexp-opt-depth re)))
- `((,(concat noncontinued-line-end
- (c-lang-const c-opt-cpp-prefix)
- re
- (c-lang-const c-syntactic-ws)
- "\\(<[^>\n\r]*>?\\)")
- (,(+ ncle-depth re-depth sws-depth 1)
- font-lock-string-face)
-
- ;; Use an anchored matcher to put paren syntax
- ;; on the brackets.
- (,(byte-compile
- `(lambda (limit)
- (let ((beg (match-beginning
- ,(+ ncle-depth re-depth sws-depth 1)))
- (end (1- (match-end ,(+ ncle-depth re-depth
- sws-depth 1)))))
- (if (eq (char-after end) ?>)
- (progn
- (c-mark-<-as-paren beg)
- (c-mark->-as-paren end))
- (c-unmark-<->-as-paren beg)))
- nil)))))))
+ ;; We used to use a font-lock "anchored matcher" here for
+ ;; the paren syntax. This failed when the ">" was at EOL,
+ ;; since `font-lock-fontify-anchored-keywords' terminated
+ ;; its loop at EOL without executing our lambda form at
+ ;; all.
+ `((,(c-make-font-lock-search-function
+ (concat noncontinued-line-end
+ (c-lang-const c-opt-cpp-prefix)
+ re
+ (c-lang-const c-syntactic-ws)
+ "\\(<[^>\n\r]*>?\\)")
+ `(,(+ ncle-depth re-depth sws-depth 1)
+ font-lock-string-face t)
+ `((let ((beg (match-beginning
+ ,(+ ncle-depth re-depth sws-depth 1)))
+ (end (1- (match-end ,(+ ncle-depth re-depth
+ sws-depth 1)))))
+ (if (eq (char-after end) ?>)
+ (progn
+ (c-mark-<-as-paren beg)
+ (c-mark->-as-paren end))
+ (c-unmark-<->-as-paren beg)))
+ nil))))))
;; #define.
,@(when (c-lang-const c-opt-cpp-macro-define)
c-symbol-key) "\\)"
(concat "\\(" ; 2 + ncle + nsws + c-sym-key
;; Macro with arguments - a "function".
- "\\(\(\\)" ; 3 + ncle + nsws + c-sym-key
+ "\\((\\)" ; 3 + ncle + nsws + c-sym-key
"\\|"
;; Macro without arguments - a "variable".
- "\\([^\(]\\|$\\)"
+ "\\([^(]\\|$\\)"
"\\)"))
`((if (match-beginning
,(+ 3 ncle-depth nsws-depth
;;(message "c-font-lock-declarators from %s to %s" (point) limit)
(c-fontify-types-and-refs
((pos (point)) next-pos id-start id-end
+ decl-res
paren-depth
- id-face got-init
+ id-face got-type got-init
c-last-identifier-range
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start))
brackets-after-id)
;; The following `while' fontifies a single declarator id each time round.
;; It loops only when LIST is non-nil.
(while
- ;; Inside the following "condition form", we move forward over the
- ;; declarator's identifier up as far as any opening bracket (for array
- ;; size) or paren (for parameters of function-type) or brace (for
- ;; array/struct initialization) or "=" or terminating delimiter
- ;; (e.g. "," or ";" or "}").
- (and
- pos
- (< (point) limit)
-
- ;; The following form moves forward over the declarator's
- ;; identifier (and what precedes it), returning t. If there
- ;; wasn't one, it returns nil, terminating the `while'.
- (let (got-identifier)
- (setq paren-depth 0)
- ;; Skip over type decl prefix operators, one for each iteration
- ;; of the while. These are, e.g. "*" in "int *foo" or "(" and
- ;; "*" in "int (*foo) (void)" (Note similar code in
- ;; `c-forward-decl-or-cast-1'.)
- (while (and (looking-at c-type-decl-prefix-key)
- (if (and (c-major-mode-is 'c++-mode)
- (match-beginning 3))
- ;; If the third submatch matches in C++ then
- ;; we're looking at an identifier that's a
- ;; prefix only if it specifies a member pointer.
- (progn
- (setq id-start (point))
- (c-forward-name)
- (if (looking-at "\\(::\\)")
- ;; We only check for a trailing "::" and
- ;; let the "*" that should follow be
- ;; matched in the next round.
- t
- ;; It turned out to be the real identifier,
- ;; so flag that and stop.
- (setq got-identifier t)
- nil))
- t))
- (if (eq (char-after) ?\()
- (progn
- (setq paren-depth (1+ paren-depth))
- (forward-char))
- (goto-char (match-end 1)))
- (c-forward-syntactic-ws))
-
- ;; If we haven't passed the identifier already, do it now.
- (unless got-identifier
- (setq id-start (point))
- (c-forward-name))
- (setq id-end (point))
-
- (/= id-end pos))
-
- ;; Skip out of the parens surrounding the identifier. If closing
- ;; parens are missing, this form returns nil.
- (or (= paren-depth 0)
- (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
-
- (<= (point) limit)
-
- ;; Skip over any trailing bit, such as "__attribute__".
- (progn
- (when (looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1))
- (<= (point) limit))
-
- ;; Search syntactically to the end of the declarator (";",
- ;; ",", a closing paren, eob etc) or to the beginning of an
- ;; initializer or function prototype ("=" or "\\s\(").
- ;; Note that square brackets are now not also treated as
- ;; initializers, since this broke when there were also
- ;; initializing brace lists.
- (let (found)
- (while
- (and (setq found (c-syntactic-re-search-forward
- "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t))
- (eq (char-before) ?\[)
- (c-go-up-list-forward))
- (setq brackets-after-id t))
- found))
-
- (setq next-pos (match-beginning 0)
- id-face (if (and (eq (char-after next-pos) ?\()
- (not brackets-after-id))
+ (and pos (setq decl-res (c-forward-declarator limit)))
+ (setq next-pos (point)
+ id-start (car decl-res)
+ id-face (if (and (eq (char-after) ?\()
+ (not (car (cddr decl-res))) ; brackets-after-id
+ (or (not (c-major-mode-is 'c++-mode))
+ (save-excursion
+ (let (c-last-identifier-range)
+ (forward-char)
+ (c-forward-syntactic-ws)
+ (catch 'is-function
+ (while
+ (progn
+ (if (eq (char-after) ?\))
+ (throw 'is-function t))
+ (setq got-type (c-forward-type))
+ (cond
+ ((null got-type)
+ (throw 'is-function nil))
+ ((not (eq got-type 'maybe))
+ (throw 'is-function t)))
+ (c-forward-declarator limit t)
+ (eq (char-after) ?,))
+ (forward-char)
+ (c-forward-syntactic-ws))
+ t)))))
'font-lock-function-name-face
'font-lock-variable-name-face)
- got-init (and (match-beginning 1)
- (char-after (match-beginning 1))))
+ got-init (and (cadr (cddr decl-res)) ; got-init
+ (char-after)))
(if types
;; Register and fontify the identifier as a type.
(looking-at "{"))
(c-safe (c-forward-sexp) t) ; over { .... }
t)
+ (< (point) limit)
;; FIXME: Should look for c-decl-end markers here;
;; we might go far into the following declarations
;; in e.g. ObjC mode (see e.g. methods-4.m).
(setq pos (point)))))) ; acts to make the `while' form continue.
nil)
-(defconst c-font-lock-maybe-decl-faces
- ;; List of faces that might be put at the start of a type when
- ;; `c-font-lock-declarations' runs. This needs to be evaluated to
- ;; ensure that face name aliases in Emacs are resolved.
- (list nil
- font-lock-type-face
- c-reference-face-name
- font-lock-keyword-face))
-
(defun c-font-lock-declarations (limit)
;; Fontify all the declarations, casts and labels from the point to LIMIT.
;; Assumes that strings and comments have been fontified already.
;; Same as `max-type-decl-*', but used when we're before
;; `token-pos'.
(max-type-decl-end-before-token 0)
+ ;; End of <..> construct which has had c-<>-arg-sep c-type
+ ;; properties set within it.
+ (max-<>-end 0)
;; Set according to the context to direct the heuristics for
;; recognizing C++ templates.
c-restricted-<>-arglists
(c-find-decl-spots
limit
c-decl-start-re
- c-font-lock-maybe-decl-faces
+ (eval c-maybe-decl-faces)
(lambda (match-pos inside-macro)
;; Note to maintainers: don't use `limit' inside this lambda form;
(setq decl-or-cast (c-forward-decl-or-cast-1
match-pos context last-cast-end))
+ ;; Ensure that c-<>-arg-sep c-type properties are in place on the
+ ;; commas separating the arguments inside template/generic <..>s.
+ (when (and (eq (char-before match-pos) ?<)
+ (> match-pos max-<>-end))
+ (save-excursion
+ (goto-char match-pos)
+ (c-backward-token-2)
+ (if (and
+ (eq (char-after) ?<)
+ (let ((c-restricted-<>-arglists
+ (save-excursion
+ (c-backward-token-2)
+ (and
+ (not (looking-at c-opt-<>-sexp-key))
+ (progn (c-backward-syntactic-ws)
+ (memq (char-before) '(?\( ?,)))
+ (not (eq (c-get-char-property (1- (point))
+ 'c-type)
+ 'c-decl-arg-start))))))
+ (c-forward-<>-arglist nil)))
+ (setq max-<>-end (point)))))
+
(cond
((eq decl-or-cast 'cast)
;; Save the position after the previous cast so we can feed
(unless (c-skip-comments-and-strings limit)
(c-forward-syntactic-ws)
;; Handle prefix declaration specifiers.
- (when (or (looking-at c-prefix-spec-kwds-re)
- (and (c-major-mode-is 'java-mode)
- (looking-at "@[A-Za-z0-9]+")))
- (c-forward-keyword-clause 1))
+ (while
+ (or
+ (when (or (looking-at c-prefix-spec-kwds-re)
+ (and (c-major-mode-is 'java-mode)
+ (looking-at "@[A-Za-z0-9]+")))
+ (c-forward-keyword-clause 1)
+ t)
+ (when (looking-at c-noise-macro-with-parens-name-re)
+ (c-forward-noise-clause)
+ t)))
,(if (c-major-mode-is 'c++-mode)
`(when (and (c-forward-type)
(eq (char-after) ?=))
;; "\\|"
;; (c-lang-const c-symbol-key)
;; "\\)")
-;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face';
-;; ; `t' would mean `font-lock-function-name-face'.
+;; `((c-font-lock-declarators limit t nil) ; That nil says use `font-lock-variable-name-face';
+;; ; t would mean `font-lock-function-name-face'.
;; (progn
;; (c-put-char-property (match-beginning 0) 'c-type
;; 'c-decl-id-start)
"\\)\\>"
;; Disallow various common punctuation chars that can't come
;; before the '{' of the enum list, to avoid searching too far.
- "[^\]\[{}();/#=]*"
+ "[^][{};/#=]*"
"{")
'((c-font-lock-declarators limit t nil)
(save-match-data
(cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
(assq 'other c-doc-comment-style)))
c-doc-comment-style))
- (list (nconc (apply 'nconc
- (mapcar
- (lambda (doc-style)
- (let ((sym (intern
- (concat (symbol-name doc-style)
- "-font-lock-keywords"))))
- (cond ((fboundp sym)
- (funcall sym))
- ((boundp sym)
- (append (eval sym) nil)))))
- (if (listp doc-keywords)
- doc-keywords
- (list doc-keywords))))
+ (list (nconc (c--mapcan
+ (lambda (doc-style)
+ (let ((sym (intern
+ (concat (symbol-name doc-style)
+ "-font-lock-keywords"))))
+ (cond ((fboundp sym)
+ (funcall sym))
+ ((boundp sym)
+ (append (eval sym) nil)))))
+ (if (listp doc-keywords)
+ doc-keywords
+ (list doc-keywords)))
base-list)))
;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we
(unless (looking-at
(cc-eval-when-compile
(concat (c-lang-const c-symbol-start c++)
- "\\|[*:\)\[]")))
+ "\\|[*:)[]")))
;; There's something after the would-be type that
;; can't be there, so this is a placement arglist.
(setq expr1-res nil)))
(unless (looking-at
(cc-eval-when-compile
(concat (c-lang-const c-symbol-start c++)
- "\\|[*:\)\[]")))
+ "\\|[*:)[]")))
;; There's something after the would-be type that can't
;; be there, so this is an initialization expression.
(setq expr2-res nil))
nil)
(defconst autodoc-font-lock-doc-comments
- `(("@\\(\\w+{\\|\\[\\([^\]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)"
+ `(("@\\(\\w+{\\|\\[\\([^]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)"
;; In-text markup.
0 ,c-doc-markup-face-name prepend nil)
(autodoc-font-lock-line-markup)
;; 2006-07-10: awk-font-lock-keywords has been moved back to cc-awk.el.
(cc-provide 'cc-fonts)
-;;; Local Variables:
-;;; indent-tabs-mode: t
-;;; tab-width: 8
-;;; End:
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
;;; cc-fonts.el ends here