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