Commit | Line | Data |
---|---|---|
d9e94c22 MS |
1 | ;;; cc-fonts.el --- font lock support for CC Mode |
2 | ||
3 | ;; Copyright (C) 2002, 03 Free Software Foundation, Inc. | |
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 | |
16 | ;; the Free Software Foundation; either version 2, or (at your option) | |
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 | |
26 | ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
27 | ;; Boston, MA 02111-1307, USA. | |
28 | ||
29 | ;;; Commentary: | |
30 | ||
31 | ;; Some comments on the use of faces: | |
32 | ;; | |
33 | ;; o `c-label-face-name' is either `font-lock-constant-face' (in Emacs | |
34 | ;; 20 and later), or `font-lock-reference-face'. | |
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 | ;; | |
50 | ;; o `c-invalid-face-name' is `font-lock-warning-face' in Emacs. In | |
51 | ;; older XEmacs there's no corresponding standard face, so there | |
52 | ;; it's mapped to a special `c-invalid-face'. | |
53 | ;; | |
54 | ;; TBD: We should probably provide real faces for the above uses and | |
55 | ;; instead initialize them from the standard faces. | |
56 | ||
57 | ;;; Code: | |
58 | ||
59 | ;; The faces that already have been put onto the text is tested in | |
60 | ;; various places to direct further fontifications. For this to work, | |
61 | ;; the following assumptions regarding the faces must hold (apart from | |
62 | ;; the dependencies on the font locking order): | |
63 | ;; | |
64 | ;; o `font-lock-comment-face' and the face in `c-doc-face-name' is | |
65 | ;; not used in anything but comments. | |
66 | ;; o If any face (e.g. `c-doc-markup-face-name') but those above is | |
67 | ;; used in comments, it doesn't replace them. | |
68 | ;; o `font-lock-string-face' is not used in anything but string | |
69 | ;; literals (single or double quoted). | |
70 | ;; o `font-lock-keyword-face' and the face in `c-label-face-name' are | |
71 | ;; never overlaid with other faces. | |
72 | ||
73 | (eval-when-compile | |
74 | (let ((load-path | |
75 | (if (and (boundp 'byte-compile-dest-file) | |
76 | (stringp byte-compile-dest-file)) | |
77 | (cons (file-name-directory byte-compile-dest-file) load-path) | |
78 | load-path))) | |
79 | (load "cc-bytecomp" nil t))) | |
80 | ||
81 | (cc-require 'cc-defs) | |
82 | (cc-require-when-compile 'cc-langs) | |
83 | (cc-require 'cc-vars) | |
84 | (cc-require 'cc-engine) | |
85 | (cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to | |
86 | ;; prevent cc-awk being loaded when it's not needed. There is now a (require | |
87 | ;; 'cc-awk) in (defun awk-mode ..). | |
88 | ||
89 | ;; Avoid repeated loading through the eval-after-load directive in | |
90 | ;; cc-mode.el. | |
91 | (provide 'cc-fonts) | |
92 | ||
93 | (cc-external-require 'font-lock) | |
94 | ||
95 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only. | |
96 | ||
97 | ;; Need to declare these local symbols during compilation since | |
98 | ;; they're referenced from lambdas in `byte-compile' calls that are | |
99 | ;; executed at compile time. They don't need to have the proper | |
100 | ;; definitions, though, since the generated functions aren't called | |
101 | ;; during compilation. | |
102 | (cc-bytecomp-defvar c-preprocessor-face-name) | |
103 | (cc-bytecomp-defvar c-reference-face-name) | |
104 | (cc-bytecomp-defun c-fontify-recorded-types-and-refs) | |
105 | (cc-bytecomp-defun c-font-lock-declarators) | |
106 | (cc-bytecomp-defun c-font-lock-objc-iip-decl) | |
107 | (cc-bytecomp-defun c-font-lock-objc-method) | |
108 | (cc-bytecomp-defun c-font-lock-invalid-string) | |
109 | ||
110 | ;; Emacs 19 doesn't have `defface'. This "replacement" leaves a lot | |
111 | ;; to be wished for but at least it avoids any errors. | |
112 | (cc-eval-when-compile | |
113 | (or (fboundp 'defface) | |
114 | (cc-bytecomp-defmacro defface (face spec doc &rest args) | |
115 | `(make-face ',face)))) | |
116 | ||
117 | \f | |
118 | ;; Note that font-lock in XEmacs doesn't expand face names as | |
119 | ;; variables, so we have to use the (eval . FORM) in the font lock | |
120 | ;; matchers wherever we use these alias variables. | |
121 | ||
122 | (defconst c-preprocessor-face-name | |
123 | (cond ((c-face-name-p 'font-lock-preprocessor-face) | |
124 | ;; XEmacs has a font-lock-preprocessor-face. | |
125 | 'font-lock-preprocessor-face) | |
126 | ((c-face-name-p 'font-lock-builtin-face) | |
127 | ;; In Emacs 20 and later font-lock-builtin-face has | |
128 | ;; traditionally been used for preprocessor directives. | |
129 | 'font-lock-builtin-face) | |
130 | (t | |
131 | 'font-lock-reference-face))) | |
132 | ||
133 | (cc-bytecomp-defvar font-lock-constant-face) | |
134 | ||
135 | (defconst c-label-face-name | |
136 | (cond ((c-face-name-p 'font-lock-label-face) | |
137 | ;; If it happens to occur in the future. (Well, the more | |
138 | ;; pragmatic reason is to get unique faces for the test | |
139 | ;; suite.) | |
140 | 'font-lock-label-face) | |
141 | ((and (c-face-name-p 'font-lock-constant-face) | |
142 | (eq font-lock-constant-face 'font-lock-constant-face)) | |
143 | ;; Test both if font-lock-constant-face exists and that it's | |
144 | ;; not an alias for something else. This is important since | |
145 | ;; we compare already set faces in various places. | |
146 | 'font-lock-constant-face) | |
147 | (t | |
148 | 'font-lock-reference-face))) | |
149 | ||
150 | (defconst c-constant-face-name | |
151 | (if (and (c-face-name-p 'font-lock-constant-face) | |
152 | (eq font-lock-constant-face 'font-lock-constant-face)) | |
153 | ;; This doesn't exist in XEmacs <= 20 and some earlier versions | |
154 | ;; of XEmacs 21. | |
155 | 'font-lock-constant-face | |
156 | c-label-face-name)) | |
157 | ||
158 | (defconst c-reference-face-name | |
159 | (if (and (c-face-name-p 'font-lock-reference-face) | |
160 | (eq font-lock-reference-face 'font-lock-reference-face)) | |
161 | ;; This is considered obsolete in Emacs 20 and later, but it | |
162 | ;; still maps well to this use. (Another reason to do this is | |
163 | ;; to get unique faces for the test suite.) | |
164 | 'font-lock-reference-face | |
165 | c-label-face-name)) | |
166 | ||
167 | ;; This should not mapped to a face that also is used to fontify things | |
168 | ;; that aren't comments or string literals. | |
169 | (defconst c-doc-face-name | |
170 | (cond ((c-face-name-p 'font-lock-doc-string-face) | |
171 | ;; XEmacs. | |
172 | 'font-lock-doc-string-face) | |
173 | ((c-face-name-p 'font-lock-doc-face) | |
174 | ;; Emacs 21 and later. | |
175 | 'font-lock-doc-face) | |
176 | (t | |
177 | 'font-lock-comment-face))) | |
178 | ||
179 | (defconst c-doc-markup-face-name | |
180 | (if (c-face-name-p 'font-lock-doc-markup-face) | |
181 | ;; If it happens to occur in the future. (Well, the more | |
182 | ;; pragmatic reason is to get unique faces for the test | |
183 | ;; suite.) | |
184 | 'font-lock-doc-markup-face | |
185 | c-label-face-name)) | |
186 | ||
187 | (defconst c-invalid-face-name | |
188 | (if (c-face-name-p 'font-lock-warning-face) | |
189 | ;; Emacs >= 20 and XEmacs >= 21 has a font-lock-warning-face. | |
190 | 'font-lock-warning-face | |
191 | ;; Otherwise we provide a face. | |
192 | 'c-invalid-face)) | |
193 | ||
194 | (unless (c-face-name-p c-invalid-face-name) | |
195 | (defconst c-invalid-face 'c-invalid-face) ; Necessary in Emacs 19. | |
196 | (defface c-invalid-face | |
197 | '((((class color) (background light)) (:foreground "red")) | |
198 | (((class color)) (:foreground "hotpink")) | |
199 | (t (:inverse-video t))) | |
200 | "Face used to highlight invalid syntax." | |
201 | :group 'c-fonts)) | |
202 | ||
203 | ;; To make hard spaces visible an inverted version of | |
204 | ;; `c-invalid-face-name' is used. Since font-lock in Emacs expands | |
205 | ;; all face names in `font-lock-keywords' as variables we need to have | |
206 | ;; a variable for it that resolves to its own name. | |
207 | (defconst c-nonbreakable-space-face 'c-nonbreakable-space-face) | |
208 | ||
209 | (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. | |
210 | (cc-bytecomp-defun face-property-instance) ; Only in XEmacs. | |
211 | ||
212 | (defun c-make-inverse-face (oldface newface) | |
213 | ;; Emacs and XEmacs have completely different face manipulation | |
214 | ;; routines. :P | |
215 | ;; | |
216 | ;; This function does not do any hidden buffer changes | |
217 | (copy-face oldface newface) | |
218 | (cond ((fboundp 'face-inverse-video-p) | |
219 | ;; Emacs 20 and later. This only looks at the inverse flag | |
220 | ;; in the current frame. Other display configurations might | |
221 | ;; be different, but it can only show if the same Emacs has | |
222 | ;; frames on e.g. a color and a monochrome display | |
223 | ;; simultaneously. | |
224 | (unless (face-inverse-video-p oldface) | |
225 | (invert-face newface))) | |
226 | ((fboundp 'face-property-instance) | |
227 | ;; XEmacs. Same pitfall here. | |
228 | (unless (face-property-instance oldface 'reverse) | |
229 | (invert-face newface))) | |
230 | (t | |
231 | ;; Emacs 19 has no inverse flag at all. Just inverse the | |
232 | ;; face and hope it wasn't inversed already. | |
233 | (invert-face newface)))) | |
234 | ||
235 | (eval-and-compile | |
236 | ;; We need the following functions during compilation since they're | |
237 | ;; called when the `c-lang-defconst' initializers are evaluated. | |
238 | ;; Define them at runtime too for the sake of derived modes. | |
239 | ||
240 | (defmacro c-put-font-lock-face (from to face) | |
241 | ;; Put a face on a region (overriding any existing face) in the way | |
242 | ;; font-lock would do it. In XEmacs that means putting an | |
243 | ;; additional font-lock property, or else the font-lock package | |
244 | ;; won't recognize it as fontified and might override it | |
245 | ;; incorrectly. | |
246 | (if (fboundp 'font-lock-set-face) | |
247 | ;; Note: This function has no docstring in XEmacs so it might be | |
248 | ;; considered internal. | |
249 | `(font-lock-set-face ,from ,to ,face) | |
250 | `(put-text-property ,from ,to 'face ,face))) | |
251 | ||
252 | (defmacro c-remove-font-lock-face (from to) | |
253 | ;; This is the inverse of `c-put-font-lock-face'. | |
254 | (if (fboundp 'font-lock-remove-face) | |
255 | `(font-lock-remove-face ,from ,to) | |
256 | `(remove-text-properties ,from ,to '(face nil)))) | |
257 | ||
258 | (defmacro c-put-font-lock-string-face (from to) | |
259 | ;; Put `font-lock-string-face' on a string. The surrounding | |
260 | ;; quotes are included in Emacs but not in XEmacs. The passed | |
261 | ;; region should include them. | |
262 | (if (featurep 'xemacs) | |
263 | `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face) | |
264 | `(c-put-font-lock-face ,from ,to 'font-lock-string-face))) | |
265 | ||
266 | (defmacro c-fontify-types-and-refs (varlist &rest body) | |
267 | ;; Like `let', but additionally activates `c-record-type-identifiers' | |
268 | ;; and `c-record-ref-identifiers', and fontifies the recorded ranges | |
269 | ;; accordingly on exit. | |
270 | `(let ((c-record-type-identifiers t) | |
271 | c-record-ref-identifiers | |
272 | ,@varlist) | |
273 | (prog1 (progn ,@body) | |
274 | (c-fontify-recorded-types-and-refs)))) | |
275 | (put 'c-fontify-types-and-refs 'lisp-indent-function 1) | |
276 | (eval-after-load "edebug" '(def-edebug-spec c-fontify-types-and-refs let*)) | |
277 | ||
278 | (defun c-skip-comments-and-strings (limit) | |
279 | ;; If the point is within a region fontified as a comment or | |
280 | ;; string literal skip to the end of it or to LIMIT, whichever | |
281 | ;; comes first, and return t. Otherwise return nil. The match | |
282 | ;; data is not clobbered. | |
283 | (when (c-got-face-at (point) c-literal-faces) | |
284 | (while (progn | |
285 | (goto-char (next-single-property-change | |
286 | (point) 'face nil limit)) | |
287 | (and (< (point) limit) | |
288 | (c-got-face-at (point) c-literal-faces)))) | |
289 | t)) | |
290 | ||
291 | (defun c-make-font-lock-search-function (regexp &rest highlights) | |
292 | ;; This function makes a byte compiled function that works much like | |
293 | ;; a matcher element in `font-lock-keywords'. It cuts out a little | |
294 | ;; bit of the overhead compared to a real matcher. The main reason | |
295 | ;; is however to pass the real search limit to the anchored | |
296 | ;; matcher(s), since most (if not all) font-lock implementations | |
297 | ;; arbitrarily limits anchored matchers to the same line, and also | |
298 | ;; to insulate against various other irritating differences between | |
299 | ;; the different (X)Emacs font-lock packages. | |
300 | ;; | |
301 | ;; REGEXP is the matcher, which must be a regexp. Only matches | |
302 | ;; where the beginning is outside any comment or string literal are | |
303 | ;; significant. | |
304 | ;; | |
305 | ;; HIGHLIGHTS is a list of highlight specs, just like in | |
306 | ;; `font-lock-keywords', with these limitations: The face is always | |
307 | ;; overridden (no big disadvantage, since hits in comments etc are | |
308 | ;; filtered anyway), there is no "laxmatch", and an anchored matcher | |
309 | ;; is always a form which must do all the fontification directly. | |
310 | ;; `limit' is a variable bound to the real limit in the context of | |
311 | ;; the anchored matcher forms. | |
312 | ;; | |
313 | ;; This function does not do any hidden buffer changes, but the | |
314 | ;; generated functions will. They are however used in places | |
315 | ;; covered by the font-lock context. | |
316 | ||
317 | ;; Note: Replace `byte-compile' with `eval' to debug the generated | |
318 | ;; lambda easier. | |
319 | (byte-compile | |
320 | `(lambda (limit) | |
321 | (let (-match-end-pos- | |
322 | ;; The font-lock package in Emacs is known to clobber | |
323 | ;; `parse-sexp-lookup-properties' (when it exists). | |
324 | (parse-sexp-lookup-properties | |
325 | (cc-eval-when-compile | |
326 | (boundp 'parse-sexp-lookup-properties)))) | |
327 | (while (re-search-forward ,regexp limit t) | |
328 | (setq -match-end-pos- (point)) | |
329 | (unless (progn | |
330 | (goto-char (match-beginning 0)) | |
331 | (c-skip-comments-and-strings limit)) | |
332 | (goto-char -match-end-pos-) | |
333 | ,@(mapcar | |
334 | (lambda (highlight) | |
335 | (if (integerp (car highlight)) | |
336 | (progn | |
337 | (unless (nth 2 highlight) | |
338 | (error | |
339 | "The override flag must currently be set in %s" | |
340 | highlight)) | |
341 | (when (nth 3 highlight) | |
342 | (error | |
343 | "The laxmatch flag may currently not be set in %s" | |
344 | highlight)) | |
345 | `(save-match-data | |
346 | (c-put-font-lock-face | |
347 | (match-beginning ,(car highlight)) | |
348 | (match-end ,(car highlight)) | |
349 | ,(elt highlight 1)))) | |
350 | (when (nth 3 highlight) | |
351 | (error "Match highlights currently not supported in %s" | |
352 | highlight)) | |
353 | `(progn | |
354 | ,(nth 1 highlight) | |
355 | (save-match-data ,(car highlight)) | |
356 | ,(nth 2 highlight)))) | |
357 | highlights)))) | |
358 | nil)))) | |
359 | ||
360 | (defun c-fontify-recorded-types-and-refs () | |
361 | ;; Converts the ranges recorded on `c-record-type-identifiers' and | |
362 | ;; `c-record-ref-identifiers' to fontification. | |
363 | (let (elem) | |
364 | (while (consp c-record-type-identifiers) | |
365 | (setq elem (car c-record-type-identifiers) | |
366 | c-record-type-identifiers (cdr c-record-type-identifiers)) | |
367 | (c-put-font-lock-face (car elem) (cdr elem) | |
368 | 'font-lock-type-face)) | |
369 | (while c-record-ref-identifiers | |
370 | (setq elem (car c-record-ref-identifiers) | |
371 | c-record-ref-identifiers (cdr c-record-ref-identifiers)) | |
372 | ;; Note that the reference face is a variable that is | |
373 | ;; dereferenced, since it's an alias in Emacs. | |
374 | (c-put-font-lock-face (car elem) (cdr elem) | |
375 | c-reference-face-name)))) | |
376 | ||
377 | (c-lang-defconst c-cpp-matchers | |
378 | "Font lock matchers for preprocessor directives and purely lexical | |
379 | stuff. Used on level 1 and higher." | |
380 | ||
381 | ;; Note: `c-font-lock-declarations' assumes that no matcher here | |
382 | ;; sets `font-lock-type-face' in languages where | |
383 | ;; `c-recognize-<>-arglists' is set. | |
384 | ||
385 | t `(,@(when (c-lang-const c-opt-cpp-prefix) | |
386 | (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)") | |
387 | (ncle-depth (c-regexp-opt-depth noncontinued-line-end)) | |
388 | (sws-depth (c-lang-const c-syntactic-ws-depth))) | |
389 | `(;; The stuff after #error and #warning is a message, so | |
390 | ;; fontify it as a string. | |
391 | (,(concat noncontinued-line-end | |
392 | (c-lang-const c-opt-cpp-prefix) | |
393 | "\\(error\\|warning\\)\\>\\s *\\(.*\\)$") | |
394 | ,(+ ncle-depth 2) font-lock-string-face) | |
395 | ||
396 | ;; Fontify filenames in #include <...> as strings. | |
397 | (,(concat noncontinued-line-end | |
398 | (c-lang-const c-opt-cpp-prefix) | |
399 | "\\(import\\|include\\)\\>" | |
400 | (c-lang-const c-syntactic-ws) | |
401 | "\\(<[^>\n\r]*>?\\)") | |
402 | (,(+ ncle-depth sws-depth 2) | |
403 | font-lock-string-face) | |
404 | ||
405 | ;; Use an anchored matcher to put paren syntax on the brackets. | |
406 | (,(byte-compile | |
407 | `(lambda (limit) | |
408 | (let ((beg-pos | |
409 | (match-beginning ,(+ ncle-depth sws-depth 2))) | |
410 | (end-pos | |
411 | (1- (match-end ,(+ ncle-depth sws-depth 2))))) | |
412 | (if (eq (char-after end-pos) ?>) | |
413 | (progn | |
414 | (c-mark-<-as-paren beg-pos) | |
415 | (c-mark->-as-paren end-pos)) | |
416 | (c-clear-char-property beg-pos 'syntax-table))) | |
417 | nil)))) | |
418 | ||
419 | ;; #define. | |
420 | (,(c-make-font-lock-search-function | |
421 | (concat | |
422 | noncontinued-line-end | |
423 | (c-lang-const c-opt-cpp-prefix) | |
424 | "define\\>" | |
425 | (c-lang-const c-syntactic-ws) | |
426 | "\\(" (c-lang-const c-symbol-key) "\\)" ; 1 + ncle + sws | |
427 | (concat "\\(" ; 2 + ncle + sws + c-sym-key | |
428 | ;; Macro with arguments - a "function". | |
429 | "\\(\(\\)" ; 3 + ncle + sws + c-sym-key | |
430 | "\\|" | |
431 | ;; Macro without arguments - a "variable". | |
432 | "\\([^\(]\\|$\\)" | |
433 | "\\)")) | |
434 | `((if (match-beginning ,(+ 3 ncle-depth sws-depth | |
435 | (c-lang-const c-symbol-key-depth))) | |
436 | ;; "Function". Fontify the name and the arguments. | |
437 | (save-restriction | |
438 | (c-put-font-lock-face | |
439 | (match-beginning ,(+ 1 ncle-depth sws-depth)) | |
440 | (match-end ,(+ 1 ncle-depth sws-depth)) | |
441 | 'font-lock-function-name-face) | |
442 | (goto-char (match-end | |
443 | ,(+ 3 ncle-depth sws-depth | |
444 | (c-lang-const c-symbol-key-depth)))) | |
445 | ||
446 | (narrow-to-region (point-min) limit) | |
447 | (while (and | |
448 | (progn | |
449 | (c-forward-syntactic-ws) | |
450 | (looking-at c-symbol-key)) | |
451 | (progn | |
452 | (c-put-font-lock-face | |
453 | (match-beginning 0) (match-end 0) | |
454 | 'font-lock-variable-name-face) | |
455 | (goto-char (match-end 0)) | |
456 | (c-forward-syntactic-ws) | |
457 | (eq (char-after) ?,))) | |
458 | (forward-char))) | |
459 | ||
460 | ;; "Variable". | |
461 | (c-put-font-lock-face | |
462 | (match-beginning ,(+ 1 ncle-depth sws-depth)) | |
463 | (match-end ,(+ 1 ncle-depth sws-depth)) | |
464 | 'font-lock-variable-name-face))))) | |
465 | ||
466 | ;; Fontify cpp function names in preprocessor | |
467 | ;; expressions in #if and #elif. | |
468 | ,(when (c-lang-const c-cpp-defined-fns) | |
469 | `(,(c-make-font-lock-search-function | |
470 | (concat noncontinued-line-end | |
471 | (c-lang-const c-opt-cpp-prefix) | |
472 | "\\(if\\|elif\\)\\>" ; 1 + ncle-depth | |
473 | ;; Match the whole logical line to look | |
474 | ;; for the functions in. | |
475 | "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") | |
476 | `((let ((limit (match-end 0))) | |
477 | (while (re-search-forward | |
478 | ,(concat "\\<\\(" | |
479 | (c-regexp-opt | |
480 | (c-lang-const c-cpp-defined-fns) | |
481 | nil) | |
482 | "\\)\\>" | |
483 | "\\s *\(?") | |
484 | limit 'move) | |
485 | (c-put-font-lock-face (match-beginning 1) | |
486 | (match-end 1) | |
487 | c-preprocessor-face-name))) | |
488 | (goto-char (match-end ,(1+ ncle-depth))))))) | |
489 | ||
490 | ;; Fontify the directive names. | |
491 | (,(c-make-font-lock-search-function | |
492 | (concat noncontinued-line-end | |
493 | "\\(" | |
494 | (c-lang-const c-opt-cpp-prefix) | |
495 | "[" (c-lang-const c-symbol-chars) "]+" | |
496 | "\\)") | |
497 | `(,(1+ ncle-depth) c-preprocessor-face-name t))) | |
498 | ))) | |
499 | ||
500 | ,@(when (c-major-mode-is 'pike-mode) | |
501 | `((eval . (list "\\`#![^\n\r]*" | |
502 | 0 c-preprocessor-face-name)))) | |
503 | ||
504 | ;; Make hard spaces visible through an inverted `c-invalid-face-name'. | |
505 | (eval . (list | |
506 | "\240" | |
507 | 0 (progn | |
508 | (unless (c-face-name-p 'c-nonbreakable-space-face) | |
509 | (c-make-inverse-face c-invalid-face-name | |
510 | 'c-nonbreakable-space-face)) | |
511 | 'c-nonbreakable-space-face))) | |
512 | )) | |
513 | ||
514 | (defun c-font-lock-invalid-string () | |
515 | ;; Assuming the point is after the opening character of a string, | |
516 | ;; fontify that char with `c-invalid-face-name' if the string | |
a6782a6e MS |
517 | ;; decidedly isn't terminated properly. |
518 | (let ((start (1- (point)))) | |
519 | (save-excursion | |
520 | (and (nth 3 (parse-partial-sexp start (c-point 'eol))) | |
521 | (if (c-major-mode-is '(c-mode c++-mode objc-mode pike-mode)) | |
522 | ;; There's no \ before the newline. | |
523 | (not (eq (char-before (point)) ?\\)) | |
524 | ;; Quoted newlines aren't supported. | |
525 | t) | |
526 | (if (c-major-mode-is 'pike-mode) | |
527 | ;; There's no # before the string, so newlines | |
528 | ;; aren't allowed. | |
529 | (not (eq (char-before start) ?#)) | |
530 | t) | |
531 | (c-put-font-lock-face start (1+ start) c-invalid-face-name))))) | |
d9e94c22 MS |
532 | |
533 | (c-lang-defconst c-basic-matchers-before | |
534 | "Font lock matchers for basic keywords, labels, references and various | |
535 | other easily recognizable things that should be fontified before generic | |
536 | casts and declarations are fontified. Used on level 2 and higher." | |
537 | ||
538 | ;; Note: `c-font-lock-declarations' assumes that no matcher here | |
539 | ;; sets `font-lock-type-face' in languages where | |
540 | ;; `c-recognize-<>-arglists' is set. | |
541 | ||
542 | t `(;; Put a warning face on the opener of unclosed strings that | |
543 | ;; can't span lines. Later font | |
544 | ;; lock packages have a `font-lock-syntactic-face-function' for | |
545 | ;; this, but it doesn't give the control we want since any | |
546 | ;; fontification done inside the function will be | |
547 | ;; unconditionally overridden. | |
548 | ,(c-make-font-lock-search-function | |
549 | ;; Match a char before the string starter to make | |
550 | ;; `c-skip-comments-and-strings' work correctly. | |
551 | (concat ".\\(" c-string-limit-regexp "\\)") | |
552 | '((c-font-lock-invalid-string))) | |
553 | ||
554 | ;; Fontify keyword constants. | |
555 | ,@(when (c-lang-const c-constant-kwds) | |
556 | (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) | |
557 | (if (c-major-mode-is 'pike-mode) | |
558 | ;; No symbol is a keyword after "->" in Pike. | |
559 | `((eval . (list ,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" | |
560 | "\\<\\(" re "\\)\\>") | |
561 | 3 c-constant-face-name))) | |
562 | `((eval . (list ,(concat "\\<\\(" re "\\)\\>") | |
563 | 1 c-constant-face-name)))))) | |
564 | ||
565 | ;; Fontify all keywords except the primitive types. | |
566 | ,(if (c-major-mode-is 'pike-mode) | |
567 | ;; No symbol is a keyword after "->" in Pike. | |
568 | `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" | |
569 | "\\<" (c-lang-const c-regular-keywords-regexp)) | |
570 | 3 font-lock-keyword-face) | |
571 | `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp)) | |
572 | 1 font-lock-keyword-face)) | |
573 | ||
574 | ;; Fontify leading identifiers in fully qualified names like | |
575 | ;; "foo::bar" in languages that supports such things. | |
576 | ,@(when (c-lang-const c-opt-identifier-concat-key) | |
2a15eb73 MS |
577 | (if (c-major-mode-is 'java-mode) |
578 | ;; Java needs special treatment since "." is used both to | |
579 | ;; qualify names and in normal indexing. Here we look for | |
580 | ;; capital characters at the beginning of an identifier to | |
581 | ;; recognize the class. "*" is also recognized to cover | |
582 | ;; wildcard import declarations. All preceding dot separated | |
583 | ;; identifiers are taken as package names and therefore | |
584 | ;; fontified as references. | |
585 | `(,(c-make-font-lock-search-function | |
586 | ;; Search for class identifiers preceded by ".". The | |
587 | ;; anchored matcher takes it from there. | |
588 | (concat (c-lang-const c-opt-identifier-concat-key) | |
589 | "[ \t\n\r\f\v]*" | |
590 | (concat "\\(" | |
591 | "[" c-upper "][" (c-lang-const c-symbol-chars) "]*" | |
592 | "\\|" | |
593 | "\\*" | |
594 | "\\)")) | |
595 | `((let (id-end) | |
596 | (goto-char (1+ (match-beginning 0))) | |
597 | (while (and (eq (char-before) ?.) | |
598 | (progn | |
599 | (backward-char) | |
600 | (c-backward-syntactic-ws) | |
601 | (setq id-end (point)) | |
602 | (< (skip-chars-backward | |
603 | ,(c-lang-const c-symbol-chars)) 0)) | |
604 | (not (get-text-property (point) 'face))) | |
605 | (c-put-font-lock-face (point) id-end c-reference-face-name) | |
606 | (c-backward-syntactic-ws))) | |
607 | nil | |
608 | (goto-char (match-end 0))))) | |
609 | ||
610 | `((,(byte-compile | |
611 | ;; Must use a function here since we match longer than we | |
612 | ;; want to move before doing a new search. This is not | |
613 | ;; necessary for XEmacs >= 20 since it restarts the search | |
614 | ;; from the end of the first highlighted submatch (something | |
615 | ;; that causes problems in other places). | |
616 | `(lambda (limit) | |
617 | (while (re-search-forward | |
618 | ,(concat "\\(\\<" ; 1 | |
619 | "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 | |
620 | "[ \t\n\r\f\v]*" | |
621 | (c-lang-const c-opt-identifier-concat-key) | |
622 | "[ \t\n\r\f\v]*" | |
623 | "\\)" | |
624 | "\\(" | |
625 | (c-lang-const c-opt-after-id-concat-key) | |
626 | "\\)") | |
627 | limit t) | |
628 | (unless (progn | |
629 | (goto-char (match-beginning 0)) | |
630 | (c-skip-comments-and-strings limit)) | |
631 | (or (get-text-property (match-beginning 2) 'face) | |
632 | (c-put-font-lock-face (match-beginning 2) | |
633 | (match-end 2) | |
634 | c-reference-face-name)) | |
635 | (goto-char (match-end 1)))))))))) | |
d9e94c22 MS |
636 | |
637 | ;; Fontify the special declarations in Objective-C. | |
638 | ,@(when (c-major-mode-is 'objc-mode) | |
639 | `(;; Fontify class names in the beginning of message expressions. | |
640 | ,(c-make-font-lock-search-function | |
641 | "\\[" | |
642 | '((c-fontify-types-and-refs () | |
643 | (c-forward-syntactic-ws limit) | |
644 | (let ((start (point))) | |
645 | ;; In this case we accept both primitive and known types. | |
646 | (when (eq (c-forward-type) 'known) | |
647 | (goto-char start) | |
648 | (let ((c-promote-possible-types t)) | |
649 | (c-forward-type)))) | |
650 | (if (> (point) limit) (goto-char limit))))) | |
651 | ||
652 | ;; The @interface/@implementation/@protocol directives. | |
653 | (,(concat "\\<" | |
654 | (c-regexp-opt | |
655 | '("@interface" "@implementation" "@protocol") | |
656 | t) | |
657 | "\\>") | |
658 | (,(byte-compile | |
659 | (lambda (limit) | |
660 | (let (;; The font-lock package in Emacs is known to clobber | |
661 | ;; `parse-sexp-lookup-properties' (when it exists). | |
662 | (parse-sexp-lookup-properties | |
663 | (cc-eval-when-compile | |
664 | (boundp 'parse-sexp-lookup-properties)))) | |
665 | (save-restriction | |
666 | (narrow-to-region (point-min) limit) | |
667 | (c-font-lock-objc-iip-decl))) | |
668 | nil)))))) | |
669 | )) | |
670 | ||
671 | (defun c-font-lock-complex-decl-prepare (limit) | |
672 | ;; Called before any of the matchers in `c-complex-decl-matchers'. | |
673 | ;; Nil is always returned. | |
674 | ||
675 | ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit) | |
676 | ||
677 | ;; Clear the list of found types if we start from the start of the | |
678 | ;; buffer, to make it easier to get rid of misspelled types and | |
679 | ;; variables that has gotten recognized as types in malformed code. | |
680 | (when (bobp) | |
681 | (c-clear-found-types)) | |
682 | ||
683 | ;; Clear the c-type char properties in the region to recalculate | |
684 | ;; them properly. This is necessary e.g. to handle constructs that | |
685 | ;; might been required as declarations temporarily during editing. | |
686 | ;; The interesting properties are anyway those put on the closest | |
687 | ;; token before the region. | |
688 | (c-clear-char-properties (point) limit 'c-type) | |
689 | ||
690 | ;; Update `c-state-cache' to the beginning of the region. This will | |
691 | ;; make `c-beginning-of-syntax' go faster when it's used later on, | |
692 | ;; and it's near the point most of the time. | |
693 | (c-parse-state) | |
694 | ||
695 | ;; Check if the fontified region starts inside a declarator list so | |
696 | ;; that `c-font-lock-declarators' should be called at the start. | |
697 | (let ((prop (save-excursion | |
698 | (c-backward-syntactic-ws) | |
699 | (unless (bobp) | |
700 | (c-get-char-property (1- (point)) 'c-type))))) | |
701 | (when (memq prop '(c-decl-id-start c-decl-type-start)) | |
702 | (c-forward-syntactic-ws limit) | |
703 | (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)))) | |
704 | ||
705 | nil) | |
706 | ||
707 | (defun c-font-lock-<>-arglists (limit) | |
708 | ;; Fontify types and references in names containing angle bracket | |
709 | ;; arglists from the point to LIMIT. This will also fontify cases | |
710 | ;; like normal function calls on the form "foo (a < b, c > d)", but | |
711 | ;; `c-font-lock-declarations' will undo that later. Nil is always | |
712 | ;; returned. | |
713 | ||
714 | (let (;; The font-lock package in Emacs is known to clobber | |
715 | ;; `parse-sexp-lookup-properties' (when it exists). | |
716 | (parse-sexp-lookup-properties | |
717 | (cc-eval-when-compile | |
718 | (boundp 'parse-sexp-lookup-properties))) | |
719 | id-start id-end pos kwd-sym) | |
720 | ||
721 | (while (and (< (point) limit) | |
722 | (re-search-forward c-opt-<>-arglist-start limit t)) | |
723 | ||
724 | (setq id-start (match-beginning 1) | |
725 | id-end (match-end 1) | |
726 | pos (point)) | |
727 | ||
728 | (goto-char id-start) | |
729 | (unless (c-skip-comments-and-strings limit) | |
730 | (setq kwd-sym nil) | |
731 | (if (or (not (eq (get-text-property id-start 'face) | |
732 | 'font-lock-keyword-face)) | |
733 | (when (looking-at c-opt-<>-sexp-key) | |
734 | (setq kwd-sym (c-keyword-sym (match-string 1))))) | |
735 | (progn | |
736 | (goto-char (1- pos)) | |
737 | ;; Check for comment/string both at the identifier and | |
738 | ;; at the "<". | |
739 | (unless (c-skip-comments-and-strings limit) | |
740 | ||
741 | (when (c-forward-<>-arglist (c-keyword-member kwd-sym | |
742 | 'c-<>-type-kwds) | |
743 | t) | |
744 | (when (and c-opt-identifier-concat-key | |
745 | (not (get-text-property id-start 'face))) | |
746 | (c-forward-syntactic-ws) | |
747 | (if (looking-at c-opt-identifier-concat-key) | |
748 | (c-put-font-lock-face id-start id-end | |
749 | c-reference-face-name) | |
750 | (c-put-font-lock-face id-start id-end | |
751 | 'font-lock-type-face)))) | |
752 | ||
753 | (goto-char pos))) | |
754 | (goto-char pos))))) | |
755 | nil) | |
756 | ||
757 | (defun c-font-lock-declarators (limit list types) | |
758 | ;; Assuming the point is at the start of a declarator in a | |
759 | ;; declaration, fontify it. If LIST is non-nil, fontify also all | |
760 | ;; following declarators in a comma separated list (e.g. "foo" and | |
761 | ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is | |
762 | ;; non-nil, fontify all identifiers as types. Nil is always | |
763 | ;; returned. | |
764 | ||
765 | ;;(message "c-font-lock-declarators from %s to %s" (point) limit) | |
766 | (c-fontify-types-and-refs | |
767 | ((pos (point)) next-pos id-start id-end | |
768 | paren-depth | |
769 | id-face got-init | |
770 | c-last-identifier-range | |
771 | (separator-prop (if types 'c-decl-type-start 'c-decl-id-start))) | |
772 | ||
773 | (while (and | |
774 | pos | |
775 | (< (point) limit) | |
776 | ||
777 | (let (got-identifier) | |
778 | (setq paren-depth 0) | |
779 | ;; Skip over type decl prefix operators. (Note similar | |
780 | ;; code in `c-font-lock-declarations'.) | |
781 | (while (and (looking-at c-type-decl-prefix-key) | |
782 | (if (and (c-major-mode-is 'c++-mode) | |
783 | (match-beginning 2)) | |
784 | ;; If the second submatch matches in C++ then | |
785 | ;; we're looking at an identifier that's a | |
786 | ;; prefix only if it specifies a member pointer. | |
787 | (progn | |
788 | (setq id-start (point)) | |
789 | (c-forward-name) | |
790 | (if (looking-at "\\(::\\)") | |
791 | ;; We only check for a trailing "::" and | |
792 | ;; let the "*" that should follow be | |
793 | ;; matched in the next round. | |
794 | t | |
795 | ;; It turned out to be the real identifier, | |
796 | ;; so flag that and stop. | |
797 | (setq got-identifier t) | |
798 | nil)) | |
799 | t)) | |
800 | (if (eq (char-after) ?\() | |
801 | (progn | |
802 | (setq paren-depth (1+ paren-depth)) | |
803 | (forward-char)) | |
804 | (goto-char (match-end 1))) | |
805 | (c-forward-syntactic-ws)) | |
806 | ||
807 | ;; If we didn't pass the identifier above already, do it now. | |
808 | (unless got-identifier | |
809 | (setq id-start (point)) | |
810 | (c-forward-name)) | |
811 | (setq id-end (point)) | |
812 | ||
813 | (/= id-end pos)) | |
814 | ||
815 | ;; Skip out of the parens surrounding the identifier. | |
816 | (or (= paren-depth 0) | |
817 | (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) | |
818 | ||
819 | (<= (point) limit) | |
820 | ||
821 | ;; Search syntactically to the end of the declarator (";", | |
2a15eb73 MS |
822 | ;; ",", a closen paren, eob etc) or to the beginning of an |
823 | ;; initializer or function prototype ("=" or "\\s\("). | |
824 | ;; Note that the open paren will match array specs in | |
825 | ;; square brackets, and we treat them as initializers too. | |
d9e94c22 | 826 | (c-syntactic-re-search-forward |
2a15eb73 | 827 | "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t)) |
d9e94c22 MS |
828 | |
829 | (setq next-pos (match-beginning 0) | |
2a15eb73 | 830 | id-face (if (eq (char-after next-pos) ?\() |
d9e94c22 MS |
831 | 'font-lock-function-name-face |
832 | 'font-lock-variable-name-face) | |
2a15eb73 MS |
833 | got-init (and (match-beginning 1) |
834 | (char-after (match-beginning 1)))) | |
d9e94c22 MS |
835 | |
836 | (if types | |
837 | ;; Register and fontify the identifer as a type. | |
838 | (let ((c-promote-possible-types t)) | |
839 | (goto-char id-start) | |
840 | (c-forward-type)) | |
841 | ;; Fontify the last symbol in the identifier if it isn't fontified | |
842 | ;; already. The check is necessary only in certain cases where this | |
843 | ;; function is used "sloppily", e.g. in `c-simple-decl-matchers'. | |
844 | (when (and c-last-identifier-range | |
845 | (not (get-text-property (car c-last-identifier-range) | |
846 | 'face))) | |
847 | (c-put-font-lock-face (car c-last-identifier-range) | |
848 | (cdr c-last-identifier-range) | |
849 | id-face))) | |
850 | ||
851 | (goto-char next-pos) | |
852 | (setq pos nil) | |
853 | (when list | |
854 | ;; Jump past any initializer or function prototype to see if | |
855 | ;; there's a ',' to continue at. | |
856 | ||
857 | (cond ((eq id-face 'font-lock-function-name-face) | |
858 | ;; Skip a parenthesized initializer (C++) or a function | |
859 | ;; prototype. | |
860 | (if (c-safe (c-forward-sexp 1) t) | |
861 | (c-forward-syntactic-ws limit) | |
862 | (goto-char limit))) | |
863 | ||
864 | (got-init | |
2a15eb73 MS |
865 | ;; Skip an initializer expression. If we're at a '=' |
866 | ;; then accept a brace list directly after it to cope | |
867 | ;; with array initializers. Otherwise stop at braces | |
868 | ;; to avoid going past full function and class blocks. | |
869 | (and (if (and (eq got-init ?=) | |
870 | (= (c-forward-token-2) 0) | |
871 | (looking-at "{")) | |
872 | (c-safe (c-forward-sexp) t) | |
873 | t) | |
874 | (c-syntactic-re-search-forward "[;,{]" limit 'move t) | |
875 | (backward-char))) | |
d9e94c22 MS |
876 | |
877 | (t (c-forward-syntactic-ws limit))) | |
878 | ||
879 | ;; If a ',' is found we set pos to the next declarator and iterate. | |
880 | (when (and (< (point) limit) (looking-at ",")) | |
881 | (c-put-char-property (point) 'c-type separator-prop) | |
882 | (forward-char) | |
883 | (c-forward-syntactic-ws limit) | |
884 | (setq pos (point)))))) | |
885 | nil) | |
886 | ||
887 | (defconst c-font-lock-maybe-decl-faces | |
888 | ;; List of faces that might be put at the start of a type when | |
889 | ;; `c-font-lock-declarations' runs. This needs to be evaluated to | |
890 | ;; ensure that face name aliases in Emacs are resolved. | |
891 | (list nil | |
892 | font-lock-type-face | |
893 | c-reference-face-name | |
894 | font-lock-keyword-face)) | |
895 | ||
896 | ;; Macro used inside `c-font-lock-declarations'. It ought to be a | |
897 | ;; defsubst or perhaps even a defun, but it contains lots of free | |
898 | ;; variables that refer to things inside `c-font-lock-declarations'. | |
899 | (defmacro c-fl-shift-type-backward (&optional short) | |
900 | ;; `c-font-lock-declarations' can consume an arbitrary length list | |
901 | ;; of types when parsing a declaration, which means that it | |
902 | ;; sometimes consumes the identifier in the declaration as a type. | |
903 | ;; This is used to "backtrack" and make the last type be treated | |
904 | ;; as an identifier instead. | |
905 | `(progn | |
906 | ,(unless short | |
907 | ;; These identifiers are bound only in the inner let. | |
908 | '(setq identifier-type at-type | |
909 | identifier-start type-start | |
910 | identifier-end type-end)) | |
911 | (if (setq at-type (if (eq prev-at-type 'prefix) | |
912 | t | |
913 | prev-at-type)) | |
914 | (setq type-start prev-type-start | |
915 | type-end prev-type-end) | |
916 | (setq type-start start-pos | |
917 | type-end start-pos)) | |
918 | ,(unless short | |
919 | ;; These identifiers are bound only in the inner let. | |
920 | '(setq start type-end | |
921 | got-parens nil | |
922 | got-identifier t | |
923 | got-suffix t | |
924 | got-suffix-after-parens t | |
925 | paren-depth 0)))) | |
926 | ||
927 | (defun c-font-lock-declarations (limit) | |
928 | ;; Fontify all the declarations and casts from the point to LIMIT. | |
929 | ;; Assumes that strings and comments have been fontified already. | |
930 | ;; Nil is always returned. | |
931 | ;; | |
932 | ;; This function can make hidden buffer changes, but the font-lock | |
933 | ;; context covers that. | |
934 | ||
935 | ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) | |
936 | ||
937 | (save-restriction | |
938 | (let (start-pos | |
037558bf | 939 | c-restricted-<>-arglists |
d9e94c22 MS |
940 | ;; Nonzero if the `c-decl-prefix-re' match is in an arglist context, |
941 | ;; as opposed to a statement-level context. The major difference is | |
942 | ;; that "," works as declaration delimiter in an arglist context, | |
943 | ;; whereas it only separates declarators in the same declaration in | |
944 | ;; a statement context. If it's nonzero then the value is the | |
945 | ;; matched char, e.g. ?\( or ?,. | |
946 | arglist-match | |
947 | ;; 'decl if we're in an arglist containing declarations (but if | |
948 | ;; `c-recognize-paren-inits' is set it might also be an initializer | |
949 | ;; arglist), '<> if the arglist is of angle bracket type, 'other if | |
950 | ;; it's some other arglist, or nil if not in an arglist at all. | |
951 | arglist-type | |
952 | ;; Set to the result of `c-forward-type'. | |
953 | at-type | |
954 | ;; These record the start and end of the type or possible type found | |
955 | ;; by `c-forward-type'. `type-start' is at the start of the first | |
956 | ;; type token, and `type-end' is at the start of the first token | |
957 | ;; after the type (and after any specifiers). | |
958 | type-start type-end | |
959 | ;; These store `at-type', `type-start' and `type-end' of the | |
960 | ;; identifier before the one in those variables. The previous | |
961 | ;; identifier might turn out to be the real type in a declaration if | |
962 | ;; the last one has to be the declarator in it. If `prev-at-type' | |
963 | ;; is nil then the other variables have undefined values. | |
964 | prev-at-type prev-type-start prev-type-end | |
965 | ;; Whether we've found a declaration or a cast. We might know this | |
966 | ;; before we've found the type in it. | |
967 | at-decl-or-cast | |
968 | ;; Set when we need to back up to parse this as a declaration but | |
969 | ;; not as a cast. | |
970 | backup-if-not-cast | |
971 | ;; Set if we've found a "typedef" specifier. The identifiers in the | |
972 | ;; declaration are then fontified as types. | |
973 | at-typedef | |
974 | ;; Set if we've found a specifier that can start a declaration where | |
975 | ;; there's no type. | |
976 | maybe-typeless | |
977 | ;; The position of the next token after the closing paren of the | |
978 | ;; last fontified cast. | |
979 | last-cast-end | |
980 | ;; The same for the currently investigated cast. | |
981 | cast-end | |
982 | ;; The maximum of the end positions of all the checked type decl | |
983 | ;; expressions in the successfully identified declarations. The | |
984 | ;; position might be either before or after the syntactic whitespace | |
985 | ;; following the last token in the type decl expression. | |
986 | (max-type-decl-end 0) | |
987 | ;; Same as `max-type-decl-*', but used when we're before | |
988 | ;; `token-pos'. | |
989 | (max-type-decl-end-before-token 0) | |
990 | ;; Allow recording of identifier ranges in `c-forward-type' etc for | |
991 | ;; later fontification. Not using `c-fontify-types-and-refs' here | |
992 | ;; since the ranges should be fontified selectively only when a | |
993 | ;; declaration or cast has been successfully recognized. | |
994 | c-record-type-identifiers | |
995 | c-record-ref-identifiers | |
996 | ;; The font-lock package in Emacs is known to clobber | |
997 | ;; `parse-sexp-lookup-properties' (when it exists). | |
998 | (parse-sexp-lookup-properties | |
999 | (cc-eval-when-compile | |
1000 | (boundp 'parse-sexp-lookup-properties)))) | |
1001 | ||
1002 | ;; Below we fontify a whole declaration even when it crosses the limit, | |
1003 | ;; to avoid gaps when lazy-lock fontifies the file a screenful at a | |
1004 | ;; time. That is however annoying during editing, e.g. the following is | |
1005 | ;; a common situation while the first line is being written: | |
1006 | ;; | |
1007 | ;; my_variable | |
1008 | ;; some_other_variable = 0; | |
1009 | ;; | |
1010 | ;; font-lock will put the limit at the beginning of the second line | |
1011 | ;; here, and if we go past it we'll fontify "my_variable" as a type and | |
1012 | ;; "some_other_variable" as an identifier, and the latter will not | |
1013 | ;; correct itself until the second line is changed. To avoid that we | |
1014 | ;; narrow to the limit if the region to fontify is a single line. | |
1015 | (when (<= limit (c-point 'bonl)) | |
1016 | (narrow-to-region | |
1017 | (point-min) | |
1018 | (save-excursion | |
1019 | ;; Narrow after any operator chars following the limit though, since | |
1020 | ;; those characters can be useful in recognizing a declaration (in | |
1021 | ;; particular the '{' that opens a function body after the header). | |
1022 | (goto-char limit) | |
1023 | (skip-chars-forward c-nonsymbol-chars) | |
1024 | (point)))) | |
1025 | ||
1026 | (c-find-decl-spots | |
1027 | limit | |
1028 | c-identifier-start | |
1029 | c-font-lock-maybe-decl-faces | |
1030 | ||
1031 | (lambda (match-pos inside-macro) | |
1032 | (catch 'false-alarm | |
1033 | ;; Don't do anything more if we're looking at a keyword | |
1034 | ;; that can't start a declaration. | |
1035 | (when (and (eq (get-text-property (point) 'face) | |
1036 | 'font-lock-keyword-face) | |
1037 | (looking-at c-not-decl-init-keywords)) | |
1038 | (throw 'false-alarm t)) | |
1039 | ||
1040 | ;; Set `arglist-match' and `arglist-type'. Look for "<" for the | |
1041 | ;; sake of C++-style template arglists. | |
1042 | (setq arglist-match (char-before match-pos)) | |
1043 | (if (memq arglist-match '(?\( ?, ?\[ ?<)) | |
1044 | ||
1045 | ;; Find out the type of the arglist. | |
1046 | (if (<= match-pos (point-min)) | |
1047 | (setq arglist-type 'other) | |
1048 | (let ((type (c-get-char-property (1- match-pos) 'c-type))) | |
1049 | (cond ((eq type 'c-decl-arg-start) | |
1050 | ;; Got a cached hit in a declaration arglist. | |
1051 | (setq arglist-type 'decl)) | |
1052 | ((or (eq type 'c-<>-arg-sep) | |
1053 | (eq arglist-match ?<)) | |
1054 | ;; Inside an angle bracket arglist. | |
1055 | (setq arglist-type '<>)) | |
1056 | (type | |
1057 | ;; Got a cached hit in some other type of arglist. | |
1058 | (setq arglist-type 'other)) | |
1059 | ((if inside-macro | |
1060 | (< match-pos max-type-decl-end-before-token) | |
1061 | (< match-pos max-type-decl-end)) | |
1062 | ;; The point is within the range of a previously | |
1063 | ;; encountered type decl expression, so the arglist | |
1064 | ;; is probably one that contains declarations. | |
1065 | ;; However, if `c-recognize-paren-inits' is set it | |
1066 | ;; might also be an initializer arglist. | |
1067 | (setq arglist-type 'decl) | |
1068 | ;; The result of this check is cached with a char | |
1069 | ;; property on the match token, so that we can look | |
1070 | ;; it up again when refontifying single lines in a | |
1071 | ;; multiline declaration. | |
1072 | (c-put-char-property (1- match-pos) | |
1073 | 'c-type 'c-decl-arg-start)) | |
1074 | (t | |
1075 | (setq arglist-type 'other))))) | |
1076 | ||
1077 | (setq arglist-match nil | |
1078 | arglist-type nil)) | |
1079 | ||
1080 | (setq at-type nil | |
1081 | at-decl-or-cast nil | |
1082 | backup-if-not-cast nil | |
1083 | at-typedef nil | |
1084 | maybe-typeless nil | |
1085 | c-record-type-identifiers t | |
1086 | c-record-ref-identifiers nil | |
1087 | ;; `start-pos' is used below to point to the start of the | |
1088 | ;; first type, i.e. after any leading specifiers. It might | |
1089 | ;; also point at the beginning of the preceding syntactic | |
1090 | ;; whitespace. | |
1091 | start-pos (point) | |
1092 | ;; If we're in a normal arglist context we don't want to | |
1093 | ;; recognize commas in nested angle bracket arglists since | |
1094 | ;; those commas could be part of our own arglist. | |
037558bf | 1095 | c-restricted-<>-arglists |
d9e94c22 MS |
1096 | (and c-recognize-<>-arglists |
1097 | (eq arglist-type 'other))) | |
1098 | ||
037558bf | 1099 | (when (and c-restricted-<>-arglists |
d9e94c22 MS |
1100 | (/= arglist-match ?,)) |
1101 | ;; We're standing at the start of a normal arglist so remove any | |
1102 | ;; angle bracket arglists containing commas that's been | |
1103 | ;; recognized inside it by the preceding slightly opportunistic | |
1104 | ;; scan in `c-font-lock-<>-arglists'. | |
1105 | (while (and (c-syntactic-re-search-forward | |
1106 | c-opt-<>-arglist-start-in-paren nil t t) | |
1107 | (match-beginning 1)) | |
1108 | (backward-char) | |
1109 | (when (save-match-data | |
1110 | (and (c-get-char-property (point) 'syntax-table) | |
1111 | (not (c-forward-<>-arglist nil t)))) | |
1112 | (c-remove-font-lock-face (match-beginning 2) (match-end 2)))) | |
1113 | (goto-char start-pos)) | |
1114 | ||
1115 | ;; Check for a type, but be prepared to skip over leading | |
1116 | ;; specifiers like "static". Unknown symbols are treated as | |
1117 | ;; possible types, but they could also be specifiers disguised | |
1118 | ;; through macros like __INLINE__, so we recognize both types and | |
1119 | ;; known specifiers after them too. | |
1120 | (while (let ((start (point)) | |
1121 | (res (unless (eq at-type t) | |
1122 | ;; Don't look for a type if we already found a | |
1123 | ;; positive one; we only loop for the | |
1124 | ;; `c-specifier-key' check then. | |
1125 | (c-forward-type)))) | |
1126 | ||
1127 | (when res | |
1128 | ;; Found a known or possible type or a prefix of a known | |
1129 | ;; type. | |
1130 | ||
1131 | (when at-type | |
1132 | ;; Got two identifiers with nothing but whitespace | |
1133 | ;; between them. That can only happen in | |
1134 | ;; declarations. | |
1135 | (setq at-decl-or-cast t) | |
1136 | ||
1137 | (when (eq at-type 'found) | |
1138 | ;; If the previous identifier is a found type we | |
1139 | ;; record it as a real one; it might be some sort of | |
1140 | ;; alias for a prefix like "unsigned". | |
1141 | (save-excursion | |
1142 | (goto-char type-start) | |
1143 | (let ((c-promote-possible-types t)) | |
1144 | (c-forward-type))))) | |
1145 | ||
1146 | (setq prev-at-type at-type | |
1147 | prev-type-start type-start | |
1148 | prev-type-end type-end | |
1149 | at-type res | |
1150 | type-start start | |
1151 | type-end (point)) | |
1152 | ||
1153 | ;; If the type isn't known we continue so that we'll | |
1154 | ;; jump over all specifiers and type identifiers. The | |
1155 | ;; reason to do this for a known type prefix is to make | |
1156 | ;; things like "unsigned INT16" work. | |
1157 | (setq res (not (eq res t)))) | |
1158 | ||
1159 | (if (looking-at c-specifier-key) | |
1160 | ;; Found a known specifier keyword. The specifier | |
1161 | ;; keywords are restrictive, so we check for them | |
1162 | ;; anywhere inside or around the type(s). We thereby | |
1163 | ;; avoid having special cases for specifiers like MSVC | |
1164 | ;; '__declspec' which can come after the type. | |
1165 | (progn | |
1166 | (setq at-decl-or-cast t) | |
1167 | (let ((kwd-sym (c-keyword-sym (match-string 1)))) | |
1168 | (when (c-keyword-member | |
1169 | kwd-sym 'c-typedef-decl-kwds) | |
1170 | (setq at-typedef t)) | |
1171 | (when (c-keyword-member | |
1172 | kwd-sym 'c-typeless-decl-kwds) | |
1173 | (setq maybe-typeless t))) | |
1174 | (c-forward-keyword-clause) | |
1175 | ;; Move type-end forward if we've passed a type, | |
1176 | ;; otherwise move start-pos forward. | |
1177 | (if at-type | |
1178 | (setq type-end (point)) | |
1179 | (setq start-pos (point)))) | |
1180 | ||
1181 | res))) | |
1182 | ||
1183 | (cond | |
1184 | ((eq at-type 'prefix) | |
1185 | ;; A prefix type is itself a primitive type when it's not | |
1186 | ;; followed by another type. | |
1187 | (setq at-type t)) | |
1188 | ||
1189 | ((not at-type) | |
1190 | ;; Got no type but set things up to continue anyway to handle the | |
1191 | ;; various cases when a declaration doesn't start with a type. | |
1192 | (setq type-end start-pos)) | |
1193 | ||
1194 | ((and (eq at-type 'maybe) | |
1195 | (c-major-mode-is 'c++-mode)) | |
1196 | ;; If it's C++ then check if the last "type" ends on the form | |
1197 | ;; "foo::foo" or "foo::~foo", i.e. if it's the name of a | |
1198 | ;; (con|de)structor. | |
1199 | (save-excursion | |
1200 | (let (name end-2 end-1) | |
1201 | (goto-char type-end) | |
1202 | (c-backward-syntactic-ws) | |
1203 | (setq end-2 (point)) | |
1204 | (when (and | |
1205 | (c-simple-skip-symbol-backward) | |
1206 | (progn | |
1207 | (setq name | |
1208 | (buffer-substring-no-properties (point) end-2)) | |
1209 | ;; Cheating in the handling of syntactic ws below. | |
1210 | (< (skip-chars-backward ":~ \t\n\r\v\f") 0)) | |
1211 | (progn | |
1212 | (setq end-1 (point)) | |
1213 | (c-simple-skip-symbol-backward)) | |
1214 | (>= (point) type-start) | |
1215 | (equal (buffer-substring-no-properties (point) end-1) | |
1216 | name)) | |
1217 | ;; It is a (con|de)structor name. In that case the | |
1218 | ;; declaration is typeless so zap out any preceding | |
1219 | ;; identifier(s) that we might have taken as types. | |
1220 | (goto-char type-start) | |
1221 | (setq at-type nil | |
1222 | prev-at-type nil | |
1223 | type-end type-start)))))) | |
1224 | ||
1225 | ;; Check for and step over a type decl expression after the thing | |
1226 | ;; that is or might be a type. This can't be skipped since we need | |
1227 | ;; the correct end position of the declarator for | |
1228 | ;; `max-type-decl-end-*'. | |
1229 | (let ((start (point)) (paren-depth 0) pos | |
1230 | ;; True if there's a non-open-paren match of | |
1231 | ;; `c-type-decl-prefix-key'. | |
1232 | got-prefix | |
1233 | ;; True if the declarator is surrounded by a parenthesis pair. | |
1234 | got-parens | |
1235 | ;; True if there is an identifier in the declarator. | |
1236 | got-identifier | |
1237 | ;; True if there's a non-close-paren match of | |
1238 | ;; `c-type-decl-suffix-key'. | |
1239 | got-suffix | |
1240 | ;; True if there's a prefix or suffix match outside the | |
1241 | ;; outermost paren pair that surrounds the declarator. | |
1242 | got-prefix-before-parens | |
1243 | got-suffix-after-parens | |
1244 | ;; True if we've parsed the type decl to a token that | |
1245 | ;; is known to end declarations in this context. | |
1246 | at-decl-end | |
1247 | ;; The earlier values of `at-type', `type-start' and | |
1248 | ;; `type-end' if we've shifted the type backwards. | |
1249 | identifier-type identifier-start identifier-end) | |
1250 | (goto-char type-end) | |
1251 | ||
1252 | ;; Skip over type decl prefix operators. (Note similar code in | |
1253 | ;; `c-font-lock-declarators'.) | |
1254 | (while (and (looking-at c-type-decl-prefix-key) | |
1255 | (if (and (c-major-mode-is 'c++-mode) | |
1256 | (match-beginning 2)) | |
1257 | ;; If the second submatch matches in C++ then | |
1258 | ;; we're looking at an identifier that's a prefix | |
1259 | ;; only if it specifies a member pointer. | |
1260 | (when (setq got-identifier (c-forward-name)) | |
1261 | (if (looking-at "\\(::\\)") | |
1262 | ;; We only check for a trailing "::" and | |
1263 | ;; let the "*" that should follow be | |
1264 | ;; matched in the next round. | |
1265 | (progn (setq got-identifier nil) t) | |
1266 | ;; It turned out to be the real identifier, | |
1267 | ;; so stop. | |
1268 | nil)) | |
1269 | t)) | |
1270 | (if (eq (char-after) ?\() | |
1271 | (progn | |
1272 | (setq paren-depth (1+ paren-depth)) | |
1273 | (forward-char)) | |
1274 | (unless got-prefix-before-parens | |
1275 | (setq got-prefix-before-parens (= paren-depth 0))) | |
1276 | (setq got-prefix t) | |
1277 | (goto-char (match-end 1))) | |
1278 | (c-forward-syntactic-ws)) | |
1279 | (setq got-parens (> paren-depth 0)) | |
1280 | ||
1281 | ;; Skip over an identifier. | |
1282 | (or got-identifier | |
1283 | (and (looking-at c-identifier-start) | |
1284 | (setq got-identifier (c-forward-name)))) | |
1285 | ||
1286 | ;; Skip over type decl suffix operators. | |
1287 | (while (if (looking-at c-type-decl-suffix-key) | |
1288 | (if (eq (char-after) ?\)) | |
1289 | (when (> paren-depth 0) | |
1290 | (setq paren-depth (1- paren-depth)) | |
1291 | (forward-char) | |
1292 | t) | |
1293 | (when (if (save-match-data (looking-at "\\s\(")) | |
1294 | (c-safe (c-forward-sexp 1) t) | |
1295 | (goto-char (match-end 1)) | |
1296 | t) | |
1297 | (unless got-suffix-after-parens | |
1298 | (setq got-suffix-after-parens (= paren-depth 0))) | |
1299 | (setq got-suffix t))) | |
1300 | ;; No suffix matched. We might have matched the | |
1301 | ;; identifier as a type and the open paren of a function | |
1302 | ;; arglist as a type decl prefix. In that case we | |
1303 | ;; should "backtrack": Reinterpret the last type as the | |
1304 | ;; identifier, move out of the arglist and continue | |
1305 | ;; searching for suffix operators. | |
1306 | ;; | |
1307 | ;; Do this even if there's no preceding type, to cope | |
1308 | ;; with old style function declarations in K&R C, | |
1309 | ;; (con|de)structors in C++ and `c-typeless-decl-kwds' | |
1310 | ;; style declarations. That isn't applicable in an | |
1311 | ;; arglist context, though. | |
1312 | (when (and (= paren-depth 1) | |
1313 | (not got-prefix-before-parens) | |
1314 | (not (eq at-type t)) | |
1315 | (or prev-at-type | |
1316 | maybe-typeless | |
1317 | (when c-recognize-typeless-decls | |
1318 | (not arglist-type))) | |
1319 | (setq pos (c-up-list-forward (point))) | |
1320 | (eq (char-before pos) ?\))) | |
1321 | (c-fl-shift-type-backward) | |
1322 | (goto-char pos) | |
1323 | t)) | |
1324 | (c-forward-syntactic-ws)) | |
1325 | ||
1326 | (when (and maybe-typeless | |
1327 | (not got-identifier) | |
1328 | (not got-prefix) | |
1329 | at-type | |
1330 | (not (eq at-type t))) | |
1331 | ;; Have found no identifier but `c-typeless-decl-kwds' has | |
1332 | ;; matched so we know we're inside a declaration. The | |
1333 | ;; preceding type must be the identifier instead. | |
1334 | (c-fl-shift-type-backward)) | |
1335 | ||
1336 | (setq | |
1337 | at-decl-or-cast | |
1338 | (catch 'at-decl-or-cast | |
1339 | ||
1340 | (when (> paren-depth 0) | |
1341 | ;; Encountered something inside parens that isn't matched by | |
1342 | ;; the `c-type-decl-*' regexps, so it's not a type decl | |
1343 | ;; expression. Try to skip out to the same paren depth to | |
1344 | ;; not confuse the cast check below. | |
1345 | (c-safe (goto-char (scan-lists (point) 1 paren-depth))) | |
1346 | (throw 'at-decl-or-cast nil)) | |
1347 | ||
1348 | (setq at-decl-end | |
1349 | (looking-at (cond ((eq arglist-type '<>) "[,>]") | |
1350 | (arglist-type "[,\)]") | |
1351 | (t "[,;]")))) | |
1352 | ||
1353 | ;; Now we've collected info about various characteristics of | |
1354 | ;; the construct we're looking at. Below follows a decision | |
1355 | ;; tree based on that. It's ordered to check more certain | |
1356 | ;; signs before less certain ones. | |
1357 | ||
1358 | (if got-identifier | |
1359 | (progn | |
1360 | ||
1361 | (when (and (or at-type maybe-typeless) | |
1362 | (not (or got-prefix got-parens))) | |
1363 | ;; Got another identifier directly after the type, so | |
1364 | ;; it's a declaration. | |
1365 | (throw 'at-decl-or-cast t)) | |
1366 | ||
1367 | (when (and got-parens | |
1368 | (not got-prefix) | |
1369 | (not got-suffix-after-parens) | |
1370 | (or prev-at-type maybe-typeless)) | |
1371 | ;; Got a declaration of the form "foo bar (gnu);" | |
1372 | ;; where we've recognized "bar" as the type and "gnu" | |
1373 | ;; as the declarator. In this case it's however more | |
1374 | ;; likely that "bar" is the declarator and "gnu" a | |
1375 | ;; function argument or initializer (if | |
1376 | ;; `c-recognize-paren-inits' is set), since the parens | |
1377 | ;; around "gnu" would be superfluous if it's a | |
1378 | ;; declarator. Shift the type one step backward. | |
1379 | (c-fl-shift-type-backward))) | |
1380 | ||
1381 | ;; Found no identifier. | |
1382 | ||
1383 | (if prev-at-type | |
1384 | (when (or (= (point) start) | |
1385 | (and got-suffix | |
1386 | (not got-prefix) | |
1387 | (not got-parens))) | |
1388 | ;; Got two types after each other, so if this isn't a | |
1389 | ;; cast then the latter probably is the identifier and | |
1390 | ;; we should back up to the previous type. | |
1391 | (setq backup-if-not-cast t) | |
1392 | (throw 'at-decl-or-cast t)) | |
1393 | ||
1394 | (when (eq at-type t) | |
1395 | ;; If the type is known we know that there can't be any | |
1396 | ;; identifier somewhere else, and it's only in | |
1397 | ;; declarations in e.g. function prototypes and in casts | |
1398 | ;; that the identifier may be left out. | |
1399 | (throw 'at-decl-or-cast t)) | |
1400 | ||
1401 | (when (= (point) start) | |
1402 | ;; Only got a single identifier (parsed as a type so | |
1403 | ;; far). | |
1404 | (if (and | |
1405 | ;; Check that the identifier isn't at the start of | |
1406 | ;; an expression. | |
1407 | at-decl-end | |
1408 | (cond | |
1409 | ((eq arglist-type 'decl) | |
1410 | ;; Inside an arglist that contains declarations. | |
1411 | ;; If K&R style declarations and parenthesis | |
1412 | ;; style initializers aren't allowed then the | |
1413 | ;; single identifier must be a type, else we | |
1414 | ;; require that it's known or found (primitive | |
1415 | ;; types are handled above). | |
1416 | (or (and (not c-recognize-knr-p) | |
1417 | (not c-recognize-paren-inits)) | |
1418 | (memq at-type '(known found)))) | |
1419 | ((eq arglist-type '<>) | |
1420 | ;; Inside a template arglist. Accept known and | |
1421 | ;; found types; other identifiers could just as | |
1422 | ;; well be constants in C++. | |
1423 | (memq at-type '(known found))))) | |
1424 | (throw 'at-decl-or-cast t) | |
1425 | (throw 'at-decl-or-cast nil)))) | |
1426 | ||
1427 | (if (and | |
1428 | got-parens | |
1429 | (not got-prefix) | |
1430 | (not arglist-type) | |
1431 | (not (eq at-type t)) | |
1432 | (or | |
1433 | prev-at-type | |
1434 | maybe-typeless | |
1435 | (when c-recognize-typeless-decls | |
1436 | (or (not got-suffix) | |
1437 | (not (looking-at | |
1438 | c-after-suffixed-type-maybe-decl-key)))))) | |
1439 | ;; Got an empty paren pair and a preceding type that | |
1440 | ;; probably really is the identifier. Shift the type | |
1441 | ;; backwards to make the last one the identifier. This | |
1442 | ;; is analogous to the "backtracking" done inside the | |
1443 | ;; `c-type-decl-suffix-key' loop above. | |
1444 | ;; | |
1445 | ;; Exception: In addition to the conditions in that | |
1446 | ;; "backtracking" code, do not shift backward if we're | |
1447 | ;; not looking at either `c-after-suffixed-type-decl-key' | |
1448 | ;; or "[;,]". Since there's no preceding type, the | |
1449 | ;; shift would mean that the declaration is typeless. | |
1450 | ;; But if the regexp doesn't match then we will simply | |
1451 | ;; fall through in the tests below and not recognize it | |
1452 | ;; at all, so it's better to try it as an abstract | |
1453 | ;; declarator instead. | |
1454 | (c-fl-shift-type-backward) | |
1455 | ||
1456 | ;; Still no identifier. | |
1457 | ||
1458 | (when (and got-prefix (or got-parens got-suffix)) | |
1459 | ;; Require `got-prefix' together with either | |
1460 | ;; `got-parens' or `got-suffix' to recognize it as an | |
1461 | ;; abstract declarator: `got-parens' only is probably an | |
1462 | ;; empty function call. `got-suffix' only can build an | |
1463 | ;; ordinary expression together with the preceding | |
1464 | ;; identifier which we've taken as a type. We could | |
1465 | ;; actually accept on `got-prefix' only, but that can | |
1466 | ;; easily occur temporarily while writing an expression | |
1467 | ;; so we avoid that case anyway. We could do a better | |
1468 | ;; job if we knew the point when the fontification was | |
1469 | ;; invoked. | |
1470 | (throw 'at-decl-or-cast t)))) | |
1471 | ||
1472 | (when at-decl-or-cast | |
1473 | ;; By now we've located the type in the declaration that we | |
1474 | ;; know we're in. | |
1475 | (throw 'at-decl-or-cast t)) | |
1476 | ||
1477 | (when (and got-identifier | |
1478 | (not arglist-type) | |
1479 | (looking-at c-after-suffixed-type-decl-key) | |
1480 | (if (and got-parens | |
1481 | (not got-prefix) | |
1482 | (not got-suffix) | |
1483 | (not (eq at-type t))) | |
1484 | ;; Shift the type backward in the case that | |
1485 | ;; there's a single identifier inside parens. | |
1486 | ;; That can only occur in K&R style function | |
1487 | ;; declarations so it's more likely that it | |
1488 | ;; really is a function call. Therefore we | |
1489 | ;; only do this after | |
1490 | ;; `c-after-suffixed-type-decl-key' has | |
1491 | ;; matched. | |
1492 | (progn (c-fl-shift-type-backward) t) | |
1493 | got-suffix-after-parens)) | |
1494 | ;; A declaration according to | |
1495 | ;; `c-after-suffixed-type-decl-key'. | |
1496 | (throw 'at-decl-or-cast t)) | |
1497 | ||
1498 | (when (and (or got-prefix (not got-parens)) | |
1499 | (memq at-type '(t known))) | |
1500 | ;; It's a declaration if a known type precedes it and it | |
1501 | ;; can't be a function call. | |
1502 | (throw 'at-decl-or-cast t)) | |
1503 | ||
1504 | ;; If we get here we can't tell if this is a type decl or a | |
1505 | ;; normal expression by looking at it alone. (That's under | |
1506 | ;; the assumption that normal expressions always can look like | |
1507 | ;; type decl expressions, which isn't really true but the | |
1508 | ;; cases where it doesn't hold are so uncommon (e.g. some | |
1509 | ;; placements of "const" in C++) it's not worth the effort to | |
1510 | ;; look for them.) | |
1511 | ||
1512 | (unless (or at-decl-end (looking-at "=[^=]")) | |
1513 | ;; If this is a declaration it should end here or its | |
1514 | ;; initializer(*) should start here, so check for allowed | |
1515 | ;; separation tokens. Note that this rule doesn't work | |
1516 | ;; e.g. with a K&R arglist after a function header. | |
1517 | ;; | |
1518 | ;; *) Don't check for C++ style initializers using parens | |
1519 | ;; since those already have been matched as suffixes. | |
1520 | (throw 'at-decl-or-cast nil)) | |
1521 | ||
1522 | ;; Below are tests that only should be applied when we're | |
1523 | ;; certain to not have parsed halfway through an expression. | |
1524 | ||
1525 | (when (memq at-type '(t known)) | |
1526 | ;; The expression starts with a known type so treat it as a | |
1527 | ;; declaration. | |
1528 | (throw 'at-decl-or-cast t)) | |
1529 | ||
1530 | (when (and (c-major-mode-is 'c++-mode) | |
1531 | ;; In C++ we check if the identifier is a known | |
1532 | ;; type, since (con|de)structors use the class name | |
1533 | ;; as identifier. We've always shifted over the | |
1534 | ;; identifier as a type and then backed up again in | |
1535 | ;; this case. | |
1536 | identifier-type | |
a6782a6e | 1537 | (or (memq identifier-type '(found known)) |
d9e94c22 MS |
1538 | (and (eq (char-after identifier-start) ?~) |
1539 | ;; `at-type' probably won't be 'found for | |
1540 | ;; destructors since the "~" is then part | |
1541 | ;; of the type name being checked against | |
1542 | ;; the list of known types, so do a check | |
1543 | ;; without that operator. | |
a6782a6e MS |
1544 | (or (save-excursion |
1545 | (goto-char (1+ identifier-start)) | |
1546 | (c-forward-syntactic-ws) | |
1547 | (c-with-syntax-table | |
1548 | c-identifier-syntax-table | |
1549 | (looking-at c-known-type-key))) | |
1550 | (c-check-type (1+ identifier-start) | |
1551 | identifier-end))))) | |
d9e94c22 MS |
1552 | (throw 'at-decl-or-cast t)) |
1553 | ||
1554 | (if got-identifier | |
1555 | (progn | |
1556 | (when (and got-prefix-before-parens | |
1557 | at-type | |
1558 | (or at-decl-end (looking-at "=[^=]")) | |
1559 | (not arglist-type) | |
1560 | (not got-suffix)) | |
1561 | ;; Got something like "foo * bar;". Since we're not | |
1562 | ;; inside an arglist it would be a meaningless | |
1563 | ;; expression because the result isn't used. We | |
1564 | ;; therefore choose to recognize it as a declaration. | |
1565 | ;; Do not allow a suffix since it could then be a | |
1566 | ;; function call. | |
1567 | (throw 'at-decl-or-cast t)) | |
1568 | ||
1569 | (when (and (or got-suffix-after-parens | |
1570 | (looking-at "=[^=]")) | |
1571 | (eq at-type 'found) | |
1572 | (not (eq arglist-type 'other))) | |
1573 | ;; Got something like "a (*b) (c);" or "a (b) = c;". | |
1574 | ;; It could be an odd expression or it could be a | |
1575 | ;; declaration. Treat it as a declaration if "a" has | |
1576 | ;; been used as a type somewhere else (if it's a known | |
1577 | ;; type we won't get here). | |
1578 | (throw 'at-decl-or-cast t))) | |
1579 | ||
1580 | (when (and arglist-type | |
1581 | (or got-prefix | |
1582 | (and (eq arglist-type 'decl) | |
1583 | (not c-recognize-paren-inits) | |
1584 | (or got-parens got-suffix)))) | |
1585 | ;; Got a type followed by an abstract declarator. If | |
1586 | ;; `got-prefix' is set it's something like "a *" without | |
1587 | ;; anything after it. If `got-parens' or `got-suffix' is | |
1588 | ;; set it's "a()", "a[]", "a()[]", or similar, which we | |
1589 | ;; accept only if the context rules out expressions. | |
1590 | (throw 'at-decl-or-cast t))) | |
1591 | ||
1592 | ;; If we had a complete symbol table here (which rules out | |
1593 | ;; `c-found-types') we should return t due to the | |
1594 | ;; disambiguation rule (in at least C++) that anything that | |
1595 | ;; can be parsed as a declaration is a declaration. Now we're | |
1596 | ;; being more defensive and prefer to highlight things like | |
1597 | ;; "foo (bar);" as a declaration only if we're inside an | |
1598 | ;; arglist that contains declarations. | |
1599 | (eq arglist-type 'decl)))) | |
1600 | ||
1601 | ;; Point is now after the type decl expression. | |
1602 | ||
1603 | (cond | |
1604 | ;; Check for a cast. | |
1605 | ((save-excursion | |
1606 | (and | |
1607 | c-cast-parens | |
1608 | ||
1609 | ;; Should be the first type/identifier in a cast paren. | |
1610 | (memq arglist-match c-cast-parens) | |
1611 | ||
1612 | ;; The closing paren should follow. | |
1613 | (progn | |
1614 | (c-forward-syntactic-ws) | |
1615 | (looking-at "\\s\)")) | |
1616 | ||
1617 | ;; There should be a primary expression after it. | |
1618 | (let (pos) | |
1619 | (forward-char) | |
1620 | (c-forward-syntactic-ws) | |
1621 | (setq cast-end (point)) | |
1622 | (and (looking-at c-primary-expr-regexp) | |
1623 | (progn | |
1624 | (setq pos (match-end 0)) | |
1625 | (or | |
1626 | ;; Check if the expression begins with a prefix | |
1627 | ;; keyword. | |
1628 | (match-beginning 2) | |
1629 | (if (match-beginning 1) | |
1630 | ;; Expression begins with an ambiguous operator. | |
1631 | ;; Treat it as a cast if it's a type decl or if | |
1632 | ;; we've recognized the type somewhere else. | |
1633 | (or at-decl-or-cast | |
1634 | (memq at-type '(t known found))) | |
1635 | ;; Unless it's a keyword, it's the beginning of a | |
1636 | ;; primary expression. | |
1637 | (not (looking-at c-keywords-regexp))))) | |
1638 | ;; If `c-primary-expr-regexp' matched a nonsymbol | |
1639 | ;; token, check that it matched a whole one so that we | |
1640 | ;; don't e.g. confuse the operator '-' with '->'. It's | |
1641 | ;; ok if it matches further, though, since it e.g. can | |
1642 | ;; match the float '.5' while the operator regexp only | |
1643 | ;; matches '.'. | |
1644 | (or (not (looking-at c-nonsymbol-token-regexp)) | |
1645 | (<= (match-end 0) pos)))) | |
1646 | ||
1647 | ;; There should either be a cast before it or something that | |
1648 | ;; isn't an identifier or close paren. | |
1649 | (/= match-pos 0) | |
1650 | (progn | |
1651 | (goto-char (1- match-pos)) | |
1652 | (or (eq (point) last-cast-end) | |
1653 | (progn | |
1654 | (c-backward-syntactic-ws) | |
1655 | (if (< (skip-syntax-backward "w_") 0) | |
1656 | ;; It's a symbol. Accept it only if it's one of | |
1657 | ;; the keywords that can precede an expression | |
1658 | ;; (without surrounding parens). | |
1659 | (looking-at c-simple-stmt-key) | |
1660 | (and | |
1661 | ;; Check that it isn't a close paren (block close | |
1662 | ;; is ok, though). | |
1663 | (not (memq (char-before) '(?\) ?\]))) | |
1664 | ;; Check that it isn't a nonsymbol identifier. | |
1665 | (not (c-on-identifier))))))))) | |
1666 | ||
1667 | ;; Handle the cast. | |
1668 | (setq last-cast-end cast-end) | |
1669 | (when (and at-type (not (eq at-type t))) | |
1670 | (let ((c-promote-possible-types t)) | |
1671 | (goto-char type-start) | |
1672 | (c-forward-type)))) | |
1673 | ||
1674 | (at-decl-or-cast | |
1675 | ;; We're at a declaration. Highlight the type and the following | |
1676 | ;; declarators. | |
1677 | ||
1678 | (when backup-if-not-cast | |
1679 | (c-fl-shift-type-backward t)) | |
1680 | ||
1681 | (when (and (eq arglist-type 'decl) (looking-at ",")) | |
1682 | ;; Make sure to propagate the `c-decl-arg-start' property to | |
1683 | ;; the next argument if it's set in this one, to cope with | |
1684 | ;; interactive refontification. | |
1685 | (c-put-char-property (point) 'c-type 'c-decl-arg-start)) | |
1686 | ||
1687 | ;; Set `max-type-decl-end' or `max-type-decl-end-before-token' | |
1688 | ;; under the assumption that we're after the first type decl | |
1689 | ;; expression in the declaration now. That's not really true; we | |
1690 | ;; could also be after a parenthesized initializer expression in | |
1691 | ;; C++, but this is only used as a last resort to slant ambiguous | |
1692 | ;; expression/declarations, and overall it's worth the risk to | |
1693 | ;; occasionally fontify an expression as a declaration in an | |
1694 | ;; initializer expression compared to getting ambiguous things in | |
1695 | ;; normal function prototypes fontified as expressions. | |
1696 | (if inside-macro | |
1697 | (when (> (point) max-type-decl-end-before-token) | |
1698 | (setq max-type-decl-end-before-token (point))) | |
1699 | (when (> (point) max-type-decl-end) | |
1700 | (setq max-type-decl-end (point)))) | |
1701 | ||
1702 | (when (and at-type (not (eq at-type t))) | |
1703 | (let ((c-promote-possible-types t)) | |
1704 | (goto-char type-start) | |
1705 | (c-forward-type))) | |
1706 | ||
1707 | (goto-char type-end) | |
1708 | ||
1709 | (let ((decl-list | |
1710 | (if arglist-type | |
1711 | ;; Should normally not fontify a list of declarators | |
1712 | ;; inside an arglist, but the first argument in the | |
1713 | ;; ';' separated list of a "for" statement is an | |
1714 | ;; exception. | |
1715 | (when (and (eq arglist-match ?\() (/= match-pos 0)) | |
1716 | (save-excursion | |
1717 | (goto-char (1- match-pos)) | |
1718 | (c-backward-syntactic-ws) | |
1719 | (and (c-simple-skip-symbol-backward) | |
1720 | (looking-at c-paren-stmt-key)))) | |
1721 | t))) | |
1722 | ||
1723 | ;; Fix the `c-decl-id-start' or `c-decl-type-start' property | |
1724 | ;; before the first declarator if it's a list. | |
1725 | ;; `c-font-lock-declarators' handles the rest. | |
1726 | (when decl-list | |
1727 | (save-excursion | |
1728 | (c-backward-syntactic-ws) | |
1729 | (unless (bobp) | |
1730 | (c-put-char-property (1- (point)) 'c-type | |
1731 | (if at-typedef | |
1732 | 'c-decl-type-start | |
1733 | 'c-decl-id-start))))) | |
1734 | ||
1735 | (c-font-lock-declarators (point-max) decl-list at-typedef))) | |
1736 | ||
1737 | (t | |
1738 | ;; False alarm. Skip the fontification done below. | |
1739 | (throw 'false-alarm t))) | |
1740 | ||
1741 | ;; A cast or declaration has been successfully identified, so do | |
1742 | ;; all the fontification of types and refs that's been recorded by | |
1743 | ;; the calls to `c-forward-type' and `c-forward-name' above. | |
1744 | (c-fontify-recorded-types-and-refs) | |
1745 | nil))) | |
1746 | ||
1747 | nil))) | |
1748 | ||
1749 | (c-lang-defconst c-simple-decl-matchers | |
1750 | "Simple font lock matchers for types and declarations. These are used | |
1751 | on level 2 only and so aren't combined with `c-complex-decl-matchers'." | |
1752 | ||
1753 | t `(;; Objective-C methods. | |
1754 | ,@(when (c-major-mode-is 'objc-mode) | |
1755 | `((,(c-lang-const c-opt-method-key) | |
1756 | (,(byte-compile | |
1757 | (lambda (limit) | |
1758 | (let (;; The font-lock package in Emacs is known to clobber | |
1759 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1760 | (parse-sexp-lookup-properties | |
1761 | (cc-eval-when-compile | |
1762 | (boundp 'parse-sexp-lookup-properties)))) | |
1763 | (save-restriction | |
1764 | (narrow-to-region (point-min) limit) | |
1765 | (c-font-lock-objc-method))) | |
1766 | nil)) | |
1767 | (goto-char (match-end 1)))))) | |
1768 | ||
1769 | ;; Fontify all type names and the identifiers in the | |
1770 | ;; declarations they might start. Use eval here since | |
1771 | ;; `c-known-type-key' gets its value from | |
1772 | ;; `*-font-lock-extra-types' on mode init. | |
1773 | (eval . (list ,(c-make-font-lock-search-function | |
1774 | 'c-known-type-key | |
1775 | '(1 'font-lock-type-face t) | |
1776 | '((c-font-lock-declarators limit t nil) | |
1777 | (save-match-data | |
1778 | (goto-char (match-end 1)) | |
1779 | (c-forward-syntactic-ws)) | |
1780 | (goto-char (match-end 1)))))) | |
1781 | ||
1782 | ;; Fontify types preceded by `c-type-prefix-kwds' and the | |
1783 | ;; identifiers in the declarations they might start. | |
1784 | ,@(when (c-lang-const c-type-prefix-kwds) | |
1785 | (let ((prefix-re (c-make-keywords-re nil | |
1786 | (c-lang-const c-type-prefix-kwds)))) | |
1787 | `((,(c-make-font-lock-search-function | |
1788 | (concat "\\<\\(" prefix-re "\\)" | |
1789 | "[ \t\n\r\f\v]+" | |
1790 | "\\(" (c-lang-const c-symbol-key) "\\)") | |
1791 | `(,(+ (c-regexp-opt-depth prefix-re) 2) | |
1792 | 'font-lock-type-face t) | |
1793 | '((c-font-lock-declarators limit t nil) | |
1794 | (save-match-data | |
1795 | (goto-char (match-end 2)) | |
1796 | (c-forward-syntactic-ws)) | |
1797 | (goto-char (match-end 2)))))))) | |
1798 | ||
1799 | ;; Fontify special declarations that lacks a type. | |
1800 | ,@(when (c-lang-const c-typeless-decl-kwds) | |
1801 | `((,(c-make-font-lock-search-function | |
1802 | (concat "\\<\\(" | |
1803 | (c-regexp-opt (c-lang-const c-typeless-decl-kwds)) | |
1804 | "\\)\\>") | |
1805 | '((c-font-lock-declarators limit t nil) | |
1806 | (save-match-data | |
1807 | (goto-char (match-end 1)) | |
1808 | (c-forward-syntactic-ws)) | |
1809 | (goto-char (match-end 1))))))) | |
1810 | )) | |
1811 | ||
1812 | (c-lang-defconst c-complex-decl-matchers | |
1813 | "Complex font lock matchers for types and declarations. Used on level | |
1814 | 3 and higher." | |
1815 | ||
1816 | t `(;; Initialize some things before the search functions below. | |
1817 | c-font-lock-complex-decl-prepare | |
1818 | ||
1819 | ;; Fontify angle bracket arglists like templates in C++. | |
1820 | ,@(when (c-lang-const c-recognize-<>-arglists) | |
1821 | `(c-font-lock-<>-arglists)) | |
1822 | ||
1823 | ,@(if (c-major-mode-is 'objc-mode) | |
1824 | ;; Fontify method declarations in Objective-C, but first | |
1825 | ;; we have to put the `c-decl-end' `c-type' property on | |
1826 | ;; all the @-style directives that haven't been handled in | |
1827 | ;; `c-basic-matchers-before'. | |
1828 | `(,(c-make-font-lock-search-function | |
1829 | (c-make-keywords-re t | |
1830 | ;; Exclude "@class" since that directive ends with a | |
1831 | ;; semicolon anyway. | |
1832 | (delete "@class" | |
1833 | (append (c-lang-const c-protection-kwds) | |
1834 | (c-lang-const c-other-decl-kwds) | |
1835 | nil))) | |
1836 | '((c-put-char-property (1- (match-end 1)) | |
1837 | 'c-type 'c-decl-end))) | |
1838 | ||
1839 | c-font-lock-objc-methods) | |
1840 | ||
1841 | (when (c-lang-const c-opt-access-key) | |
1842 | `(,(c-make-font-lock-search-function | |
1843 | (c-lang-const c-opt-access-key) | |
1844 | '((c-put-char-property (1- (match-end 0)) | |
1845 | 'c-type 'c-decl-end)))))) | |
1846 | ||
1847 | ;; Fontify all declarations and casts. | |
1848 | c-font-lock-declarations | |
1849 | ||
1850 | ;; The first two rules here mostly find occurences that | |
1851 | ;; `c-font-lock-declarations' has found already, but not | |
1852 | ;; declarations containing blocks in the type (see note below). | |
1853 | ;; It's also useful to fontify these everywhere to show e.g. when | |
1854 | ;; a type keyword is accidentally used as an identifier. | |
1855 | ||
1856 | ;; Fontify basic types. | |
1857 | ,(let ((re (c-make-keywords-re nil | |
1858 | (c-lang-const c-primitive-type-kwds)))) | |
1859 | (if (c-major-mode-is 'pike-mode) | |
1860 | ;; No symbol is a keyword after "->" in Pike. | |
1861 | `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" | |
1862 | "\\<\\(" re "\\)\\>") | |
1863 | 3 font-lock-type-face) | |
1864 | `(,(concat "\\<\\(" re "\\)\\>") | |
1865 | 1 'font-lock-type-face))) | |
1866 | ||
1867 | ;; Fontify types preceded by `c-type-prefix-kwds'. | |
1868 | ,@(when (c-lang-const c-type-prefix-kwds) | |
1869 | `((,(byte-compile | |
1870 | `(lambda (limit) | |
1871 | (c-fontify-types-and-refs | |
1872 | ((c-promote-possible-types t) | |
1873 | ;; The font-lock package in Emacs is known to clobber | |
1874 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1875 | (parse-sexp-lookup-properties | |
1876 | (cc-eval-when-compile | |
1877 | (boundp 'parse-sexp-lookup-properties)))) | |
1878 | (save-restriction | |
1879 | ;; Narrow to avoid going past the limit in | |
1880 | ;; `c-forward-type'. | |
1881 | (narrow-to-region (point) limit) | |
1882 | (while (re-search-forward | |
1883 | ,(concat "\\<\\(" | |
1884 | (c-make-keywords-re nil | |
1885 | (c-lang-const c-type-prefix-kwds)) | |
1886 | "\\)\\>") | |
1887 | limit t) | |
1888 | (unless (c-skip-comments-and-strings limit) | |
1889 | (c-forward-syntactic-ws) | |
1890 | ;; Handle prefix declaration specifiers. | |
1891 | (when (looking-at c-specifier-key) | |
1892 | (c-forward-keyword-clause)) | |
1893 | ,(if (c-major-mode-is 'c++-mode) | |
1894 | `(when (and (c-forward-type) | |
1895 | (eq (char-after) ?=)) | |
1896 | ;; In C++ we additionally check for a "class | |
1897 | ;; X = Y" construct which is used in | |
1898 | ;; templates, to fontify Y as a type. | |
1899 | (forward-char) | |
1900 | (c-forward-syntactic-ws) | |
1901 | (c-forward-type)) | |
1902 | `(c-forward-type)) | |
1903 | ))))))))) | |
1904 | ||
1905 | ;; Fontify symbols after closing braces as declaration | |
1906 | ;; identifiers under the assumption that they are part of | |
1907 | ;; declarations like "class Foo { ... } foo;". It's too | |
1908 | ;; expensive to check this accurately by skipping past the | |
1909 | ;; brace block, so we use the heuristic that it's such a | |
1910 | ;; declaration if the first identifier is on the same line as | |
1911 | ;; the closing brace. `c-font-lock-declarations' will later | |
1912 | ;; override it if it turns out to be an new declaration, but | |
1913 | ;; it will be wrong if it's an expression (see the test | |
1914 | ;; decls-8.cc). | |
1915 | ,@(when (c-lang-const c-opt-block-decls-with-vars-key) | |
1916 | `((,(c-make-font-lock-search-function | |
1917 | (concat "}" | |
1918 | (c-lang-const c-single-line-syntactic-ws) | |
1919 | "\\(" ; 1 + c-single-line-syntactic-ws-depth | |
1920 | (c-lang-const c-type-decl-prefix-key) | |
1921 | "\\|" | |
1922 | (c-lang-const c-symbol-key) | |
1923 | "\\)") | |
1924 | `((c-font-lock-declarators limit t nil) | |
1925 | (progn | |
1926 | (c-put-char-property (match-beginning 0) 'c-type | |
1927 | 'c-decl-id-start) | |
1928 | (goto-char (match-beginning | |
1929 | ,(1+ (c-lang-const | |
1930 | c-single-line-syntactic-ws-depth))))) | |
1931 | (goto-char (match-end 0))))))) | |
1932 | ||
1933 | ;; Fontify the type in C++ "new" expressions. | |
1934 | ,@(when (c-major-mode-is 'c++-mode) | |
1935 | `(("\\<new\\>" | |
1936 | (c-font-lock-c++-new)))) | |
1937 | )) | |
1938 | ||
1939 | (defun c-font-lock-labels (limit) | |
1940 | ;; Fontify all the declarations from the point to LIMIT. Assumes | |
1941 | ;; that strings and comments have been fontified already. Nil is | |
1942 | ;; always returned. | |
1943 | ;; | |
1944 | ;; This function can make hidden buffer changes, but the font-lock | |
1945 | ;; context covers that. | |
1946 | ||
1947 | (let (continue-pos id-start | |
1948 | ;; The font-lock package in Emacs is known to clobber | |
1949 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1950 | (parse-sexp-lookup-properties | |
1951 | (cc-eval-when-compile | |
1952 | (boundp 'parse-sexp-lookup-properties)))) | |
1953 | ||
1954 | (while (re-search-forward ":[^:]" limit t) | |
1955 | (setq continue-pos (point)) | |
1956 | (goto-char (match-beginning 0)) | |
1957 | (unless (c-skip-comments-and-strings limit) | |
1958 | ||
1959 | (c-backward-syntactic-ws) | |
1960 | (and (setq id-start (c-on-identifier)) | |
1961 | ||
1962 | (not (get-text-property id-start 'face)) | |
1963 | ||
1964 | (progn | |
1965 | (goto-char id-start) | |
1966 | (c-backward-syntactic-ws) | |
1967 | (or | |
1968 | ;; Check for a char that precedes a statement. | |
1969 | (memq (char-before) '(?\} ?\{ ?\;)) | |
1970 | ;; Check for a preceding label. We exploit the font | |
1971 | ;; locking made earlier by this function. | |
1972 | (and (eq (char-before) ?:) | |
1973 | (progn | |
1974 | (backward-char) | |
1975 | (c-backward-syntactic-ws) | |
1976 | (not (bobp))) | |
1977 | (eq (get-text-property (1- (point)) 'face) | |
1978 | c-label-face-name)) | |
1979 | ;; Check for a keyword that precedes a statement. | |
1980 | (c-after-conditional))) | |
1981 | ||
1982 | (progn | |
1983 | ;; Got a label. | |
1984 | (goto-char id-start) | |
1985 | (looking-at c-symbol-key) | |
1986 | (c-put-font-lock-face (match-beginning 0) (match-end 0) | |
1987 | c-label-face-name))) | |
1988 | ||
1989 | (goto-char continue-pos)))) | |
1990 | nil) | |
1991 | ||
1992 | (c-lang-defconst c-basic-matchers-after | |
1993 | "Font lock matchers for various things that should be fontified after | |
1994 | generic casts and declarations are fontified. Used on level 2 and | |
1995 | higher." | |
1996 | ||
1997 | t `(;; Fontify the identifiers inside enum lists. (The enum type | |
1998 | ;; name is handled by `c-simple-decl-matchers' or | |
1999 | ;; `c-complex-decl-matchers' below. | |
2000 | ,@(when (c-lang-const c-brace-id-list-kwds) | |
2001 | `((,(c-make-font-lock-search-function | |
2002 | (concat | |
2003 | "\\<\\(" | |
2004 | (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds)) | |
2005 | "\\)\\>" | |
2006 | ;; Disallow various common punctuation chars that can't come | |
2007 | ;; before the '{' of the enum list, to avoid searching too far. | |
2008 | "[^\]\[{}();,/#=]*" | |
2009 | "{") | |
2010 | '((c-font-lock-declarators limit t nil) | |
2011 | (save-match-data | |
2012 | (goto-char (match-end 0)) | |
2013 | (c-put-char-property (1- (point)) 'c-type | |
2014 | 'c-decl-id-start) | |
2015 | (c-forward-syntactic-ws)) | |
2016 | (goto-char (match-end 0))))))) | |
2017 | ||
2018 | ;; Fontify labels in languages that supports them. | |
2019 | ,@(when (c-lang-const c-label-key) | |
2020 | ||
2021 | `(;; Fontify labels after goto etc. | |
2022 | ;; (Got three different interpretation levels here, | |
2023 | ;; which makes it a bit complicated: 1) The backquote | |
2024 | ;; stuff is expanded when compiled or loaded, 2) the | |
2025 | ;; eval form is evaluated at font-lock setup (to | |
2026 | ;; substitute c-label-face-name correctly), and 3) the | |
2027 | ;; resulting structure is interpreted during | |
2028 | ;; fontification.) | |
2029 | (eval | |
2030 | . ,(let* ((c-before-label-re | |
2031 | (c-make-keywords-re nil | |
2032 | (c-lang-const c-before-label-kwds)))) | |
2033 | `(list | |
2034 | ,(concat "\\<\\(" c-before-label-re "\\)\\>" | |
2035 | "\\s *" | |
2036 | "\\(" ; identifier-offset | |
2037 | (c-lang-const c-symbol-key) | |
2038 | "\\)") | |
2039 | (list ,(+ (c-regexp-opt-depth c-before-label-re) 2) | |
2040 | c-label-face-name nil t)))) | |
2041 | ||
2042 | ;; Fontify normal labels. | |
2043 | c-font-lock-labels)) | |
2044 | ||
2045 | ;; Fontify the clauses after various keywords. | |
2046 | ,@(when (or (c-lang-const c-type-list-kwds) | |
2047 | (c-lang-const c-ref-list-kwds) | |
2048 | (c-lang-const c-colon-type-list-kwds) | |
2049 | (c-lang-const c-paren-type-kwds)) | |
2050 | `((,(c-make-font-lock-search-function | |
2051 | (concat "\\<\\(" | |
2052 | (c-make-keywords-re nil | |
2053 | (append (c-lang-const c-type-list-kwds) | |
2054 | (c-lang-const c-ref-list-kwds) | |
2055 | (c-lang-const c-colon-type-list-kwds) | |
2056 | (c-lang-const c-paren-type-kwds))) | |
2057 | "\\)\\>") | |
2058 | '((c-fontify-types-and-refs ((c-promote-possible-types t)) | |
2059 | (c-forward-keyword-clause) | |
2060 | (if (> (point) limit) (goto-char limit)))))))) | |
2061 | )) | |
2062 | ||
2063 | (c-lang-defconst c-matchers-1 | |
2064 | t (c-lang-const c-cpp-matchers)) | |
2065 | ||
2066 | (c-lang-defconst c-matchers-2 | |
2067 | t (append (c-lang-const c-matchers-1) | |
2068 | (c-lang-const c-basic-matchers-before) | |
2069 | (c-lang-const c-simple-decl-matchers) | |
2070 | (c-lang-const c-basic-matchers-after))) | |
2071 | ||
2072 | (c-lang-defconst c-matchers-3 | |
2073 | t (append (c-lang-const c-matchers-1) | |
2074 | (c-lang-const c-basic-matchers-before) | |
2075 | (c-lang-const c-complex-decl-matchers) | |
2076 | (c-lang-const c-basic-matchers-after))) | |
2077 | ||
2078 | (defun c-compose-keywords-list (base-list) | |
2079 | ;; Incorporate the font lock keyword lists according to | |
2080 | ;; `c-doc-comment-style' on the given keyword list and return it. | |
2081 | ;; This is used in the function bindings of the | |
2082 | ;; `*-font-lock-keywords-*' symbols since we have to build the list | |
2083 | ;; when font-lock is initialized. | |
2084 | ||
2085 | (unless (memq c-doc-face-name c-literal-faces) | |
2086 | (setq c-literal-faces (cons c-doc-face-name c-literal-faces))) | |
2087 | ||
2088 | (let* ((doc-keywords | |
2089 | (if (consp (car-safe c-doc-comment-style)) | |
2090 | (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style) | |
2091 | (assq 'other c-doc-comment-style))) | |
2092 | c-doc-comment-style)) | |
2093 | (list (nconc (apply 'nconc | |
2094 | (mapcar | |
2095 | (lambda (doc-style) | |
2096 | (let ((sym (intern | |
2097 | (concat (symbol-name doc-style) | |
2098 | "-font-lock-keywords")))) | |
2099 | (cond ((fboundp sym) | |
2100 | (funcall sym)) | |
2101 | ((boundp sym) | |
2102 | (append (eval sym) nil))))) | |
2103 | (if (listp doc-keywords) | |
2104 | doc-keywords | |
2105 | (list doc-keywords)))) | |
2106 | base-list))) | |
2107 | ||
2108 | ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we | |
2109 | ;; move it first since the doc comment font lockers might add | |
7bfc3fdb | 2110 | ;; `c-type' text properties, so they have to be cleared before that. |
d9e94c22 MS |
2111 | (when (memq 'c-font-lock-complex-decl-prepare list) |
2112 | (setq list (cons 'c-font-lock-complex-decl-prepare | |
2113 | (delq 'c-font-lock-complex-decl-prepare | |
2114 | (append list nil))))) | |
2115 | ||
2116 | list)) | |
2117 | ||
2118 | (defun c-override-default-keywords (def-var) | |
2119 | ;; This is used to override the value on a `*-font-lock-keywords' | |
2120 | ;; variable only if it's nil or has the same value as one of the | |
2121 | ;; `*-font-lock-keywords-*' variables. Older font-lock packages | |
2122 | ;; define a default value for `*-font-lock-keywords' which we want | |
2123 | ;; to override, but we should otoh avoid clobbering a user setting. | |
2124 | ;; This heuristic for that isn't perfect, but I can't think of any | |
2125 | ;; better. /mast | |
2126 | ;; | |
2127 | ;; This function does not do any hidden buffer changes. | |
2128 | (when (and (boundp def-var) | |
2129 | (memq (symbol-value def-var) | |
2130 | (cons nil | |
2131 | (mapcar | |
2132 | (lambda (suffix) | |
2133 | (let ((sym (intern (concat (symbol-name def-var) | |
2134 | suffix)))) | |
2135 | (and (boundp sym) (symbol-value sym)))) | |
2136 | '("-1" "-2" "-3"))))) | |
2137 | ;; The overriding is done by unbinding the variable so that the normal | |
2138 | ;; defvar will install its default value later on. | |
2139 | (makunbound def-var))) | |
2140 | ||
2141 | \f | |
2142 | ;;; C. | |
2143 | ||
2144 | (c-override-default-keywords 'c-font-lock-keywords) | |
2145 | ||
2146 | (defconst c-font-lock-keywords-1 (c-lang-const c-matchers-1 c) | |
2147 | "Minimal font locking for C mode. | |
2148 | Fontifies only preprocessor directives (in addition to the syntactic | |
2149 | fontification of strings and comments).") | |
2150 | ||
2151 | (defconst c-font-lock-keywords-2 (c-lang-const c-matchers-2 c) | |
2152 | "Fast normal font locking for C mode. | |
2153 | In addition to `c-font-lock-keywords-1', this adds fontification of | |
2154 | keywords, simple types, declarations that are easy to recognize, the | |
2155 | user defined types on `c-font-lock-extra-types', and the doc comment | |
2156 | styles specified by `c-doc-comment-style'.") | |
2157 | ||
2158 | (defconst c-font-lock-keywords-3 (c-lang-const c-matchers-3 c) | |
2159 | "Accurate normal font locking for C mode. | |
2160 | Like `c-font-lock-keywords-2' but detects declarations in a more | |
2161 | accurate way that works in most cases for arbitrary types without the | |
2162 | need for `c-font-lock-extra-types'.") | |
2163 | ||
2164 | (defvar c-font-lock-keywords c-font-lock-keywords-3 | |
2165 | "Default expressions to highlight in C mode.") | |
2166 | ||
2167 | (defun c-font-lock-keywords-2 () | |
2168 | (c-compose-keywords-list c-font-lock-keywords-2)) | |
2169 | (defun c-font-lock-keywords-3 () | |
2170 | (c-compose-keywords-list c-font-lock-keywords-3)) | |
2171 | (defun c-font-lock-keywords () | |
2172 | (c-compose-keywords-list c-font-lock-keywords)) | |
2173 | ||
2174 | \f | |
2175 | ;;; C++. | |
2176 | ||
2177 | (defun c-font-lock-c++-new (limit) | |
2178 | ;; Assuming point is after a "new" word, check that it isn't inside | |
2179 | ;; a string or comment, and if so try to fontify the type in the | |
2180 | ;; allocation expression. Nil is always returned. | |
2181 | ;; | |
2182 | ;; As usual, C++ takes the prize in coming up with a hard to parse | |
2183 | ;; syntax. :P | |
2184 | ||
2185 | (unless (c-skip-comments-and-strings limit) | |
2186 | (save-excursion | |
2187 | (catch 'false-alarm | |
2188 | ;; A "new" keyword is followed by one to three expressions, where | |
2189 | ;; the type is the middle one, and the only required part. | |
2190 | (let (expr1-pos expr2-pos | |
2191 | ;; Enable recording of identifier ranges in `c-forward-type' | |
2192 | ;; etc for later fontification. Not using | |
2193 | ;; `c-fontify-types-and-refs' here since the ranges should | |
2194 | ;; be fontified selectively only when an allocation | |
2195 | ;; expression is successfully recognized. | |
2196 | (c-record-type-identifiers t) | |
2197 | c-record-ref-identifiers | |
2198 | ;; The font-lock package in Emacs is known to clobber | |
2199 | ;; `parse-sexp-lookup-properties' (when it exists). | |
2200 | (parse-sexp-lookup-properties | |
2201 | (cc-eval-when-compile | |
2202 | (boundp 'parse-sexp-lookup-properties)))) | |
2203 | (c-forward-syntactic-ws) | |
2204 | ||
2205 | ;; The first placement arglist is always parenthesized, if it | |
2206 | ;; exists. | |
2207 | (when (eq (char-after) ?\() | |
2208 | (setq expr1-pos (1+ (point))) | |
2209 | (condition-case nil | |
2210 | (c-forward-sexp) | |
2211 | (scan-error (throw 'false-alarm t))) | |
2212 | (c-forward-syntactic-ws)) | |
2213 | ||
2214 | ;; The second expression is either a type followed by some "*" or | |
2215 | ;; "[...]" or similar, or a parenthesized type followed by a full | |
2216 | ;; identifierless declarator. | |
2217 | (setq expr2-pos (1+ (point))) | |
2218 | (cond ((eq (char-after) ?\()) | |
2219 | ((let ((c-promote-possible-types t)) | |
2220 | (c-forward-type))) | |
2221 | (t (setq expr2-pos nil))) | |
2222 | ||
2223 | (when expr1-pos | |
2224 | (cond | |
2225 | ((not expr2-pos) | |
2226 | ;; No second expression, so the first has to be a | |
2227 | ;; parenthesized type. | |
2228 | (goto-char expr1-pos) | |
2229 | (let ((c-promote-possible-types t)) | |
2230 | (c-forward-type))) | |
2231 | ||
2232 | ((eq (char-before expr2-pos) ?\() | |
2233 | ;; Got two parenthesized expressions, so we have to look | |
2234 | ;; closer at them to decide which is the type. No need to | |
2235 | ;; handle `c-record-ref-identifiers' since all references | |
2236 | ;; has already been handled by other fontification rules. | |
2237 | (let (expr1-res expr2-res) | |
2238 | ||
2239 | (goto-char expr1-pos) | |
2240 | (when (setq expr1-res (c-forward-type)) | |
2241 | (unless (looking-at | |
2242 | (cc-eval-when-compile | |
2243 | (concat (c-lang-const c-symbol-start c++) | |
2244 | "\\|[*:\)\[]"))) | |
2245 | ;; There's something after the would-be type that | |
2246 | ;; can't be there, so this is a placement arglist. | |
2247 | (setq expr1-res nil))) | |
2248 | ||
2249 | (goto-char expr2-pos) | |
2250 | (when (setq expr2-res (c-forward-type)) | |
2251 | (unless (looking-at | |
2252 | (cc-eval-when-compile | |
2253 | (concat (c-lang-const c-symbol-start c++) | |
2254 | "\\|[*:\)\[]"))) | |
2255 | ;; There's something after the would-be type that can't | |
2256 | ;; be there, so this is an initialization expression. | |
2257 | (setq expr2-res nil)) | |
2258 | (when (and (c-go-up-list-forward) | |
2259 | (progn (c-forward-syntactic-ws) | |
2260 | (eq (char-after) ?\())) | |
2261 | ;; If there's a third initialization expression | |
2262 | ;; then the second one is the type, so demote the | |
2263 | ;; first match. | |
2264 | (setq expr1-res nil))) | |
2265 | ||
2266 | ;; We fontify the most likely type, with a preference for | |
2267 | ;; the first argument since a placement arglist is more | |
2268 | ;; unusual than an initializer. | |
2269 | (cond ((memq expr1-res '(t known prefix))) | |
2270 | ((memq expr2-res '(t known prefix))) | |
2271 | ((eq expr1-res 'found) | |
2272 | (let ((c-promote-possible-types t)) | |
2273 | (goto-char expr1-pos) | |
2274 | (c-forward-type))) | |
2275 | ((eq expr2-res 'found) | |
2276 | (let ((c-promote-possible-types t)) | |
2277 | (goto-char expr2-pos) | |
2278 | (c-forward-type))) | |
2279 | ((and (eq expr1-res 'maybe) (not expr2-res)) | |
2280 | (let ((c-promote-possible-types t)) | |
2281 | (goto-char expr1-pos) | |
2282 | (c-forward-type))) | |
2283 | ((and (not expr1-res) (eq expr2-res 'maybe)) | |
2284 | (let ((c-promote-possible-types t)) | |
2285 | (goto-char expr2-pos) | |
2286 | (c-forward-type))) | |
2287 | ;; If both type matches are 'maybe then we're | |
2288 | ;; too uncertain to promote either of them. | |
2289 | ))))) | |
2290 | ||
2291 | ;; Fontify the type that now is recorded in | |
2292 | ;; `c-record-type-identifiers', if any. | |
2293 | (c-fontify-recorded-types-and-refs))))) | |
2294 | nil) | |
2295 | ||
2296 | (c-override-default-keywords 'c++-font-lock-keywords) | |
2297 | ||
2298 | (defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++) | |
2299 | "Minimal font locking for C++ mode. | |
2300 | Fontifies only preprocessor directives (in addition to the syntactic | |
2301 | fontification of strings and comments).") | |
2302 | ||
2303 | (defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++) | |
2304 | "Fast normal font locking for C++ mode. | |
2305 | In addition to `c++-font-lock-keywords-1', this adds fontification of | |
2306 | keywords, simple types, declarations that are easy to recognize, the | |
2307 | user defined types on `c++-font-lock-extra-types', and the doc comment | |
2308 | styles specified by `c-doc-comment-style'.") | |
2309 | ||
2310 | (defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++) | |
2311 | "Accurate normal font locking for C++ mode. | |
2312 | Like `c++-font-lock-keywords-2' but detects declarations in a more | |
2313 | accurate way that works in most cases for arbitrary types without the | |
2314 | need for `c++-font-lock-extra-types'.") | |
2315 | ||
2316 | (defvar c++-font-lock-keywords c++-font-lock-keywords-3 | |
2317 | "Default expressions to highlight in C++ mode.") | |
2318 | ||
2319 | (defun c++-font-lock-keywords-2 () | |
2320 | (c-compose-keywords-list c++-font-lock-keywords-2)) | |
2321 | (defun c++-font-lock-keywords-3 () | |
2322 | (c-compose-keywords-list c++-font-lock-keywords-3)) | |
2323 | (defun c++-font-lock-keywords () | |
2324 | (c-compose-keywords-list c++-font-lock-keywords)) | |
2325 | ||
2326 | \f | |
2327 | ;;; Objective-C. | |
2328 | ||
2329 | (defun c-font-lock-objc-iip-decl () | |
2330 | ;; Assuming the point is after an "@interface", "@implementation", | |
2331 | ;; "@protocol" declaration, fontify all the types in the directive. | |
2332 | ;; Return t if the directive was fully recognized. Point will then | |
2333 | ;; be at the end of it. | |
2334 | ||
2335 | (c-fontify-types-and-refs | |
2336 | (start-char | |
2337 | (c-promote-possible-types t) | |
2338 | ;; Turn off recognition of angle bracket arglists while parsing | |
2339 | ;; types here since the protocol reference list might then be | |
2340 | ;; considered part of the preceding name or superclass-name. | |
2341 | c-recognize-<>-arglists) | |
2342 | (catch 'break | |
2343 | ||
2344 | ;; Handle the name of the class itself. | |
2345 | (c-forward-syntactic-ws) | |
2346 | (unless (c-forward-type) (throw 'break nil)) | |
2347 | ||
2348 | ;; Look for ": superclass-name" or "( category-name )". | |
2349 | (when (looking-at "[:\(]") | |
2350 | (setq start-char (char-after)) | |
2351 | (forward-char) | |
2352 | (c-forward-syntactic-ws) | |
2353 | (unless (c-forward-type) (throw 'break nil)) | |
2354 | (when (eq start-char ?\() | |
2355 | (unless (eq (char-after) ?\)) (throw 'break nil)) | |
2356 | (forward-char) | |
2357 | (c-forward-syntactic-ws))) | |
2358 | ||
2359 | ;; Look for a protocol reference list. | |
2360 | (when (if (eq (char-after) ?<) | |
2361 | (progn | |
2362 | (setq c-recognize-<>-arglists t) | |
2363 | (c-forward-<>-arglist t t)) | |
2364 | t) | |
2365 | (c-put-char-property (1- (point)) 'c-type 'c-decl-end) | |
2366 | t)))) | |
2367 | ||
2368 | (defun c-font-lock-objc-method () | |
2369 | ;; Assuming the point is after the + or - that starts an Objective-C | |
2370 | ;; method declaration, fontify it. This must be done before normal | |
2371 | ;; casts, declarations and labels are fontified since they will get | |
2372 | ;; false matches in these things. | |
2373 | ||
2374 | (c-fontify-types-and-refs | |
2375 | ((first t) | |
2376 | (c-promote-possible-types t)) | |
2377 | ||
2378 | (while (and | |
2379 | (progn | |
2380 | (c-forward-syntactic-ws) | |
2381 | ||
2382 | ;; An optional method type. | |
2383 | (if (eq (char-after) ?\() | |
2384 | (progn | |
2385 | (forward-char) | |
2386 | (c-forward-syntactic-ws) | |
2387 | (c-forward-type) | |
2388 | (prog1 (c-go-up-list-forward) | |
2389 | (c-forward-syntactic-ws))) | |
2390 | t)) | |
2391 | ||
2392 | ;; The name. The first time it's the first part of | |
2393 | ;; the function name, the rest of the time it's an | |
2394 | ;; argument name. | |
2395 | (looking-at c-symbol-key) | |
2396 | (progn | |
2397 | (goto-char (match-end 0)) | |
2398 | (c-put-font-lock-face (match-beginning 0) | |
2399 | (point) | |
2400 | (if first | |
2401 | 'font-lock-function-name-face | |
2402 | 'font-lock-variable-name-face)) | |
2403 | (c-forward-syntactic-ws) | |
2404 | ||
2405 | ;; Another optional part of the function name. | |
2406 | (when (looking-at c-symbol-key) | |
2407 | (goto-char (match-end 0)) | |
2408 | (c-put-font-lock-face (match-beginning 0) | |
2409 | (point) | |
2410 | 'font-lock-function-name-face) | |
2411 | (c-forward-syntactic-ws)) | |
2412 | ||
2413 | ;; There's another argument if a colon follows. | |
2414 | (eq (char-after) ?:))) | |
2415 | (forward-char) | |
2416 | (setq first nil)))) | |
2417 | ||
2418 | (defun c-font-lock-objc-methods (limit) | |
2419 | ;; Fontify method declarations in Objective-C. Nil is always | |
2420 | ;; returned. | |
2421 | ||
2422 | (let (;; The font-lock package in Emacs is known to clobber | |
2423 | ;; `parse-sexp-lookup-properties' (when it exists). | |
2424 | (parse-sexp-lookup-properties | |
2425 | (cc-eval-when-compile | |
2426 | (boundp 'parse-sexp-lookup-properties)))) | |
2427 | ||
2428 | (c-find-decl-spots | |
2429 | limit | |
2430 | "[-+]" | |
2431 | nil | |
2432 | (lambda (match-pos inside-macro) | |
2433 | (forward-char) | |
2434 | (c-font-lock-objc-method)))) | |
2435 | nil) | |
2436 | ||
2437 | (c-override-default-keywords 'objc-font-lock-keywords) | |
2438 | ||
2439 | (defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc) | |
2440 | "Minimal font locking for Objective-C mode. | |
2441 | Fontifies only compiler directives (in addition to the syntactic | |
2442 | fontification of strings and comments).") | |
2443 | ||
2444 | (defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc) | |
2445 | "Fast normal font locking for Objective-C mode. | |
2446 | In addition to `objc-font-lock-keywords-1', this adds fontification of | |
2447 | keywords, simple types, declarations that are easy to recognize, the | |
2448 | user defined types on `objc-font-lock-extra-types', and the doc | |
2449 | comment styles specified by `c-doc-comment-style'.") | |
2450 | ||
2451 | (defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc) | |
2452 | "Accurate normal font locking for Objective-C mode. | |
2453 | Like `objc-font-lock-keywords-2' but detects declarations in a more | |
2454 | accurate way that works in most cases for arbitrary types without the | |
2455 | need for `objc-font-lock-extra-types'.") | |
2456 | ||
2457 | (defvar objc-font-lock-keywords objc-font-lock-keywords-3 | |
2458 | "Default expressions to highlight in Objective-C mode.") | |
2459 | ||
2460 | (defun objc-font-lock-keywords-2 () | |
2461 | (c-compose-keywords-list objc-font-lock-keywords-2)) | |
2462 | (defun objc-font-lock-keywords-3 () | |
2463 | (c-compose-keywords-list objc-font-lock-keywords-3)) | |
2464 | (defun objc-font-lock-keywords () | |
2465 | (c-compose-keywords-list objc-font-lock-keywords)) | |
2466 | ||
2467 | ;; Kludge to override the default value that | |
2468 | ;; `objc-font-lock-extra-types' might have gotten from the font-lock | |
2469 | ;; package. The value replaced here isn't relevant now anyway since | |
2470 | ;; those types are builtin and therefore listed directly in | |
2471 | ;; `c-primitive-type-kwds'. | |
2472 | (when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp) | |
2473 | '("BOOL" "Class" "IMP" "SEL")) | |
2474 | (setq objc-font-lock-extra-types | |
2475 | (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*"))))) | |
2476 | ||
2477 | \f | |
2478 | ;;; Java. | |
2479 | ||
2480 | (c-override-default-keywords 'java-font-lock-keywords) | |
2481 | ||
2482 | (defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java) | |
2483 | "Minimal font locking for Java mode. | |
2484 | Fontifies nothing except the syntactic fontification of strings and | |
2485 | comments.") | |
2486 | ||
2487 | (defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java) | |
2488 | "Fast normal font locking for Java mode. | |
2489 | In addition to `java-font-lock-keywords-1', this adds fontification of | |
2490 | keywords, simple types, declarations that are easy to recognize, the | |
2491 | user defined types on `java-font-lock-extra-types', and the doc | |
2492 | comment styles specified by `c-doc-comment-style'.") | |
2493 | ||
2494 | (defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java) | |
2495 | "Accurate normal font locking for Java mode. | |
2496 | Like `java-font-lock-keywords-2' but detects declarations in a more | |
2497 | accurate way that works in most cases for arbitrary types without the | |
2498 | need for `java-font-lock-extra-types'.") | |
2499 | ||
2500 | (defvar java-font-lock-keywords java-font-lock-keywords-3 | |
2501 | "Default expressions to highlight in Java mode.") | |
2502 | ||
2503 | (defun java-font-lock-keywords-2 () | |
2504 | (c-compose-keywords-list java-font-lock-keywords-2)) | |
2505 | (defun java-font-lock-keywords-3 () | |
2506 | (c-compose-keywords-list java-font-lock-keywords-3)) | |
2507 | (defun java-font-lock-keywords () | |
2508 | (c-compose-keywords-list java-font-lock-keywords)) | |
2509 | ||
2510 | \f | |
2511 | ;;; CORBA IDL. | |
2512 | ||
2513 | (c-override-default-keywords 'idl-font-lock-keywords) | |
2514 | ||
2515 | (defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl) | |
2516 | "Minimal font locking for CORBA IDL mode. | |
2517 | Fontifies nothing except the syntactic fontification of strings and | |
2518 | comments.") | |
2519 | ||
2520 | (defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl) | |
2521 | "Fast normal font locking for CORBA IDL mode. | |
2522 | In addition to `idl-font-lock-keywords-1', this adds fontification of | |
2523 | keywords, simple types, declarations that are easy to recognize, the | |
2524 | user defined types on `idl-font-lock-extra-types', and the doc comment | |
2525 | styles specified by `c-doc-comment-style'.") | |
2526 | ||
2527 | (defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl) | |
2528 | "Accurate normal font locking for CORBA IDL mode. | |
2529 | Like `idl-font-lock-keywords-2' but detects declarations in a more | |
2530 | accurate way that works in most cases for arbitrary types without the | |
2531 | need for `idl-font-lock-extra-types'.") | |
2532 | ||
2533 | (defvar idl-font-lock-keywords idl-font-lock-keywords-3 | |
2534 | "Default expressions to highlight in CORBA IDL mode.") | |
2535 | ||
2536 | (defun idl-font-lock-keywords-2 () | |
2537 | (c-compose-keywords-list idl-font-lock-keywords-2)) | |
2538 | (defun idl-font-lock-keywords-3 () | |
2539 | (c-compose-keywords-list idl-font-lock-keywords-3)) | |
2540 | (defun idl-font-lock-keywords () | |
2541 | (c-compose-keywords-list idl-font-lock-keywords)) | |
2542 | ||
2543 | \f | |
2544 | ;;; Pike. | |
2545 | ||
2546 | (c-override-default-keywords 'pike-font-lock-keywords) | |
2547 | ||
2548 | (defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike) | |
2549 | "Minimal font locking for Pike mode. | |
2550 | Fontifies only preprocessor directives (in addition to the syntactic | |
2551 | fontification of strings and comments).") | |
2552 | ||
2553 | (defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike) | |
2554 | "Fast normal font locking for Pike mode. | |
2555 | In addition to `pike-font-lock-keywords-1', this adds fontification of | |
2556 | keywords, simple types, declarations that are easy to recognize, the | |
2557 | user defined types on `pike-font-lock-extra-types', and the doc | |
2558 | comment styles specified by `c-doc-comment-style'.") | |
2559 | ||
2560 | (defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike) | |
2561 | "Accurate normal font locking for Pike mode. | |
2562 | Like `pike-font-lock-keywords-2' but detects declarations in a more | |
2563 | accurate way that works in most cases for arbitrary types without the | |
2564 | need for `pike-font-lock-extra-types'.") | |
2565 | ||
2566 | (defvar pike-font-lock-keywords pike-font-lock-keywords-3 | |
2567 | "Default expressions to highlight in Pike mode.") | |
2568 | ||
2569 | (defun pike-font-lock-keywords-2 () | |
2570 | (c-compose-keywords-list pike-font-lock-keywords-2)) | |
2571 | (defun pike-font-lock-keywords-3 () | |
2572 | (c-compose-keywords-list pike-font-lock-keywords-3)) | |
2573 | (defun pike-font-lock-keywords () | |
2574 | (c-compose-keywords-list pike-font-lock-keywords)) | |
2575 | ||
2576 | \f | |
2577 | ;;; Doc comments. | |
2578 | ||
2579 | (defun c-font-lock-doc-comments (prefix limit keywords) | |
2580 | ;; Fontify the comments between the point and LIMIT whose start | |
2581 | ;; matches PREFIX with `c-doc-face-name'. Assumes comments have been | |
2582 | ;; fontified with `font-lock-comment-face' already. nil is always | |
2583 | ;; returned. | |
2584 | ;; | |
2585 | ;; After the fontification of a matching comment, fontification | |
2586 | ;; according to KEYWORDS is applied inside it. It's a list like | |
2587 | ;; `font-lock-keywords' except that anchored matches and eval | |
2588 | ;; clauses aren't supported and that some abbreviated forms can't be | |
2589 | ;; used. The buffer is narrowed to the comment while KEYWORDS is | |
2590 | ;; applied; leading comment starters are included but trailing | |
2591 | ;; comment enders for block comment are not. | |
2592 | ;; | |
2593 | ;; Note that faces added through KEYWORDS should never replace the | |
2594 | ;; existing `c-doc-face-name' face since the existence of that face | |
2595 | ;; is used as a flag in other code to skip comments. | |
2596 | ||
2597 | (let (comment-beg region-beg) | |
2598 | (if (eq (get-text-property (point) 'face) | |
2599 | 'font-lock-comment-face) | |
2600 | ;; Handle the case when the fontified region starts inside a | |
2601 | ;; comment. | |
2602 | (let ((range (c-literal-limits))) | |
2603 | (setq region-beg (point)) | |
2604 | (when range | |
2605 | (goto-char (car range))) | |
2606 | (when (looking-at prefix) | |
2607 | (setq comment-beg (point))))) | |
2608 | ||
2609 | (while (or | |
2610 | comment-beg | |
2611 | ||
2612 | ;; Search for the prefix until a match is found at the start | |
2613 | ;; of a comment. | |
2614 | (while (when (re-search-forward prefix limit t) | |
2615 | (setq comment-beg (match-beginning 0)) | |
2616 | (or (not (c-got-face-at comment-beg | |
2617 | c-literal-faces)) | |
2618 | (and (/= comment-beg (point-min)) | |
2619 | (c-got-face-at (1- comment-beg) | |
2620 | c-literal-faces)))) | |
2621 | (setq comment-beg nil)) | |
2622 | (setq region-beg comment-beg)) | |
2623 | ||
2624 | (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t) | |
2625 | ;; Collect a sequence of doc style line comments. | |
2626 | (progn | |
2627 | (goto-char comment-beg) | |
2628 | (while (and (progn | |
2629 | (c-forward-single-comment) | |
2630 | (skip-syntax-forward " ") | |
2631 | (< (point) limit)) | |
2632 | (looking-at prefix)))) | |
2633 | (goto-char comment-beg) | |
2634 | (c-forward-single-comment)) | |
2635 | (if (> (point) limit) (goto-char limit)) | |
2636 | (setq comment-beg nil) | |
2637 | ||
2638 | (let ((region-end (point)) | |
2639 | (keylist keywords) keyword matcher highlights) | |
2640 | (c-put-font-lock-face region-beg region-end c-doc-face-name) | |
2641 | (save-restriction | |
2642 | ;; Narrow to the doc comment. Among other things, this | |
2643 | ;; helps by making "^" match at the start of the comment. | |
2644 | ;; Do not include a trailing block comment ender, though. | |
2645 | (and (> region-end (1+ region-beg)) | |
2646 | (progn (goto-char region-end) | |
2647 | (backward-char 2) | |
2648 | (looking-at "\\*/")) | |
2649 | (setq region-end (point))) | |
2650 | (narrow-to-region region-beg region-end) | |
2651 | ||
2652 | (while keylist | |
2653 | (setq keyword (car keylist) | |
2654 | keylist (cdr keylist) | |
2655 | matcher (car keyword)) | |
2656 | (goto-char region-beg) | |
2657 | (while (if (stringp matcher) | |
2658 | (re-search-forward matcher region-end t) | |
2659 | (funcall matcher region-end)) | |
2660 | (setq highlights (cdr keyword)) | |
2661 | (if (consp (car highlights)) | |
2662 | (while highlights | |
2663 | (font-lock-apply-highlight (car highlights)) | |
2664 | (setq highlights (cdr highlights))) | |
2665 | (font-lock-apply-highlight highlights)))) | |
2666 | ||
2667 | (goto-char region-end))))) | |
2668 | nil) | |
2669 | (put 'c-font-lock-doc-comments 'lisp-indent-function 2) | |
2670 | ||
2671 | (defun c-find-invalid-doc-markup (regexp limit) | |
2672 | ;; Used to fontify invalid markup in doc comments after the correct | |
2673 | ;; ones have been fontified: Find the first occurence of REGEXP | |
2674 | ;; between the point and LIMIT that only is fontified with | |
2675 | ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds | |
2676 | ;; the first char and t is returned, otherwise nil is returned. | |
2677 | (let (start) | |
2678 | (while (if (re-search-forward regexp limit t) | |
2679 | (not (eq (get-text-property | |
2680 | (setq start (match-beginning 0)) 'face) | |
2681 | c-doc-face-name)) | |
2682 | (setq start nil))) | |
2683 | (when start | |
2684 | (store-match-data (list (copy-marker start) | |
2685 | (copy-marker (1+ start)))) | |
2686 | t))) | |
2687 | ||
7bfc3fdb MS |
2688 | (defconst javadoc-font-lock-doc-comments |
2689 | `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup. | |
2690 | 0 ,c-doc-markup-face-name prepend nil) | |
2691 | ("^\\(/\\*\\)?[ \t*]*\\(@[a-z]+\\)" ; "@foo ..." markup. | |
2692 | 2 ,c-doc-markup-face-name prepend nil) | |
2693 | (,(concat "</?\\sw" ; HTML tags. | |
2694 | "\\(" | |
2695 | (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|" | |
2696 | "\"[^\"]*\"\\|'[^']*'") | |
2697 | "\\)*>") | |
2698 | 0 ,c-doc-markup-face-name prepend nil) | |
2699 | ("&\\(\\sw\\|[.:]\\)+;" ; HTML entities. | |
2700 | 0 ,c-doc-markup-face-name prepend nil) | |
2701 | ;; Fontify remaining markup characters as invalid. Note | |
2702 | ;; that the Javadoc spec is hazy about when "@" is | |
2703 | ;; allowed in non-markup use. | |
2704 | (,(lambda (limit) | |
2705 | (c-find-invalid-doc-markup "[<>&]\\|{@" limit)) | |
2706 | 0 ,c-invalid-face-name prepend nil))) | |
2707 | ||
2708 | (defconst javadoc-font-lock-keywords | |
2709 | `((,(lambda (limit) | |
2710 | (c-font-lock-doc-comments "/\\*\\*" limit | |
2711 | javadoc-font-lock-doc-comments))))) | |
d9e94c22 MS |
2712 | |
2713 | (defconst autodoc-decl-keywords | |
2714 | ;; Adorned regexp matching the keywords that introduce declarations | |
2715 | ;; in Pike Autodoc. | |
2716 | (cc-eval-when-compile | |
2717 | (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode))) | |
2718 | ||
2719 | (defconst autodoc-decl-type-keywords | |
2720 | ;; Adorned regexp matching the keywords that are followed by a type. | |
2721 | (cc-eval-when-compile | |
2722 | (c-make-keywords-re t '("@elem" "@member") 'pike-mode))) | |
2723 | ||
2724 | (defun autodoc-font-lock-line-markup (limit) | |
2725 | ;; Fontify all line oriented keywords between the point and LIMIT. | |
2726 | ;; Nil is always returned. | |
2727 | ||
2728 | (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\(" | |
2729 | c-current-comment-prefix | |
2730 | "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)")) | |
2731 | (markup-faces (list c-doc-markup-face-name c-doc-face-name))) | |
2732 | ||
2733 | (while (re-search-forward line-re limit t) | |
2734 | (goto-char (match-end 1)) | |
2735 | ||
2736 | (if (looking-at autodoc-decl-keywords) | |
2737 | (let* ((kwd-pos (point)) | |
2738 | (start (match-end 1)) | |
2739 | (pos start) | |
2740 | end) | |
2741 | ||
2742 | (c-put-font-lock-face (point) pos markup-faces) | |
2743 | ||
2744 | ;; Put a declaration end mark at the markup keyword and | |
2745 | ;; remove the faces from the rest of the line so that it | |
2746 | ;; gets refontified as a declaration later on by | |
2747 | ;; `c-font-lock-declarations'. | |
2748 | (c-put-char-property (1- pos) 'c-type 'c-decl-end) | |
2749 | (goto-char pos) | |
2750 | (while (progn | |
2751 | (end-of-line) | |
2752 | (setq end (point)) | |
2753 | (and (eq (char-before) ?@) | |
2754 | (not (eobp)) | |
2755 | (progn (forward-char) | |
2756 | (skip-chars-forward " \t") | |
2757 | (looking-at c-current-comment-prefix)))) | |
2758 | (goto-char (match-end 0)) | |
2759 | (c-remove-font-lock-face pos (1- end)) | |
2760 | (c-put-font-lock-face (1- end) end markup-faces) | |
2761 | (setq pos (point))) | |
2762 | ||
2763 | ;; Include the final newline in the removed area. This | |
2764 | ;; has no visual effect but it avoids some tricky special | |
2765 | ;; cases in the testsuite wrt the differences in string | |
2766 | ;; fontification in Emacs vs XEmacs. | |
2767 | (c-remove-font-lock-face pos (min (1+ (point)) (point-max))) | |
2768 | ||
2769 | ;; Must handle string literals explicitly inside the declaration. | |
2770 | (goto-char start) | |
2771 | (while (re-search-forward | |
2772 | "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'" | |
2773 | end 'move) | |
2774 | (c-put-font-lock-string-face (match-beginning 0) | |
2775 | (point))) | |
2776 | ||
2777 | ;; Fontify types after keywords that always are followed | |
2778 | ;; by them. | |
2779 | (goto-char kwd-pos) | |
2780 | (when (looking-at autodoc-decl-type-keywords) | |
2781 | (c-fontify-types-and-refs ((c-promote-possible-types t)) | |
2782 | (goto-char start) | |
2783 | (c-forward-syntactic-ws) | |
2784 | (c-forward-type)))) | |
2785 | ||
2786 | ;; Mark each whole line as markup, as long as the logical line | |
2787 | ;; continues. | |
2788 | (while (progn | |
2789 | (c-put-font-lock-face (point) | |
2790 | (progn (end-of-line) (point)) | |
2791 | markup-faces) | |
2792 | (and (eq (char-before) ?@) | |
2793 | (not (eobp)) | |
2794 | (progn (forward-char) | |
2795 | (skip-chars-forward " \t") | |
2796 | (looking-at c-current-comment-prefix)))) | |
2797 | (goto-char (match-end 0)))))) | |
2798 | ||
2799 | nil) | |
2800 | ||
7bfc3fdb MS |
2801 | (defconst autodoc-font-lock-doc-comments |
2802 | `(("@\\(\\w+{\\|\\[\\([^\]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)" | |
2803 | ;; In-text markup. | |
2804 | 0 ,c-doc-markup-face-name prepend nil) | |
2805 | (autodoc-font-lock-line-markup) | |
2806 | ;; Fontify remaining markup characters as invalid. | |
2807 | (,(lambda (limit) | |
2808 | (c-find-invalid-doc-markup "@" limit)) | |
2809 | 0 ,c-invalid-face-name prepend nil) | |
2810 | )) | |
2811 | ||
d9e94c22 MS |
2812 | (defun autodoc-font-lock-keywords () |
2813 | ;; Note that we depend on that `c-current-comment-prefix' has got | |
2814 | ;; its proper value here. | |
2815 | ||
2816 | ;; The `c-type' text property with `c-decl-end' is used to mark the | |
2817 | ;; end of the `autodoc-decl-keywords' occurrences to fontify the | |
2818 | ;; following declarations. | |
2819 | (setq c-type-decl-end-used t) | |
2820 | ||
7bfc3fdb MS |
2821 | `((,(lambda (limit) |
2822 | (c-font-lock-doc-comments "/[*/]!" limit | |
2823 | autodoc-font-lock-doc-comments))))) | |
d9e94c22 MS |
2824 | |
2825 | \f | |
2826 | ;; AWK. | |
2827 | ||
2828 | ;; Awk regexps written with help from Peter Galbraith | |
2829 | ;; <galbraith@mixing.qc.dfo.ca>. | |
2830 | ;; Take GNU Emacs's 'words out of the following regexp-opts. They dont work | |
2831 | ;; in Xemacs 21.4.4. acm 2002/9/19. | |
2832 | (eval-after-load "cc-awk" ; Evaluate while loading cc-fonts | |
2833 | `(defconst awk-font-lock-keywords ; Evaluate after loading cc-awk | |
2834 | ',(eval-when-compile ; Evaluate while compiling cc-fonts | |
2835 | (list | |
2836 | ;; Function names. | |
2837 | '("^[ \t]*\\(func\\(tion\\)?\\)\\>[ \t]*\\(\\sw+\\)?" | |
2838 | (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) | |
2839 | ;; | |
2840 | ;; Variable names. | |
2841 | (cons | |
2842 | (concat "\\<" | |
2843 | (c-regexp-opt | |
2844 | '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON" | |
2845 | "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE" | |
2846 | "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH" | |
2847 | "RS" "RSTART" "RT" "SUBSEP" "TEXTDOMAIN") t) "\\>") | |
2848 | 'font-lock-variable-name-face) | |
2849 | ||
2850 | ;; Special file names. (acm, 2002/7/22) | |
2851 | ;; The following regexp was created by first evaluating this in GNU Emacs 21.1: | |
2852 | ;; (c-regexp-opt '("/dev/stdin" "/dev/stdout" "/dev/stderr" "/dev/fd/n" "/dev/pid" | |
2853 | ;; "/dev/ppid" "/dev/pgrpid" "/dev/user") 'words) | |
2854 | ;; , removing the "?:" from each "\\(?:" (for backward compatibility with older Emacsen) | |
2855 | ;; , replacing the "n" in "dev/fd/n" with "[0-9]+" | |
2856 | ;; , removing the unwanted \\< at the beginning, and finally filling out the | |
2857 | ;; regexp so that a " must come before, and either a " or heuristic stuff after. | |
2858 | ;; The surrounding quotes are fontified along with the filename, since, semantically, | |
2859 | ;; they are an indivisible unit. | |
2860 | '("\\(\"/dev/\\(fd/[0-9]+\\|p\\(\\(\\(gr\\)?p\\)?id\\)\\|\ | |
2861 | std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ | |
2862 | \\(\\(\"\\)\\|\\([^\"/\n\r][^\"\n\r]*\\)?$\\)" | |
2863 | (1 font-lock-variable-name-face t) | |
2864 | (8 font-lock-variable-name-face t t)) | |
2865 | ;; Do the same (almost) with | |
2866 | ;; (c-regexp-opt '("/inet/tcp/lport/rhost/rport" "/inet/udp/lport/rhost/rport" | |
2867 | ;; "/inet/raw/lport/rhost/rport") 'words) | |
2868 | ;; This cannot be combined with the above pattern, because the match number | |
2869 | ;; for the (optional) closing \" would then exceed 9. | |
2870 | '("\\(\"/inet/\\(\\(raw\\|\\(tc\\|ud\\)p\\)/lport/rhost/rport\\)\\)\\>\ | |
2871 | \\(\\(\"\\)\\|\\([^\"/\n\r][^\"\n\r]*\\)?$\\)" | |
2872 | (1 font-lock-variable-name-face t) | |
2873 | (6 font-lock-variable-name-face t t)) | |
2874 | ||
2875 | ;; Keywords. | |
2876 | (concat "\\<" | |
2877 | (c-regexp-opt | |
2878 | '("BEGIN" "END" "break" "continue" "delete" "do" "else" | |
2879 | "exit" "for" "getline" "if" "in" "next" "nextfile" | |
2880 | "return" "while") | |
2881 | t) "\\>") | |
2882 | ||
2883 | ;; Builtins. | |
2884 | `(eval . (list | |
2885 | ,(concat | |
2886 | "\\<" | |
2887 | (c-regexp-opt | |
2888 | '("adump" "and" "asort" "atan2" "bindtextdomain" "close" | |
2889 | "compl" "cos" "dcgettext" "exp" "extension" "fflush" | |
2890 | "gensub" "gsub" "index" "int" "length" "log" "lshift" | |
2891 | "match" "mktime" "or" "print" "printf" "rand" "rshift" | |
2892 | "sin" "split" "sprintf" "sqrt" "srand" "stopme" | |
2893 | "strftime" "strtonum" "sub" "substr" "system" | |
2894 | "systime" "tolower" "toupper" "xor") t) | |
2895 | "\\>") | |
2896 | 0 c-preprocessor-face-name)) | |
2897 | ||
2898 | ;; gawk debugging keywords. (acm, 2002/7/21) | |
2899 | ;; (Removed, 2003/6/6. These functions are now fontified as built-ins) | |
2900 | ;; (list (concat "\\<" (c-regexp-opt '("adump" "stopme") t) "\\>") | |
2901 | ;; 0 'font-lock-warning-face) | |
2902 | ||
2903 | ;; User defined functions with an apparent spurious space before the | |
2904 | ;; opening parenthesis. acm, 2002/5/30. | |
2905 | `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "[ \t]" | |
2906 | c-awk-escaped-nls*-with-space* "(") | |
2907 | (0 'font-lock-warning-face)) | |
2908 | ||
2909 | ;; Space after \ in what looks like an escaped newline. 2002/5/31 | |
2910 | '("\\\\[ \t]+$" 0 font-lock-warning-face t) | |
2911 | ||
2912 | ;; Unbalanced string (") or regexp (/) delimiters. 2002/02/16. | |
2913 | '("\\s|" 0 font-lock-warning-face t nil) | |
2914 | ;; gawk 3.1 localizable strings ( _"translate me!"). 2002/5/21 | |
2915 | '("\\(_\\)\\s|" 1 font-lock-warning-face) | |
2916 | '("\\(_\\)\\s\"" 1 font-lock-string-face) ; FIXME! not for XEmacs. 2002/10/6 | |
2917 | )) | |
2918 | "Default expressions to highlight in AWK mode.")) | |
2919 | ||
2920 | \f | |
2921 | (cc-provide 'cc-fonts) | |
2922 | ||
ab5796a9 | 2923 | ;;; arch-tag: 2f65f405-735f-4da5-8d4b-b957844c5203 |
d9e94c22 | 2924 | ;;; cc-fonts.el ends here |