1;;; cc-fonts.el --- font lock support for CC Mode -*- lexical-binding: t -*- 2 3;; Copyright (C) 2002-2021 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;; Keywords: c languages 10;; Package: cc-mode 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 3 of the License, or 17;; (at your option) 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 26 27;;; Commentary: 28 29;; Some comments on the use of faces: 30;; 31;; o `c-label-face-name' is either `font-lock-constant-face' (in 32;; Emacs), or `font-lock-reference-face'. 33;; 34;; o `c-constant-face-name', `c-reference-face-name' and 35;; `c-doc-markup-face-name' are essentially set up like 36;; `c-label-face-name'. 37;; 38;; o `c-preprocessor-face-name' is `font-lock-preprocessor-face' in 39;; XEmacs and - in lack of a closer equivalent - 40;; `font-lock-builtin-face' or `font-lock-reference-face' in Emacs. 41;; 42;; o `c-doc-face-name' is `font-lock-doc-string-face' in XEmacs, 43;; `font-lock-doc-face' in Emacs 21 and later, or 44;; `font-lock-comment-face' in older Emacs (that since source 45;; documentation are actually comments in these languages, as opposed 46;; to elisp). 47;; 48;; TBD: We should probably provide real faces for the above uses and 49;; instead initialize them from the standard faces. 50 51;;; Code: 52 53;; The faces that already have been put onto the text is tested in 54;; various places to direct further fontifications. For this to work, 55;; the following assumptions regarding the faces must hold (apart from 56;; the dependencies on the font locking order): 57;; 58;; o `font-lock-comment-face' and the face in `c-doc-face-name' is 59;; not used in anything but comments. 60;; o If any face (e.g. `c-doc-markup-face-name') but those above is 61;; used in comments, it doesn't replace them. 62;; o `font-lock-string-face' is not used in anything but string 63;; literals (single or double quoted). 64;; o `font-lock-keyword-face' and the face in `c-label-face-name' are 65;; never overlaid with other faces. 66 67(eval-when-compile 68 (let ((load-path 69 (if (and (boundp 'byte-compile-dest-file) 70 (stringp byte-compile-dest-file)) 71 (cons (file-name-directory byte-compile-dest-file) load-path) 72 load-path))) 73 (load "cc-bytecomp" nil t))) 74 75(cc-require 'cc-defs) 76(cc-require-when-compile 'cc-langs) 77(cc-require 'cc-vars) 78(cc-require 'cc-engine) 79 80;; Avoid repeated loading through the eval-after-load directive in 81;; cc-mode.el. 82(provide 'cc-fonts) 83 84(cc-external-require 'font-lock) 85 86(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only. 87 88;; Need to declare these local symbols during compilation since 89;; they're referenced from lambdas in `byte-compile' calls that are 90;; executed at compile time. They don't need to have the proper 91;; definitions, though, since the generated functions aren't called 92;; during compilation. 93(cc-bytecomp-defvar c-preprocessor-face-name) 94(cc-bytecomp-defvar c-reference-face-name) 95(cc-bytecomp-defvar c-block-comment-flag) 96(cc-bytecomp-defun c-fontify-recorded-types-and-refs) 97(cc-bytecomp-defun c-font-lock-declarators) 98(cc-bytecomp-defun c-font-lock-objc-method) 99(cc-bytecomp-defun c-font-lock-invalid-string) 100(cc-bytecomp-defun c-font-lock-fontify-region) 101 102 103;; Note that font-lock in XEmacs doesn't expand face names as 104;; variables, so we have to use the (eval . FORM) in the font lock 105;; matchers wherever we use these alias variables. 106 107(defconst c-preprocessor-face-name 108 (cond ((c-face-name-p 'font-lock-preprocessor-face) 109 ;; XEmacs has a font-lock-preprocessor-face. 110 'font-lock-preprocessor-face) 111 ((c-face-name-p 'font-lock-builtin-face) 112 ;; In Emacs font-lock-builtin-face has traditionally been 113 ;; used for preprocessor directives. 114 'font-lock-builtin-face) 115 (t 116 'font-lock-reference-face))) 117 118(cc-bytecomp-defvar font-lock-constant-face) 119 120(defconst c-label-face-name 121 (cond ((c-face-name-p 'font-lock-label-face) 122 ;; If it happens to occur in the future. (Well, the more 123 ;; pragmatic reason is to get unique faces for the test 124 ;; suite.) 125 'font-lock-label-face) 126 ((and (c-face-name-p 'font-lock-constant-face) 127 (eq font-lock-constant-face 'font-lock-constant-face)) 128 ;; Test both if font-lock-constant-face exists and that it's 129 ;; not an alias for something else. This is important since 130 ;; we compare already set faces in various places. 131 'font-lock-constant-face) 132 (t 133 'font-lock-reference-face))) 134 135(defconst c-constant-face-name 136 (if (and (c-face-name-p 'font-lock-constant-face) 137 (eq font-lock-constant-face 'font-lock-constant-face)) 138 ;; This doesn't exist in some earlier versions of XEmacs 21. 139 'font-lock-constant-face 140 c-label-face-name)) 141 142(defconst c-reference-face-name 143 (with-no-warnings 144 (if (and (c-face-name-p 'font-lock-reference-face) 145 (eq font-lock-reference-face 'font-lock-reference-face)) 146 ;; This is considered obsolete in Emacs, but it still maps well 147 ;; to this use. (Another reason to do this is to get unique 148 ;; faces for the test suite.) 149 'font-lock-reference-face 150 c-label-face-name))) 151 152;; This should not mapped to a face that also is used to fontify things 153;; that aren't comments or string literals. 154(defconst c-doc-face-name 155 (cond ((c-face-name-p 'font-lock-doc-string-face) 156 ;; XEmacs. 157 'font-lock-doc-string-face) 158 ((c-face-name-p 'font-lock-doc-face) 159 ;; Emacs 21 and later. 160 'font-lock-doc-face) 161 (t 162 'font-lock-comment-face))) 163 164(defconst c-doc-markup-face-name 165 (if (c-face-name-p 'font-lock-doc-markup-face) 166 ;; If it happens to occur in the future. (Well, the more 167 ;; pragmatic reason is to get unique faces for the test 168 ;; suite.) 169 'font-lock-doc-markup-face 170 c-label-face-name)) 171 172(defconst c-negation-char-face-name 173 (if (c-face-name-p 'font-lock-negation-char-face) 174 ;; Emacs 22 has a special face for negation chars. 175 'font-lock-negation-char-face)) 176 177(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. 178 179(defun c-make-inverse-face (oldface newface) 180 ;; Emacs and XEmacs have completely different face manipulation 181 ;; routines. :P 182 (copy-face oldface newface) 183 (cond ((fboundp 'face-inverse-video-p) 184 ;; Emacs. This only looks at the inverse flag in the current 185 ;; frame. Other display configurations might be different, 186 ;; but it can only show if the same Emacs has frames on 187 ;; e.g. a color and a monochrome display simultaneously. 188 (unless (face-inverse-video-p oldface) 189 (invert-face newface))) 190 ((fboundp 'face-property-instance) 191 ;; XEmacs. Same pitfall here. 192 (unless (face-property-instance oldface 'reverse) 193 (invert-face newface))))) 194 195(defvar c-annotation-face 'c-annotation-face) 196 197(defface c-annotation-face 198 '((default :inherit font-lock-constant-face)) 199 "Face for highlighting annotations in Java mode and similar modes." 200 :version "24.1" 201 :group 'c) 202 203(eval-and-compile 204 ;; We need the following definitions during compilation since they're 205 ;; used when the `c-lang-defconst' initializers are evaluated. Define 206 ;; them at runtime too for the sake of derived modes. 207 208 ;; This indicates the "font locking context", and is set just before 209 ;; fontification is done. If non-nil, it says, e.g., point starts 210 ;; from within a #if preprocessor construct. 211 (defvar c-font-lock-context nil) 212 (make-variable-buffer-local 'c-font-lock-context) 213 214 (defmacro c-put-font-lock-face (from to face) 215 ;; Put a face on a region (overriding any existing face) in the way 216 ;; font-lock would do it. In XEmacs that means putting an 217 ;; additional font-lock property, or else the font-lock package 218 ;; won't recognize it as fontified and might override it 219 ;; incorrectly. 220 ;; 221 ;; This function does a hidden buffer change. 222 (declare (debug t)) 223 (if (fboundp 'font-lock-set-face) 224 ;; Note: This function has no docstring in XEmacs so it might be 225 ;; considered internal. 226 `(font-lock-set-face ,from ,to ,face) 227 `(put-text-property ,from ,to 'face ,face))) 228 229 (defmacro c-remove-font-lock-face (from to) 230 ;; This is the inverse of `c-put-font-lock-face'. 231 ;; 232 ;; This function does a hidden buffer change. 233 (declare (debug t)) 234 (if (fboundp 'font-lock-remove-face) 235 `(font-lock-remove-face ,from ,to) 236 `(remove-text-properties ,from ,to '(face nil)))) 237 238 (defmacro c-put-font-lock-string-face (from to) 239 ;; Put `font-lock-string-face' on a string. The surrounding 240 ;; quotes are included in Emacs but not in XEmacs. The passed 241 ;; region should include them. 242 ;; 243 ;; This function does a hidden buffer change. 244 (declare (debug t)) 245 (if (featurep 'xemacs) 246 `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face) 247 `(c-put-font-lock-face ,from ,to 'font-lock-string-face))) 248 249 (defmacro c-fontify-types-and-refs (varlist &rest body) 250 (declare (indent 1) (debug let*)) 251 ;; Like `let', but additionally activates `c-record-type-identifiers' 252 ;; and `c-record-ref-identifiers', and fontifies the recorded ranges 253 ;; accordingly on exit. 254 ;; 255 ;; This function does hidden buffer changes. 256 `(let ((c-record-type-identifiers t) 257 c-record-ref-identifiers 258 ,@varlist) 259 (prog1 (progn ,@body) 260 (c-fontify-recorded-types-and-refs)))) 261 262 (defun c-skip-comments-and-strings (limit) 263 ;; If the point is within a region fontified as a comment or 264 ;; string literal skip to the end of it or to LIMIT, whichever 265 ;; comes first, and return t. Otherwise return nil. The match 266 ;; data is not clobbered. 267 ;; 268 ;; This function might do hidden buffer changes. 269 (when (c-got-face-at (point) c-literal-faces) 270 (while (progn 271 (goto-char (c-next-single-property-change 272 (point) 'face nil limit)) 273 (and (< (point) limit) 274 (c-got-face-at (point) c-literal-faces)))) 275 t)) 276 277 (defun c-make-syntactic-matcher (regexp) 278 ;; Returns a byte compiled function suitable for use in place of a 279 ;; regexp string in a `font-lock-keywords' matcher, except that 280 ;; only matches outside comments and string literals count. 281 ;; 282 ;; This function does not do any hidden buffer changes, but the 283 ;; generated functions will. (They are however used in places 284 ;; covered by the font-lock context.) 285 (byte-compile 286 `(lambda (limit) 287 (let (res) 288 (while (and (setq res (re-search-forward ,regexp limit t)) 289 (progn 290 (goto-char (match-beginning 0)) 291 (or (c-skip-comments-and-strings limit) 292 (progn 293 (goto-char (match-end 0)) 294 nil))))) 295 res)))) 296 297 (defun c-make-font-lock-search-form (regexp highlights &optional check-point) 298 ;; Return a lisp form which will fontify every occurrence of REGEXP 299 ;; (a regular expression, NOT a function) between POINT and `limit' 300 ;; with HIGHLIGHTS, a list of highlighters as specified on page 301 ;; "Search-based Fontification" in the elisp manual. If CHECK-POINT 302 ;; is non-nil, we will check (< (point) limit) in the main loop. 303 `(while 304 ,(if check-point 305 `(and (< (point) limit) 306 (re-search-forward ,regexp limit t)) 307 `(re-search-forward ,regexp limit t)) 308 (unless (progn 309 (goto-char (match-beginning 0)) 310 (c-skip-comments-and-strings limit)) 311 (goto-char (match-end 0)) 312 ,@(mapcar 313 (lambda (highlight) 314 (if (integerp (car highlight)) 315 ;; e.g. highlight is (1 font-lock-type-face t) 316 (progn 317 (unless (eq (nth 2 highlight) t) 318 (error 319 "The override flag must currently be t in %s" 320 highlight)) 321 (when (nth 3 highlight) 322 (error 323 "The laxmatch flag may currently not be set in %s" 324 highlight)) 325 `(save-match-data 326 (c-put-font-lock-face 327 (match-beginning ,(car highlight)) 328 (match-end ,(car highlight)) 329 ,(elt highlight 1)))) 330 ;; highlight is an "ANCHORED HIGHLIGHTER" of the form 331 ;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...) 332 (when (nth 3 highlight) 333 (error "Match highlights currently not supported in %s" 334 highlight)) 335 `(progn 336 ,(nth 1 highlight) 337 (save-match-data ,(car highlight)) 338 ,(nth 2 highlight)))) 339 highlights)))) 340 341 (defun c-make-font-lock-search-function (regexp &rest highlights) 342 ;; This function makes a byte compiled function that works much like 343 ;; a matcher element in `font-lock-keywords'. It cuts out a little 344 ;; bit of the overhead compared to a real matcher. The main reason 345 ;; is however to pass the real search limit to the anchored 346 ;; matcher(s), since most (if not all) font-lock implementations 347 ;; arbitrarily limit anchored matchers to the same line, and also 348 ;; to insulate against various other irritating differences between 349 ;; the different (X)Emacs font-lock packages. 350 ;; 351 ;; REGEXP is the matcher, which must be a regexp. Only matches 352 ;; where the beginning is outside any comment or string literal are 353 ;; significant. 354 ;; 355 ;; HIGHLIGHTS is a list of highlight specs, just like in 356 ;; `font-lock-keywords', with these limitations: The face is always 357 ;; overridden (no big disadvantage, since hits in comments etc are 358 ;; filtered anyway), there is no "laxmatch", and an anchored matcher 359 ;; is always a form which must do all the fontification directly. 360 ;; `limit' is a variable bound to the real limit in the context of 361 ;; the anchored matcher forms. 362 ;; 363 ;; This function does not do any hidden buffer changes, but the 364 ;; generated functions will. (They are however used in places 365 ;; covered by the font-lock context.) 366 367 ;; Note: Replace `byte-compile' with `eval' to debug the generated 368 ;; lambda more easily. 369 (byte-compile 370 `(lambda (limit) 371 (let ( ;; The font-lock package in Emacs is known to clobber 372 ;; `parse-sexp-lookup-properties' (when it exists). 373 (parse-sexp-lookup-properties 374 (cc-eval-when-compile 375 (boundp 'parse-sexp-lookup-properties)))) 376 ,(c-make-font-lock-search-form regexp highlights)) 377 nil))) 378 379 (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights) 380 ;; This function makes a byte compiled function that first moves back 381 ;; to the beginning of the current declaration (if any), then searches 382 ;; forward for matcher elements (as in `font-lock-keywords') and 383 ;; fontifies them. 384 ;; 385 ;; The motivation for moving back to the declaration start is to 386 ;; establish a context for the current text when, e.g., a character 387 ;; is typed on a C++ inheritance continuation line, or a jit-lock 388 ;; chunk starts there. 389 ;; 390 ;; The new function works much like a matcher element in 391 ;; `font-lock-keywords'. It cuts out a little bit of the overhead 392 ;; compared to a real matcher. The main reason is however to pass the 393 ;; real search limit to the anchored matcher(s), since most (if not 394 ;; all) font-lock implementations arbitrarily limit anchored matchers 395 ;; to the same line, and also to insulate against various other 396 ;; irritating differences between the different (X)Emacs font-lock 397 ;; packages. 398 ;; 399 ;; REGEXP is the matcher, which must be a regexp. Only matches 400 ;; where the beginning is outside any comment or string literal are 401 ;; significant. 402 ;; 403 ;; HIGHLIGHTS is a list of highlight specs, just like in 404 ;; `font-lock-keywords', with these limitations: The face is always 405 ;; overridden (no big disadvantage, since hits in comments etc are 406 ;; filtered anyway), there is no "laxmatch", and an anchored matcher 407 ;; is always a form which must do all the fontification directly. 408 ;; `limit' is a variable bound to the real limit in the context of 409 ;; the anchored matcher forms. 410 ;; 411 ;; This function does not do any hidden buffer changes, but the 412 ;; generated functions will. (They are however used in places 413 ;; covered by the font-lock context.) 414 415 ;; Note: Replace `byte-compile' with `eval' to debug the generated 416 ;; lambda more easily. 417 (byte-compile 418 `(lambda (limit) 419 (let ( ;; The font-lock package in Emacs is known to clobber 420 ;; `parse-sexp-lookup-properties' (when it exists). 421 (parse-sexp-lookup-properties 422 (cc-eval-when-compile 423 (boundp 'parse-sexp-lookup-properties))) 424 (BOD-limit 425 (c-determine-limit 1000))) 426 (goto-char 427 (let ((here (point))) 428 (if (eq (car (c-beginning-of-decl-1 BOD-limit)) 'same) 429 (point) 430 here))) 431 ,(c-make-font-lock-search-form regexp highlights)) 432 nil))) 433 434 (defun c-make-font-lock-context-search-function (normal &rest state-stanzas) 435 ;; This function makes a byte compiled function that works much like 436 ;; a matcher element in `font-lock-keywords', with the following 437 ;; enhancement: the generated function will test for particular "font 438 ;; lock contexts" at the start of the region, i.e. is this point in 439 ;; the middle of some particular construct? if so the generated 440 ;; function will first fontify the tail of the construct, before 441 ;; going into the main loop and fontify full constructs up to limit. 442 ;; 443 ;; The generated function takes one parameter called `limit', and 444 ;; will fontify the region between POINT and LIMIT. 445 ;; 446 ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is 447 ;; used to fontify the "regular" bit of the region. 448 ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP 449 ;; HIGHLIGHTS), each element coding one possible font lock context. 450 451 ;; o - REGEXP is a font-lock regular expression (NOT a function), 452 ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined 453 ;; on page "Search-based Fontification" in the elisp manual. As 454 ;; yet (2009-06), they must have OVERRIDE set, and may not have 455 ;; LAXMATCH set. 456 ;; 457 ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is 458 ;; not quoted. 459 ;; o - LIM is a lisp form whose evaluation will yield the limit 460 ;; position in the buffer for fontification by this stanza. 461 ;; 462 ;; This function does not do any hidden buffer changes, but the 463 ;; generated functions will. (They are however used in places 464 ;; covered by the font-lock context.) 465 ;; 466 ;; Note: Replace `byte-compile' with `eval' to debug the generated 467 ;; lambda more easily. 468 (byte-compile 469 `(lambda (limit) 470 (let ( ;; The font-lock package in Emacs is known to clobber 471 ;; `parse-sexp-lookup-properties' (when it exists). 472 (parse-sexp-lookup-properties 473 (cc-eval-when-compile 474 (boundp 'parse-sexp-lookup-properties)))) 475 ,@(mapcar 476 (lambda (stanza) 477 (let ((state (car stanza)) 478 (lim (nth 1 stanza)) 479 (regexp (nth 2 stanza)) 480 (highlights (cdr (cddr stanza)))) 481 `(if (eq c-font-lock-context ',state) 482 (let ((limit ,lim)) 483 ,(c-make-font-lock-search-form 484 regexp highlights))))) 485 state-stanzas) 486 ;; In the next form, check that point hasn't been moved beyond 487 ;; `limit' in any of the above stanzas. 488 ,(c-make-font-lock-search-form (car normal) (cdr normal) t) 489 nil))))) 490 491(defun c-fontify-recorded-types-and-refs () 492 ;; Convert the ranges recorded on `c-record-type-identifiers' and 493 ;; `c-record-ref-identifiers' to fontification. 494 ;; 495 ;; This function does hidden buffer changes. 496 (let (elem) 497 (while (consp c-record-type-identifiers) 498 (setq elem (car c-record-type-identifiers) 499 c-record-type-identifiers (cdr c-record-type-identifiers)) 500 (c-put-font-lock-face (car elem) (cdr elem) 501 'font-lock-type-face)) 502 (while c-record-ref-identifiers 503 (setq elem (car c-record-ref-identifiers) 504 c-record-ref-identifiers (cdr c-record-ref-identifiers)) 505 ;; Note that the reference face is a variable that is 506 ;; dereferenced, since it's an alias in Emacs. 507 (c-put-font-lock-face (car elem) (cdr elem) 508 c-reference-face-name)))) 509 510(c-lang-defconst c-cpp-matchers 511 "Font lock matchers for preprocessor directives and purely lexical 512stuff. Used on level 1 and higher." 513 514 ;; Note: `c-font-lock-declarations' assumes that no matcher here 515 ;; sets `font-lock-type-face' in languages where 516 ;; `c-recognize-<>-arglists' is set. 517 518 t `(,@(when (c-lang-const c-opt-cpp-prefix) 519 (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)") 520 (ncle-depth (regexp-opt-depth noncontinued-line-end)) 521 (sws-depth (c-lang-const c-syntactic-ws-depth)) 522 (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth))) 523 524 `(;; Fontify "invalid" comment delimiters 525 ,@(when (and (c-lang-const c-block-comment-starter) 526 (c-lang-const c-line-comment-starter)) 527 `(c-maybe-font-lock-wrong-style-comments)) 528 529 ;; The stuff after #error and #warning is a message, so 530 ;; fontify it as a string. 531 ,@(when (c-lang-const c-cpp-message-directives) 532 (let* ((re (c-make-keywords-re 'appendable ; nil 533 (c-lang-const c-cpp-message-directives))) 534 (re-depth (regexp-opt-depth re))) 535 `((,(concat noncontinued-line-end 536 (c-lang-const c-opt-cpp-prefix) 537 re 538 "\\s +\\(.*\\)$") 539 ,(+ ncle-depth re-depth 1) font-lock-string-face t)))) 540 541 ;; Fontify filenames in #include <...> as strings. 542 ,@(when (c-lang-const c-cpp-include-directives) 543 (let* ((re (c-make-keywords-re nil 544 (c-lang-const c-cpp-include-directives))) 545 (re-depth (regexp-opt-depth re))) 546 ;; We used to use a font-lock "anchored matcher" here for 547 ;; the paren syntax. This failed when the ">" was at EOL, 548 ;; since `font-lock-fontify-anchored-keywords' terminated 549 ;; its loop at EOL without executing our lambda form at 550 ;; all. 551 `((,(c-make-font-lock-search-function 552 (concat noncontinued-line-end 553 (c-lang-const c-opt-cpp-prefix) 554 re 555 (c-lang-const c-syntactic-ws) 556 "\\(<[^>\n\r]*>?\\)") 557 `(,(+ ncle-depth re-depth sws-depth 1) 558 font-lock-string-face t) 559 `((let ((beg (match-beginning 560 ,(+ ncle-depth re-depth sws-depth 1))) 561 (end (1- (match-end ,(+ ncle-depth re-depth 562 sws-depth 1))))) 563 (if (eq (char-after end) ?>) 564 (progn 565 (c-mark-<-as-paren beg) 566 (c-mark->-as-paren end)) 567 (c-unmark-<->-as-paren beg))) 568 nil)))))) 569 570 ;; #define. 571 ,@(when (c-lang-const c-opt-cpp-macro-define) 572 `((,(c-make-font-lock-search-function 573 (concat 574 noncontinued-line-end 575 (c-lang-const c-opt-cpp-prefix) 576 (c-lang-const c-opt-cpp-macro-define) 577 (c-lang-const c-nonempty-syntactic-ws) 578 "\\(" (c-lang-const ; 1 + ncle + nsws 579 c-symbol-key) "\\)" 580 (concat "\\(" ; 2 + ncle + nsws + c-sym-key 581 ;; Macro with arguments - a "function". 582 "\\((\\)" ; 3 + ncle + nsws + c-sym-key 583 "\\|" 584 ;; Macro without arguments - a "variable". 585 "\\([^(]\\|$\\)" 586 "\\)")) 587 `((if (match-beginning 588 ,(+ 3 ncle-depth nsws-depth 589 (c-lang-const c-symbol-key-depth))) 590 591 ;; "Function". Fontify the name and the arguments. 592 (save-restriction 593 (c-put-font-lock-face 594 (match-beginning ,(+ 1 ncle-depth nsws-depth)) 595 (match-end ,(+ 1 ncle-depth nsws-depth)) 596 'font-lock-function-name-face) 597 (goto-char 598 (match-end 599 ,(+ 3 ncle-depth nsws-depth 600 (c-lang-const c-symbol-key-depth)))) 601 602 (narrow-to-region (point-min) limit) 603 (while (and 604 (progn 605 (c-forward-syntactic-ws) 606 (looking-at c-symbol-key)) 607 (progn 608 (c-put-font-lock-face 609 (match-beginning 0) (match-end 0) 610 'font-lock-variable-name-face) 611 (goto-char (match-end 0)) 612 (c-forward-syntactic-ws) 613 (eq (char-after) ?,))) 614 (forward-char))) 615 616 ;; "Variable". 617 (c-put-font-lock-face 618 (match-beginning ,(+ 1 ncle-depth nsws-depth)) 619 (match-end ,(+ 1 ncle-depth nsws-depth)) 620 'font-lock-variable-name-face))))))) 621 622 ;; Fontify cpp function names in preprocessor 623 ;; expressions in #if and #elif. 624 ,@(when (and (c-lang-const c-cpp-expr-directives) 625 (c-lang-const c-cpp-expr-functions)) 626 (let ((ced-re (c-make-keywords-re t 627 (c-lang-const c-cpp-expr-directives))) 628 (cef-re (c-make-keywords-re t 629 (c-lang-const c-cpp-expr-functions)))) 630 631 `((,(c-make-font-lock-context-search-function 632 `(,(concat noncontinued-line-end 633 (c-lang-const c-opt-cpp-prefix) 634 ced-re ; 1 + ncle-depth 635 ;; Match the whole logical line to look 636 ;; for the functions in. 637 "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") 638 ((let ((limit (match-end 0))) 639 (while (re-search-forward ,cef-re limit 'move) 640 (c-put-font-lock-face (match-beginning 1) 641 (match-end 1) 642 c-preprocessor-face-name))) 643 (goto-char (match-end ,(1+ ncle-depth))))) 644 `(in-cpp-expr 645 (save-excursion (c-end-of-macro) (point)) 646 ,cef-re 647 (1 c-preprocessor-face-name t))))))) 648 649 ;; Fontify the directive names. 650 (,(c-make-font-lock-search-function 651 (concat noncontinued-line-end 652 "\\(" 653 (c-lang-const c-opt-cpp-prefix) 654 "[" (c-lang-const c-symbol-chars) "]+" 655 "\\)") 656 `(,(1+ ncle-depth) c-preprocessor-face-name t))) 657 658 (eval . (list ,(c-make-syntactic-matcher 659 (concat noncontinued-line-end 660 (c-lang-const c-opt-cpp-prefix) 661 "if\\(n\\)def\\>")) 662 ,(+ ncle-depth 1) 663 c-negation-char-face-name 664 'append)) 665 ))) 666 667 ,@(when (c-major-mode-is 'pike-mode) 668 ;; Recognize hashbangs in Pike. 669 '((eval . (list "\\`#![^\n\r]*" 670 0 c-preprocessor-face-name)))) 671 672 ;; Make hard spaces visible through an inverted `font-lock-warning-face'. 673 (eval . (list 674 "\240" 675 0 (progn 676 (unless (c-face-name-p 'c-nonbreakable-space-face) 677 (c-make-inverse-face 'font-lock-warning-face 678 'c-nonbreakable-space-face)) 679 ''c-nonbreakable-space-face))) 680 )) 681 682(defun c-font-lock-invalid-single-quotes (limit) 683 ;; This function will be called from font-lock for a region bounded by POINT 684 ;; and LIMIT, as though it were to identify a keyword for 685 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 686 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 687 ;; Fontification". 688 ;; 689 ;; This function fontifies invalid single quotes with 690 ;; `font-lock-warning-face'. These are the single quotes which 691 ;; o - aren't inside a literal; 692 ;; o - are marked with a syntax-table text property value '(1); and 693 ;; o - are NOT marked with a non-null c-digit-separator property. 694 (let ((limits (c-literal-limits)) 695 state beg end) 696 (if limits 697 (goto-char (cdr limits))) ; Even for being in a ' ' 698 (while (< (point) limit) 699 (setq beg (point)) 700 (setq state (parse-partial-sexp (point) limit nil nil nil 'syntax-table)) 701 (setq end (point)) 702 (goto-char beg) 703 (while (progn (skip-chars-forward "^'" end) 704 (< (point) end)) 705 (if (and (equal (c-get-char-property (point) 'syntax-table) '(1)) 706 (not (c-get-char-property (point) 'c-digit-separator))) 707 (c-put-font-lock-face (point) (1+ (point)) font-lock-warning-face)) 708 (forward-char)) 709 (parse-partial-sexp end limit nil nil state 'syntax-table))) 710 nil) 711 712(defun c-maybe-font-lock-wrong-style-comments (limit) 713 ;; This function will be called from font-lock-for a region bounded by POINT 714 ;; and LIMIT, as though it were to identify a keyword for 715 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 716 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 717 ;; Fontification". 718 ;; 719 ;; This function fontifies "invalid" comment delimiters with 720 ;; `font-lock-warning-face'. A delimiter is "invalid" when 721 ;; `c-mark-wrong-style-of-comment' is non-nil, and the delimiter style is 722 ;; not the default specified by `c-block-comment-flag'. 723 (when c-mark-wrong-style-of-comment 724 (let* ((lit (c-semi-pp-to-literal (point))) 725 (s (car lit)) ; parse-partial-sexp state. 726 ) 727 ;; First, deal with and move out of any literal we start in. 728 (cond 729 ((null (cadr lit))) ; Not in a literal 730 ((eq (cadr lit) 'string) 731 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))) 732 ((and (not c-block-comment-flag) ; In an "invalid" block comment 733 (eq (cadr lit) 'c)) 734 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)) 735 ;; Font lock the block comment ender with warning face. 736 (when (not (nth 4 s)) 737 (c-put-font-lock-face (- (point) (length c-block-comment-ender)) 738 (point) font-lock-warning-face))) 739 (t ; In a line comment, or a "valid" block comment 740 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)))) 741 742 (while (< (point) limit) 743 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)) 744 (cond 745 ((or (nth 3 s) ; In a string 746 (and (nth 4 s) ; In a comment 747 (eq (nth 7 s) ; Comment style 748 (if c-block-comment-flag 749 nil ; Block comment 750 1)))) ; Line comment 751 ;; Move over a "valid" literal. 752 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))) 753 ((nth 4 s) ; In an invalid comment 754 ;; Fontify the invalid comment opener. 755 (c-put-font-lock-face (nth 8 s) (point) font-lock-warning-face) 756 ;; Move to end of comment or LIMIT. 757 (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)) 758 ;; Fontify an invalid block comment ender, if that's what we have. 759 (when (and (not c-block-comment-flag) 760 (not (nth 4 s))) ; We're outside the comment 761 (c-put-font-lock-face (- (point) (length c-block-comment-ender)) 762 (point) font-lock-warning-face))))))) 763 nil) 764 765(c-lang-defconst c-basic-matchers-before 766 "Font lock matchers for basic keywords, labels, references and various 767other easily recognizable things that should be fontified before generic 768casts and declarations are fontified. Used on level 2 and higher." 769 770 ;; Note: `c-font-lock-declarations' assumes that no matcher here 771 ;; sets `font-lock-type-face' in languages where 772 ;; `c-recognize-<>-arglists' is set. 773 774 t `(;; Put a warning face on the opener of unclosed strings that 775 ;; can't span lines and on the "terminating" newlines. Later font 776 ;; lock packages have a `font-lock-syntactic-face-function' for 777 ;; this, but it doesn't give the control we want since any 778 ;; fontification done inside the function will be 779 ;; unconditionally overridden. 780 ("\\s|" 0 font-lock-warning-face t nil) 781 782 ;; Invalid single quotes. 783 c-font-lock-invalid-single-quotes 784 785 ;; Fontify multiline strings. 786 ,@(when (c-lang-const c-ml-string-opener-re) 787 '(c-font-lock-ml-strings)) 788 789 ;; Fontify keyword constants. 790 ,@(when (c-lang-const c-constant-kwds) 791 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) 792 (if (c-major-mode-is 'pike-mode) 793 ;; No symbol is a keyword after "->" in Pike. 794 `((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" 795 "\\<\\(" re "\\)\\>") 796 2 c-constant-face-name))) 797 `((eval . (list ,(concat "\\<\\(" re "\\)\\>") 798 1 c-constant-face-name)))))) 799 800 ;; Fontify all keywords except the primitive types. 801 ,(if (c-major-mode-is 'pike-mode) 802 ;; No symbol is a keyword after "->" in Pike. 803 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" 804 "\\<" (c-lang-const c-regular-keywords-regexp)) 805 2 font-lock-keyword-face) 806 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp)) 807 1 font-lock-keyword-face)) 808 809 ;; Fontify leading identifiers in fully qualified names like 810 ;; "foo::bar" in languages that supports such things. 811 ,@(when (c-lang-const c-opt-identifier-concat-key) 812 (if (c-major-mode-is 'java-mode) 813 ;; Java needs special treatment since "." is used both to 814 ;; qualify names and in normal indexing. Here we look for 815 ;; capital characters at the beginning of an identifier to 816 ;; recognize the class. "*" is also recognized to cover 817 ;; wildcard import declarations. All preceding dot separated 818 ;; identifiers are taken as package names and therefore 819 ;; fontified as references. 820 `(,(c-make-font-lock-search-function 821 ;; Search for class identifiers preceded by ".". The 822 ;; anchored matcher takes it from there. 823 (concat (c-lang-const c-opt-identifier-concat-key) 824 (c-lang-const c-simple-ws) "*" 825 (concat "\\(" 826 "[" c-upper "]" 827 "[" (c-lang-const c-symbol-chars) "]*" 828 "\\|" 829 "\\*" 830 "\\)")) 831 `((let (id-end) 832 (goto-char (1+ (match-beginning 0))) 833 (while (and (eq (char-before) ?.) 834 (progn 835 (backward-char) 836 (c-backward-syntactic-ws) 837 (setq id-end (point)) 838 (< (skip-chars-backward 839 ,(c-lang-const c-symbol-chars)) 840 0)) 841 (not (get-text-property (point) 'face))) 842 (c-put-font-lock-face (point) id-end 843 c-reference-face-name) 844 (c-backward-syntactic-ws))) 845 nil 846 (goto-char (match-end 0))))) 847 848 `((,(byte-compile 849 ;; Must use a function here since we match longer than 850 ;; we want to move before doing a new search. This is 851 ;; not necessary for XEmacs since it restarts the 852 ;; search from the end of the first highlighted 853 ;; submatch (something that causes problems in other 854 ;; places). 855 `(lambda (limit) 856 (while (re-search-forward 857 ,(concat "\\(\\<" ; 1 858 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 859 (c-lang-const c-simple-ws) "*" 860 (c-lang-const c-opt-identifier-concat-key) 861 (c-lang-const c-simple-ws) "*" 862 "\\)" 863 "\\(" 864 (c-lang-const c-opt-after-id-concat-key) 865 "\\)") 866 limit t) 867 (unless (progn 868 (goto-char (match-beginning 0)) 869 (c-skip-comments-and-strings limit)) 870 (or (get-text-property (match-beginning 2) 'face) 871 (c-put-font-lock-face (match-beginning 2) 872 (match-end 2) 873 c-reference-face-name)) 874 (goto-char (match-end 1)))))))))) 875 876 ;; Fontify the special declarations in Objective-C. 877 ,@(when (c-major-mode-is 'objc-mode) 878 `(;; Fontify class names in the beginning of message expressions. 879 ,(c-make-font-lock-search-function 880 "\\[" 881 '((c-fontify-types-and-refs () 882 (c-forward-syntactic-ws limit) 883 (let ((start (point))) 884 ;; In this case we accept both primitive and known types. 885 (when (eq (c-forward-type) 'known) 886 (goto-char start) 887 (let ((c-promote-possible-types t)) 888 (c-forward-type)))) 889 (if (> (point) limit) (goto-char limit))))) 890 891 ;; The @interface/@implementation/@protocol directives. 892 ,(c-make-font-lock-search-function 893 (concat "\\<" 894 (regexp-opt 895 '("@interface" "@implementation" "@protocol") 896 t) 897 "\\>") 898 '((c-fontify-types-and-refs 899 (;; The font-lock package in Emacs is known to clobber 900 ;; `parse-sexp-lookup-properties' (when it exists). 901 (parse-sexp-lookup-properties 902 (cc-eval-when-compile 903 (boundp 'parse-sexp-lookup-properties)))) 904 (c-forward-objc-directive) 905 nil) 906 (goto-char (match-beginning 0)))))) 907 908 (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name)) 909 )) 910 911(defun c-font-lock-complex-decl-prepare (limit) 912 ;; This function will be called from font-lock for a region bounded by POINT 913 ;; and LIMIT, as though it were to identify a keyword for 914 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 915 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 916 ;; Fontification". 917 ;; 918 ;; Called before any of the matchers in `c-complex-decl-matchers'. 919 ;; 920 ;; This function does hidden buffer changes. 921 922 ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit) 923 (c-skip-comments-and-strings limit) 924 (when (< (point) limit) 925 926 ;; Clear the c-type char properties which mark the region, to recalculate 927 ;; them properly. The most interesting properties are those put on the 928 ;; closest token before the region. 929 (save-excursion 930 (let ((pos (point))) 931 (c-backward-syntactic-ws (max (- (point) 500) (point-min))) 932 (c-clear-char-properties 933 (if (and (not (bobp)) 934 (memq (c-get-char-property (1- (point)) 'c-type) 935 '(c-decl-arg-start 936 c-decl-end 937 c-decl-id-start 938 c-decl-type-start))) 939 (1- (point)) 940 pos) 941 limit 'c-type))) 942 943 ;; Update `c-state-cache' to the beginning of the region. This will 944 ;; make `c-beginning-of-syntax' go faster when it's used later on, 945 ;; and it's near the point most of the time. 946 (c-parse-state) 947 948 ;; Check if the fontified region starts inside a declarator list so 949 ;; that `c-font-lock-declarators' should be called at the start. 950 ;; The declared identifiers are font-locked correctly as types, if 951 ;; that is what they are. 952 (let ((prop (save-excursion 953 (c-backward-syntactic-ws (max (- (point) 500) (point-min))) 954 (unless (bobp) 955 (c-get-char-property (1- (point)) 'c-type))))) 956 (when (memq prop '(c-decl-id-start c-decl-type-start)) 957 (c-forward-syntactic-ws limit) 958 (c-font-lock-declarators limit t (eq prop 'c-decl-type-start) 959 (not (c-bs-at-toplevel-p (point)))))) 960 961 (setq c-font-lock-context ;; (c-guess-font-lock-context) 962 (save-excursion 963 (if (and c-cpp-expr-intro-re 964 (c-beginning-of-macro) 965 (looking-at c-cpp-expr-intro-re)) 966 'in-cpp-expr))) 967 nil)) 968 969(defun c-font-lock-<>-arglists (limit) 970 ;; This function will be called from font-lock for a region bounded by POINT 971 ;; and LIMIT, as though it were to identify a keyword for 972 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 973 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 974 ;; Fontification". 975 ;; 976 ;; Fontify types and references in names containing angle bracket 977 ;; arglists from the point to LIMIT. Note that 978 ;; `c-font-lock-declarations' has already handled many of them. 979 ;; 980 ;; This function might do hidden buffer changes. 981 982 (c-skip-comments-and-strings limit) 983 (when (< (point) limit) 984 985 (let (;; The font-lock package in Emacs is known to clobber 986 ;; `parse-sexp-lookup-properties' (when it exists). 987 (parse-sexp-lookup-properties 988 (cc-eval-when-compile 989 (boundp 'parse-sexp-lookup-properties))) 990 (c-parse-and-markup-<>-arglists t) 991 c-restricted-<>-arglists 992 id-start id-end id-face pos kwd-sym 993 old-pos) 994 995 (while (and (< (point) limit) 996 (setq old-pos (point)) 997 (c-syntactic-re-search-forward "<" limit t nil t)) 998 (setq pos (point)) 999 (save-excursion 1000 (backward-char) 1001 (c-backward-syntactic-ws old-pos) 1002 (if (re-search-backward 1003 (concat "\\(\\`\\|" c-nonsymbol-key "\\)\\(" c-symbol-key"\\)\\=") 1004 old-pos t) 1005 (setq id-start (match-beginning 2) 1006 id-end (match-end 2)) 1007 (setq id-start nil id-end nil))) 1008 1009 (when id-start 1010 (goto-char id-start) 1011 (unless (c-skip-comments-and-strings limit) 1012 (setq kwd-sym nil 1013 c-restricted-<>-arglists nil 1014 id-face (get-text-property id-start 'face)) 1015 1016 (if (cond 1017 ((eq id-face 'font-lock-type-face) 1018 ;; The identifier got the type face so it has already been 1019 ;; handled in `c-font-lock-declarations'. 1020 nil) 1021 1022 ((eq id-face 'font-lock-keyword-face) 1023 (when (looking-at c-opt-<>-sexp-key) 1024 ;; There's a special keyword before the "<" that tells 1025 ;; that it's an angle bracket arglist. 1026 (setq kwd-sym (c-keyword-sym (match-string 2))))) 1027 1028 (t 1029 ;; There's a normal identifier before the "<". If we're not in 1030 ;; a declaration context then we set `c-restricted-<>-arglists' 1031 ;; to avoid recognizing templates in function calls like "foo (a 1032 ;; < b, c > d)". 1033 (c-backward-syntactic-ws) 1034 (when (and (memq (char-before) '(?\( ?,)) 1035 (not (eq (get-text-property (1- (point)) 'c-type) 1036 'c-decl-arg-start))) 1037 (setq c-restricted-<>-arglists t)) 1038 t)) 1039 1040 (progn 1041 (goto-char (1- pos)) 1042 ;; Check for comment/string both at the identifier and 1043 ;; at the "<". 1044 (unless (c-skip-comments-and-strings limit) 1045 1046 (c-fontify-types-and-refs () 1047 (when (c-forward-<>-arglist (c-keyword-member 1048 kwd-sym 'c-<>-type-kwds)) 1049 (when (and c-opt-identifier-concat-key 1050 (not (get-text-property id-start 'face))) 1051 (c-forward-syntactic-ws) 1052 (cond ((looking-at c-opt-identifier-concat-key) 1053 (c-put-font-lock-face id-start id-end 1054 c-reference-face-name)) 1055 ((eq (char-after) ?\()) 1056 (t (c-put-font-lock-face id-start id-end 1057 'font-lock-type-face)))))) 1058 1059 (goto-char pos))) 1060 (goto-char pos))))))) 1061 nil) 1062 1063(defun c-font-lock-declarators (limit list types not-top 1064 &optional template-class) 1065 ;; Assuming the point is at the start of a declarator in a declaration, 1066 ;; fontify the identifier it declares. (If TYPES is t, it does this via the 1067 ;; macro `c-fontify-types-and-refs'.) 1068 ;; 1069 ;; If LIST is non-nil, also fontify the ids in any following declarators in 1070 ;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;"); 1071 ;; additionally, mark the commas with c-type property 'c-decl-id-start or 1072 ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. 1073 ;; 1074 ;; If TYPES is t, fontify all identifiers as types, if it is nil fontify as 1075 ;; either variables or functions, otherwise TYPES is a face to use. If 1076 ;; NOT-TOP is non-nil, we are not at the top-level ("top-level" includes 1077 ;; being directly inside a class or namespace, etc.). 1078 ;; 1079 ;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters 1080 ;; and was introduced by, e.g. "typename" or "class", such that if there is 1081 ;; a default (introduced by "="), it will be fontified as a type. 1082 ;; E.g. "<class X = Y>". 1083 ;; 1084 ;; Nil is always returned. The function leaves point at the delimiter after 1085 ;; the last declarator it processes. 1086 ;; 1087 ;; This function might do hidden buffer changes. 1088 1089 ;;(message "c-font-lock-declarators from %s to %s" (point) limit) 1090 (c-fontify-types-and-refs 1091 () 1092 (c-do-declarators 1093 limit list not-top 1094 (cond ((eq types t) 'c-decl-type-start) 1095 ((null types) 'c-decl-id-start)) 1096 (lambda (id-start _id-end end-pos _not-top is-function init-char) 1097 (if (eq types t) 1098 ;; Register and fontify the identifier as a type. 1099 (let ((c-promote-possible-types t)) 1100 (goto-char id-start) 1101 (c-forward-type)) 1102 ;; The following doesn't work properly (yet, 2018-09-22). 1103 ;; (c-put-font-lock-face id-start id-end 1104 ;; (if is-function 1105 ;; 'font-lock-function-name-face 1106 ;; 'font-lock-variable-name-face)) 1107 (when (and c-last-identifier-range 1108 (not (get-text-property (car c-last-identifier-range) 1109 'face))) 1110 ;; We use `c-last-identifier-range' rather than `id-start' and 1111 ;; `id-end', since the latter two can be erroneous. E.g. in 1112 ;; "~Foo", `id-start' is at the tilde. This is a bug in 1113 ;; `c-forward-declarator'. 1114 (c-put-font-lock-face (car c-last-identifier-range) 1115 (cdr c-last-identifier-range) 1116 (cond 1117 ((not (memq types '(nil t))) types) 1118 (is-function 'font-lock-function-name-face) 1119 (t 'font-lock-variable-name-face))))) 1120 (and template-class 1121 (eq init-char ?=) ; C++ "<class X = Y>"? 1122 (progn 1123 (goto-char end-pos) 1124 (c-forward-token-2 1 nil limit) ; Over "=" 1125 (let ((c-promote-possible-types t)) 1126 (c-forward-type t)))))) 1127 nil)) 1128 1129(defun c-get-fontification-context (match-pos not-front-decl &optional toplev) 1130 ;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS. 1131 ;; NOT-FRONT-DECL is non-nil when a declaration later in the buffer than 1132 ;; MATCH-POS has already been parsed. TOPLEV is non-nil when MATCH-POS is 1133 ;; known to be at "top level", i.e. outside any braces, or directly inside a 1134 ;; namespace, class, etc. 1135 ;; 1136 ;; CONTEXT is the fontification context of MATCH-POS, and is one of the 1137 ;; following: 1138 ;; 'decl In a comma-separated declaration context (typically 1139 ;; inside a function declaration arglist). 1140 ;; '<> In an angle bracket arglist. 1141 ;; 'arglist Some other type of arglist. 1142 ;; 'top Some other context and point is at the top-level (either 1143 ;; outside any braces or directly inside a class or namespace, 1144 ;; etc.) 1145 ;; nil Some other context or unknown context. Includes 1146 ;; within the parens of an if, for, ... construct. 1147 ;; 'not-decl Definitely not in a declaration. 1148 ;; 1149 ;; RESTRICTED-<>-ARGLISTS is non-nil when a scan of template/generic 1150 ;; arguments lists (i.e. lists enclosed by <...>) is more strict about what 1151 ;; characters it allows within the list. 1152 (let ((type (and (> match-pos (point-min)) 1153 (c-get-char-property (1- match-pos) 'c-type)))) 1154 (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) 1155 (cons (and toplev 'top) nil)) 1156 ;; A control flow expression or a decltype 1157 ((and (eq (char-before match-pos) ?\() 1158 (save-excursion 1159 (goto-char match-pos) 1160 (backward-char) 1161 (c-backward-token-2) 1162 (cond 1163 ((looking-at c-paren-stmt-key) 1164 ;; Allow comma separated <> arglists in for statements. 1165 (cons nil nil)) 1166 ((or (looking-at c-block-stmt-2-key) 1167 (looking-at c-block-stmt-1-2-key) 1168 (looking-at c-typeof-key)) 1169 (cons nil t)) 1170 (t nil))))) 1171 ;; Near BOB. 1172 ((<= match-pos (point-min)) 1173 (cons 'arglist t)) 1174 ;; Got a cached hit in a declaration arglist. 1175 ((eq type 'c-decl-arg-start) 1176 (cons 'decl nil)) 1177 ;; We're inside (probably) a brace list. 1178 ((eq type 'c-not-decl) 1179 (cons 'not-decl nil)) 1180 ;; Inside a C++11 lambda function arglist. 1181 ((and (c-major-mode-is 'c++-mode) 1182 (eq (char-before match-pos) ?\() 1183 (save-excursion 1184 (goto-char match-pos) 1185 (c-backward-token-2) 1186 (and 1187 (c-safe (goto-char (scan-sexps (point) -1))) 1188 (c-looking-at-c++-lambda-capture-list)))) 1189 (c-put-char-property (1- match-pos) 'c-type 1190 'c-decl-arg-start) 1191 (cons 'decl nil)) 1192 ;; We're inside a brace list. 1193 ((and (eq (char-before match-pos) ?{) 1194 (c-inside-bracelist-p (1- match-pos) 1195 (cdr (c-parse-state)) 1196 nil)) 1197 (c-put-char-property (1- match-pos) 'c-type 1198 'c-not-decl) 1199 (cons 'not-decl nil)) 1200 ;; We're inside an "ordinary" open brace. 1201 ((eq (char-before match-pos) ?{) 1202 (cons (and toplev 'top) nil)) 1203 ;; Inside an angle bracket arglist. 1204 ((or (eq type 'c-<>-arg-sep) 1205 (eq (char-before match-pos) ?<)) 1206 (cons '<> nil)) 1207 ;; Got a cached hit in some other type of arglist. 1208 (type 1209 (cons 'arglist t)) 1210 ;; We're at a C++ uniform initialization. 1211 ((and (c-major-mode-is 'c++-mode) 1212 (eq (char-before match-pos) ?\() 1213 (save-excursion 1214 (goto-char match-pos) 1215 (and 1216 (zerop (c-backward-token-2 2)) 1217 (looking-at c-identifier-start) 1218 (c-got-face-at (point) 1219 '(font-lock-variable-name-face))))) 1220 (cons 'not-decl nil)) 1221 ((and not-front-decl 1222 ;; The point is within the range of a previously 1223 ;; encountered type decl expression, so the arglist 1224 ;; is probably one that contains declarations. 1225 ;; However, if `c-recognize-paren-inits' is set it 1226 ;; might also be an initializer arglist. 1227 (or (not c-recognize-paren-inits) 1228 (save-excursion 1229 (goto-char match-pos) 1230 (not (c-back-over-member-initializers))))) 1231 ;; The result of this check is cached with a char 1232 ;; property on the match token, so that we can look 1233 ;; it up again when refontifying single lines in a 1234 ;; multiline declaration. 1235 (c-put-char-property (1- match-pos) 1236 'c-type 'c-decl-arg-start) 1237 (cons 'decl nil)) 1238 ;; Got (an) open paren(s) preceded by an arith operator. 1239 ((and (eq (char-before match-pos) ?\() 1240 (save-excursion 1241 (goto-char match-pos) 1242 (while 1243 (and (zerop (c-backward-token-2)) 1244 (eq (char-after) ?\())) 1245 (looking-at c-arithmetic-op-regexp))) 1246 (cons nil nil)) 1247 ;; In a C++ member initialization list. 1248 ((and (eq (char-before match-pos) ?,) 1249 (c-major-mode-is 'c++-mode) 1250 (save-excursion 1251 (goto-char match-pos) 1252 (c-back-over-member-initializers))) 1253 (c-put-char-property (1- match-pos) 'c-type 'c-not-decl) 1254 (cons 'not-decl nil)) 1255 ;; At start of a declaration inside a declaration paren. 1256 ((save-excursion 1257 (goto-char match-pos) 1258 (and (memq (char-before match-pos) '(?\( ?\,)) 1259 (c-go-up-list-backward match-pos 1260 ; c-determine-limit is too slow, here. 1261 (max (- (point) 2000) (point-min))) 1262 (eq (char-after) ?\() 1263 (let ((type (c-get-char-property (point) 'c-type))) 1264 (or (memq type '(c-decl-arg-start c-decl-type-start)) 1265 (and 1266 (progn (c-backward-syntactic-ws) t) 1267 (c-back-over-compound-identifier) 1268 (progn 1269 (c-backward-syntactic-ws) 1270 (or (bobp) 1271 (progn 1272 (setq type (c-get-char-property (1- (point)) 1273 'c-type)) 1274 (memq type '(c-decl-arg-start 1275 c-decl-type-start)))))))))) 1276 (cons 'decl nil)) 1277 (t (cons 'arglist t))))) 1278 1279(defun c-font-lock-single-decl (limit decl-or-cast match-pos context toplev) 1280 ;; Try to fontify a single declaration, together with all its declarators. 1281 ;; Return nil if we're successful, non-nil if we fail. POINT should be 1282 ;; positioned at the start of the putative declaration before calling. 1283 ;; POINT is left undefined by this function. 1284 ;; 1285 ;; LIMIT sets a maximum position we'll fontify out to. 1286 ;; DECL-OR-CAST has the form of a result from `c-forward-decl-or-cast-1', 1287 ;; and must indicate a declaration (i.e. not be nil or 'cast). 1288 ;; MATCH-POS is the position after the last symbol before the decl. 1289 ;; CONTEXT is the context of the current decl., as determined by 1290 ;; c-get-fontification-context. 1291 ;; TOPLEV is non-nil if the decl. is at the top level (i.e. outside any 1292 ;; braces, or directly inside a class, namespace, etc.) 1293 1294 ;; Do we have an expression as the second or third clause of 1295 ;; a "for" paren expression? 1296 (if (save-excursion 1297 (and 1298 (car (cddr decl-or-cast)) ; maybe-expression flag. 1299 (c-go-up-list-backward nil (c-determine-limit 500)) 1300 (eq (char-after) ?\() 1301 (progn (c-backward-syntactic-ws) 1302 (c-simple-skip-symbol-backward)) 1303 (looking-at c-paren-stmt-key) 1304 (progn (goto-char match-pos) 1305 (while (and (eq (char-before) ?\)) 1306 (c-go-list-backward)) 1307 (c-backward-syntactic-ws)) 1308 (eq (char-before) ?\;)))) 1309 ;; We've got an expression in "for" parens. Remove the 1310 ;; "type" that would spuriously get fontified. 1311 (let ((elt (and (consp c-record-type-identifiers) 1312 (assq (cadr (cddr decl-or-cast)) 1313 c-record-type-identifiers)))) 1314 (when elt 1315 (setq c-record-type-identifiers 1316 (c-delq-from-dotted-list 1317 elt c-record-type-identifiers))) 1318 t) 1319 ;; Back up to the type to fontify the declarator(s). 1320 (goto-char (car decl-or-cast)) 1321 1322 (let ((decl-list 1323 (if (not (memq context '(nil top))) 1324 ;; Should normally not fontify a list of 1325 ;; declarators inside an arglist, but the first 1326 ;; argument in the ';' separated list of a "for" 1327 ;; statement is an exception. 1328 (when (eq (char-before match-pos) ?\() 1329 (save-excursion 1330 (goto-char (1- match-pos)) 1331 (c-backward-syntactic-ws) 1332 (and (c-simple-skip-symbol-backward) 1333 (looking-at c-paren-stmt-key)))) 1334 t)) 1335 (template-class (and (eq context '<>) 1336 (save-excursion 1337 (goto-char match-pos) 1338 (c-forward-syntactic-ws) 1339 (looking-at c-template-typename-key))))) 1340 ;; Fix the `c-decl-id-start' or `c-decl-type-start' property 1341 ;; before the first declarator if it's a list. 1342 ;; `c-font-lock-declarators' handles the rest. 1343 (when decl-list 1344 (save-excursion 1345 (c-backward-syntactic-ws) 1346 (unless (bobp) 1347 (c-put-char-property (1- (point)) 'c-type 1348 (if (cadr decl-or-cast) 1349 'c-decl-type-start 1350 'c-decl-id-start))))) 1351 (c-font-lock-declarators 1352 (min limit (point-max)) decl-list 1353 (not (null (cadr decl-or-cast))) 1354 (not toplev) template-class)) 1355 1356 ;; A declaration has been successfully identified, so do all the 1357 ;; fontification of types and refs that've been recorded. 1358 (c-fontify-recorded-types-and-refs) 1359 nil)) 1360 1361 1362(defun c-font-lock-declarations (limit) 1363 ;; Fontify all the declarations, casts and labels from the point to LIMIT. 1364 ;; Assumes that strings and comments have been fontified already. 1365 ;; 1366 ;; This function will be called from font-lock for a region bounded by POINT 1367 ;; and LIMIT, as though it were to identify a keyword for 1368 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1369 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1370 ;; Fontification". 1371 ;; 1372 ;; This function might do hidden buffer changes. 1373 1374 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) 1375 (c-skip-comments-and-strings limit) 1376 (when (< (point) limit) 1377 1378 (save-restriction 1379 (let (;; The position where `c-find-decl-spots' last stopped. 1380 start-pos 1381 ;; o - 'decl if we're in an arglist containing declarations 1382 ;; (but if `c-recognize-paren-inits' is set it might also be 1383 ;; an initializer arglist); 1384 ;; o - '<> if the arglist is of angle bracket type; 1385 ;; o - 'arglist if it's some other arglist; 1386 ;; o - nil, if not in an arglist at all. This includes the 1387 ;; parenthesized condition which follows "if", "while", etc. 1388 context 1389 ;; A list of starting positions of possible type declarations, or of 1390 ;; the typedef preceding one, if any. 1391 last-cast-end 1392 ;; The result from `c-forward-decl-or-cast-1'. 1393 decl-or-cast 1394 ;; The maximum of the end positions of all the checked type 1395 ;; decl expressions in the successfully identified 1396 ;; declarations. The position might be either before or 1397 ;; after the syntactic whitespace following the last token 1398 ;; in the type decl expression. 1399 (max-type-decl-end 0) 1400 ;; Same as `max-type-decl-*', but used when we're before 1401 ;; `token-pos'. 1402 (max-type-decl-end-before-token 0) 1403 ;; End of <..> construct which has had c-<>-arg-sep c-type 1404 ;; properties set within it. 1405 (max-<>-end 0) 1406 ;; Set according to the context to direct the heuristics for 1407 ;; recognizing C++ templates. 1408 c-restricted-<>-arglists 1409 ;; Turn on recording of identifier ranges in 1410 ;; `c-forward-decl-or-cast-1' and `c-forward-label' for 1411 ;; later fontification. 1412 (c-record-type-identifiers t) 1413 label-type 1414 c-record-ref-identifiers 1415 ;; Make `c-forward-type' calls mark up template arglists if 1416 ;; it finds any. That's necessary so that we later will 1417 ;; stop inside them to fontify types there. 1418 (c-parse-and-markup-<>-arglists t) 1419 ;; The font-lock package in Emacs is known to clobber 1420 ;; `parse-sexp-lookup-properties' (when it exists). 1421 (parse-sexp-lookup-properties 1422 (cc-eval-when-compile 1423 (boundp 'parse-sexp-lookup-properties)) 1424 )) 1425 1426 ;; Below we fontify a whole declaration even when it crosses the limit, 1427 ;; to avoid gaps when jit/lazy-lock fontifies the file a block at a 1428 ;; time. That is however annoying during editing, e.g. the following is 1429 ;; a common situation while the first line is being written: 1430 ;; 1431 ;; my_variable 1432 ;; some_other_variable = 0; 1433 ;; 1434 ;; font-lock will put the limit at the beginning of the second line 1435 ;; here, and if we go past it we'll fontify "my_variable" as a type and 1436 ;; "some_other_variable" as an identifier, and the latter will not 1437 ;; correct itself until the second line is changed. To avoid that we 1438 ;; narrow to the limit if the region to fontify is a single line. 1439 (if (<= limit (c-point 'bonl)) 1440 (narrow-to-region 1441 (point-min) 1442 (save-excursion 1443 ;; Narrow after any operator chars following the limit though, 1444 ;; since those characters can be useful in recognizing a 1445 ;; declaration (in particular the '{' that opens a function body 1446 ;; after the header). 1447 (goto-char limit) 1448 (skip-chars-forward c-nonsymbol-chars) 1449 (point)))) 1450 1451 (c-find-decl-spots 1452 limit 1453 c-decl-start-re 1454 (eval c-maybe-decl-faces) 1455 1456 (lambda (match-pos inside-macro &optional toplev) 1457 ;; Note to maintainers: don't use `limit' inside this lambda form; 1458 ;; c-find-decl-spots sometimes narrows to less than `limit'. 1459 (setq start-pos (point)) 1460 (when 1461 ;; The result of the form below is true when we don't recognize a 1462 ;; declaration or cast, and we don't recognize a "non-decl", 1463 ;; typically a brace list. 1464 (if (or (and (eq (get-text-property (point) 'face) 1465 'font-lock-keyword-face) 1466 (looking-at c-not-decl-init-keywords)) 1467 (and c-macro-with-semi-re 1468 (looking-at c-macro-with-semi-re))) ; 2008-11-04 1469 ;; Don't do anything more if we're looking at a keyword that 1470 ;; can't start a declaration. 1471 t 1472 1473 ;; Set `context' and `c-restricted-<>-arglists'. Look for 1474 ;; "<" for the sake of C++-style template arglists. 1475 ;; Ignore "(" when it's part of a control flow construct 1476 ;; (e.g. "for ("). 1477 (let ((got-context 1478 (c-get-fontification-context 1479 match-pos 1480 (< match-pos (if inside-macro 1481 max-type-decl-end-before-token 1482 max-type-decl-end)) 1483 toplev))) 1484 (setq context (car got-context) 1485 c-restricted-<>-arglists (cdr got-context))) 1486 1487 ;; Check we haven't missed a preceding "typedef". 1488 (when (not (looking-at c-typedef-key)) 1489 (c-backward-syntactic-ws 1490 (max (- (point) 1000) (point-min))) 1491 (c-backward-token-2) 1492 (or (looking-at c-typedef-key) 1493 (goto-char start-pos))) 1494 1495 ;; In QT, "more" is an irritating keyword that expands to nothing. 1496 ;; We skip over it to prevent recognition of "more slots: <symbol>" 1497 ;; as a bitfield declaration. 1498 (when (and (c-major-mode-is 'c++-mode) 1499 (looking-at 1500 (concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)"))) 1501 (goto-char (match-end 1)) 1502 (c-forward-syntactic-ws)) 1503 1504 ;; Now analyze the construct. 1505 (if (eq context 'not-decl) 1506 (progn 1507 (setq decl-or-cast nil) 1508 (if (c-syntactic-re-search-forward 1509 "," (min limit (point-max)) 'at-limit t) 1510 (c-put-char-property (1- (point)) 'c-type 'c-not-decl)) 1511 nil) 1512 (setq decl-or-cast 1513 (c-forward-decl-or-cast-1 1514 match-pos context last-cast-end)) 1515 1516 ;; Ensure that c-<>-arg-sep c-type properties are in place on the 1517 ;; commas separating the arguments inside template/generic <..>s. 1518 (when (and (eq (char-before match-pos) ?<) 1519 (> match-pos max-<>-end)) 1520 (save-excursion 1521 (goto-char match-pos) 1522 (c-backward-token-2) 1523 (if (and 1524 (eq (char-after) ?<) 1525 (let ((c-restricted-<>-arglists 1526 (save-excursion 1527 (c-backward-token-2) 1528 (and 1529 (not (looking-at c-opt-<>-sexp-key)) 1530 (progn 1531 (c-backward-syntactic-ws 1532 (max (- (point) 1000) (point-min))) 1533 (memq (char-before) '(?\( ?,))) 1534 (not (eq (c-get-char-property (1- (point)) 1535 'c-type) 1536 'c-decl-arg-start)))))) 1537 (c-forward-<>-arglist nil))) 1538 (setq max-<>-end (point))))) 1539 1540 (cond 1541 ((eq decl-or-cast 'cast) 1542 ;; Save the position after the previous cast so we can feed 1543 ;; it to `c-forward-decl-or-cast-1' in the next round. That 1544 ;; helps it discover cast chains like "(a) (b) c". 1545 (setq last-cast-end (point)) 1546 (c-fontify-recorded-types-and-refs) 1547 nil) 1548 1549 (decl-or-cast 1550 ;; We've found a declaration. 1551 1552 ;; Set `max-type-decl-end' or `max-type-decl-end-before-token' 1553 ;; under the assumption that we're after the first type decl 1554 ;; expression in the declaration now. That's not really true; 1555 ;; we could also be after a parenthesized initializer 1556 ;; expression in C++, but this is only used as a last resort 1557 ;; to slant ambiguous expression/declarations, and overall 1558 ;; it's worth the risk to occasionally fontify an expression 1559 ;; as a declaration in an initializer expression compared to 1560 ;; getting ambiguous things in normal function prototypes 1561 ;; fontified as expressions. 1562 (if inside-macro 1563 (when (> (point) max-type-decl-end-before-token) 1564 (setq max-type-decl-end-before-token (point))) 1565 (when (> (point) max-type-decl-end) 1566 (setq max-type-decl-end (point)))) 1567 (goto-char start-pos) 1568 (c-font-lock-single-decl limit decl-or-cast match-pos 1569 context 1570 (or toplev (nth 4 decl-or-cast)))) 1571 1572 (t t)))) 1573 1574 ;; It was a false alarm. Check if we're in a label (or other 1575 ;; construct with `:' except bitfield) instead. 1576 (goto-char start-pos) 1577 (when (setq label-type (c-forward-label t match-pos nil)) 1578 ;; Can't use `c-fontify-types-and-refs' here since we 1579 ;; use the label face at times. 1580 (cond ((eq label-type 'goto-target) 1581 (c-put-font-lock-face (caar c-record-ref-identifiers) 1582 (cdar c-record-ref-identifiers) 1583 c-label-face-name)) 1584 ((eq label-type 'qt-1kwd-colon) 1585 (c-put-font-lock-face (caar c-record-ref-identifiers) 1586 (cdar c-record-ref-identifiers) 1587 'font-lock-keyword-face)) 1588 ((eq label-type 'qt-2kwds-colon) 1589 (mapc 1590 (lambda (kwd) 1591 (c-put-font-lock-face (car kwd) (cdr kwd) 1592 'font-lock-keyword-face)) 1593 c-record-ref-identifiers))) 1594 (setq c-record-ref-identifiers nil) 1595 ;; `c-forward-label' has probably added a `c-decl-end' 1596 ;; marker, so return t to `c-find-decl-spots' to signal 1597 ;; that. 1598 t)))) 1599 1600 nil)))) 1601 1602(defun c-font-lock-enum-body (limit) 1603 ;; Fontify the identifiers of each enum we find by searching forward. 1604 ;; 1605 ;; This function will be called from font-lock for a region bounded by POINT 1606 ;; and LIMIT, as though it were to identify a keyword for 1607 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1608 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1609 ;; Fontification". 1610 (while (and (< (point) limit) 1611 (search-forward-regexp c-enum-clause-introduction-re limit t)) 1612 (when (save-excursion 1613 (backward-char) 1614 (c-backward-over-enum-header)) 1615 (c-forward-syntactic-ws) 1616 (c-font-lock-declarators limit t nil t))) 1617 nil) 1618 1619(defun c-font-lock-enum-tail (limit) 1620 ;; Fontify an enum's identifiers when POINT is within the enum's brace 1621 ;; block. 1622 ;; 1623 ;; This function will be called from font-lock for a region bounded by POINT 1624 ;; and LIMIT, as though it were to identify a keyword for 1625 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1626 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1627 ;; Fontification". 1628 ;; 1629 ;; Note that this function won't attempt to fontify beyond the end of the 1630 ;; current enum block, if any. 1631 (c-skip-comments-and-strings limit) 1632 (when (< (point) limit) 1633 (let* ((paren-state (c-parse-state)) 1634 (encl-pos (c-most-enclosing-brace paren-state))) 1635 (when (and 1636 encl-pos 1637 (eq (char-after encl-pos) ?\{) 1638 (save-excursion 1639 (goto-char encl-pos) 1640 (c-backward-over-enum-header))) 1641 (c-syntactic-skip-backward "^{," nil t) 1642 (c-put-char-property (1- (point)) 'c-type 'c-decl-id-start) 1643 1644 (c-forward-syntactic-ws) 1645 (c-font-lock-declarators limit t nil t)))) 1646 nil) 1647 1648(defun c-font-lock-cut-off-declarators (limit) 1649 ;; Fontify any declarators "cut off" from their declaring type at the start 1650 ;; of the region being fontified. 1651 ;; 1652 ;; This function will be called from font-lock- for a region bounded by 1653 ;; POINT and LIMIT, as though it were to identify a keyword for 1654 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1655 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1656 ;; fontification". 1657 (c-skip-comments-and-strings limit) 1658 (when (< (point) limit) 1659 (let ((here (point)) 1660 (decl-search-lim (c-determine-limit 1000)) 1661 paren-state encl-pos token-end context decl-or-cast 1662 start-pos top-level c-restricted-<>-arglists 1663 c-recognize-knr-p) ; Strictly speaking, bogus, but it 1664 ; speeds up lisp.h tremendously. 1665 (save-excursion 1666 (when (not (c-back-over-member-initializers decl-search-lim)) 1667 (unless (or (eobp) 1668 (looking-at "\\s(\\|\\s)")) 1669 (forward-char)) 1670 (c-syntactic-skip-backward "^;{}" decl-search-lim t) 1671 (when (eq (char-before) ?}) 1672 (c-go-list-backward) ; brace block of struct, etc.? 1673 (c-syntactic-skip-backward "^;{}" decl-search-lim t)) 1674 (when (or (bobp) 1675 (memq (char-before) '(?\; ?{ ?}))) 1676 (setq token-end (point)) 1677 (c-forward-syntactic-ws here) 1678 (when (< (point) here) 1679 ;; We're now putatively at the declaration. 1680 (setq start-pos (point)) 1681 (setq paren-state (c-parse-state)) 1682 ;; At top level or inside a "{"? 1683 (if (or (not (setq encl-pos 1684 (c-most-enclosing-brace paren-state))) 1685 (eq (char-after encl-pos) ?\{)) 1686 (progn 1687 (setq top-level (c-at-toplevel-p)) 1688 (let ((got-context (c-get-fontification-context 1689 token-end nil top-level))) 1690 (setq context (car got-context) 1691 c-restricted-<>-arglists (cdr got-context))) 1692 (setq decl-or-cast 1693 (c-forward-decl-or-cast-1 token-end context nil)) 1694 (when (consp decl-or-cast) 1695 (goto-char start-pos) 1696 (c-font-lock-single-decl limit decl-or-cast token-end 1697 context top-level)))))))) 1698 nil))) 1699 1700(defun c-font-lock-enclosing-decls (limit) 1701 ;; Fontify the declarators of (nested) declarations we're in the middle of. 1702 ;; This is mainly for when a jit-lock etc. chunk starts inside the brace 1703 ;; block of a struct/union/class, etc. 1704 ;; 1705 ;; This function will be called from font-lock for a region bounded by POINT 1706 ;; and LIMIT, as though it were to identify a keyword for 1707 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1708 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1709 ;; Fontification". 1710 (c-skip-comments-and-strings limit) 1711 (when (< (point) limit) 1712 (let* ((paren-state (c-parse-state)) 1713 (decl-search-lim (c-determine-limit 1000)) 1714 in-typedef ps-elt) 1715 ;; Are we in any nested struct/union/class/etc. braces? 1716 (while paren-state 1717 (setq ps-elt (car paren-state) 1718 paren-state (cdr paren-state)) 1719 (when (and (atom ps-elt) 1720 (eq (char-after ps-elt) ?\{)) 1721 (goto-char ps-elt) 1722 (c-syntactic-skip-backward "^;{}" decl-search-lim) 1723 (c-forward-syntactic-ws) 1724 (setq in-typedef (looking-at c-typedef-key)) 1725 (if in-typedef (c-forward-over-token-and-ws)) 1726 (when (and c-opt-block-decls-with-vars-key 1727 (looking-at c-opt-block-decls-with-vars-key)) 1728 (goto-char ps-elt) 1729 (when (c-safe (c-forward-sexp)) 1730 (c-forward-syntactic-ws) 1731 (c-font-lock-declarators limit t in-typedef 1732 (not (c-bs-at-toplevel-p (point))))))))))) 1733 1734(defun c-font-lock-ml-strings (limit) 1735 ;; Fontify multi-line strings. 1736 ;; 1737 ;; This function will be called from font-lock for a region bounded by POINT 1738 ;; and LIMIT, as though it were to identify a keyword for 1739 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1740 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1741 ;; Fontification". 1742 (let* ((state (c-semi-pp-to-literal (point))) 1743 (string-start (and (eq (cadr state) 'string) 1744 (car (cddr state)))) 1745 (open-delim (and string-start 1746 (save-excursion 1747 (goto-char (1+ string-start)) 1748 (c-ml-string-opener-around-point)))) 1749 (string-delims (and open-delim 1750 (cons open-delim (c-get-ml-closer open-delim)))) 1751 found) 1752 ;; We go round the next loop twice per raw string, once for each "end". 1753 (while (< (point) limit) 1754 (cond 1755 ;; Point is not in an ml string 1756 ((not string-delims) 1757 (while (and (setq found (re-search-forward c-ml-string-opener-re 1758 limit 'limit)) 1759 (> (match-beginning 0) (point-min)) 1760 (memq (c-get-char-property (1- (match-beginning 0)) 'face) 1761 '(font-lock-comment-face font-lock-string-face 1762 font-lock-comment-delimiter-face)))) 1763 (when found 1764 (setq open-delim (cons (match-beginning 1) 1765 (cons (match-end 1) (match-beginning 2))) 1766 string-delims (cons open-delim (c-get-ml-closer open-delim))) 1767 (goto-char (caar string-delims)))) 1768 1769 ;; Point is in the body of an ml string. 1770 ((and string-delims 1771 (>= (point) (cadar string-delims)) 1772 (or (not (cdr string-delims)) 1773 (< (point) (cadr string-delims)))) 1774 (if (cdr string-delims) 1775 (goto-char (cadr string-delims)) 1776 (if (equal (c-get-char-property (1- (cadar string-delims)) 1777 'syntax-table) 1778 '(15)) ; "Always" the case. 1779 ;; The next search should be successful for an unterminated ml 1780 ;; string inside a macro, but not for any other unterminated 1781 ;; string. 1782 (progn 1783 (or (c-search-forward-char-property 'syntax-table '(15) limit) 1784 (goto-char limit)) 1785 (setq string-delims nil)) 1786 (c-benign-error "Missing '(15) syntax-table property at %d" 1787 (1- (cadar string-delims))) 1788 (setq string-delims nil)))) 1789 1790 ;; Point is at or in a closing delimiter 1791 ((and string-delims 1792 (cdr string-delims) 1793 (>= (point) (cadr string-delims))) 1794 (c-put-font-lock-face (cadr string-delims) (1+ (cadr string-delims)) 1795 'font-lock-string-face) 1796 (c-remove-font-lock-face (1+ (cadr string-delims)) 1797 (caddr string-delims)) 1798 (goto-char (caddr string-delims)) 1799 (setq string-delims nil)) 1800 1801 ;; point is at or in an opening delimiter. 1802 (t 1803 (if (cdr string-delims) 1804 (progn 1805 (c-remove-font-lock-face (caar string-delims) 1806 (1- (cadar string-delims))) 1807 (c-put-font-lock-face (1- (cadar string-delims)) 1808 (cadar string-delims) 1809 'font-lock-string-face)) 1810 (c-put-font-lock-face (caar string-delims) (cadar string-delims) 1811 'font-lock-warning-face)) 1812 (goto-char (cadar string-delims))))) 1813 nil)) 1814 1815(defun c-font-lock-c++-lambda-captures (limit) 1816 ;; Fontify the lambda capture component of C++ lambda declarations. 1817 ;; 1818 ;; This function will be called from font-lock for a region bounded by POINT 1819 ;; and LIMIT, as though it were to identify a keyword for 1820 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1821 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1822 ;; Fontification". 1823 (let (mode capture-default id-start id-end declaration sub-begin sub-end) 1824 (while (and (< (point) limit) 1825 (search-forward "[" limit t)) 1826 (when (progn (backward-char) 1827 (prog1 1828 (c-looking-at-c++-lambda-capture-list) 1829 (forward-char))) 1830 (c-forward-syntactic-ws) 1831 (setq mode (and (memq (char-after) '(?= ?&)) 1832 (char-after))) 1833 ;; Is the first element of the list a bare "=" or "&"? 1834 (when mode 1835 (forward-char) 1836 (c-forward-syntactic-ws) 1837 (if (memq (char-after) '(?, ?\])) 1838 (progn 1839 (setq capture-default mode) 1840 (when (eq (char-after) ?,) 1841 (forward-char) 1842 (c-forward-syntactic-ws))) 1843 (c-backward-token-2))) 1844 1845 ;; Go round the following loop once per captured item. We use "\\s)" 1846 ;; rather than "\\]" here to avoid infinite looping in this situation: 1847 ;; "unsigned items [] { [ }". The second "[" triggers this function, 1848 ;; but if we don't match the "}" with an "\\s)", the 1849 ;; `c-syntactic-re-search-forward' at the end of the loop fails to 1850 ;; move forward over it, leaving point stuck at the "}". 1851 (while (and (not (looking-at "\\s)")) 1852 (< (point) limit)) 1853 (if (eq (char-after) ?&) 1854 (progn (setq mode ?&) 1855 (forward-char) 1856 (c-forward-syntactic-ws)) 1857 (setq mode ?=)) 1858 (if (c-on-identifier) 1859 (progn 1860 (setq id-start (point)) 1861 (forward-char) 1862 (c-end-of-current-token) 1863 (setq id-end (point)) 1864 (c-forward-syntactic-ws) 1865 1866 (setq declaration (eq (char-after) ?=)) 1867 (when declaration 1868 (forward-char) ; over "=" 1869 (c-forward-syntactic-ws) 1870 (setq sub-begin (point))) 1871 (if (or (and (< (point) limit) 1872 (c-syntactic-re-search-forward "," limit t t)) 1873 (and (c-go-up-list-forward nil limit) 1874 (eq (char-before) ?\]))) 1875 (backward-char) 1876 (goto-char limit)) 1877 (when declaration 1878 (save-excursion 1879 (setq sub-end (point)) 1880 (goto-char sub-begin) 1881 (c-font-lock-c++-lambda-captures sub-end))) 1882 1883 (c-put-font-lock-face id-start id-end 1884 (cond 1885 (declaration 1886 'font-lock-variable-name-face) 1887 ((and capture-default 1888 (eq mode capture-default)) 1889 'font-lock-warning-face) 1890 ((eq mode ?=) font-lock-constant-face) 1891 (t 'font-lock-variable-name-face)))) 1892 (c-syntactic-re-search-forward "," limit 'bound t)) 1893 1894 (c-forward-syntactic-ws) 1895 (when (eq (char-after) ?,) 1896 (forward-char) 1897 (c-forward-syntactic-ws))) 1898 1899 (setq capture-default nil) 1900 (if (< (point) limit) 1901 (forward-char))))) ; over the terminating "]" or other close paren. 1902 nil) 1903 1904 1905(c-lang-defconst c-simple-decl-matchers 1906 "Simple font lock matchers for types and declarations. These are used 1907on level 2 only and so aren't combined with `c-complex-decl-matchers'." 1908 1909 t `(;; Objective-C methods. 1910 ,@(when (c-major-mode-is 'objc-mode) 1911 `((,(c-lang-const c-opt-method-key) 1912 (,(byte-compile 1913 (lambda (limit) 1914 (let (;; The font-lock package in Emacs is known to clobber 1915 ;; `parse-sexp-lookup-properties' (when it exists). 1916 (parse-sexp-lookup-properties 1917 (cc-eval-when-compile 1918 (boundp 'parse-sexp-lookup-properties)))) 1919 (save-restriction 1920 (narrow-to-region (point-min) limit) 1921 (c-font-lock-objc-method))) 1922 nil)) 1923 (goto-char (match-end 1)))))) 1924 1925 ;; Fontify all type names and the identifiers in the 1926 ;; declarations they might start. Use eval here since 1927 ;; `c-known-type-key' gets its value from 1928 ;; `*-font-lock-extra-types' on mode init. 1929 (eval . (list ,(c-make-font-lock-search-function 1930 'c-known-type-key 1931 '(1 'font-lock-type-face t) 1932 '((c-font-lock-declarators limit t nil nil) 1933 (save-match-data 1934 (goto-char (match-end 1)) 1935 (c-forward-syntactic-ws)) 1936 (goto-char (match-end 1)))))) 1937 1938 ;; Fontify types preceded by `c-type-prefix-kwds' and the 1939 ;; identifiers in the declarations they might start. 1940 ,@(when (c-lang-const c-type-prefix-kwds) 1941 (let* ((prefix-re (c-make-keywords-re nil 1942 (c-lang-const c-type-prefix-kwds))) 1943 (type-match (+ 2 1944 (regexp-opt-depth prefix-re) 1945 (c-lang-const c-simple-ws-depth)))) 1946 `((,(c-make-font-lock-search-function 1947 (concat "\\<\\(" prefix-re "\\)" ; 1 1948 (c-lang-const c-simple-ws) "+" 1949 (concat "\\(" ; 2 + prefix-re + c-simple-ws 1950 (c-lang-const c-symbol-key) 1951 "\\)")) 1952 `(,type-match 1953 'font-lock-type-face t) 1954 `((c-font-lock-declarators limit t nil nil) 1955 (save-match-data 1956 (goto-char (match-end ,type-match)) 1957 (c-forward-syntactic-ws)) 1958 (goto-char (match-end ,type-match)))))))) 1959 1960 ;; Fontify special declarations that lacks a type. 1961 ,@(when (c-lang-const c-typeless-decl-kwds) 1962 `((,(c-make-font-lock-search-function 1963 (concat "\\<\\(" 1964 (regexp-opt (c-lang-const c-typeless-decl-kwds)) 1965 "\\)\\>") 1966 '((c-font-lock-declarators limit t nil nil) 1967 (save-match-data 1968 (goto-char (match-end 1)) 1969 (c-forward-syntactic-ws)) 1970 (goto-char (match-end 1))))))) 1971 1972 ;; Fontify generic colon labels in languages that support them. 1973 ,@(when (c-lang-const c-recognize-colon-labels) 1974 '(c-font-lock-labels)))) 1975 1976(c-lang-defconst c-complex-decl-matchers 1977 "Complex font lock matchers for types and declarations. Used on level 19783 and higher." 1979 1980 ;; Note: This code in this form dumps a number of functions into the 1981 ;; resulting constant, `c-matchers-3'. At run time, font lock will call 1982 ;; each of them as a "FUNCTION" (see Elisp page "Search-based 1983 ;; Fontification"). The font lock region is delimited by POINT and the 1984 ;; single parameter, LIMIT. Each of these functions returns NIL (thus 1985 ;; inhibiting spurious font-lock-keyword-face highlighting and another 1986 ;; call). 1987 1988 t `(;; Initialize some things before the search functions below. 1989 c-font-lock-complex-decl-prepare 1990 1991 ,@(if (c-major-mode-is 'objc-mode) 1992 ;; Fontify method declarations in Objective-C, but first 1993 ;; we have to put the `c-decl-end' `c-type' property on 1994 ;; all the @-style directives that haven't been handled in 1995 ;; `c-basic-matchers-before'. 1996 `(,(c-make-font-lock-search-function 1997 (c-make-keywords-re t 1998 ;; Exclude "@class" since that directive ends with a 1999 ;; semicolon anyway. 2000 (delete "@class" 2001 (append (c-lang-const c-protection-kwds) 2002 (c-lang-const c-other-decl-kwds) 2003 nil))) 2004 '((c-put-char-property (1- (match-end 1)) 2005 'c-type 'c-decl-end))) 2006 c-font-lock-objc-methods)) 2007 2008 ;; Fontify declarators which have been cut off from their declaring 2009 ;; types at the start of the region. 2010 c-font-lock-cut-off-declarators 2011 2012 ;; Fontify all declarations, casts and normal labels. 2013 c-font-lock-declarations 2014 2015 ;; Fontify declarators when POINT is within their declaration. 2016 c-font-lock-enclosing-decls 2017 2018 ;; Fontify angle bracket arglists like templates in C++. 2019 ,@(when (c-lang-const c-recognize-<>-arglists) 2020 '(c-font-lock-<>-arglists)) 2021 2022 ,@(when (c-major-mode-is 'c++-mode) 2023 '(c-font-lock-c++-lambda-captures)) 2024 2025 ,@(when (c-lang-const c-using-key) 2026 `(c-font-lock-c++-using)) 2027 2028 ;; The first two rules here mostly find occurrences that 2029 ;; `c-font-lock-declarations' has found already, but not 2030 ;; declarations containing blocks in the type (see note below). 2031 ;; It's also useful to fontify these everywhere to show e.g. when 2032 ;; a type keyword is accidentally used as an identifier. 2033 2034 ;; Fontify basic types. 2035 ,(let ((re (c-make-keywords-re nil 2036 (c-lang-const c-primitive-type-kwds)))) 2037 (if (c-major-mode-is 'pike-mode) 2038 ;; No symbol is a keyword after "->" in Pike. 2039 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" 2040 "\\<\\(" re "\\)\\>") 2041 2 font-lock-type-face) 2042 `(,(concat "\\<\\(" re "\\)\\>") 2043 1 'font-lock-type-face))) 2044 ;; Fontify the type in C++ "new" expressions. 2045 ,@(when (c-major-mode-is 'c++-mode) 2046 ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)" 2047 ;; (see Elisp page "Search-based Fontification"). 2048 '(("\\<new\\>" 2049 (c-font-lock-c++-new)))) 2050 )) 2051 2052(defun c-font-lock-labels (limit) 2053 ;; Fontify all statement labels from the point to LIMIT. Assumes 2054 ;; that strings and comments have been fontified already. Nil is 2055 ;; always returned. 2056 ;; 2057 ;; Note: This function is only used on decoration level 2; this is 2058 ;; taken care of directly by the gargantuan 2059 ;; `c-font-lock-declarations' on higher levels. 2060 ;; 2061 ;; This function might do hidden buffer changes. 2062 2063 (let (continue-pos id-start 2064 ;; The font-lock package in Emacs is known to clobber 2065 ;; `parse-sexp-lookup-properties' (when it exists). 2066 (parse-sexp-lookup-properties 2067 (cc-eval-when-compile 2068 (boundp 'parse-sexp-lookup-properties)))) 2069 2070 (while (re-search-forward ":[^:]" limit t) 2071 (setq continue-pos (point)) 2072 (goto-char (match-beginning 0)) 2073 (unless (c-skip-comments-and-strings limit) 2074 2075 (c-backward-syntactic-ws) 2076 (and (setq id-start (c-on-identifier)) 2077 2078 (not (get-text-property id-start 'face)) 2079 2080 (progn 2081 (goto-char id-start) 2082 (c-backward-syntactic-ws) 2083 (or 2084 ;; Check for a char that precedes a statement. 2085 (memq (char-before) '(?\} ?\{ ?\;)) 2086 ;; Check for a preceding label. We exploit the font 2087 ;; locking made earlier by this function. 2088 (and (eq (char-before) ?:) 2089 (progn 2090 (backward-char) 2091 (c-backward-syntactic-ws) 2092 (not (bobp))) 2093 (eq (get-text-property (1- (point)) 'face) 2094 c-label-face-name)) 2095 ;; Check for a keyword that precedes a statement. 2096 (c-after-conditional))) 2097 2098 (progn 2099 ;; Got a label. 2100 (goto-char id-start) 2101 (looking-at c-symbol-key) 2102 (c-put-font-lock-face (match-beginning 0) (match-end 0) 2103 c-label-face-name))) 2104 2105 (goto-char continue-pos)))) 2106 nil) 2107 2108(c-lang-defconst c-basic-matchers-after 2109 "Font lock matchers for various things that should be fontified after 2110generic casts and declarations are fontified. Used on level 2 and 2111higher." 2112 2113 t `(,@(when (c-lang-const c-brace-list-decl-kwds) 2114 ;; Fontify the remaining identifiers inside an enum list when we start 2115 ;; inside it. 2116 '(c-font-lock-enum-tail 2117 ;; Fontify the identifiers inside enum lists. (The enum type 2118 ;; name is handled by `c-simple-decl-matchers' or 2119 ;; `c-complex-decl-matchers' below. 2120 c-font-lock-enum-body)) 2121 2122 ;; Fontify labels after goto etc. 2123 ,@(when (c-lang-const c-before-label-kwds) 2124 `(;; (Got three different interpretation levels here, 2125 ;; which makes it a bit complicated: 1) The backquote 2126 ;; stuff is expanded when compiled or loaded, 2) the 2127 ;; eval form is evaluated at font-lock setup (to 2128 ;; substitute c-label-face-name correctly), and 3) the 2129 ;; resulting structure is interpreted during 2130 ;; fontification.) 2131 (eval 2132 . ,(let* ((c-before-label-re 2133 (c-make-keywords-re nil 2134 (c-lang-const c-before-label-kwds)))) 2135 `(list 2136 ,(concat "\\<\\(" c-before-label-re "\\)\\>" 2137 "\\s *" 2138 "\\(" ; identifier-offset 2139 (c-lang-const c-symbol-key) 2140 "\\)") 2141 (list ,(+ (regexp-opt-depth c-before-label-re) 2) 2142 c-label-face-name nil t)))))) 2143 2144 ;; Fontify the clauses after various keywords. 2145 ,@(when (or (c-lang-const c-type-list-kwds) 2146 (c-lang-const c-ref-list-kwds) 2147 (c-lang-const c-colon-type-list-kwds)) 2148 `((,(c-make-font-lock-BO-decl-search-function 2149 (concat "\\<\\(" 2150 (c-make-keywords-re nil 2151 (append (c-lang-const c-type-list-kwds) 2152 (c-lang-const c-ref-list-kwds) 2153 (c-lang-const c-colon-type-list-kwds))) 2154 "\\)\\>") 2155 '((c-fontify-types-and-refs ((c-promote-possible-types t)) 2156 (c-forward-keyword-clause 1) 2157 (if (> (point) limit) (goto-char limit)))))))) 2158 2159 ,@(when (c-lang-const c-paren-type-kwds) 2160 `((,(c-make-font-lock-search-function 2161 (concat "\\<\\(" 2162 (c-make-keywords-re nil 2163 (c-lang-const c-paren-type-kwds)) 2164 "\\)\\>") 2165 '((c-fontify-types-and-refs ((c-promote-possible-types t)) 2166 (c-forward-keyword-clause 1) 2167 (if (> (point) limit) (goto-char limit)))))))) 2168 2169 ,@(when (c-major-mode-is 'java-mode) 2170 '((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face)))) 2171 )) 2172 2173(c-lang-defconst c-matchers-1 2174 t (c-lang-const c-cpp-matchers)) 2175 2176(c-lang-defconst c-matchers-2 2177 t (append (c-lang-const c-matchers-1) 2178 (c-lang-const c-basic-matchers-before) 2179 (c-lang-const c-simple-decl-matchers) 2180 (c-lang-const c-basic-matchers-after))) 2181 2182(c-lang-defconst c-matchers-3 2183 t (append (c-lang-const c-matchers-1) 2184 (c-lang-const c-basic-matchers-before) 2185 (c-lang-const c-complex-decl-matchers) 2186 (c-lang-const c-basic-matchers-after))) 2187 2188(defun c-get-doc-comment-style () 2189 ;; Get the symbol (or list of symbols) constituting the document style. 2190 ;; Return nil if there is no such, otherwise something like `autodoc'. 2191 (if (consp (car-safe c-doc-comment-style)) 2192 (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style) 2193 (assq 'other c-doc-comment-style))) 2194 c-doc-comment-style)) 2195 2196(defun c-compose-keywords-list (base-list) 2197 ;; Incorporate the font lock keyword lists according to 2198 ;; `c-doc-comment-style' on the given keyword list and return it. 2199 ;; This is used in the function bindings of the 2200 ;; `*-font-lock-keywords-*' symbols since we have to build the list 2201 ;; when font-lock is initialized. 2202 2203 (unless (memq c-doc-face-name c-literal-faces) 2204 (setq c-literal-faces (cons c-doc-face-name c-literal-faces))) 2205 2206 (let* ((doc-keywords (c-get-doc-comment-style)) 2207 (list (nconc (c--mapcan 2208 (lambda (doc-style) 2209 (let ((sym (intern 2210 (concat (symbol-name doc-style) 2211 "-font-lock-keywords")))) 2212 (cond ((fboundp sym) 2213 (funcall sym)) 2214 ((boundp sym) 2215 (append (eval sym) nil))))) 2216 (if (listp doc-keywords) 2217 doc-keywords 2218 (list doc-keywords))) 2219 base-list))) 2220 2221 ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we 2222 ;; move it first since the doc comment font lockers might add 2223 ;; `c-type' text properties, so they have to be cleared before that. 2224 (when (memq 'c-font-lock-complex-decl-prepare list) 2225 (setq list (cons 'c-font-lock-complex-decl-prepare 2226 (delq 'c-font-lock-complex-decl-prepare 2227 (append list nil))))) 2228 2229 list)) 2230 2231(defun c-override-default-keywords (def-var) 2232 ;; This is used to override the value on a `*-font-lock-keywords' 2233 ;; variable only if it's nil or has the same value as one of the 2234 ;; `*-font-lock-keywords-*' variables. Older font-lock packages 2235 ;; define a default value for `*-font-lock-keywords' which we want 2236 ;; to override, but we should otoh avoid clobbering a user setting. 2237 ;; This heuristic for that isn't perfect, but I can't think of any 2238 ;; better. /mast 2239 (when (and (boundp def-var) 2240 (memq (symbol-value def-var) 2241 (cons nil 2242 (mapcar 2243 (lambda (suffix) 2244 (let ((sym (intern (concat (symbol-name def-var) 2245 suffix)))) 2246 (and (boundp sym) (symbol-value sym)))) 2247 '("-1" "-2" "-3"))))) 2248 ;; The overriding is done by unbinding the variable so that the normal 2249 ;; defvar will install its default value later on. 2250 (makunbound def-var))) 2251 2252;; `c-re-redisplay-timer' is a timer which, when triggered, causes a 2253;; redisplay. 2254(defvar c-re-redisplay-timer nil) 2255 2256(defun c-force-redisplay (start end) 2257 ;; Force redisplay immediately. This assumes `font-lock-support-mode' is 2258 ;; 'jit-lock-mode. Set the variable `c-re-redisplay-timer' to nil. 2259 (save-excursion (c-font-lock-fontify-region start end)) 2260 (jit-lock-force-redisplay (copy-marker start) (copy-marker end)) 2261 (setq c-re-redisplay-timer nil)) 2262 2263(defun c-fontify-new-found-type (type) 2264 ;; Cause the fontification of TYPE, a string, wherever it occurs in the 2265 ;; buffer. If TYPE is currently displayed in a window, cause redisplay to 2266 ;; happen "instantaneously". These actions are done only when jit-lock-mode 2267 ;; is active. 2268 (when (and font-lock-mode 2269 (boundp 'font-lock-support-mode) 2270 (eq font-lock-support-mode 'jit-lock-mode)) 2271 (c-save-buffer-state 2272 ((window-boundaries 2273 (mapcar (lambda (win) 2274 (cons (window-start win) 2275 (window-end win))) 2276 (get-buffer-window-list (current-buffer) 'no-mini t))) 2277 (target-re (concat "\\_<" type "\\_>"))) 2278 (save-excursion 2279 (save-restriction 2280 (widen) 2281 (goto-char (point-min)) 2282 (while (re-search-forward target-re nil t) 2283 (put-text-property (match-beginning 0) (match-end 0) 2284 'fontified nil) 2285 (dolist (win-boundary window-boundaries) 2286 (when (and (< (match-beginning 0) (cdr win-boundary)) 2287 (> (match-end 0) (car win-boundary)) 2288 (not c-re-redisplay-timer)) 2289 (setq c-re-redisplay-timer 2290 (run-with-timer 0 nil #'c-force-redisplay 2291 (match-beginning 0) (match-end 0))))))))))) 2292 2293 2294;;; C. 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. 2300Fontifies only preprocessor directives (in addition to the syntactic 2301fontification 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. 2305In addition to `c-font-lock-keywords-1', this adds fontification of 2306keywords, simple types, declarations that are easy to recognize, the 2307user defined types on `c-font-lock-extra-types', and the doc comment 2308styles 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. 2312Like the variable `c-font-lock-keywords-2' but detects declarations in a more 2313accurate way that works in most cases for arbitrary types without the 2314need 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 2327;;; C++. 2328(defun c-font-lock-c++-using (limit) 2329 ;; Fontify any clauses starting with the keyword `using'. 2330 ;; 2331 ;; This function will be called from font-lock- for a region bounded by 2332 ;; POINT and LIMIT, as though it were to identify a keyword for 2333 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 2334 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 2335 ;; fontification". 2336 (let (pos) 2337 (while (c-syntactic-re-search-forward c-using-key limit 'end) 2338 (while ; Do one declarator of a comma separated list, each time around. 2339 (progn 2340 (c-forward-syntactic-ws) 2341 (setq pos (point)) ; token after "using". 2342 (when (and (c-on-identifier) 2343 (c-forward-name)) 2344 (cond 2345 ((eq (char-after) ?=) ; using foo = <type-id>; 2346 (goto-char pos) 2347 (c-font-lock-declarators limit nil t nil)) 2348 ((save-excursion 2349 (and c-colon-type-list-re 2350 (c-go-up-list-backward) 2351 (eq (char-after) ?{) 2352 (eq (car (c-beginning-of-decl-1 2353 (c-determine-limit 1000))) 2354 'same) 2355 (looking-at c-colon-type-list-re))) 2356 ;; Inherited protected member: leave unfontified 2357 ) 2358 (t (goto-char pos) 2359 (c-font-lock-declarators limit nil c-label-face-name nil))) 2360 (eq (char-after) ?,))) 2361 (forward-char))) ; over the comma. 2362 nil)) 2363 2364(defun c-font-lock-c++-new (limit) 2365 ;; FIXME!!! Put in a comment about the context of this function's 2366 ;; invocation. I think it's called as an ANCHORED-MATCHER within an 2367 ;; ANCHORED-HIGHLIGHTER. (2007/2/10). 2368 ;; 2369 ;; Assuming point is after a "new" word, check that it isn't inside 2370 ;; a string or comment, and if so try to fontify the type in the 2371 ;; allocation expression. Nil is always returned. 2372 ;; 2373 ;; As usual, C++ takes the prize in coming up with a hard to parse 2374 ;; syntax. :P 2375 ;; 2376 ;; This function might do hidden buffer changes. 2377 2378 (unless (c-skip-comments-and-strings limit) 2379 (save-excursion 2380 (catch 'false-alarm 2381 ;; A "new" keyword is followed by one to three expressions, where 2382 ;; the type is the middle one, and the only required part. 2383 (let (expr1-pos expr2-pos 2384 ;; Enable recording of identifier ranges in `c-forward-type' 2385 ;; etc for later fontification. Not using 2386 ;; `c-fontify-types-and-refs' here since the ranges should 2387 ;; be fontified selectively only when an allocation 2388 ;; expression is successfully recognized. 2389 (c-record-type-identifiers t) 2390 c-record-ref-identifiers 2391 ;; The font-lock package in Emacs is known to clobber 2392 ;; `parse-sexp-lookup-properties' (when it exists). 2393 (parse-sexp-lookup-properties 2394 (cc-eval-when-compile 2395 (boundp 'parse-sexp-lookup-properties)))) 2396 (c-forward-syntactic-ws) 2397 2398 ;; The first placement arglist is always parenthesized, if it 2399 ;; exists. 2400 (when (eq (char-after) ?\() 2401 (setq expr1-pos (1+ (point))) 2402 (condition-case nil 2403 (c-forward-sexp) 2404 (scan-error (throw 'false-alarm t))) 2405 (c-forward-syntactic-ws)) 2406 2407 ;; The second expression is either a type followed by some "*" or 2408 ;; "[...]" or similar, or a parenthesized type followed by a full 2409 ;; identifierless declarator. 2410 (setq expr2-pos (1+ (point))) 2411 (cond ((eq (char-after) ?\()) 2412 ((let ((c-promote-possible-types t)) 2413 (c-forward-type))) 2414 (t (setq expr2-pos nil))) 2415 2416 (when expr1-pos 2417 (cond 2418 ((not expr2-pos) 2419 ;; No second expression, so the first has to be a 2420 ;; parenthesized type. 2421 (goto-char expr1-pos) 2422 (let ((c-promote-possible-types t)) 2423 (c-forward-type))) 2424 2425 ((eq (char-before expr2-pos) ?\() 2426 ;; Got two parenthesized expressions, so we have to look 2427 ;; closer at them to decide which is the type. No need to 2428 ;; handle `c-record-ref-identifiers' since all references 2429 ;; have already been handled by other fontification rules. 2430 (let (expr1-res expr2-res) 2431 2432 (goto-char expr1-pos) 2433 (when (setq expr1-res (c-forward-type)) 2434 (unless (looking-at 2435 (cc-eval-when-compile 2436 (concat (c-lang-const c-symbol-start c++) 2437 "\\|[*:)[]"))) 2438 ;; There's something after the would-be type that 2439 ;; can't be there, so this is a placement arglist. 2440 (setq expr1-res nil))) 2441 2442 (goto-char expr2-pos) 2443 (when (setq expr2-res (c-forward-type)) 2444 (unless (looking-at 2445 (cc-eval-when-compile 2446 (concat (c-lang-const c-symbol-start c++) 2447 "\\|[*:)[]"))) 2448 ;; There's something after the would-be type that can't 2449 ;; be there, so this is an initialization expression. 2450 (setq expr2-res nil)) 2451 (when (and (c-go-up-list-forward) 2452 (progn (c-forward-syntactic-ws) 2453 (eq (char-after) ?\())) 2454 ;; If there's a third initialization expression 2455 ;; then the second one is the type, so demote the 2456 ;; first match. 2457 (setq expr1-res nil))) 2458 2459 ;; We fontify the most likely type, with a preference for 2460 ;; the first argument since a placement arglist is more 2461 ;; unusual than an initializer. 2462 (cond ((memq expr1-res '(t known prefix))) 2463 ((memq expr2-res '(t known prefix))) 2464 ;; Presumably 'decltype's will be fontified elsewhere. 2465 ((eq expr1-res 'decltype)) 2466 ((eq expr2-res 'decltype)) 2467 ((eq expr1-res 'found) 2468 (let ((c-promote-possible-types t)) 2469 (goto-char expr1-pos) 2470 (c-forward-type))) 2471 ((eq expr2-res 'found) 2472 (let ((c-promote-possible-types t)) 2473 (goto-char expr2-pos) 2474 (c-forward-type))) 2475 ((and (eq expr1-res 'maybe) (not expr2-res)) 2476 (let ((c-promote-possible-types t)) 2477 (goto-char expr1-pos) 2478 (c-forward-type))) 2479 ((and (not expr1-res) (eq expr2-res 'maybe)) 2480 (let ((c-promote-possible-types t)) 2481 (goto-char expr2-pos) 2482 (c-forward-type))) 2483 ;; If both type matches are 'maybe then we're 2484 ;; too uncertain to promote either of them. 2485 ))))) 2486 2487 ;; Fontify the type that now is recorded in 2488 ;; `c-record-type-identifiers', if any. 2489 (c-fontify-recorded-types-and-refs))))) 2490 nil) 2491 2492(c-override-default-keywords 'c++-font-lock-keywords) 2493 2494(defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++) 2495 "Minimal font locking for C++ mode. 2496Fontifies only preprocessor directives (in addition to the syntactic 2497fontification of strings and comments).") 2498 2499(defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++) 2500 "Fast normal font locking for C++ mode. 2501In addition to `c++-font-lock-keywords-1', this adds fontification of 2502keywords, simple types, declarations that are easy to recognize, the 2503user defined types on `c++-font-lock-extra-types', and the doc comment 2504styles specified by `c-doc-comment-style'.") 2505 2506(defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++) 2507 "Accurate normal font locking for C++ mode. 2508Like the variable `c++-font-lock-keywords-2' but detects declarations in a more 2509accurate way that works in most cases for arbitrary types without the 2510need for `c++-font-lock-extra-types'.") 2511 2512(defvar c++-font-lock-keywords c++-font-lock-keywords-3 2513 "Default expressions to highlight in C++ mode.") 2514 2515(defun c++-font-lock-keywords-2 () 2516 (c-compose-keywords-list c++-font-lock-keywords-2)) 2517(defun c++-font-lock-keywords-3 () 2518 (c-compose-keywords-list c++-font-lock-keywords-3)) 2519(defun c++-font-lock-keywords () 2520 (c-compose-keywords-list c++-font-lock-keywords)) 2521 2522 2523;;; Objective-C. 2524 2525(defun c-font-lock-objc-method () 2526 ;; Assuming the point is after the + or - that starts an Objective-C 2527 ;; method declaration, fontify it. This must be done before normal 2528 ;; casts, declarations and labels are fontified since they will get 2529 ;; false matches in these things. 2530 ;; 2531 ;; This function might do hidden buffer changes. 2532 2533 (c-fontify-types-and-refs 2534 ((first t) 2535 (c-promote-possible-types t)) 2536 2537 (while (and 2538 (progn 2539 (c-forward-syntactic-ws) 2540 2541 ;; An optional method type. 2542 (if (eq (char-after) ?\() 2543 (progn 2544 (forward-char) 2545 (c-forward-syntactic-ws) 2546 (c-forward-type) 2547 (prog1 (c-go-up-list-forward) 2548 (c-forward-syntactic-ws))) 2549 t)) 2550 2551 ;; The name. The first time it's the first part of 2552 ;; the function name, the rest of the time it's an 2553 ;; argument name. 2554 (looking-at c-symbol-key) 2555 (progn 2556 (goto-char (match-end 0)) 2557 (c-put-font-lock-face (match-beginning 0) 2558 (point) 2559 (if first 2560 'font-lock-function-name-face 2561 'font-lock-variable-name-face)) 2562 (c-forward-syntactic-ws) 2563 2564 ;; Another optional part of the function name. 2565 (when (looking-at c-symbol-key) 2566 (goto-char (match-end 0)) 2567 (c-put-font-lock-face (match-beginning 0) 2568 (point) 2569 'font-lock-function-name-face) 2570 (c-forward-syntactic-ws)) 2571 2572 ;; There's another argument if a colon follows. 2573 (eq (char-after) ?:))) 2574 (forward-char) 2575 (setq first nil)))) 2576 2577(defun c-font-lock-objc-methods (limit) 2578 ;; Fontify method declarations in Objective-C. Nil is always 2579 ;; returned. 2580 ;; 2581 ;; This function might do hidden buffer changes. 2582 2583 (let (;; The font-lock package in Emacs is known to clobber 2584 ;; `parse-sexp-lookup-properties' (when it exists). 2585 (parse-sexp-lookup-properties 2586 (cc-eval-when-compile 2587 (boundp 'parse-sexp-lookup-properties)))) 2588 2589 (c-find-decl-spots 2590 limit 2591 "[-+]" 2592 nil 2593 (lambda (_match-pos _inside-macro &optional _top-level) 2594 (forward-char) 2595 (c-font-lock-objc-method)))) 2596 nil) 2597 2598(c-override-default-keywords 'objc-font-lock-keywords) 2599 2600(defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc) 2601 "Minimal font locking for Objective-C mode. 2602Fontifies only compiler directives (in addition to the syntactic 2603fontification of strings and comments).") 2604 2605(defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc) 2606 "Fast normal font locking for Objective-C mode. 2607In addition to `objc-font-lock-keywords-1', this adds fontification of 2608keywords, simple types, declarations that are easy to recognize, the 2609user defined types on `objc-font-lock-extra-types', and the doc 2610comment styles specified by `c-doc-comment-style'.") 2611 2612(defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc) 2613 "Accurate normal font locking for Objective-C mode. 2614Like the variable `objc-font-lock-keywords-2' but detects declarations in a more 2615accurate way that works in most cases for arbitrary types without the 2616need for `objc-font-lock-extra-types'.") 2617 2618(defvar objc-font-lock-keywords objc-font-lock-keywords-3 2619 "Default expressions to highlight in Objective-C mode.") 2620 2621(defun objc-font-lock-keywords-2 () 2622 (c-compose-keywords-list objc-font-lock-keywords-2)) 2623(defun objc-font-lock-keywords-3 () 2624 (c-compose-keywords-list objc-font-lock-keywords-3)) 2625(defun objc-font-lock-keywords () 2626 (c-compose-keywords-list objc-font-lock-keywords)) 2627 2628;; Kludge to override the default value that 2629;; `objc-font-lock-extra-types' might have gotten from the font-lock 2630;; package. The value replaced here isn't relevant now anyway since 2631;; those types are builtin and therefore listed directly in 2632;; `c-primitive-type-kwds'. 2633(when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp) 2634 '("BOOL" "Class" "IMP" "SEL")) 2635 (setq objc-font-lock-extra-types 2636 (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*"))))) 2637 2638 2639;;; Java. 2640 2641(c-override-default-keywords 'java-font-lock-keywords) 2642 2643(defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java) 2644 "Minimal font locking for Java mode. 2645Fontifies nothing except the syntactic fontification of strings and 2646comments.") 2647 2648(defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java) 2649 "Fast normal font locking for Java mode. 2650In addition to `java-font-lock-keywords-1', this adds fontification of 2651keywords, simple types, declarations that are easy to recognize, the 2652user defined types on `java-font-lock-extra-types', and the doc 2653comment styles specified by `c-doc-comment-style'.") 2654 2655(defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java) 2656 "Accurate normal font locking for Java mode. 2657Like variable `java-font-lock-keywords-2' but detects declarations in a more 2658accurate way that works in most cases for arbitrary types without the 2659need for `java-font-lock-extra-types'.") 2660 2661(defvar java-font-lock-keywords java-font-lock-keywords-3 2662 "Default expressions to highlight in Java mode.") 2663 2664(defun java-font-lock-keywords-2 () 2665 (c-compose-keywords-list java-font-lock-keywords-2)) 2666(defun java-font-lock-keywords-3 () 2667 (c-compose-keywords-list java-font-lock-keywords-3)) 2668(defun java-font-lock-keywords () 2669 (c-compose-keywords-list java-font-lock-keywords)) 2670 2671 2672;;; CORBA IDL. 2673 2674(c-override-default-keywords 'idl-font-lock-keywords) 2675 2676(defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl) 2677 "Minimal font locking for CORBA IDL mode. 2678Fontifies nothing except the syntactic fontification of strings and 2679comments.") 2680 2681(defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl) 2682 "Fast normal font locking for CORBA IDL mode. 2683In addition to `idl-font-lock-keywords-1', this adds fontification of 2684keywords, simple types, declarations that are easy to recognize, the 2685user defined types on `idl-font-lock-extra-types', and the doc comment 2686styles specified by `c-doc-comment-style'.") 2687 2688(defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl) 2689 "Accurate normal font locking for CORBA IDL mode. 2690Like the variable `idl-font-lock-keywords-2' but detects declarations in a more 2691accurate way that works in most cases for arbitrary types without the 2692need for `idl-font-lock-extra-types'.") 2693 2694(defvar idl-font-lock-keywords idl-font-lock-keywords-3 2695 "Default expressions to highlight in CORBA IDL mode.") 2696 2697(defun idl-font-lock-keywords-2 () 2698 (c-compose-keywords-list idl-font-lock-keywords-2)) 2699(defun idl-font-lock-keywords-3 () 2700 (c-compose-keywords-list idl-font-lock-keywords-3)) 2701(defun idl-font-lock-keywords () 2702 (c-compose-keywords-list idl-font-lock-keywords)) 2703 2704 2705;;; Pike. 2706 2707(c-override-default-keywords 'pike-font-lock-keywords) 2708 2709(defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike) 2710 "Minimal font locking for Pike mode. 2711Fontifies only preprocessor directives (in addition to the syntactic 2712fontification of strings and comments).") 2713 2714(defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike) 2715 "Fast normal font locking for Pike mode. 2716In addition to `pike-font-lock-keywords-1', this adds fontification of 2717keywords, simple types, declarations that are easy to recognize, the 2718user defined types on `pike-font-lock-extra-types', and the doc 2719comment styles specified by `c-doc-comment-style'.") 2720 2721(defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike) 2722 "Accurate normal font locking for Pike mode. 2723Like the variable `pike-font-lock-keywords-2' but detects declarations in a more 2724accurate way that works in most cases for arbitrary types without the 2725need for `pike-font-lock-extra-types'.") 2726 2727(defvar pike-font-lock-keywords pike-font-lock-keywords-3 2728 "Default expressions to highlight in Pike mode.") 2729 2730(defun pike-font-lock-keywords-2 () 2731 (c-set-doc-comment-res) 2732 (c-compose-keywords-list pike-font-lock-keywords-2)) 2733(defun pike-font-lock-keywords-3 () 2734 (c-set-doc-comment-res) 2735 (c-compose-keywords-list pike-font-lock-keywords-3)) 2736(defun pike-font-lock-keywords () 2737 (c-set-doc-comment-res) 2738 (c-compose-keywords-list pike-font-lock-keywords)) 2739 2740 2741;;; Doc comments. 2742 2743(cc-bytecomp-defvar c-doc-line-join-re) 2744;; matches a join of two lines in a doc comment. 2745;; This should not be changed directly, but instead set by 2746;; `c-setup-doc-comment-style'. This variable is used in `c-find-decl-spots' 2747;; in (e.g.) autodoc style comments to bridge the gap between a "@\n" at an 2748;; EOL and the token following "//!" on the next line. 2749 2750(cc-bytecomp-defvar c-doc-bright-comment-start-re) 2751;; Matches the start of a "bright" comment, one whose contents may be 2752;; fontified by, e.g., `c-font-lock-declarations'. 2753 2754(cc-bytecomp-defvar c-doc-line-join-end-ch) 2755;; A list of characters, each being a last character of a doc comment marker, 2756;; e.g. the ! from pike autodoc's "//!". 2757 2758(defmacro c-set-doc-comment-re-element (suffix) 2759 ;; Set the variable `c-doc-line-join-re' to a buffer local value suitable 2760 ;; for the current doc comment style, or kill the local value. 2761 (declare (debug t)) 2762 (let ((var (intern (concat "c-doc" suffix)))) 2763 `(let* ((styles (c-get-doc-comment-style)) 2764 elts) 2765 (when (atom styles) 2766 (setq styles (list styles))) 2767 (setq elts 2768 (mapcar (lambda (style) 2769 (let ((sym 2770 (intern-soft 2771 (concat (symbol-name style) ,suffix)))) 2772 (and sym 2773 (boundp sym) 2774 (symbol-value sym)))) 2775 styles)) 2776 (setq elts (delq nil elts)) 2777 (setq elts (and elts 2778 (concat "\\(" 2779 (mapconcat #'identity elts "\\|") 2780 "\\)"))) 2781 (if elts 2782 (set (make-local-variable ',var) elts) 2783 (kill-local-variable ',var))))) 2784 2785(defmacro c-set-doc-comment-char-list (suffix) 2786 ;; Set the variable 'c-doc-<suffix>' to the list of *-<suffix>, which must 2787 ;; be characters, and * represents the doc comment style. 2788 (declare (debug t)) 2789 (let ((var (intern (concat "c-doc" suffix)))) 2790 `(let* ((styles (c-get-doc-comment-style)) 2791 elts) 2792 (when (atom styles) 2793 (setq styles (list styles))) 2794 (setq elts 2795 (mapcar (lambda (style) 2796 (let ((sym 2797 (intern-soft 2798 (concat (symbol-name style) ,suffix)))) 2799 (and sym 2800 (boundp sym) 2801 (symbol-value sym)))) 2802 styles)) 2803 (setq elts (delq nil elts)) 2804 (if elts 2805 (set (make-local-variable ',var) elts) 2806 (kill-local-variable ',var))))) 2807 2808(defun c-set-doc-comment-res () 2809 ;; Set the variables `c-doc-line-join-re' and 2810 ;; `c-doc-bright-comment-start-re' from the current doc comment style(s). 2811 (c-set-doc-comment-re-element "-line-join-re") 2812 (c-set-doc-comment-re-element "-bright-comment-start-re") 2813 (c-set-doc-comment-char-list "-line-join-end-ch")) 2814 2815(defun c-font-lock-doc-comments (prefix limit keywords) 2816 ;; Fontify the comments between the point and LIMIT whose start 2817 ;; matches PREFIX with `c-doc-face-name'. Assumes comments have been 2818 ;; fontified with `font-lock-comment-face' already. nil is always 2819 ;; returned. 2820 ;; 2821 ;; After the fontification of a matching comment, fontification 2822 ;; according to KEYWORDS is applied inside it. It's a list like 2823 ;; `font-lock-keywords' except that anchored matches and eval 2824 ;; clauses aren't supported and that some abbreviated forms can't be 2825 ;; used. The buffer is narrowed to the comment while KEYWORDS is 2826 ;; applied; leading comment starters are included but trailing 2827 ;; comment enders for block comment are not. 2828 ;; 2829 ;; Note that faces added through KEYWORDS should never replace the 2830 ;; existing `c-doc-face-name' face since the existence of that face 2831 ;; is used as a flag in other code to skip comments. 2832 ;; 2833 ;; This function might do hidden buffer changes. 2834 (declare (indent 2)) 2835 (let (comment-beg region-beg comment-mid) 2836 (if (memq (get-text-property (point) 'face) 2837 '(font-lock-comment-face font-lock-comment-delimiter-face)) 2838 ;; Handle the case when the fontified region starts inside a 2839 ;; comment. 2840 (let ((start (c-literal-start))) 2841 (setq region-beg (point) 2842 comment-mid (point)) 2843 (when start 2844 (goto-char start)) 2845 (when (looking-at prefix) 2846 (setq comment-beg (point))))) 2847 2848 (while (or 2849 comment-beg 2850 2851 ;; Search for the prefix until a match is found at the start 2852 ;; of a comment. 2853 (while (when (re-search-forward prefix limit t) 2854 (setq comment-beg (match-beginning 0)) 2855 (or (not (c-got-face-at comment-beg 2856 c-literal-faces)) 2857 (and (/= comment-beg (point-min)) 2858 ;; Cheap check which is unreliable (the previous 2859 ;; character could be the end of a previous 2860 ;; comment). 2861 (c-got-face-at (1- comment-beg) 2862 c-literal-faces) 2863 ;; Expensive reliable check. 2864 (save-excursion 2865 (goto-char comment-beg) 2866 (c-in-literal))))) 2867 (setq comment-beg nil)) 2868 (setq region-beg comment-beg 2869 comment-mid comment-beg)) 2870 2871 (if (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) 2872 ;; Collect a sequence of doc style line comments. 2873 (progn 2874 (goto-char comment-beg) 2875 (while (and (progn 2876 (c-forward-single-comment) 2877 (c-put-font-lock-face comment-mid (point) 2878 c-doc-face-name) 2879 (skip-syntax-forward " ") 2880 (setq comment-beg (point) 2881 comment-mid (point)) 2882 (< (point) limit)) 2883 (looking-at prefix)))) 2884 (goto-char comment-beg) 2885 (c-forward-single-comment) 2886 (c-put-font-lock-face region-beg (point) c-doc-face-name)) 2887 (if (> (point) limit) (goto-char limit)) 2888 (setq comment-beg nil) 2889 2890 (let ((region-end (point)) 2891 (keylist keywords) keyword matcher highlights) 2892 (save-restriction 2893 ;; Narrow to the doc comment. Among other things, this 2894 ;; helps by making "^" match at the start of the comment. 2895 ;; Do not include a trailing block comment ender, though. 2896 (and (> region-end (1+ region-beg)) 2897 (progn (goto-char region-end) 2898 (backward-char 2) 2899 (looking-at "\\*/")) 2900 (setq region-end (point))) 2901 (narrow-to-region region-beg region-end) 2902 2903 (while keylist 2904 (setq keyword (car keylist) 2905 keylist (cdr keylist) 2906 matcher (car keyword)) 2907 (goto-char region-beg) 2908 (while (if (stringp matcher) 2909 (re-search-forward matcher region-end t) 2910 (funcall matcher region-end)) 2911 (setq highlights (cdr keyword)) 2912 (if (consp (car highlights)) 2913 (while highlights 2914 (font-lock-apply-highlight (car highlights)) 2915 (setq highlights (cdr highlights))) 2916 (font-lock-apply-highlight highlights)))) 2917 2918 (goto-char region-end))))) 2919 nil) 2920 2921(defun c-find-invalid-doc-markup (regexp limit) 2922 ;; Used to fontify invalid markup in doc comments after the correct 2923 ;; ones have been fontified: Find the first occurrence of REGEXP 2924 ;; between the point and LIMIT that only is fontified with 2925 ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds 2926 ;; the first char and t is returned, otherwise nil is returned. 2927 ;; 2928 ;; This function might do hidden buffer changes. 2929 (let (start) 2930 (while (if (re-search-forward regexp limit t) 2931 (not (eq (get-text-property 2932 (setq start (match-beginning 0)) 'face) 2933 c-doc-face-name)) 2934 (setq start nil))) 2935 (when start 2936 (store-match-data (list (copy-marker start) 2937 (copy-marker (1+ start)))) 2938 t))) 2939 2940;; GtkDoc patterns contributed by Masatake YAMATO <yamato@redhat.com>. 2941 2942(defconst gtkdoc-font-lock-doc-comments 2943 (let ((symbol "[a-zA-Z0-9_]+") 2944 (header "^ \\* ")) 2945 `((,(concat header "\\(" symbol "\\):[ \t]*$") 2946 1 ,c-doc-markup-face-name prepend nil) 2947 (,(concat symbol "()") 2948 0 ,c-doc-markup-face-name prepend nil) 2949 (,(concat header "\\(" "@" symbol "\\):") 2950 1 ,c-doc-markup-face-name prepend nil) 2951 (,(concat "[#%@]" symbol) 2952 0 ,c-doc-markup-face-name prepend nil)) 2953 )) 2954 2955(defconst gtkdoc-font-lock-doc-protection 2956 `(("< \\(public\\|private\\|protected\\) >" 2957 1 ,c-doc-markup-face-name prepend nil))) 2958 2959(defconst gtkdoc-font-lock-keywords 2960 `((,(lambda (limit) 2961 (c-font-lock-doc-comments "/\\*\\*\\([^*/\n\r].*\\)?$" limit 2962 gtkdoc-font-lock-doc-comments) 2963 (c-font-lock-doc-comments "/\\*< " limit 2964 gtkdoc-font-lock-doc-protection) 2965 )))) 2966 2967;; Javadoc. 2968 2969(defconst javadoc-font-lock-doc-comments 2970 `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup. 2971 0 ,c-doc-markup-face-name prepend nil) 2972 ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup. 2973 3 ,c-doc-markup-face-name prepend nil) 2974 (,(concat "</?\\sw" ; HTML tags. 2975 "\\(" 2976 (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|" 2977 "\"[^\"]*\"\\|'[^']*'") 2978 "\\)*>") 2979 0 ,c-doc-markup-face-name prepend nil) 2980 ("&\\(\\sw\\|[.:]\\)+;" ; HTML entities. 2981 0 ,c-doc-markup-face-name prepend nil) 2982 ;; Fontify remaining markup characters as invalid. Note 2983 ;; that the Javadoc spec is hazy about when "@" is 2984 ;; allowed in non-markup use. 2985 (,(lambda (limit) 2986 (c-find-invalid-doc-markup "[<>&]\\|{@" limit)) 2987 0 'font-lock-warning-face prepend nil))) 2988 2989(defconst javadoc-font-lock-keywords 2990 `((,(lambda (limit) 2991 (c-font-lock-doc-comments "/\\*\\*" limit 2992 javadoc-font-lock-doc-comments))))) 2993 2994;; Pike autodoc. 2995 2996(defconst autodoc-decl-keywords 2997 ;; Adorned regexp matching the keywords that introduce declarations 2998 ;; in Pike Autodoc. 2999 (cc-eval-when-compile 3000 (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode))) 3001 3002(defconst autodoc-decl-type-keywords 3003 ;; Adorned regexp matching the keywords that are followed by a type. 3004 (cc-eval-when-compile 3005 (c-make-keywords-re t '("@elem" "@member") 'pike-mode))) 3006 3007(defun autodoc-font-lock-line-markup (limit) 3008 ;; Fontify all line oriented keywords between the point and LIMIT. 3009 ;; Nil is always returned. 3010 ;; 3011 ;; This function might do hidden buffer changes. 3012 3013 (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\(" 3014 c-current-comment-prefix 3015 "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)")) 3016 (markup-faces (list c-doc-markup-face-name c-doc-face-name))) 3017 3018 (while (and (< (point) limit) 3019 (re-search-forward line-re limit t)) 3020 (goto-char (match-end 1)) 3021 3022 (if (looking-at autodoc-decl-keywords) 3023 (let* ((kwd-pos (point)) 3024 (start (match-end 1)) 3025 (pos start) 3026 end) 3027 3028 (c-put-font-lock-face (point) pos markup-faces) 3029 3030 ;; Put a declaration end mark at the markup keyword and 3031 ;; remove the faces from the rest of the line so that it 3032 ;; gets refontified as a declaration later on by 3033 ;; `c-font-lock-declarations'. 3034 (c-put-char-property (1- pos) 'c-type 'c-decl-end) 3035 (goto-char pos) 3036 (while (progn 3037 (end-of-line) 3038 (setq end (point)) 3039 (and (eq (char-before) ?@) 3040 (not (eobp)) 3041 (progn (forward-char) 3042 (skip-syntax-forward " ") 3043 (looking-at c-current-comment-prefix)))) 3044 (goto-char (match-end 0)) 3045 (c-remove-font-lock-face pos (1- end)) 3046 (c-put-font-lock-face (1- end) end markup-faces) 3047 (setq pos (point))) 3048 3049 ;; Include the final newline in the removed area. This 3050 ;; has no visual effect but it avoids some tricky special 3051 ;; cases in the testsuite wrt the differences in string 3052 ;; fontification in Emacs vs XEmacs. 3053 (c-remove-font-lock-face pos (min (1+ (point)) (point-max))) 3054 3055 ;; Must handle string literals explicitly inside the declaration. 3056 (goto-char start) 3057 (while (re-search-forward 3058 "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'" 3059 end 'move) 3060 (c-put-font-lock-string-face (match-beginning 0) 3061 (point))) 3062 3063 ;; Fontify types after keywords that always are followed 3064 ;; by them. 3065 (goto-char kwd-pos) 3066 (when (looking-at autodoc-decl-type-keywords) 3067 (c-fontify-types-and-refs ((c-promote-possible-types t)) 3068 (goto-char start) 3069 (c-forward-syntactic-ws) 3070 (c-forward-type)))) 3071 3072 ;; Mark each whole line as markup, as long as the logical line 3073 ;; continues. 3074 (while (progn 3075 (c-put-font-lock-face (point) 3076 (progn (end-of-line) (point)) 3077 markup-faces) 3078 (and (eq (char-before) ?@) 3079 (not (eobp)) 3080 (progn (forward-char) 3081 (skip-syntax-forward " ") 3082 (looking-at c-current-comment-prefix)))) 3083 (goto-char (match-end 0)))))) 3084 3085 nil) 3086 3087(defconst autodoc-font-lock-doc-comments 3088 `(("@\\(\\w+{\\|\\[\\([^]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)" 3089 ;; In-text markup. 3090 0 ,c-doc-markup-face-name prepend nil) 3091 (autodoc-font-lock-line-markup) 3092 ;; Fontify remaining markup characters as invalid. 3093 (,(lambda (limit) 3094 (c-find-invalid-doc-markup "@" limit)) 3095 0 'font-lock-warning-face prepend nil) 3096 )) 3097 3098(defconst autodoc-line-join-re "@[\n\r][ \t]*/[/*]!") 3099;; Matches a line continuation in autodoc comment style. 3100(defconst autodoc-bright-comment-start-re "/[/*]!") 3101;; Matches an autodoc comment opener. 3102(defconst autodoc-line-join-end-ch ?!) 3103;; The final character of `autodoc-line-join-re'. 3104 3105(defun autodoc-font-lock-keywords () 3106 ;; Note that we depend on that `c-current-comment-prefix' has got 3107 ;; its proper value here. 3108 ;; 3109 ;; This function might do hidden buffer changes. 3110 3111 ;; The `c-type' text property with `c-decl-end' is used to mark the 3112 ;; end of the `autodoc-decl-keywords' occurrences to fontify the 3113 ;; following declarations. 3114 (setq c-type-decl-end-used t) 3115 3116 `((,(lambda (limit) 3117 (c-font-lock-doc-comments "/[*/]!" limit 3118 autodoc-font-lock-doc-comments))))) 3119 3120;; Doxygen 3121 3122(defconst doxygen-font-lock-doc-comments 3123 ;; TODO: Handle @code, @verbatim, @dot, @f etc. better by not highlighting 3124 ;; text inside of those commands. Something smarter than just regexes may be 3125 ;; needed to do that efficiently. 3126 `((,(concat 3127 ;; Make sure that the special character has not been escaped. E.g. in 3128 ;; `\@foo' only `\@' is a command (similarly for other characters like 3129 ;; `\\foo', `\<foo' and `\&foo'). The downside now is that we don't 3130 ;; match command started just after an escaped character, e.g. in 3131 ;; `\@\foo' we should match `\@' as well as `\foo' but only the former 3132 ;; is matched. 3133 "\\(?:^\\|[^\\@]\\)\\(" 3134 ;; Doxygen commands start with backslash or an at sign. Note that for 3135 ;; brevity in the comments only `\' will be mentioned. 3136 "[\\@]\\(?:" 3137 ;; Doxygen commands except those starting with `f' 3138 "[a-eg-z][a-z]*" 3139 ;; Doxygen command starting with `f': 3140 "\\|f\\(?:" 3141 "[][$}]" ; \f$ \f} \f[ \f] 3142 "\\|{\\(?:[a-zA-Z]+\\*?}{?\\)?" ; \f{ \f{env} \f{env}{ 3143 "\\|[a-z]+" ; \foo 3144 "\\)" 3145 "\\|~[a-zA-Z]*" ; \~ \~language 3146 "\\|[$@&~<=>#%\".|\\\\]" ; single-character escapes 3147 "\\|::\\|---?" ; \:: \-- \--- 3148 "\\)" 3149 ;; HTML tags and entities: 3150 "\\|</?\\sw\\(?:\\sw\\|\\s \\|[=\n\r*.:]\\|\"[^\"]*\"\\|'[^']*'\\)*>" 3151 "\\|&\\(?:\\sw+\\|#[0-9]+\\|#x[0-9a-fA-F]+\\);" 3152 "\\)") 3153 1 ,c-doc-markup-face-name prepend nil) 3154 ;; Commands inside of strings are not commands so override highlighting with 3155 ;; string face. This also affects HTML attribute values if they are 3156 ;; surrounded with double quotes which may or may not be considered a good 3157 ;; thing. 3158 ("\\(?:^\\|[^\\@]\\)\\(\"[^\"[:cntrl:]]+\"\\)" 3159 1 font-lock-string-face prepend nil) 3160 ;; HTML comments inside of the Doxygen comments. 3161 ("\\(?:^\\|[^\\@]\\)\\(<!--.*?-->\\)" 3162 1 font-lock-comment-face prepend nil) 3163 ;; Autolinking. Doxygen auto-links anything that is a class name but we have 3164 ;; no hope of matching those. We are, however, able to match functions and 3165 ;; members using explicit scoped syntax. For functions, we can also find 3166 ;; them by noticing argument-list. Note that Doxygen accepts `::' as well 3167 ;; as `#' as scope operators. 3168 (,(let* ((ref "[\\@]ref\\s-+") 3169 (ref-opt (concat "\\(?:" ref "\\)?")) 3170 (id "[a-zA-Z_][a-zA-Z_0-9]*") 3171 (args "\\(?:()\\|([^()]*)\\)") 3172 (scope "\\(?:#\\|::\\)")) 3173 (concat 3174 "\\(?:^\\|[^\\@/%:]\\)\\(?:" 3175 ref-opt "\\(?1:" scope "?" "\\(?:" id scope "\\)+" "~?" id "\\)" 3176 "\\|" ref-opt "\\(?1:" scope "~?" id "\\)" 3177 "\\|" ref-opt "\\(?1:" scope "?" "~?" id "\\)" args 3178 "\\|" ref "\\(?1:" "~?" id "\\)" 3179 "\\|" ref-opt "\\(?1:~[A-Z][a-zA-Z0-9_]+\\)" 3180 "\\)")) 3181 1 font-lock-function-name-face prepend nil) 3182 ;; Match URLs and emails. This has two purposes. First of all, Doxygen 3183 ;; autolinks URLs. Second of all, `@bar' in `foo@bar.baz' has been matched 3184 ;; above as a command; try and overwrite it. 3185 (,(let* ((host "[A-Za-z0-9]\\(?:[A-Za-z0-9-]\\{0,61\\}[A-Za-z0-9]\\)") 3186 (fqdn (concat "\\(?:" host "\\.\\)+" host)) 3187 (comp "[!-(*--/-=?-~]+") 3188 (path (concat "/\\(?:" comp "[.]+" "\\)*" comp))) 3189 (concat "\\(?:mailto:\\)?[a-zA-0_.]+@" fqdn 3190 "\\|https?://" fqdn "\\(?:" path "\\)?")) 3191 0 font-lock-keyword-face prepend nil))) 3192 3193(defconst doxygen-font-lock-keywords 3194 `((,(lambda (limit) 3195 (c-font-lock-doc-comments "/\\(?:/[/!]\\|\\*[\\*!]\\)" 3196 limit doxygen-font-lock-doc-comments))))) 3197 3198 3199;; 2006-07-10: awk-font-lock-keywords has been moved back to cc-awk.el. 3200(cc-provide 'cc-fonts) 3201 3202;; Local Variables: 3203;; indent-tabs-mode: t 3204;; tab-width: 8 3205;; End: 3206;;; cc-fonts.el ends here 3207