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