Add "Package:" file headers to denote built-in packages.
[bpt/emacs.git] / lisp / progmodes / cc-fonts.el
CommitLineData
d9e94c22
MS
1;;; cc-fonts.el --- font lock support for CC Mode
2
114f9c96 3;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
d9e94c22
MS
4
5;; Authors: 2003- Alan Mackenzie
6;; 2002- Martin Stjernholm
7;; Maintainer: bug-cc-mode@gnu.org
8;; Created: 07-Jan-2002
bd78fa1d
CY
9;; Keywords: c languages
10;; Package: cc-mode
d9e94c22
MS
11
12;; This file is part of GNU Emacs.
13
b1fc2b50 14;; GNU Emacs is free software: you can redistribute it and/or modify
d9e94c22 15;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
d9e94c22
MS
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
b1fc2b50 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
d9e94c22
MS
26
27;;; Commentary:
28
29;; Some comments on the use of faces:
30;;
0386b551
AM
31;; o `c-label-face-name' is either `font-lock-constant-face' (in
32;; Emacs), or `font-lock-reference-face'.
d9e94c22
MS
33;;
34;; o `c-constant-face-name', `c-reference-face-name' and
35;; `c-doc-markup-face-name' are essentially set up like
36;; `c-label-face-name'.
37;;
38;; o `c-preprocessor-face-name' is `font-lock-preprocessor-face' in
39;; XEmacs and - in lack of a closer equivalent -
40;; `font-lock-builtin-face' or `font-lock-reference-face' in Emacs.
41;;
42;; o `c-doc-face-name' is `font-lock-doc-string-face' in XEmacs,
43;; `font-lock-doc-face' in Emacs 21 and later, or
44;; `font-lock-comment-face' in older Emacs (that since source
45;; documentation are actually comments in these languages, as opposed
46;; to elisp).
47;;
d9e94c22
MS
48;; TBD: We should probably provide real faces for the above uses and
49;; instead initialize them from the standard faces.
50
51;;; Code:
52
53;; The faces that already have been put onto the text is tested in
54;; various places to direct further fontifications. For this to work,
55;; the following assumptions regarding the faces must hold (apart from
56;; the dependencies on the font locking order):
57;;
58;; o `font-lock-comment-face' and the face in `c-doc-face-name' is
59;; not used in anything but comments.
60;; o If any face (e.g. `c-doc-markup-face-name') but those above is
61;; used in comments, it doesn't replace them.
62;; o `font-lock-string-face' is not used in anything but string
63;; literals (single or double quoted).
64;; o `font-lock-keyword-face' and the face in `c-label-face-name' are
65;; never overlaid with other faces.
66
67(eval-when-compile
68 (let ((load-path
69 (if (and (boundp 'byte-compile-dest-file)
70 (stringp byte-compile-dest-file))
71 (cons (file-name-directory byte-compile-dest-file) load-path)
72 load-path)))
73 (load "cc-bytecomp" nil t)))
74
75(cc-require 'cc-defs)
76(cc-require-when-compile 'cc-langs)
77(cc-require 'cc-vars)
78(cc-require 'cc-engine)
79(cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to
80;; prevent cc-awk being loaded when it's not needed. There is now a (require
81;; 'cc-awk) in (defun awk-mode ..).
82
83;; Avoid repeated loading through the eval-after-load directive in
84;; cc-mode.el.
85(provide 'cc-fonts)
86
87(cc-external-require 'font-lock)
88
89(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only.
90
91;; Need to declare these local symbols during compilation since
92;; they're referenced from lambdas in `byte-compile' calls that are
93;; executed at compile time. They don't need to have the proper
94;; definitions, though, since the generated functions aren't called
95;; during compilation.
96(cc-bytecomp-defvar c-preprocessor-face-name)
97(cc-bytecomp-defvar c-reference-face-name)
98(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
99(cc-bytecomp-defun c-font-lock-declarators)
d9e94c22
MS
100(cc-bytecomp-defun c-font-lock-objc-method)
101(cc-bytecomp-defun c-font-lock-invalid-string)
102
d9e94c22
MS
103\f
104;; Note that font-lock in XEmacs doesn't expand face names as
105;; variables, so we have to use the (eval . FORM) in the font lock
106;; matchers wherever we use these alias variables.
107
108(defconst c-preprocessor-face-name
109 (cond ((c-face-name-p 'font-lock-preprocessor-face)
110 ;; XEmacs has a font-lock-preprocessor-face.
111 'font-lock-preprocessor-face)
112 ((c-face-name-p 'font-lock-builtin-face)
0386b551
AM
113 ;; In Emacs font-lock-builtin-face has traditionally been
114 ;; used for preprocessor directives.
d9e94c22
MS
115 'font-lock-builtin-face)
116 (t
117 'font-lock-reference-face)))
118
119(cc-bytecomp-defvar font-lock-constant-face)
120
121(defconst c-label-face-name
122 (cond ((c-face-name-p 'font-lock-label-face)
123 ;; If it happens to occur in the future. (Well, the more
124 ;; pragmatic reason is to get unique faces for the test
125 ;; suite.)
126 'font-lock-label-face)
127 ((and (c-face-name-p 'font-lock-constant-face)
128 (eq font-lock-constant-face 'font-lock-constant-face))
129 ;; Test both if font-lock-constant-face exists and that it's
130 ;; not an alias for something else. This is important since
131 ;; we compare already set faces in various places.
132 'font-lock-constant-face)
133 (t
134 'font-lock-reference-face)))
135
136(defconst c-constant-face-name
137 (if (and (c-face-name-p 'font-lock-constant-face)
138 (eq font-lock-constant-face 'font-lock-constant-face))
0386b551 139 ;; This doesn't exist in some earlier versions of XEmacs 21.
d9e94c22
MS
140 'font-lock-constant-face
141 c-label-face-name))
142
143(defconst c-reference-face-name
0386b551
AM
144 (with-no-warnings
145 (if (and (c-face-name-p 'font-lock-reference-face)
146 (eq font-lock-reference-face 'font-lock-reference-face))
147 ;; This is considered obsolete in Emacs, but it still maps well
148 ;; to this use. (Another reason to do this is to get unique
149 ;; faces for the test suite.)
150 'font-lock-reference-face
151 c-label-face-name)))
d9e94c22
MS
152
153;; This should not mapped to a face that also is used to fontify things
154;; that aren't comments or string literals.
155(defconst c-doc-face-name
156 (cond ((c-face-name-p 'font-lock-doc-string-face)
157 ;; XEmacs.
158 'font-lock-doc-string-face)
159 ((c-face-name-p 'font-lock-doc-face)
160 ;; Emacs 21 and later.
161 'font-lock-doc-face)
162 (t
163 'font-lock-comment-face)))
164
165(defconst c-doc-markup-face-name
166 (if (c-face-name-p 'font-lock-doc-markup-face)
167 ;; If it happens to occur in the future. (Well, the more
168 ;; pragmatic reason is to get unique faces for the test
169 ;; suite.)
170 'font-lock-doc-markup-face
171 c-label-face-name))
172
0386b551
AM
173(defconst c-negation-char-face-name
174 (if (c-face-name-p 'font-lock-negation-char-face)
175 ;; Emacs 22 has a special face for negation chars.
176 'font-lock-negation-char-face))
d9e94c22
MS
177
178(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
179(cc-bytecomp-defun face-property-instance) ; Only in XEmacs.
180
181(defun c-make-inverse-face (oldface newface)
182 ;; Emacs and XEmacs have completely different face manipulation
183 ;; routines. :P
d9e94c22
MS
184 (copy-face oldface newface)
185 (cond ((fboundp 'face-inverse-video-p)
0386b551
AM
186 ;; Emacs. This only looks at the inverse flag in the current
187 ;; frame. Other display configurations might be different,
188 ;; but it can only show if the same Emacs has frames on
189 ;; e.g. a color and a monochrome display simultaneously.
d9e94c22
MS
190 (unless (face-inverse-video-p oldface)
191 (invert-face newface)))
192 ((fboundp 'face-property-instance)
193 ;; XEmacs. Same pitfall here.
194 (unless (face-property-instance oldface 'reverse)
0386b551 195 (invert-face newface)))))
d9e94c22 196
452ea855
AM
197(defvar c-annotation-face (make-face 'c-annotation-face)
198 "Face used to highlight annotations in java-mode and other modes that may wish to use it.")
199(set-face-foreground 'c-annotation-face "blue")
200
d9e94c22
MS
201(eval-and-compile
202 ;; We need the following functions during compilation since they're
203 ;; called when the `c-lang-defconst' initializers are evaluated.
204 ;; Define them at runtime too for the sake of derived modes.
205
206 (defmacro c-put-font-lock-face (from to face)
207 ;; Put a face on a region (overriding any existing face) in the way
208 ;; font-lock would do it. In XEmacs that means putting an
209 ;; additional font-lock property, or else the font-lock package
210 ;; won't recognize it as fontified and might override it
211 ;; incorrectly.
0386b551
AM
212 ;;
213 ;; This function does a hidden buffer change.
d9e94c22
MS
214 (if (fboundp 'font-lock-set-face)
215 ;; Note: This function has no docstring in XEmacs so it might be
216 ;; considered internal.
217 `(font-lock-set-face ,from ,to ,face)
218 `(put-text-property ,from ,to 'face ,face)))
219
220 (defmacro c-remove-font-lock-face (from to)
221 ;; This is the inverse of `c-put-font-lock-face'.
0386b551
AM
222 ;;
223 ;; This function does a hidden buffer change.
d9e94c22
MS
224 (if (fboundp 'font-lock-remove-face)
225 `(font-lock-remove-face ,from ,to)
226 `(remove-text-properties ,from ,to '(face nil))))
227
228 (defmacro c-put-font-lock-string-face (from to)
229 ;; Put `font-lock-string-face' on a string. The surrounding
230 ;; quotes are included in Emacs but not in XEmacs. The passed
231 ;; region should include them.
0386b551
AM
232 ;;
233 ;; This function does a hidden buffer change.
d9e94c22
MS
234 (if (featurep 'xemacs)
235 `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
236 `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
237
238 (defmacro c-fontify-types-and-refs (varlist &rest body)
239 ;; Like `let', but additionally activates `c-record-type-identifiers'
240 ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
241 ;; accordingly on exit.
0386b551
AM
242 ;;
243 ;; This function does hidden buffer changes.
d9e94c22
MS
244 `(let ((c-record-type-identifiers t)
245 c-record-ref-identifiers
246 ,@varlist)
247 (prog1 (progn ,@body)
248 (c-fontify-recorded-types-and-refs))))
249 (put 'c-fontify-types-and-refs 'lisp-indent-function 1)
d9e94c22
MS
250
251 (defun c-skip-comments-and-strings (limit)
252 ;; If the point is within a region fontified as a comment or
253 ;; string literal skip to the end of it or to LIMIT, whichever
254 ;; comes first, and return t. Otherwise return nil. The match
255 ;; data is not clobbered.
0386b551
AM
256 ;;
257 ;; This function might do hidden buffer changes.
d9e94c22
MS
258 (when (c-got-face-at (point) c-literal-faces)
259 (while (progn
260 (goto-char (next-single-property-change
261 (point) 'face nil limit))
262 (and (< (point) limit)
263 (c-got-face-at (point) c-literal-faces))))
264 t))
265
0386b551
AM
266 (defun c-make-syntactic-matcher (regexp)
267 ;; Returns a byte compiled function suitable for use in place of a
268 ;; regexp string in a `font-lock-keywords' matcher, except that
269 ;; only matches outside comments and string literals count.
270 ;;
271 ;; This function does not do any hidden buffer changes, but the
272 ;; generated functions will. (They are however used in places
273 ;; covered by the font-lock context.)
274 (byte-compile
275 `(lambda (limit)
276 (let (res)
277 (while (and (setq res (re-search-forward ,regexp limit t))
278 (progn
279 (goto-char (match-beginning 0))
280 (or (c-skip-comments-and-strings limit)
281 (progn
282 (goto-char (match-end 0))
283 nil)))))
284 res))))
285
d9e94c22
MS
286 (defun c-make-font-lock-search-function (regexp &rest highlights)
287 ;; This function makes a byte compiled function that works much like
288 ;; a matcher element in `font-lock-keywords'. It cuts out a little
289 ;; bit of the overhead compared to a real matcher. The main reason
290 ;; is however to pass the real search limit to the anchored
291 ;; matcher(s), since most (if not all) font-lock implementations
292 ;; arbitrarily limits anchored matchers to the same line, and also
293 ;; to insulate against various other irritating differences between
294 ;; the different (X)Emacs font-lock packages.
295 ;;
296 ;; REGEXP is the matcher, which must be a regexp. Only matches
297 ;; where the beginning is outside any comment or string literal are
298 ;; significant.
299 ;;
300 ;; HIGHLIGHTS is a list of highlight specs, just like in
301 ;; `font-lock-keywords', with these limitations: The face is always
302 ;; overridden (no big disadvantage, since hits in comments etc are
303 ;; filtered anyway), there is no "laxmatch", and an anchored matcher
304 ;; is always a form which must do all the fontification directly.
305 ;; `limit' is a variable bound to the real limit in the context of
306 ;; the anchored matcher forms.
307 ;;
308 ;; This function does not do any hidden buffer changes, but the
0386b551
AM
309 ;; generated functions will. (They are however used in places
310 ;; covered by the font-lock context.)
d9e94c22
MS
311
312 ;; Note: Replace `byte-compile' with `eval' to debug the generated
313 ;; lambda easier.
314 (byte-compile
315 `(lambda (limit)
0386b551 316 (let (;; The font-lock package in Emacs is known to clobber
d9e94c22
MS
317 ;; `parse-sexp-lookup-properties' (when it exists).
318 (parse-sexp-lookup-properties
319 (cc-eval-when-compile
320 (boundp 'parse-sexp-lookup-properties))))
321 (while (re-search-forward ,regexp limit t)
d9e94c22
MS
322 (unless (progn
323 (goto-char (match-beginning 0))
324 (c-skip-comments-and-strings limit))
0386b551 325 (goto-char (match-end 0))
d9e94c22
MS
326 ,@(mapcar
327 (lambda (highlight)
328 (if (integerp (car highlight))
329 (progn
0386b551 330 (unless (eq (nth 2 highlight) t)
d9e94c22 331 (error
0386b551 332 "The override flag must currently be t in %s"
d9e94c22
MS
333 highlight))
334 (when (nth 3 highlight)
335 (error
336 "The laxmatch flag may currently not be set in %s"
337 highlight))
338 `(save-match-data
339 (c-put-font-lock-face
340 (match-beginning ,(car highlight))
341 (match-end ,(car highlight))
342 ,(elt highlight 1))))
343 (when (nth 3 highlight)
344 (error "Match highlights currently not supported in %s"
345 highlight))
346 `(progn
347 ,(nth 1 highlight)
348 (save-match-data ,(car highlight))
349 ,(nth 2 highlight))))
350 highlights))))
0386b551
AM
351 nil)))
352
3c0ab532
AM
353; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
354; '(progn
355 (def-edebug-spec c-fontify-types-and-refs let*)
356 (def-edebug-spec c-make-syntactic-matcher t)
357 ;; If there are literal quoted or backquoted highlight specs in
358 ;; the call to `c-make-font-lock-search-function' then let's
359 ;; instrument the forms in them.
360 (def-edebug-spec c-make-font-lock-search-function
361 (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)));))
d9e94c22
MS
362
363(defun c-fontify-recorded-types-and-refs ()
0386b551 364 ;; Convert the ranges recorded on `c-record-type-identifiers' and
d9e94c22 365 ;; `c-record-ref-identifiers' to fontification.
0386b551
AM
366 ;;
367 ;; This function does hidden buffer changes.
d9e94c22
MS
368 (let (elem)
369 (while (consp c-record-type-identifiers)
370 (setq elem (car c-record-type-identifiers)
371 c-record-type-identifiers (cdr c-record-type-identifiers))
372 (c-put-font-lock-face (car elem) (cdr elem)
373 'font-lock-type-face))
374 (while c-record-ref-identifiers
375 (setq elem (car c-record-ref-identifiers)
376 c-record-ref-identifiers (cdr c-record-ref-identifiers))
377 ;; Note that the reference face is a variable that is
378 ;; dereferenced, since it's an alias in Emacs.
379 (c-put-font-lock-face (car elem) (cdr elem)
380 c-reference-face-name))))
381
382(c-lang-defconst c-cpp-matchers
383 "Font lock matchers for preprocessor directives and purely lexical
384stuff. Used on level 1 and higher."
385
386 ;; Note: `c-font-lock-declarations' assumes that no matcher here
387 ;; sets `font-lock-type-face' in languages where
388 ;; `c-recognize-<>-arglists' is set.
389
390 t `(,@(when (c-lang-const c-opt-cpp-prefix)
391 (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
0386b551
AM
392 (ncle-depth (regexp-opt-depth noncontinued-line-end))
393 (sws-depth (c-lang-const c-syntactic-ws-depth))
394 (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
395
d9e94c22
MS
396 `(;; The stuff after #error and #warning is a message, so
397 ;; fontify it as a string.
0386b551 398 ,@(when (c-lang-const c-cpp-message-directives)
2ae6c6b5 399 (let* ((re (c-make-keywords-re 'appendable ; nil
0386b551
AM
400 (c-lang-const c-cpp-message-directives)))
401 (re-depth (regexp-opt-depth re)))
402 `((,(concat noncontinued-line-end
403 (c-lang-const c-opt-cpp-prefix)
404 re
405 "\\s +\\(.*\\)$")
2ae6c6b5 406 ,(+ ncle-depth re-depth 1) font-lock-string-face t))))
d9e94c22
MS
407
408 ;; Fontify filenames in #include <...> as strings.
0386b551
AM
409 ,@(when (c-lang-const c-cpp-include-directives)
410 (let* ((re (c-make-keywords-re nil
411 (c-lang-const c-cpp-include-directives)))
412 (re-depth (regexp-opt-depth re)))
413 `((,(concat noncontinued-line-end
414 (c-lang-const c-opt-cpp-prefix)
415 re
416 (c-lang-const c-syntactic-ws)
417 "\\(<[^>\n\r]*>?\\)")
418 (,(+ ncle-depth re-depth sws-depth 1)
419 font-lock-string-face)
420
421 ;; Use an anchored matcher to put paren syntax
422 ;; on the brackets.
423 (,(byte-compile
424 `(lambda (limit)
425 (let ((beg (match-beginning
426 ,(+ ncle-depth re-depth sws-depth 1)))
427 (end (1- (match-end ,(+ ncle-depth re-depth
428 sws-depth 1)))))
429 (if (eq (char-after end) ?>)
430 (progn
431 (c-mark-<-as-paren beg)
432 (c-mark->-as-paren end))
0ec1d2c5
AM
433 ;; (c-clear-char-property beg 'syntax-table)
434 (c-clear-char-property beg 'category)))
0386b551 435 nil)))))))
d9e94c22
MS
436
437 ;; #define.
0386b551
AM
438 ,@(when (c-lang-const c-opt-cpp-macro-define)
439 `((,(c-make-font-lock-search-function
440 (concat
441 noncontinued-line-end
442 (c-lang-const c-opt-cpp-prefix)
443 (c-lang-const c-opt-cpp-macro-define)
444 (c-lang-const c-nonempty-syntactic-ws)
445 "\\(" (c-lang-const ; 1 + ncle + nsws
446 c-symbol-key) "\\)"
447 (concat "\\(" ; 2 + ncle + nsws + c-sym-key
448 ;; Macro with arguments - a "function".
449 "\\(\(\\)" ; 3 + ncle + nsws + c-sym-key
450 "\\|"
451 ;; Macro without arguments - a "variable".
452 "\\([^\(]\\|$\\)"
453 "\\)"))
454 `((if (match-beginning
455 ,(+ 3 ncle-depth nsws-depth
456 (c-lang-const c-symbol-key-depth)))
457
458 ;; "Function". Fontify the name and the arguments.
459 (save-restriction
460 (c-put-font-lock-face
461 (match-beginning ,(+ 1 ncle-depth nsws-depth))
462 (match-end ,(+ 1 ncle-depth nsws-depth))
463 'font-lock-function-name-face)
464 (goto-char
465 (match-end
466 ,(+ 3 ncle-depth nsws-depth
467 (c-lang-const c-symbol-key-depth))))
468
469 (narrow-to-region (point-min) limit)
470 (while (and
471 (progn
472 (c-forward-syntactic-ws)
473 (looking-at c-symbol-key))
474 (progn
475 (c-put-font-lock-face
476 (match-beginning 0) (match-end 0)
477 'font-lock-variable-name-face)
478 (goto-char (match-end 0))
479 (c-forward-syntactic-ws)
480 (eq (char-after) ?,)))
481 (forward-char)))
482
483 ;; "Variable".
484 (c-put-font-lock-face
485 (match-beginning ,(+ 1 ncle-depth nsws-depth))
486 (match-end ,(+ 1 ncle-depth nsws-depth))
487 'font-lock-variable-name-face)))))))
d9e94c22
MS
488
489 ;; Fontify cpp function names in preprocessor
490 ;; expressions in #if and #elif.
0386b551
AM
491 ,@(when (and (c-lang-const c-cpp-expr-directives)
492 (c-lang-const c-cpp-expr-functions))
493 (let ((ced-re (c-make-keywords-re t
494 (c-lang-const c-cpp-expr-directives)))
495 (cef-re (c-make-keywords-re t
496 (c-lang-const c-cpp-expr-functions))))
497 `((,(c-make-font-lock-search-function
498 (concat noncontinued-line-end
499 (c-lang-const c-opt-cpp-prefix)
500 ced-re ; 1 + ncle-depth
501 ;; Match the whole logical line to look
502 ;; for the functions in.
503 "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")
504 `((let ((limit (match-end 0)))
505 (while (re-search-forward ,cef-re limit 'move)
506 (c-put-font-lock-face (match-beginning 1)
507 (match-end 1)
508 c-preprocessor-face-name)))
509 (goto-char (match-end ,(1+ ncle-depth)))))))))
d9e94c22
MS
510
511 ;; Fontify the directive names.
512 (,(c-make-font-lock-search-function
513 (concat noncontinued-line-end
514 "\\("
515 (c-lang-const c-opt-cpp-prefix)
516 "[" (c-lang-const c-symbol-chars) "]+"
517 "\\)")
518 `(,(1+ ncle-depth) c-preprocessor-face-name t)))
bd8cf505 519
0386b551
AM
520 (eval . (list ,(c-make-syntactic-matcher
521 (concat noncontinued-line-end
522 (c-lang-const c-opt-cpp-prefix)
523 "if\\(n\\)def\\>"))
524 ,(+ ncle-depth 1)
525 c-negation-char-face-name
526 'append))
d9e94c22
MS
527 )))
528
529 ,@(when (c-major-mode-is 'pike-mode)
0386b551 530 ;; Recognize hashbangs in Pike.
d9e94c22
MS
531 `((eval . (list "\\`#![^\n\r]*"
532 0 c-preprocessor-face-name))))
533
0386b551 534 ;; Make hard spaces visible through an inverted `font-lock-warning-face'.
d9e94c22
MS
535 (eval . (list
536 "\240"
537 0 (progn
0386b551
AM
538 (unless (c-face-name-p 'c-nonbreakable-space-face)
539 (c-make-inverse-face 'font-lock-warning-face
540 'c-nonbreakable-space-face))
541 ''c-nonbreakable-space-face)))
d9e94c22
MS
542 ))
543
544(defun c-font-lock-invalid-string ()
545 ;; Assuming the point is after the opening character of a string,
0386b551 546 ;; fontify that char with `font-lock-warning-face' if the string
a6782a6e 547 ;; decidedly isn't terminated properly.
0386b551
AM
548 ;;
549 ;; This function does hidden buffer changes.
a6782a6e
MS
550 (let ((start (1- (point))))
551 (save-excursion
0386b551
AM
552 (and (eq (elt (parse-partial-sexp start (c-point 'eol)) 8) start)
553 (if (integerp c-multiline-string-start-char)
554 ;; There's no multiline string start char before the
555 ;; string, so newlines aren't allowed.
556 (not (eq (char-before start) c-multiline-string-start-char))
557 ;; Multiline strings are allowed anywhere if
558 ;; c-multiline-string-start-char is t.
559 (not c-multiline-string-start-char))
560 (if c-string-escaped-newlines
a6782a6e
MS
561 ;; There's no \ before the newline.
562 (not (eq (char-before (point)) ?\\))
0386b551 563 ;; Escaped newlines aren't supported.
a6782a6e 564 t)
0386b551 565 (c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
d9e94c22
MS
566
567(c-lang-defconst c-basic-matchers-before
568 "Font lock matchers for basic keywords, labels, references and various
569other easily recognizable things that should be fontified before generic
570casts and declarations are fontified. Used on level 2 and higher."
571
572 ;; Note: `c-font-lock-declarations' assumes that no matcher here
573 ;; sets `font-lock-type-face' in languages where
574 ;; `c-recognize-<>-arglists' is set.
575
576 t `(;; Put a warning face on the opener of unclosed strings that
577 ;; can't span lines. Later font
578 ;; lock packages have a `font-lock-syntactic-face-function' for
579 ;; this, but it doesn't give the control we want since any
580 ;; fontification done inside the function will be
581 ;; unconditionally overridden.
582 ,(c-make-font-lock-search-function
583 ;; Match a char before the string starter to make
584 ;; `c-skip-comments-and-strings' work correctly.
585 (concat ".\\(" c-string-limit-regexp "\\)")
586 '((c-font-lock-invalid-string)))
587
588 ;; Fontify keyword constants.
589 ,@(when (c-lang-const c-constant-kwds)
590 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
591 (if (c-major-mode-is 'pike-mode)
592 ;; No symbol is a keyword after "->" in Pike.
0386b551 593 `((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
d9e94c22 594 "\\<\\(" re "\\)\\>")
0386b551 595 2 c-constant-face-name)))
d9e94c22
MS
596 `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
597 1 c-constant-face-name))))))
598
599 ;; Fontify all keywords except the primitive types.
600 ,(if (c-major-mode-is 'pike-mode)
601 ;; No symbol is a keyword after "->" in Pike.
0386b551 602 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
d9e94c22 603 "\\<" (c-lang-const c-regular-keywords-regexp))
0386b551 604 2 font-lock-keyword-face)
d9e94c22
MS
605 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
606 1 font-lock-keyword-face))
607
608 ;; Fontify leading identifiers in fully qualified names like
609 ;; "foo::bar" in languages that supports such things.
610 ,@(when (c-lang-const c-opt-identifier-concat-key)
2a15eb73
MS
611 (if (c-major-mode-is 'java-mode)
612 ;; Java needs special treatment since "." is used both to
613 ;; qualify names and in normal indexing. Here we look for
614 ;; capital characters at the beginning of an identifier to
615 ;; recognize the class. "*" is also recognized to cover
616 ;; wildcard import declarations. All preceding dot separated
617 ;; identifiers are taken as package names and therefore
618 ;; fontified as references.
619 `(,(c-make-font-lock-search-function
620 ;; Search for class identifiers preceded by ".". The
621 ;; anchored matcher takes it from there.
622 (concat (c-lang-const c-opt-identifier-concat-key)
0386b551 623 (c-lang-const c-simple-ws) "*"
2a15eb73 624 (concat "\\("
0386b551
AM
625 "[" c-upper "]"
626 "[" (c-lang-const c-symbol-chars) "]*"
2a15eb73
MS
627 "\\|"
628 "\\*"
629 "\\)"))
630 `((let (id-end)
631 (goto-char (1+ (match-beginning 0)))
632 (while (and (eq (char-before) ?.)
633 (progn
634 (backward-char)
635 (c-backward-syntactic-ws)
636 (setq id-end (point))
637 (< (skip-chars-backward
638 ,(c-lang-const c-symbol-chars)) 0))
639 (not (get-text-property (point) 'face)))
0386b551
AM
640 (c-put-font-lock-face (point) id-end
641 c-reference-face-name)
2a15eb73
MS
642 (c-backward-syntactic-ws)))
643 nil
644 (goto-char (match-end 0)))))
645
646 `((,(byte-compile
0386b551
AM
647 ;; Must use a function here since we match longer than
648 ;; we want to move before doing a new search. This is
649 ;; not necessary for XEmacs since it restarts the
650 ;; search from the end of the first highlighted
651 ;; submatch (something that causes problems in other
652 ;; places).
2a15eb73
MS
653 `(lambda (limit)
654 (while (re-search-forward
655 ,(concat "\\(\\<" ; 1
656 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
0386b551 657 (c-lang-const c-simple-ws) "*"
2a15eb73 658 (c-lang-const c-opt-identifier-concat-key)
0386b551 659 (c-lang-const c-simple-ws) "*"
2a15eb73
MS
660 "\\)"
661 "\\("
662 (c-lang-const c-opt-after-id-concat-key)
663 "\\)")
664 limit t)
665 (unless (progn
666 (goto-char (match-beginning 0))
667 (c-skip-comments-and-strings limit))
668 (or (get-text-property (match-beginning 2) 'face)
669 (c-put-font-lock-face (match-beginning 2)
670 (match-end 2)
671 c-reference-face-name))
672 (goto-char (match-end 1))))))))))
d9e94c22
MS
673
674 ;; Fontify the special declarations in Objective-C.
675 ,@(when (c-major-mode-is 'objc-mode)
676 `(;; Fontify class names in the beginning of message expressions.
677 ,(c-make-font-lock-search-function
678 "\\["
679 '((c-fontify-types-and-refs ()
680 (c-forward-syntactic-ws limit)
681 (let ((start (point)))
682 ;; In this case we accept both primitive and known types.
683 (when (eq (c-forward-type) 'known)
684 (goto-char start)
685 (let ((c-promote-possible-types t))
686 (c-forward-type))))
687 (if (> (point) limit) (goto-char limit)))))
688
689 ;; The @interface/@implementation/@protocol directives.
0386b551
AM
690 ,(c-make-font-lock-search-function
691 (concat "\\<"
692 (regexp-opt
d9e94c22
MS
693 '("@interface" "@implementation" "@protocol")
694 t)
695 "\\>")
0386b551
AM
696 '((c-fontify-types-and-refs
697 (;; The font-lock package in Emacs is known to clobber
698 ;; `parse-sexp-lookup-properties' (when it exists).
699 (parse-sexp-lookup-properties
700 (cc-eval-when-compile
701 (boundp 'parse-sexp-lookup-properties))))
702 (c-forward-objc-directive)
703 nil)
704 (goto-char (match-beginning 0))))))
705
706 (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name))
d9e94c22
MS
707 ))
708
709(defun c-font-lock-complex-decl-prepare (limit)
1379f2c5
AM
710 ;; This function will be called from font-lock for a region bounded by POINT
711 ;; and LIMIT, as though it were to identify a keyword for
712 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
713 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
714 ;; Fontification".
715 ;;
d9e94c22 716 ;; Called before any of the matchers in `c-complex-decl-matchers'.
0386b551
AM
717 ;;
718 ;; This function does hidden buffer changes.
d9e94c22
MS
719
720 ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
721
722 ;; Clear the list of found types if we start from the start of the
723 ;; buffer, to make it easier to get rid of misspelled types and
724 ;; variables that has gotten recognized as types in malformed code.
725 (when (bobp)
726 (c-clear-found-types))
727
728 ;; Clear the c-type char properties in the region to recalculate
729 ;; them properly. This is necessary e.g. to handle constructs that
730 ;; might been required as declarations temporarily during editing.
731 ;; The interesting properties are anyway those put on the closest
732 ;; token before the region.
733 (c-clear-char-properties (point) limit 'c-type)
734
735 ;; Update `c-state-cache' to the beginning of the region. This will
736 ;; make `c-beginning-of-syntax' go faster when it's used later on,
737 ;; and it's near the point most of the time.
738 (c-parse-state)
739
740 ;; Check if the fontified region starts inside a declarator list so
741 ;; that `c-font-lock-declarators' should be called at the start.
742 (let ((prop (save-excursion
743 (c-backward-syntactic-ws)
744 (unless (bobp)
745 (c-get-char-property (1- (point)) 'c-type)))))
746 (when (memq prop '(c-decl-id-start c-decl-type-start))
747 (c-forward-syntactic-ws limit)
748 (c-font-lock-declarators limit t (eq prop 'c-decl-type-start))))
749
750 nil)
751
752(defun c-font-lock-<>-arglists (limit)
1379f2c5
AM
753 ;; This function will be called from font-lock for a region bounded by POINT
754 ;; and LIMIT, as though it were to identify a keyword for
755 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
756 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
757 ;; Fontification".
758 ;;
d9e94c22 759 ;; Fontify types and references in names containing angle bracket
0386b551 760 ;; arglists from the point to LIMIT. Note that
1379f2c5 761 ;; `c-font-lock-declarations' already has handled many of them.
0386b551
AM
762 ;;
763 ;; This function might do hidden buffer changes.
d9e94c22
MS
764
765 (let (;; The font-lock package in Emacs is known to clobber
766 ;; `parse-sexp-lookup-properties' (when it exists).
767 (parse-sexp-lookup-properties
768 (cc-eval-when-compile
769 (boundp 'parse-sexp-lookup-properties)))
0386b551
AM
770 (c-parse-and-markup-<>-arglists t)
771 c-restricted-<>-arglists
772 id-start id-end id-face pos kwd-sym)
d9e94c22
MS
773
774 (while (and (< (point) limit)
775 (re-search-forward c-opt-<>-arglist-start limit t))
776
777 (setq id-start (match-beginning 1)
778 id-end (match-end 1)
779 pos (point))
780
781 (goto-char id-start)
782 (unless (c-skip-comments-and-strings limit)
0386b551
AM
783 (setq kwd-sym nil
784 c-restricted-<>-arglists nil
785 id-face (get-text-property id-start 'face))
786
787 (if (cond
788 ((eq id-face 'font-lock-type-face)
789 ;; The identifier got the type face so it has already been
790 ;; handled in `c-font-lock-declarations'.
791 nil)
792
793 ((eq id-face 'font-lock-keyword-face)
794 (when (looking-at c-opt-<>-sexp-key)
795 ;; There's a special keyword before the "<" that tells
796 ;; that it's an angle bracket arglist.
797 (setq kwd-sym (c-keyword-sym (match-string 1)))))
798
799 (t
800 ;; There's a normal identifier before the "<". If we're not in
801 ;; a declaration context then we set `c-restricted-<>-arglists'
802 ;; to avoid recognizing templates in function calls like "foo (a
803 ;; < b, c > d)".
804 (c-backward-syntactic-ws)
805 (when (and (memq (char-before) '(?\( ?,))
806 (not (eq (get-text-property (1- (point)) 'c-type)
807 'c-decl-arg-start)))
808 (setq c-restricted-<>-arglists t))
809 t))
810
d9e94c22
MS
811 (progn
812 (goto-char (1- pos))
813 ;; Check for comment/string both at the identifier and
814 ;; at the "<".
815 (unless (c-skip-comments-and-strings limit)
816
0386b551
AM
817 (c-fontify-types-and-refs ()
818 (when (c-forward-<>-arglist (c-keyword-member
819 kwd-sym 'c-<>-type-kwds))
820 (when (and c-opt-identifier-concat-key
821 (not (get-text-property id-start 'face)))
822 (c-forward-syntactic-ws)
823 (if (looking-at c-opt-identifier-concat-key)
824 (c-put-font-lock-face id-start id-end
825 c-reference-face-name)
d9e94c22 826 (c-put-font-lock-face id-start id-end
0386b551 827 'font-lock-type-face)))))
d9e94c22
MS
828
829 (goto-char pos)))
830 (goto-char pos)))))
831 nil)
832
833(defun c-font-lock-declarators (limit list types)
834 ;; Assuming the point is at the start of a declarator in a
835 ;; declaration, fontify it. If LIST is non-nil, fontify also all
836 ;; following declarators in a comma separated list (e.g. "foo" and
837 ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is
838 ;; non-nil, fontify all identifiers as types. Nil is always
839 ;; returned.
0386b551
AM
840 ;;
841 ;; This function might do hidden buffer changes.
d9e94c22
MS
842
843 ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
844 (c-fontify-types-and-refs
845 ((pos (point)) next-pos id-start id-end
846 paren-depth
847 id-face got-init
848 c-last-identifier-range
849 (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
850
851 (while (and
852 pos
853 (< (point) limit)
854
855 (let (got-identifier)
856 (setq paren-depth 0)
857 ;; Skip over type decl prefix operators. (Note similar
0386b551 858 ;; code in `c-forward-decl-or-cast-1'.)
d9e94c22
MS
859 (while (and (looking-at c-type-decl-prefix-key)
860 (if (and (c-major-mode-is 'c++-mode)
861 (match-beginning 2))
862 ;; If the second submatch matches in C++ then
863 ;; we're looking at an identifier that's a
864 ;; prefix only if it specifies a member pointer.
865 (progn
866 (setq id-start (point))
867 (c-forward-name)
868 (if (looking-at "\\(::\\)")
869 ;; We only check for a trailing "::" and
870 ;; let the "*" that should follow be
871 ;; matched in the next round.
872 t
873 ;; It turned out to be the real identifier,
874 ;; so flag that and stop.
875 (setq got-identifier t)
876 nil))
877 t))
878 (if (eq (char-after) ?\()
879 (progn
880 (setq paren-depth (1+ paren-depth))
881 (forward-char))
882 (goto-char (match-end 1)))
883 (c-forward-syntactic-ws))
884
885 ;; If we didn't pass the identifier above already, do it now.
886 (unless got-identifier
887 (setq id-start (point))
888 (c-forward-name))
889 (setq id-end (point))
890
891 (/= id-end pos))
892
893 ;; Skip out of the parens surrounding the identifier.
894 (or (= paren-depth 0)
895 (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
896
897 (<= (point) limit)
898
0386b551
AM
899 (progn
900 (when (looking-at c-decl-hangon-key)
901 (c-forward-keyword-clause 1))
902 (<= (point) limit))
903
d9e94c22 904 ;; Search syntactically to the end of the declarator (";",
2a15eb73
MS
905 ;; ",", a closen paren, eob etc) or to the beginning of an
906 ;; initializer or function prototype ("=" or "\\s\(").
907 ;; Note that the open paren will match array specs in
908 ;; square brackets, and we treat them as initializers too.
d9e94c22 909 (c-syntactic-re-search-forward
2a15eb73 910 "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t))
d9e94c22
MS
911
912 (setq next-pos (match-beginning 0)
39f7186c
CY
913 id-face (if (and (eq (char-after next-pos) ?\()
914 (let (c-last-identifier-range)
915 (save-excursion
916 (goto-char next-pos)
917 (c-at-toplevel-p))))
d9e94c22
MS
918 'font-lock-function-name-face
919 'font-lock-variable-name-face)
2a15eb73
MS
920 got-init (and (match-beginning 1)
921 (char-after (match-beginning 1))))
d9e94c22
MS
922
923 (if types
924 ;; Register and fontify the identifer as a type.
925 (let ((c-promote-possible-types t))
926 (goto-char id-start)
927 (c-forward-type))
928 ;; Fontify the last symbol in the identifier if it isn't fontified
929 ;; already. The check is necessary only in certain cases where this
930 ;; function is used "sloppily", e.g. in `c-simple-decl-matchers'.
931 (when (and c-last-identifier-range
932 (not (get-text-property (car c-last-identifier-range)
933 'face)))
934 (c-put-font-lock-face (car c-last-identifier-range)
935 (cdr c-last-identifier-range)
936 id-face)))
937
938 (goto-char next-pos)
939 (setq pos nil)
940 (when list
941 ;; Jump past any initializer or function prototype to see if
942 ;; there's a ',' to continue at.
943
944 (cond ((eq id-face 'font-lock-function-name-face)
945 ;; Skip a parenthesized initializer (C++) or a function
946 ;; prototype.
947 (if (c-safe (c-forward-sexp 1) t)
948 (c-forward-syntactic-ws limit)
949 (goto-char limit)))
950
951 (got-init
2a15eb73
MS
952 ;; Skip an initializer expression. If we're at a '='
953 ;; then accept a brace list directly after it to cope
954 ;; with array initializers. Otherwise stop at braces
955 ;; to avoid going past full function and class blocks.
956 (and (if (and (eq got-init ?=)
3efc2cd7 957 (= (c-forward-token-2 1 nil limit) 0)
2a15eb73
MS
958 (looking-at "{"))
959 (c-safe (c-forward-sexp) t)
960 t)
0386b551
AM
961 ;; FIXME: Should look for c-decl-end markers here;
962 ;; we might go far into the following declarations
963 ;; in e.g. ObjC mode (see e.g. methods-4.m).
2a15eb73
MS
964 (c-syntactic-re-search-forward "[;,{]" limit 'move t)
965 (backward-char)))
d9e94c22
MS
966
967 (t (c-forward-syntactic-ws limit)))
968
969 ;; If a ',' is found we set pos to the next declarator and iterate.
970 (when (and (< (point) limit) (looking-at ","))
971 (c-put-char-property (point) 'c-type separator-prop)
972 (forward-char)
973 (c-forward-syntactic-ws limit)
974 (setq pos (point))))))
975 nil)
976
977(defconst c-font-lock-maybe-decl-faces
978 ;; List of faces that might be put at the start of a type when
979 ;; `c-font-lock-declarations' runs. This needs to be evaluated to
980 ;; ensure that face name aliases in Emacs are resolved.
981 (list nil
982 font-lock-type-face
983 c-reference-face-name
984 font-lock-keyword-face))
985
d9e94c22 986(defun c-font-lock-declarations (limit)
1379f2c5
AM
987 ;; This function will be called from font-lock for a region bounded by POINT
988 ;; and LIMIT, as though it were to identify a keyword for
989 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
990 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
991 ;; Fontification".
992 ;;
0386b551 993 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
1379f2c5 994 ;; Assumes that strings and comments have been fontified already.
d9e94c22 995 ;;
0386b551 996 ;; This function might do hidden buffer changes.
d9e94c22
MS
997
998 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
999
1000 (save-restriction
0386b551
AM
1001 (let (;; The position where `c-find-decl-spots' stopped.
1002 start-pos
1003 ;; 'decl if we're in an arglist containing declarations (but
1004 ;; if `c-recognize-paren-inits' is set it might also be an
1005 ;; initializer arglist), '<> if the arglist is of angle
1006 ;; bracket type, 'arglist if it's some other arglist, or nil
1007 ;; if not in an arglist at all.
1008 context
1009 ;; The position of the next token after the closing paren of
1010 ;; the last detected cast.
d9e94c22 1011 last-cast-end
0386b551
AM
1012 ;; The result from `c-forward-decl-or-cast-1'.
1013 decl-or-cast
1014 ;; The maximum of the end positions of all the checked type
1015 ;; decl expressions in the successfully identified
1016 ;; declarations. The position might be either before or
1017 ;; after the syntactic whitespace following the last token
1018 ;; in the type decl expression.
d9e94c22
MS
1019 (max-type-decl-end 0)
1020 ;; Same as `max-type-decl-*', but used when we're before
1021 ;; `token-pos'.
1022 (max-type-decl-end-before-token 0)
0386b551
AM
1023 ;; Set according to the context to direct the heuristics for
1024 ;; recognizing C++ templates.
1025 c-restricted-<>-arglists
1026 ;; Turn on recording of identifier ranges in
1027 ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
1028 ;; later fontification.
1029 (c-record-type-identifiers t)
1379f2c5 1030 label-type
d9e94c22 1031 c-record-ref-identifiers
0386b551
AM
1032 ;; Make `c-forward-type' calls mark up template arglists if
1033 ;; it finds any. That's necessary so that we later will
1034 ;; stop inside them to fontify types there.
1035 (c-parse-and-markup-<>-arglists t)
d9e94c22
MS
1036 ;; The font-lock package in Emacs is known to clobber
1037 ;; `parse-sexp-lookup-properties' (when it exists).
1038 (parse-sexp-lookup-properties
1039 (cc-eval-when-compile
1040 (boundp 'parse-sexp-lookup-properties))))
1041
1042 ;; Below we fontify a whole declaration even when it crosses the limit,
1043 ;; to avoid gaps when lazy-lock fontifies the file a screenful at a
1044 ;; time. That is however annoying during editing, e.g. the following is
1045 ;; a common situation while the first line is being written:
1046 ;;
1047 ;; my_variable
1048 ;; some_other_variable = 0;
1049 ;;
1050 ;; font-lock will put the limit at the beginning of the second line
1051 ;; here, and if we go past it we'll fontify "my_variable" as a type and
1052 ;; "some_other_variable" as an identifier, and the latter will not
1053 ;; correct itself until the second line is changed. To avoid that we
1054 ;; narrow to the limit if the region to fontify is a single line.
0386b551
AM
1055 (narrow-to-region
1056 (point-min)
1057 (if (<= limit (c-point 'bonl))
1058 (save-excursion
1059 ;; Narrow after any operator chars following the limit though,
1060 ;; since those characters can be useful in recognizing a
1061 ;; declaration (in particular the '{' that opens a function body
1062 ;; after the header).
1063 (goto-char limit)
1064 (skip-chars-forward c-nonsymbol-chars)
1065 (point))
1066 limit))
d9e94c22
MS
1067
1068 (c-find-decl-spots
1069 limit
0386b551 1070 c-decl-start-re
d9e94c22
MS
1071 c-font-lock-maybe-decl-faces
1072
1073 (lambda (match-pos inside-macro)
0386b551
AM
1074 (setq start-pos (point))
1075 (when
1076 ;; The result of the form below is true when we don't recognize a
1077 ;; declaration or cast.
1078 (if (and (eq (get-text-property (point) 'face)
1079 'font-lock-keyword-face)
1080 (looking-at c-not-decl-init-keywords))
1081 ;; Don't do anything more if we're looking at a keyword that
1082 ;; can't start a declaration.
1083 t
1084
1085 ;; Set `context'. Look for "<" for the sake of C++-style template
1086 ;; arglists.
1087 (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<))
1088
1089 ;; Find out the type of the arglist.
1090 (if (<= match-pos (point-min))
1091 (setq context 'arglist)
1092 (let ((type (c-get-char-property (1- match-pos) 'c-type)))
1093 (cond ((eq type 'c-decl-arg-start)
1094 ;; Got a cached hit in a declaration arglist.
1095 (setq context 'decl))
1096 ((or (eq type 'c-<>-arg-sep)
1097 (eq (char-before match-pos) ?<))
1098 ;; Inside an angle bracket arglist.
1099 (setq context '<>))
1100 (type
1101 ;; Got a cached hit in some other type of arglist.
1102 (setq context 'arglist))
1103 ((if inside-macro
1104 (< match-pos max-type-decl-end-before-token)
1105 (< match-pos max-type-decl-end))
1106 ;; The point is within the range of a previously
1107 ;; encountered type decl expression, so the arglist
1108 ;; is probably one that contains declarations.
1109 ;; However, if `c-recognize-paren-inits' is set it
1110 ;; might also be an initializer arglist.
1111 (setq context 'decl)
1112 ;; The result of this check is cached with a char
1113 ;; property on the match token, so that we can look
1114 ;; it up again when refontifying single lines in a
1115 ;; multiline declaration.
1116 (c-put-char-property (1- match-pos)
1117 'c-type 'c-decl-arg-start))
1118 (t
1119 (setq context 'arglist)))))
1120
1121 (setq context nil))
1122
1123 ;; If we're in a normal arglist context we don't want to
1124 ;; recognize commas in nested angle bracket arglists since
1125 ;; those commas could be part of our own arglist.
1126 (setq c-restricted-<>-arglists (and c-recognize-<>-arglists
1127 (eq context 'arglist))
1128
1129 ;; Now analyze the construct.
1130 decl-or-cast (c-forward-decl-or-cast-1
1131 match-pos context last-cast-end))
1132
1133 (if (not decl-or-cast)
1134 ;; False alarm. Return t to go on to the next check.
1135 t
1136
1137 (if (eq decl-or-cast 'cast)
1138 ;; Save the position after the previous cast so we can feed
1139 ;; it to `c-forward-decl-or-cast-1' in the next round. That
1140 ;; helps it discover cast chains like "(a) (b) c".
1141 (setq last-cast-end (point))
1142
1143 ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1144 ;; under the assumption that we're after the first type decl
1145 ;; expression in the declaration now. That's not really true;
1146 ;; we could also be after a parenthesized initializer
1147 ;; expression in C++, but this is only used as a last resort
1148 ;; to slant ambiguous expression/declarations, and overall
1149 ;; it's worth the risk to occasionally fontify an expression
1150 ;; as a declaration in an initializer expression compared to
1151 ;; getting ambiguous things in normal function prototypes
1152 ;; fontified as expressions.
1153 (if inside-macro
1154 (when (> (point) max-type-decl-end-before-token)
1155 (setq max-type-decl-end-before-token (point)))
1156 (when (> (point) max-type-decl-end)
1157 (setq max-type-decl-end (point))))
1158
1159 ;; Back up to the type to fontify the declarator(s).
1160 (goto-char (car decl-or-cast))
1161
1162 (let ((decl-list
1163 (if context
1164 ;; Should normally not fontify a list of
1165 ;; declarators inside an arglist, but the first
1166 ;; argument in the ';' separated list of a "for"
1167 ;; statement is an exception.
1168 (when (eq (char-before match-pos) ?\()
1169 (save-excursion
1170 (goto-char (1- match-pos))
1171 (c-backward-syntactic-ws)
1172 (and (c-simple-skip-symbol-backward)
1173 (looking-at c-paren-stmt-key))))
1174 t)))
1175
1176 ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1177 ;; before the first declarator if it's a list.
1178 ;; `c-font-lock-declarators' handles the rest.
1179 (when decl-list
1180 (save-excursion
1181 (c-backward-syntactic-ws)
1182 (unless (bobp)
1183 (c-put-char-property (1- (point)) 'c-type
1184 (if (cdr decl-or-cast)
1185 'c-decl-type-start
1186 'c-decl-id-start)))))
1187
1188 (c-font-lock-declarators
1189 (point-max) decl-list (cdr decl-or-cast))))
1190
1191 ;; A cast or declaration has been successfully identified, so do
1192 ;; all the fontification of types and refs that's been recorded.
1193 (c-fontify-recorded-types-and-refs)
1194 nil))
1195
1379f2c5
AM
1196 ;; It was a false alarm. Check if we're in a label (or other
1197 ;; construct with `:' except bitfield) instead.
0386b551 1198 (goto-char start-pos)
1379f2c5
AM
1199 (when (setq label-type (c-forward-label t match-pos nil))
1200 ;; Can't use `c-fontify-types-and-refs' here since we
1201 ;; use the label face at times.
1202 (cond ((eq label-type 'goto-target)
1203 (c-put-font-lock-face (caar c-record-ref-identifiers)
1204 (cdar c-record-ref-identifiers)
1205 c-label-face-name))
1206 ((eq label-type 'qt-1kwd-colon)
1207 (c-put-font-lock-face (caar c-record-ref-identifiers)
1208 (cdar c-record-ref-identifiers)
1209 'font-lock-keyword-face))
1210 ((eq label-type 'qt-2kwds-colon)
1211 (mapc
1212 (lambda (kwd)
1213 (c-put-font-lock-face (car kwd) (cdr kwd)
1214 'font-lock-keyword-face))
1215 c-record-ref-identifiers)))
1216 (setq c-record-ref-identifiers nil)
1217 ;; `c-forward-label' has probably added a `c-decl-end'
1218 ;; marker, so return t to `c-find-decl-spots' to signal
1219 ;; that.
1220 t))))
d9e94c22
MS
1221
1222 nil)))
1223
1224(c-lang-defconst c-simple-decl-matchers
1225 "Simple font lock matchers for types and declarations. These are used
1226on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1227
1228 t `(;; Objective-C methods.
1229 ,@(when (c-major-mode-is 'objc-mode)
1230 `((,(c-lang-const c-opt-method-key)
1231 (,(byte-compile
1232 (lambda (limit)
1233 (let (;; The font-lock package in Emacs is known to clobber
1234 ;; `parse-sexp-lookup-properties' (when it exists).
1235 (parse-sexp-lookup-properties
1236 (cc-eval-when-compile
1237 (boundp 'parse-sexp-lookup-properties))))
1238 (save-restriction
1239 (narrow-to-region (point-min) limit)
1240 (c-font-lock-objc-method)))
1241 nil))
1242 (goto-char (match-end 1))))))
1243
1244 ;; Fontify all type names and the identifiers in the
1245 ;; declarations they might start. Use eval here since
1246 ;; `c-known-type-key' gets its value from
1247 ;; `*-font-lock-extra-types' on mode init.
1248 (eval . (list ,(c-make-font-lock-search-function
1249 'c-known-type-key
1250 '(1 'font-lock-type-face t)
1251 '((c-font-lock-declarators limit t nil)
1252 (save-match-data
1253 (goto-char (match-end 1))
1254 (c-forward-syntactic-ws))
1255 (goto-char (match-end 1))))))
1256
1257 ;; Fontify types preceded by `c-type-prefix-kwds' and the
1258 ;; identifiers in the declarations they might start.
1259 ,@(when (c-lang-const c-type-prefix-kwds)
0386b551
AM
1260 (let* ((prefix-re (c-make-keywords-re nil
1261 (c-lang-const c-type-prefix-kwds)))
1262 (type-match (+ 2
1263 (regexp-opt-depth prefix-re)
1264 (c-lang-const c-simple-ws-depth))))
d9e94c22 1265 `((,(c-make-font-lock-search-function
0386b551
AM
1266 (concat "\\<\\(" prefix-re "\\)" ; 1
1267 (c-lang-const c-simple-ws) "+"
1268 (concat "\\(" ; 2 + prefix-re + c-simple-ws
1269 (c-lang-const c-symbol-key)
1270 "\\)"))
1271 `(,type-match
d9e94c22 1272 'font-lock-type-face t)
0386b551 1273 `((c-font-lock-declarators limit t nil)
d9e94c22 1274 (save-match-data
0386b551 1275 (goto-char (match-end ,type-match))
d9e94c22 1276 (c-forward-syntactic-ws))
0386b551 1277 (goto-char (match-end ,type-match))))))))
d9e94c22
MS
1278
1279 ;; Fontify special declarations that lacks a type.
1280 ,@(when (c-lang-const c-typeless-decl-kwds)
1281 `((,(c-make-font-lock-search-function
1282 (concat "\\<\\("
0386b551 1283 (regexp-opt (c-lang-const c-typeless-decl-kwds))
d9e94c22
MS
1284 "\\)\\>")
1285 '((c-font-lock-declarators limit t nil)
1286 (save-match-data
1287 (goto-char (match-end 1))
1288 (c-forward-syntactic-ws))
1289 (goto-char (match-end 1)))))))
0386b551
AM
1290
1291 ;; Fontify generic colon labels in languages that support them.
1292 ,@(when (c-lang-const c-recognize-colon-labels)
1293 `(c-font-lock-labels))))
d9e94c22
MS
1294
1295(c-lang-defconst c-complex-decl-matchers
1296 "Complex font lock matchers for types and declarations. Used on level
12973 and higher."
1298
1379f2c5
AM
1299 ;; Note: This code in this form dumps a number of funtions into the
1300 ;; resulting constant, `c-matchers-3'. At run time, font lock will call
1301 ;; each of them as a "FUNCTION" (see Elisp page "Search-based
1302 ;; Fontification"). The font lock region is delimited by POINT and the
1303 ;; single parameter, LIMIT. Each of these functions returns NIL (thus
1304 ;; inhibiting spurious font-lock-keyword-face highlighting and another
1305 ;; call).
1306
d9e94c22
MS
1307 t `(;; Initialize some things before the search functions below.
1308 c-font-lock-complex-decl-prepare
1309
d9e94c22
MS
1310 ,@(if (c-major-mode-is 'objc-mode)
1311 ;; Fontify method declarations in Objective-C, but first
1312 ;; we have to put the `c-decl-end' `c-type' property on
1313 ;; all the @-style directives that haven't been handled in
1314 ;; `c-basic-matchers-before'.
1315 `(,(c-make-font-lock-search-function
1316 (c-make-keywords-re t
1317 ;; Exclude "@class" since that directive ends with a
1318 ;; semicolon anyway.
1319 (delete "@class"
1320 (append (c-lang-const c-protection-kwds)
1321 (c-lang-const c-other-decl-kwds)
1322 nil)))
1323 '((c-put-char-property (1- (match-end 1))
1324 'c-type 'c-decl-end)))
0386b551 1325 c-font-lock-objc-methods))
d9e94c22 1326
0386b551 1327 ;; Fontify all declarations, casts and normal labels.
d9e94c22
MS
1328 c-font-lock-declarations
1329
0386b551
AM
1330 ;; Fontify angle bracket arglists like templates in C++.
1331 ,@(when (c-lang-const c-recognize-<>-arglists)
1332 `(c-font-lock-<>-arglists))
1333
5a89f0a7 1334 ;; The first two rules here mostly find occurrences that
d9e94c22
MS
1335 ;; `c-font-lock-declarations' has found already, but not
1336 ;; declarations containing blocks in the type (see note below).
1337 ;; It's also useful to fontify these everywhere to show e.g. when
1338 ;; a type keyword is accidentally used as an identifier.
1339
1340 ;; Fontify basic types.
1341 ,(let ((re (c-make-keywords-re nil
1342 (c-lang-const c-primitive-type-kwds))))
1343 (if (c-major-mode-is 'pike-mode)
1344 ;; No symbol is a keyword after "->" in Pike.
0386b551 1345 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
d9e94c22 1346 "\\<\\(" re "\\)\\>")
0386b551 1347 2 font-lock-type-face)
d9e94c22
MS
1348 `(,(concat "\\<\\(" re "\\)\\>")
1349 1 'font-lock-type-face)))
1350
1351 ;; Fontify types preceded by `c-type-prefix-kwds'.
1352 ,@(when (c-lang-const c-type-prefix-kwds)
1353 `((,(byte-compile
1354 `(lambda (limit)
1355 (c-fontify-types-and-refs
1356 ((c-promote-possible-types t)
1357 ;; The font-lock package in Emacs is known to clobber
1358 ;; `parse-sexp-lookup-properties' (when it exists).
1359 (parse-sexp-lookup-properties
1360 (cc-eval-when-compile
1361 (boundp 'parse-sexp-lookup-properties))))
1362 (save-restriction
1363 ;; Narrow to avoid going past the limit in
1364 ;; `c-forward-type'.
1365 (narrow-to-region (point) limit)
1366 (while (re-search-forward
1367 ,(concat "\\<\\("
1368 (c-make-keywords-re nil
1369 (c-lang-const c-type-prefix-kwds))
1370 "\\)\\>")
1371 limit t)
1372 (unless (c-skip-comments-and-strings limit)
1373 (c-forward-syntactic-ws)
1374 ;; Handle prefix declaration specifiers.
0386b551
AM
1375 (when (looking-at c-prefix-spec-kwds-re)
1376 (c-forward-keyword-clause 1))
d9e94c22
MS
1377 ,(if (c-major-mode-is 'c++-mode)
1378 `(when (and (c-forward-type)
1379 (eq (char-after) ?=))
1380 ;; In C++ we additionally check for a "class
1381 ;; X = Y" construct which is used in
1382 ;; templates, to fontify Y as a type.
1383 (forward-char)
1384 (c-forward-syntactic-ws)
1385 (c-forward-type))
1386 `(c-forward-type))
1387 )))))))))
1388
1389 ;; Fontify symbols after closing braces as declaration
1390 ;; identifiers under the assumption that they are part of
1391 ;; declarations like "class Foo { ... } foo;". It's too
1392 ;; expensive to check this accurately by skipping past the
1393 ;; brace block, so we use the heuristic that it's such a
1394 ;; declaration if the first identifier is on the same line as
1395 ;; the closing brace. `c-font-lock-declarations' will later
1396 ;; override it if it turns out to be an new declaration, but
1397 ;; it will be wrong if it's an expression (see the test
1398 ;; decls-8.cc).
1399 ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
1400 `((,(c-make-font-lock-search-function
1401 (concat "}"
1402 (c-lang-const c-single-line-syntactic-ws)
1403 "\\(" ; 1 + c-single-line-syntactic-ws-depth
1404 (c-lang-const c-type-decl-prefix-key)
1405 "\\|"
1406 (c-lang-const c-symbol-key)
1407 "\\)")
1408 `((c-font-lock-declarators limit t nil)
1409 (progn
1410 (c-put-char-property (match-beginning 0) 'c-type
1411 'c-decl-id-start)
1412 (goto-char (match-beginning
1413 ,(1+ (c-lang-const
1414 c-single-line-syntactic-ws-depth)))))
1415 (goto-char (match-end 0)))))))
1416
1417 ;; Fontify the type in C++ "new" expressions.
1418 ,@(when (c-major-mode-is 'c++-mode)
1379f2c5
AM
1419 ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)"
1420 ;; (see Elisp page "Search-based Fontification").
d9e94c22
MS
1421 `(("\\<new\\>"
1422 (c-font-lock-c++-new))))
1423 ))
1424
1425(defun c-font-lock-labels (limit)
0386b551 1426 ;; Fontify all statement labels from the point to LIMIT. Assumes
d9e94c22
MS
1427 ;; that strings and comments have been fontified already. Nil is
1428 ;; always returned.
1429 ;;
0386b551
AM
1430 ;; Note: This function is only used on decoration level 2; this is
1431 ;; taken care of directly by the gargantuan
1432 ;; `c-font-lock-declarations' on higher levels.
1433 ;;
1434 ;; This function might do hidden buffer changes.
d9e94c22
MS
1435
1436 (let (continue-pos id-start
1437 ;; The font-lock package in Emacs is known to clobber
1438 ;; `parse-sexp-lookup-properties' (when it exists).
1439 (parse-sexp-lookup-properties
1440 (cc-eval-when-compile
1441 (boundp 'parse-sexp-lookup-properties))))
1442
1443 (while (re-search-forward ":[^:]" limit t)
1444 (setq continue-pos (point))
1445 (goto-char (match-beginning 0))
1446 (unless (c-skip-comments-and-strings limit)
1447
1448 (c-backward-syntactic-ws)
1449 (and (setq id-start (c-on-identifier))
1450
1451 (not (get-text-property id-start 'face))
1452
1453 (progn
1454 (goto-char id-start)
1455 (c-backward-syntactic-ws)
1456 (or
1457 ;; Check for a char that precedes a statement.
1458 (memq (char-before) '(?\} ?\{ ?\;))
1459 ;; Check for a preceding label. We exploit the font
1460 ;; locking made earlier by this function.
1461 (and (eq (char-before) ?:)
1462 (progn
1463 (backward-char)
1464 (c-backward-syntactic-ws)
1465 (not (bobp)))
1466 (eq (get-text-property (1- (point)) 'face)
1467 c-label-face-name))
1468 ;; Check for a keyword that precedes a statement.
1469 (c-after-conditional)))
1470
1471 (progn
1472 ;; Got a label.
1473 (goto-char id-start)
1474 (looking-at c-symbol-key)
1475 (c-put-font-lock-face (match-beginning 0) (match-end 0)
1476 c-label-face-name)))
1477
1478 (goto-char continue-pos))))
1479 nil)
1480
1481(c-lang-defconst c-basic-matchers-after
1482 "Font lock matchers for various things that should be fontified after
1483generic casts and declarations are fontified. Used on level 2 and
1484higher."
1485
1486 t `(;; Fontify the identifiers inside enum lists. (The enum type
1487 ;; name is handled by `c-simple-decl-matchers' or
1488 ;; `c-complex-decl-matchers' below.
1489 ,@(when (c-lang-const c-brace-id-list-kwds)
1490 `((,(c-make-font-lock-search-function
1491 (concat
1492 "\\<\\("
1493 (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
1494 "\\)\\>"
1495 ;; Disallow various common punctuation chars that can't come
1496 ;; before the '{' of the enum list, to avoid searching too far.
1497 "[^\]\[{}();,/#=]*"
1498 "{")
1499 '((c-font-lock-declarators limit t nil)
1500 (save-match-data
1501 (goto-char (match-end 0))
1502 (c-put-char-property (1- (point)) 'c-type
1503 'c-decl-id-start)
1504 (c-forward-syntactic-ws))
1505 (goto-char (match-end 0)))))))
1506
0386b551
AM
1507 ;; Fontify labels after goto etc.
1508 ,@(when (c-lang-const c-before-label-kwds)
1509 `(;; (Got three different interpretation levels here,
d9e94c22
MS
1510 ;; which makes it a bit complicated: 1) The backquote
1511 ;; stuff is expanded when compiled or loaded, 2) the
1512 ;; eval form is evaluated at font-lock setup (to
1513 ;; substitute c-label-face-name correctly), and 3) the
1514 ;; resulting structure is interpreted during
1515 ;; fontification.)
1516 (eval
1517 . ,(let* ((c-before-label-re
1518 (c-make-keywords-re nil
1519 (c-lang-const c-before-label-kwds))))
1520 `(list
1521 ,(concat "\\<\\(" c-before-label-re "\\)\\>"
1522 "\\s *"
1523 "\\(" ; identifier-offset
1524 (c-lang-const c-symbol-key)
1525 "\\)")
0386b551
AM
1526 (list ,(+ (regexp-opt-depth c-before-label-re) 2)
1527 c-label-face-name nil t))))))
d9e94c22
MS
1528
1529 ;; Fontify the clauses after various keywords.
1530 ,@(when (or (c-lang-const c-type-list-kwds)
1531 (c-lang-const c-ref-list-kwds)
1532 (c-lang-const c-colon-type-list-kwds)
1533 (c-lang-const c-paren-type-kwds))
1534 `((,(c-make-font-lock-search-function
1535 (concat "\\<\\("
1536 (c-make-keywords-re nil
1537 (append (c-lang-const c-type-list-kwds)
1538 (c-lang-const c-ref-list-kwds)
1539 (c-lang-const c-colon-type-list-kwds)
1540 (c-lang-const c-paren-type-kwds)))
1541 "\\)\\>")
1542 '((c-fontify-types-and-refs ((c-promote-possible-types t))
0386b551 1543 (c-forward-keyword-clause 1)
d9e94c22 1544 (if (> (point) limit) (goto-char limit))))))))
452ea855
AM
1545
1546 ,@(when (c-major-mode-is 'java-mode)
1547 `((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face))))
d9e94c22
MS
1548 ))
1549
1550(c-lang-defconst c-matchers-1
1551 t (c-lang-const c-cpp-matchers))
1552
1553(c-lang-defconst c-matchers-2
1554 t (append (c-lang-const c-matchers-1)
1555 (c-lang-const c-basic-matchers-before)
1556 (c-lang-const c-simple-decl-matchers)
1557 (c-lang-const c-basic-matchers-after)))
1558
1559(c-lang-defconst c-matchers-3
1560 t (append (c-lang-const c-matchers-1)
1561 (c-lang-const c-basic-matchers-before)
1562 (c-lang-const c-complex-decl-matchers)
1563 (c-lang-const c-basic-matchers-after)))
1564
1565(defun c-compose-keywords-list (base-list)
1566 ;; Incorporate the font lock keyword lists according to
1567 ;; `c-doc-comment-style' on the given keyword list and return it.
1568 ;; This is used in the function bindings of the
1569 ;; `*-font-lock-keywords-*' symbols since we have to build the list
1570 ;; when font-lock is initialized.
1571
1572 (unless (memq c-doc-face-name c-literal-faces)
1573 (setq c-literal-faces (cons c-doc-face-name c-literal-faces)))
1574
1575 (let* ((doc-keywords
1576 (if (consp (car-safe c-doc-comment-style))
1577 (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
1578 (assq 'other c-doc-comment-style)))
1579 c-doc-comment-style))
1580 (list (nconc (apply 'nconc
1581 (mapcar
1582 (lambda (doc-style)
1583 (let ((sym (intern
1584 (concat (symbol-name doc-style)
1585 "-font-lock-keywords"))))
1586 (cond ((fboundp sym)
1587 (funcall sym))
1588 ((boundp sym)
1589 (append (eval sym) nil)))))
1590 (if (listp doc-keywords)
1591 doc-keywords
1592 (list doc-keywords))))
1593 base-list)))
1594
1595 ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we
1596 ;; move it first since the doc comment font lockers might add
7bfc3fdb 1597 ;; `c-type' text properties, so they have to be cleared before that.
d9e94c22
MS
1598 (when (memq 'c-font-lock-complex-decl-prepare list)
1599 (setq list (cons 'c-font-lock-complex-decl-prepare
1600 (delq 'c-font-lock-complex-decl-prepare
1601 (append list nil)))))
1602
1603 list))
1604
1605(defun c-override-default-keywords (def-var)
1606 ;; This is used to override the value on a `*-font-lock-keywords'
1607 ;; variable only if it's nil or has the same value as one of the
1608 ;; `*-font-lock-keywords-*' variables. Older font-lock packages
1609 ;; define a default value for `*-font-lock-keywords' which we want
1610 ;; to override, but we should otoh avoid clobbering a user setting.
1611 ;; This heuristic for that isn't perfect, but I can't think of any
1612 ;; better. /mast
d9e94c22
MS
1613 (when (and (boundp def-var)
1614 (memq (symbol-value def-var)
1615 (cons nil
1616 (mapcar
1617 (lambda (suffix)
1618 (let ((sym (intern (concat (symbol-name def-var)
1619 suffix))))
1620 (and (boundp sym) (symbol-value sym))))
1621 '("-1" "-2" "-3")))))
1622 ;; The overriding is done by unbinding the variable so that the normal
1623 ;; defvar will install its default value later on.
1624 (makunbound def-var)))
1625
1626\f
1627;;; C.
1628
1629(c-override-default-keywords 'c-font-lock-keywords)
1630
1631(defconst c-font-lock-keywords-1 (c-lang-const c-matchers-1 c)
1632 "Minimal font locking for C mode.
1633Fontifies only preprocessor directives (in addition to the syntactic
1634fontification of strings and comments).")
1635
1636(defconst c-font-lock-keywords-2 (c-lang-const c-matchers-2 c)
1637 "Fast normal font locking for C mode.
1638In addition to `c-font-lock-keywords-1', this adds fontification of
1639keywords, simple types, declarations that are easy to recognize, the
1640user defined types on `c-font-lock-extra-types', and the doc comment
1641styles specified by `c-doc-comment-style'.")
1642
1643(defconst c-font-lock-keywords-3 (c-lang-const c-matchers-3 c)
1644 "Accurate normal font locking for C mode.
1645Like `c-font-lock-keywords-2' but detects declarations in a more
1646accurate way that works in most cases for arbitrary types without the
1647need for `c-font-lock-extra-types'.")
1648
1649(defvar c-font-lock-keywords c-font-lock-keywords-3
1650 "Default expressions to highlight in C mode.")
1651
1652(defun c-font-lock-keywords-2 ()
1653 (c-compose-keywords-list c-font-lock-keywords-2))
1654(defun c-font-lock-keywords-3 ()
1655 (c-compose-keywords-list c-font-lock-keywords-3))
1656(defun c-font-lock-keywords ()
1657 (c-compose-keywords-list c-font-lock-keywords))
1658
1659\f
1660;;; C++.
1661
1662(defun c-font-lock-c++-new (limit)
1663 ;; Assuming point is after a "new" word, check that it isn't inside
1664 ;; a string or comment, and if so try to fontify the type in the
1665 ;; allocation expression. Nil is always returned.
1666 ;;
1667 ;; As usual, C++ takes the prize in coming up with a hard to parse
1668 ;; syntax. :P
0386b551
AM
1669 ;;
1670 ;; This function might do hidden buffer changes.
d9e94c22
MS
1671
1672 (unless (c-skip-comments-and-strings limit)
1673 (save-excursion
1674 (catch 'false-alarm
1675 ;; A "new" keyword is followed by one to three expressions, where
1676 ;; the type is the middle one, and the only required part.
1677 (let (expr1-pos expr2-pos
1678 ;; Enable recording of identifier ranges in `c-forward-type'
1679 ;; etc for later fontification. Not using
1680 ;; `c-fontify-types-and-refs' here since the ranges should
1681 ;; be fontified selectively only when an allocation
1682 ;; expression is successfully recognized.
1683 (c-record-type-identifiers t)
1684 c-record-ref-identifiers
1685 ;; The font-lock package in Emacs is known to clobber
1686 ;; `parse-sexp-lookup-properties' (when it exists).
1687 (parse-sexp-lookup-properties
1688 (cc-eval-when-compile
1689 (boundp 'parse-sexp-lookup-properties))))
1690 (c-forward-syntactic-ws)
1691
1692 ;; The first placement arglist is always parenthesized, if it
1693 ;; exists.
1694 (when (eq (char-after) ?\()
1695 (setq expr1-pos (1+ (point)))
1696 (condition-case nil
1697 (c-forward-sexp)
1698 (scan-error (throw 'false-alarm t)))
1699 (c-forward-syntactic-ws))
1700
1701 ;; The second expression is either a type followed by some "*" or
1702 ;; "[...]" or similar, or a parenthesized type followed by a full
1703 ;; identifierless declarator.
1704 (setq expr2-pos (1+ (point)))
1705 (cond ((eq (char-after) ?\())
1706 ((let ((c-promote-possible-types t))
1707 (c-forward-type)))
1708 (t (setq expr2-pos nil)))
1709
1710 (when expr1-pos
1711 (cond
1712 ((not expr2-pos)
1713 ;; No second expression, so the first has to be a
1714 ;; parenthesized type.
1715 (goto-char expr1-pos)
1716 (let ((c-promote-possible-types t))
1717 (c-forward-type)))
1718
1719 ((eq (char-before expr2-pos) ?\()
1720 ;; Got two parenthesized expressions, so we have to look
1721 ;; closer at them to decide which is the type. No need to
1722 ;; handle `c-record-ref-identifiers' since all references
1723 ;; has already been handled by other fontification rules.
1724 (let (expr1-res expr2-res)
1725
1726 (goto-char expr1-pos)
1727 (when (setq expr1-res (c-forward-type))
1728 (unless (looking-at
1729 (cc-eval-when-compile
1730 (concat (c-lang-const c-symbol-start c++)
1731 "\\|[*:\)\[]")))
1732 ;; There's something after the would-be type that
1733 ;; can't be there, so this is a placement arglist.
1734 (setq expr1-res nil)))
1735
1736 (goto-char expr2-pos)
1737 (when (setq expr2-res (c-forward-type))
1738 (unless (looking-at
1739 (cc-eval-when-compile
1740 (concat (c-lang-const c-symbol-start c++)
1741 "\\|[*:\)\[]")))
1742 ;; There's something after the would-be type that can't
1743 ;; be there, so this is an initialization expression.
1744 (setq expr2-res nil))
1745 (when (and (c-go-up-list-forward)
1746 (progn (c-forward-syntactic-ws)
1747 (eq (char-after) ?\()))
1748 ;; If there's a third initialization expression
1749 ;; then the second one is the type, so demote the
1750 ;; first match.
1751 (setq expr1-res nil)))
1752
1753 ;; We fontify the most likely type, with a preference for
1754 ;; the first argument since a placement arglist is more
1755 ;; unusual than an initializer.
1756 (cond ((memq expr1-res '(t known prefix)))
1757 ((memq expr2-res '(t known prefix)))
1758 ((eq expr1-res 'found)
1759 (let ((c-promote-possible-types t))
1760 (goto-char expr1-pos)
1761 (c-forward-type)))
1762 ((eq expr2-res 'found)
1763 (let ((c-promote-possible-types t))
1764 (goto-char expr2-pos)
1765 (c-forward-type)))
1766 ((and (eq expr1-res 'maybe) (not expr2-res))
1767 (let ((c-promote-possible-types t))
1768 (goto-char expr1-pos)
1769 (c-forward-type)))
1770 ((and (not expr1-res) (eq expr2-res 'maybe))
1771 (let ((c-promote-possible-types t))
1772 (goto-char expr2-pos)
1773 (c-forward-type)))
1774 ;; If both type matches are 'maybe then we're
1775 ;; too uncertain to promote either of them.
1776 )))))
1777
1778 ;; Fontify the type that now is recorded in
1779 ;; `c-record-type-identifiers', if any.
1780 (c-fontify-recorded-types-and-refs)))))
1781 nil)
1782
1783(c-override-default-keywords 'c++-font-lock-keywords)
1784
1785(defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++)
1786 "Minimal font locking for C++ mode.
1787Fontifies only preprocessor directives (in addition to the syntactic
1788fontification of strings and comments).")
1789
1790(defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++)
1791 "Fast normal font locking for C++ mode.
1792In addition to `c++-font-lock-keywords-1', this adds fontification of
1793keywords, simple types, declarations that are easy to recognize, the
1794user defined types on `c++-font-lock-extra-types', and the doc comment
1795styles specified by `c-doc-comment-style'.")
1796
1797(defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++)
1798 "Accurate normal font locking for C++ mode.
1799Like `c++-font-lock-keywords-2' but detects declarations in a more
1800accurate way that works in most cases for arbitrary types without the
1801need for `c++-font-lock-extra-types'.")
1802
1803(defvar c++-font-lock-keywords c++-font-lock-keywords-3
1804 "Default expressions to highlight in C++ mode.")
1805
1806(defun c++-font-lock-keywords-2 ()
1807 (c-compose-keywords-list c++-font-lock-keywords-2))
1808(defun c++-font-lock-keywords-3 ()
1809 (c-compose-keywords-list c++-font-lock-keywords-3))
1810(defun c++-font-lock-keywords ()
1811 (c-compose-keywords-list c++-font-lock-keywords))
1812
1813\f
1814;;; Objective-C.
1815
d9e94c22
MS
1816(defun c-font-lock-objc-method ()
1817 ;; Assuming the point is after the + or - that starts an Objective-C
1818 ;; method declaration, fontify it. This must be done before normal
1819 ;; casts, declarations and labels are fontified since they will get
1820 ;; false matches in these things.
0386b551
AM
1821 ;;
1822 ;; This function might do hidden buffer changes.
d9e94c22
MS
1823
1824 (c-fontify-types-and-refs
1825 ((first t)
1826 (c-promote-possible-types t))
1827
1828 (while (and
1829 (progn
1830 (c-forward-syntactic-ws)
1831
1832 ;; An optional method type.
1833 (if (eq (char-after) ?\()
1834 (progn
1835 (forward-char)
1836 (c-forward-syntactic-ws)
1837 (c-forward-type)
1838 (prog1 (c-go-up-list-forward)
1839 (c-forward-syntactic-ws)))
1840 t))
1841
1842 ;; The name. The first time it's the first part of
1843 ;; the function name, the rest of the time it's an
1844 ;; argument name.
1845 (looking-at c-symbol-key)
1846 (progn
1847 (goto-char (match-end 0))
1848 (c-put-font-lock-face (match-beginning 0)
1849 (point)
1850 (if first
1851 'font-lock-function-name-face
1852 'font-lock-variable-name-face))
1853 (c-forward-syntactic-ws)
1854
1855 ;; Another optional part of the function name.
1856 (when (looking-at c-symbol-key)
1857 (goto-char (match-end 0))
1858 (c-put-font-lock-face (match-beginning 0)
1859 (point)
1860 'font-lock-function-name-face)
1861 (c-forward-syntactic-ws))
1862
1863 ;; There's another argument if a colon follows.
1864 (eq (char-after) ?:)))
1865 (forward-char)
1866 (setq first nil))))
1867
1868(defun c-font-lock-objc-methods (limit)
1869 ;; Fontify method declarations in Objective-C. Nil is always
1870 ;; returned.
0386b551
AM
1871 ;;
1872 ;; This function might do hidden buffer changes.
d9e94c22
MS
1873
1874 (let (;; The font-lock package in Emacs is known to clobber
1875 ;; `parse-sexp-lookup-properties' (when it exists).
1876 (parse-sexp-lookup-properties
1877 (cc-eval-when-compile
1878 (boundp 'parse-sexp-lookup-properties))))
1879
1880 (c-find-decl-spots
1881 limit
1882 "[-+]"
1883 nil
1884 (lambda (match-pos inside-macro)
1885 (forward-char)
1886 (c-font-lock-objc-method))))
1887 nil)
1888
1889(c-override-default-keywords 'objc-font-lock-keywords)
1890
1891(defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc)
1892 "Minimal font locking for Objective-C mode.
1893Fontifies only compiler directives (in addition to the syntactic
1894fontification of strings and comments).")
1895
1896(defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc)
1897 "Fast normal font locking for Objective-C mode.
1898In addition to `objc-font-lock-keywords-1', this adds fontification of
1899keywords, simple types, declarations that are easy to recognize, the
1900user defined types on `objc-font-lock-extra-types', and the doc
1901comment styles specified by `c-doc-comment-style'.")
1902
1903(defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc)
1904 "Accurate normal font locking for Objective-C mode.
1905Like `objc-font-lock-keywords-2' but detects declarations in a more
1906accurate way that works in most cases for arbitrary types without the
1907need for `objc-font-lock-extra-types'.")
1908
1909(defvar objc-font-lock-keywords objc-font-lock-keywords-3
1910 "Default expressions to highlight in Objective-C mode.")
1911
1912(defun objc-font-lock-keywords-2 ()
1913 (c-compose-keywords-list objc-font-lock-keywords-2))
1914(defun objc-font-lock-keywords-3 ()
1915 (c-compose-keywords-list objc-font-lock-keywords-3))
1916(defun objc-font-lock-keywords ()
1917 (c-compose-keywords-list objc-font-lock-keywords))
1918
1919;; Kludge to override the default value that
1920;; `objc-font-lock-extra-types' might have gotten from the font-lock
1921;; package. The value replaced here isn't relevant now anyway since
1922;; those types are builtin and therefore listed directly in
1923;; `c-primitive-type-kwds'.
1924(when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp)
1925 '("BOOL" "Class" "IMP" "SEL"))
1926 (setq objc-font-lock-extra-types
1927 (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*")))))
1928
1929\f
1930;;; Java.
1931
1932(c-override-default-keywords 'java-font-lock-keywords)
1933
1934(defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java)
1935 "Minimal font locking for Java mode.
1936Fontifies nothing except the syntactic fontification of strings and
1937comments.")
1938
1939(defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java)
1940 "Fast normal font locking for Java mode.
1941In addition to `java-font-lock-keywords-1', this adds fontification of
1942keywords, simple types, declarations that are easy to recognize, the
1943user defined types on `java-font-lock-extra-types', and the doc
1944comment styles specified by `c-doc-comment-style'.")
1945
1946(defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java)
1947 "Accurate normal font locking for Java mode.
1948Like `java-font-lock-keywords-2' but detects declarations in a more
1949accurate way that works in most cases for arbitrary types without the
1950need for `java-font-lock-extra-types'.")
1951
1952(defvar java-font-lock-keywords java-font-lock-keywords-3
1953 "Default expressions to highlight in Java mode.")
1954
1955(defun java-font-lock-keywords-2 ()
1956 (c-compose-keywords-list java-font-lock-keywords-2))
1957(defun java-font-lock-keywords-3 ()
1958 (c-compose-keywords-list java-font-lock-keywords-3))
1959(defun java-font-lock-keywords ()
1960 (c-compose-keywords-list java-font-lock-keywords))
1961
1962\f
1963;;; CORBA IDL.
1964
1965(c-override-default-keywords 'idl-font-lock-keywords)
1966
1967(defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl)
1968 "Minimal font locking for CORBA IDL mode.
1969Fontifies nothing except the syntactic fontification of strings and
1970comments.")
1971
1972(defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl)
1973 "Fast normal font locking for CORBA IDL mode.
1974In addition to `idl-font-lock-keywords-1', this adds fontification of
1975keywords, simple types, declarations that are easy to recognize, the
1976user defined types on `idl-font-lock-extra-types', and the doc comment
1977styles specified by `c-doc-comment-style'.")
1978
1979(defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl)
1980 "Accurate normal font locking for CORBA IDL mode.
1981Like `idl-font-lock-keywords-2' but detects declarations in a more
1982accurate way that works in most cases for arbitrary types without the
1983need for `idl-font-lock-extra-types'.")
1984
1985(defvar idl-font-lock-keywords idl-font-lock-keywords-3
1986 "Default expressions to highlight in CORBA IDL mode.")
1987
1988(defun idl-font-lock-keywords-2 ()
1989 (c-compose-keywords-list idl-font-lock-keywords-2))
1990(defun idl-font-lock-keywords-3 ()
1991 (c-compose-keywords-list idl-font-lock-keywords-3))
1992(defun idl-font-lock-keywords ()
1993 (c-compose-keywords-list idl-font-lock-keywords))
1994
1995\f
1996;;; Pike.
1997
1998(c-override-default-keywords 'pike-font-lock-keywords)
1999
2000(defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike)
2001 "Minimal font locking for Pike mode.
2002Fontifies only preprocessor directives (in addition to the syntactic
2003fontification of strings and comments).")
2004
2005(defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike)
2006 "Fast normal font locking for Pike mode.
2007In addition to `pike-font-lock-keywords-1', this adds fontification of
2008keywords, simple types, declarations that are easy to recognize, the
2009user defined types on `pike-font-lock-extra-types', and the doc
2010comment styles specified by `c-doc-comment-style'.")
2011
2012(defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike)
2013 "Accurate normal font locking for Pike mode.
2014Like `pike-font-lock-keywords-2' but detects declarations in a more
2015accurate way that works in most cases for arbitrary types without the
2016need for `pike-font-lock-extra-types'.")
2017
2018(defvar pike-font-lock-keywords pike-font-lock-keywords-3
2019 "Default expressions to highlight in Pike mode.")
2020
2021(defun pike-font-lock-keywords-2 ()
2022 (c-compose-keywords-list pike-font-lock-keywords-2))
2023(defun pike-font-lock-keywords-3 ()
2024 (c-compose-keywords-list pike-font-lock-keywords-3))
2025(defun pike-font-lock-keywords ()
2026 (c-compose-keywords-list pike-font-lock-keywords))
2027
2028\f
2029;;; Doc comments.
2030
2031(defun c-font-lock-doc-comments (prefix limit keywords)
2032 ;; Fontify the comments between the point and LIMIT whose start
2033 ;; matches PREFIX with `c-doc-face-name'. Assumes comments have been
2034 ;; fontified with `font-lock-comment-face' already. nil is always
2035 ;; returned.
2036 ;;
2037 ;; After the fontification of a matching comment, fontification
2038 ;; according to KEYWORDS is applied inside it. It's a list like
2039 ;; `font-lock-keywords' except that anchored matches and eval
2040 ;; clauses aren't supported and that some abbreviated forms can't be
2041 ;; used. The buffer is narrowed to the comment while KEYWORDS is
2042 ;; applied; leading comment starters are included but trailing
2043 ;; comment enders for block comment are not.
2044 ;;
2045 ;; Note that faces added through KEYWORDS should never replace the
2046 ;; existing `c-doc-face-name' face since the existence of that face
2047 ;; is used as a flag in other code to skip comments.
0386b551
AM
2048 ;;
2049 ;; This function might do hidden buffer changes.
d9e94c22
MS
2050
2051 (let (comment-beg region-beg)
2052 (if (eq (get-text-property (point) 'face)
2053 'font-lock-comment-face)
2054 ;; Handle the case when the fontified region starts inside a
2055 ;; comment.
2056 (let ((range (c-literal-limits)))
2057 (setq region-beg (point))
2058 (when range
2059 (goto-char (car range)))
2060 (when (looking-at prefix)
2061 (setq comment-beg (point)))))
2062
2063 (while (or
2064 comment-beg
2065
2066 ;; Search for the prefix until a match is found at the start
2067 ;; of a comment.
2068 (while (when (re-search-forward prefix limit t)
2069 (setq comment-beg (match-beginning 0))
2070 (or (not (c-got-face-at comment-beg
2071 c-literal-faces))
2072 (and (/= comment-beg (point-min))
2073 (c-got-face-at (1- comment-beg)
2074 c-literal-faces))))
2075 (setq comment-beg nil))
2076 (setq region-beg comment-beg))
2077
2078 (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t)
2079 ;; Collect a sequence of doc style line comments.
2080 (progn
2081 (goto-char comment-beg)
2082 (while (and (progn
2083 (c-forward-single-comment)
2084 (skip-syntax-forward " ")
2085 (< (point) limit))
2086 (looking-at prefix))))
2087 (goto-char comment-beg)
2088 (c-forward-single-comment))
2089 (if (> (point) limit) (goto-char limit))
2090 (setq comment-beg nil)
2091
2092 (let ((region-end (point))
2093 (keylist keywords) keyword matcher highlights)
2094 (c-put-font-lock-face region-beg region-end c-doc-face-name)
2095 (save-restriction
2096 ;; Narrow to the doc comment. Among other things, this
2097 ;; helps by making "^" match at the start of the comment.
2098 ;; Do not include a trailing block comment ender, though.
2099 (and (> region-end (1+ region-beg))
2100 (progn (goto-char region-end)
2101 (backward-char 2)
2102 (looking-at "\\*/"))
2103 (setq region-end (point)))
2104 (narrow-to-region region-beg region-end)
2105
2106 (while keylist
2107 (setq keyword (car keylist)
2108 keylist (cdr keylist)
2109 matcher (car keyword))
2110 (goto-char region-beg)
2111 (while (if (stringp matcher)
2112 (re-search-forward matcher region-end t)
2113 (funcall matcher region-end))
2114 (setq highlights (cdr keyword))
2115 (if (consp (car highlights))
2116 (while highlights
2117 (font-lock-apply-highlight (car highlights))
2118 (setq highlights (cdr highlights)))
2119 (font-lock-apply-highlight highlights))))
2120
2121 (goto-char region-end)))))
2122 nil)
2123(put 'c-font-lock-doc-comments 'lisp-indent-function 2)
2124
2125(defun c-find-invalid-doc-markup (regexp limit)
2126 ;; Used to fontify invalid markup in doc comments after the correct
5a89f0a7 2127 ;; ones have been fontified: Find the first occurrence of REGEXP
d9e94c22
MS
2128 ;; between the point and LIMIT that only is fontified with
2129 ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds
2130 ;; the first char and t is returned, otherwise nil is returned.
0386b551
AM
2131 ;;
2132 ;; This function might do hidden buffer changes.
d9e94c22
MS
2133 (let (start)
2134 (while (if (re-search-forward regexp limit t)
2135 (not (eq (get-text-property
2136 (setq start (match-beginning 0)) 'face)
2137 c-doc-face-name))
2138 (setq start nil)))
2139 (when start
2140 (store-match-data (list (copy-marker start)
2141 (copy-marker (1+ start))))
2142 t)))
2143
0386b551
AM
2144;; GtkDoc patterns contributed by Masatake YAMATO <jet@gyve.org>.
2145
2146(defconst gtkdoc-font-lock-doc-comments
2147 (let ((symbol "[a-zA-Z0-9_]+")
2148 (header "^ \\* "))
2149 `((,(concat header "\\(" symbol "\\):[ \t]*$")
2150 1 ,c-doc-markup-face-name prepend nil)
2151 (,(concat symbol "()")
2152 0 ,c-doc-markup-face-name prepend nil)
2153 (,(concat header "\\(" "@" symbol "\\):")
2154 1 ,c-doc-markup-face-name prepend nil)
68a4a27a 2155 (,(concat "[#%@]" symbol)
0386b551
AM
2156 0 ,c-doc-markup-face-name prepend nil))
2157 ))
2158
2159(defconst gtkdoc-font-lock-doc-protection
2160 `(("< \\(public\\|private\\|protected\\) >"
2161 1 ,c-doc-markup-face-name prepend nil)))
2162
2163(defconst gtkdoc-font-lock-keywords
2164 `((,(lambda (limit)
2165 (c-font-lock-doc-comments "/\\*\\*$" limit
2166 gtkdoc-font-lock-doc-comments)
2167 (c-font-lock-doc-comments "/\\*< " limit
2168 gtkdoc-font-lock-doc-protection)
2169 ))))
2170
2171;; Javadoc.
2172
7bfc3fdb
MS
2173(defconst javadoc-font-lock-doc-comments
2174 `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup.
2175 0 ,c-doc-markup-face-name prepend nil)
0386b551
AM
2176 ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup.
2177 3 ,c-doc-markup-face-name prepend nil)
7bfc3fdb
MS
2178 (,(concat "</?\\sw" ; HTML tags.
2179 "\\("
2180 (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"
2181 "\"[^\"]*\"\\|'[^']*'")
2182 "\\)*>")
2183 0 ,c-doc-markup-face-name prepend nil)
2184 ("&\\(\\sw\\|[.:]\\)+;" ; HTML entities.
2185 0 ,c-doc-markup-face-name prepend nil)
2186 ;; Fontify remaining markup characters as invalid. Note
2187 ;; that the Javadoc spec is hazy about when "@" is
2188 ;; allowed in non-markup use.
2189 (,(lambda (limit)
2190 (c-find-invalid-doc-markup "[<>&]\\|{@" limit))
0386b551 2191 0 'font-lock-warning-face prepend nil)))
7bfc3fdb
MS
2192
2193(defconst javadoc-font-lock-keywords
2194 `((,(lambda (limit)
2195 (c-font-lock-doc-comments "/\\*\\*" limit
2196 javadoc-font-lock-doc-comments)))))
d9e94c22 2197
0386b551
AM
2198;; Pike autodoc.
2199
d9e94c22
MS
2200(defconst autodoc-decl-keywords
2201 ;; Adorned regexp matching the keywords that introduce declarations
2202 ;; in Pike Autodoc.
2203 (cc-eval-when-compile
2204 (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode)))
2205
2206(defconst autodoc-decl-type-keywords
2207 ;; Adorned regexp matching the keywords that are followed by a type.
2208 (cc-eval-when-compile
2209 (c-make-keywords-re t '("@elem" "@member") 'pike-mode)))
2210
2211(defun autodoc-font-lock-line-markup (limit)
2212 ;; Fontify all line oriented keywords between the point and LIMIT.
2213 ;; Nil is always returned.
0386b551
AM
2214 ;;
2215 ;; This function might do hidden buffer changes.
d9e94c22
MS
2216
2217 (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("
2218 c-current-comment-prefix
2219 "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)"))
2220 (markup-faces (list c-doc-markup-face-name c-doc-face-name)))
2221
2222 (while (re-search-forward line-re limit t)
2223 (goto-char (match-end 1))
2224
2225 (if (looking-at autodoc-decl-keywords)
2226 (let* ((kwd-pos (point))
2227 (start (match-end 1))
2228 (pos start)
2229 end)
2230
2231 (c-put-font-lock-face (point) pos markup-faces)
2232
2233 ;; Put a declaration end mark at the markup keyword and
2234 ;; remove the faces from the rest of the line so that it
2235 ;; gets refontified as a declaration later on by
2236 ;; `c-font-lock-declarations'.
2237 (c-put-char-property (1- pos) 'c-type 'c-decl-end)
2238 (goto-char pos)
2239 (while (progn
2240 (end-of-line)
2241 (setq end (point))
2242 (and (eq (char-before) ?@)
2243 (not (eobp))
2244 (progn (forward-char)
0386b551 2245 (skip-syntax-forward " ")
d9e94c22
MS
2246 (looking-at c-current-comment-prefix))))
2247 (goto-char (match-end 0))
2248 (c-remove-font-lock-face pos (1- end))
2249 (c-put-font-lock-face (1- end) end markup-faces)
2250 (setq pos (point)))
2251
2252 ;; Include the final newline in the removed area. This
2253 ;; has no visual effect but it avoids some tricky special
2254 ;; cases in the testsuite wrt the differences in string
2255 ;; fontification in Emacs vs XEmacs.
2256 (c-remove-font-lock-face pos (min (1+ (point)) (point-max)))
2257
2258 ;; Must handle string literals explicitly inside the declaration.
2259 (goto-char start)
2260 (while (re-search-forward
2261 "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'"
2262 end 'move)
2263 (c-put-font-lock-string-face (match-beginning 0)
2264 (point)))
2265
2266 ;; Fontify types after keywords that always are followed
2267 ;; by them.
2268 (goto-char kwd-pos)
2269 (when (looking-at autodoc-decl-type-keywords)
2270 (c-fontify-types-and-refs ((c-promote-possible-types t))
2271 (goto-char start)
2272 (c-forward-syntactic-ws)
2273 (c-forward-type))))
2274
2275 ;; Mark each whole line as markup, as long as the logical line
2276 ;; continues.
2277 (while (progn
2278 (c-put-font-lock-face (point)
2279 (progn (end-of-line) (point))
2280 markup-faces)
2281 (and (eq (char-before) ?@)
2282 (not (eobp))
2283 (progn (forward-char)
0386b551 2284 (skip-syntax-forward " ")
d9e94c22
MS
2285 (looking-at c-current-comment-prefix))))
2286 (goto-char (match-end 0))))))
2287
2288 nil)
2289
7bfc3fdb
MS
2290(defconst autodoc-font-lock-doc-comments
2291 `(("@\\(\\w+{\\|\\[\\([^\]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)"
2292 ;; In-text markup.
2293 0 ,c-doc-markup-face-name prepend nil)
2294 (autodoc-font-lock-line-markup)
2295 ;; Fontify remaining markup characters as invalid.
2296 (,(lambda (limit)
2297 (c-find-invalid-doc-markup "@" limit))
0386b551 2298 0 'font-lock-warning-face prepend nil)
7bfc3fdb
MS
2299 ))
2300
d9e94c22
MS
2301(defun autodoc-font-lock-keywords ()
2302 ;; Note that we depend on that `c-current-comment-prefix' has got
2303 ;; its proper value here.
0386b551
AM
2304 ;;
2305 ;; This function might do hidden buffer changes.
d9e94c22
MS
2306
2307 ;; The `c-type' text property with `c-decl-end' is used to mark the
2308 ;; end of the `autodoc-decl-keywords' occurrences to fontify the
2309 ;; following declarations.
2310 (setq c-type-decl-end-used t)
2311
7bfc3fdb
MS
2312 `((,(lambda (limit)
2313 (c-font-lock-doc-comments "/[*/]!" limit
2314 autodoc-font-lock-doc-comments)))))
d9e94c22
MS
2315
2316\f
3c0ab532 2317;; 2006-07-10: awk-font-lock-keywords has been moved back to cc-awk.el.
d9e94c22
MS
2318(cc-provide 'cc-fonts)
2319
cbee283d 2320;; arch-tag: 2f65f405-735f-4da5-8d4b-b957844c5203
d9e94c22 2321;;; cc-fonts.el ends here