/[emacs]/emacs/lisp/progmodes/cc-fonts.el
ViewVC logotype

Diff of /emacs/lisp/progmodes/cc-fonts.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.13 by nickrob, Mon Aug 1 08:37:49 2005 UTC revision 1.14 by acmacm, Fri Dec 2 12:30:36 2005 UTC
# Line 1  Line 1 
1  ;;; cc-fonts.el --- font lock support for CC Mode  ;;; cc-fonts.el --- font lock support for CC Mode
2    
3  ;; Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.  ;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4    
5  ;; Authors:    2003- Alan Mackenzie  ;; Authors:    2003- Alan Mackenzie
6  ;;             2002- Martin Stjernholm  ;;             2002- Martin Stjernholm
# Line 30  Line 30 
30    
31  ;; Some comments on the use of faces:  ;; Some comments on the use of faces:
32  ;;  ;;
33  ;; o  `c-label-face-name' is either `font-lock-constant-face' (in Emacs  ;; o  `c-label-face-name' is either `font-lock-constant-face' (in
34  ;;    20 and later), or `font-lock-reference-face'.  ;;    Emacs), or `font-lock-reference-face'.
35  ;;  ;;
36  ;; o  `c-constant-face-name', `c-reference-face-name' and  ;; o  `c-constant-face-name', `c-reference-face-name' and
37  ;;    `c-doc-markup-face-name' are essentially set up like  ;;    `c-doc-markup-face-name' are essentially set up like
# Line 47  Line 47 
47  ;;    documentation are actually comments in these languages, as opposed  ;;    documentation are actually comments in these languages, as opposed
48  ;;    to elisp).  ;;    to elisp).
49  ;;  ;;
 ;; o  `c-invalid-face-name' is `font-lock-warning-face' in Emacs.  In  
 ;;    older XEmacs there's no corresponding standard face, so there  
 ;;    it's mapped to a special `c-invalid-face'.  
 ;;  
50  ;; TBD: We should probably provide real faces for the above uses and  ;; TBD: We should probably provide real faces for the above uses and
51  ;; instead initialize them from the standard faces.  ;; instead initialize them from the standard faces.
52    
# Line 103  Line 99 
99  (cc-bytecomp-defvar c-reference-face-name)  (cc-bytecomp-defvar c-reference-face-name)
100  (cc-bytecomp-defun c-fontify-recorded-types-and-refs)  (cc-bytecomp-defun c-fontify-recorded-types-and-refs)
101  (cc-bytecomp-defun c-font-lock-declarators)  (cc-bytecomp-defun c-font-lock-declarators)
 (cc-bytecomp-defun c-font-lock-objc-iip-decl)  
102  (cc-bytecomp-defun c-font-lock-objc-method)  (cc-bytecomp-defun c-font-lock-objc-method)
103  (cc-bytecomp-defun c-font-lock-invalid-string)  (cc-bytecomp-defun c-font-lock-invalid-string)
104    
 ;; Emacs 19 doesn't have `defface'.  This "replacement" leaves a lot  
 ;; to be wished for but at least it avoids any errors.  
 (cc-eval-when-compile  
   (or (fboundp 'defface)  
       (cc-bytecomp-defmacro defface (face spec doc &rest args)  
         `(make-face ',face))))  
   
105    
106  ;; Note that font-lock in XEmacs doesn't expand face names as  ;; Note that font-lock in XEmacs doesn't expand face names as
107  ;; variables, so we have to use the (eval . FORM) in the font lock  ;; variables, so we have to use the (eval . FORM) in the font lock
# Line 124  Line 112 
112           ;; XEmacs has a font-lock-preprocessor-face.           ;; XEmacs has a font-lock-preprocessor-face.
113           'font-lock-preprocessor-face)           'font-lock-preprocessor-face)
114          ((c-face-name-p 'font-lock-builtin-face)          ((c-face-name-p 'font-lock-builtin-face)
115           ;; In Emacs 20 and later font-lock-builtin-face has           ;; In Emacs font-lock-builtin-face has traditionally been
116           ;; traditionally been used for preprocessor directives.           ;; used for preprocessor directives.
117           'font-lock-builtin-face)           'font-lock-builtin-face)
118          (t          (t
119           'font-lock-reference-face)))           'font-lock-reference-face)))
# Line 150  Line 138 
138  (defconst c-constant-face-name  (defconst c-constant-face-name
139    (if (and (c-face-name-p 'font-lock-constant-face)    (if (and (c-face-name-p 'font-lock-constant-face)
140             (eq font-lock-constant-face 'font-lock-constant-face))             (eq font-lock-constant-face 'font-lock-constant-face))
141        ;; This doesn't exist in XEmacs <= 20 and some earlier versions        ;; This doesn't exist in some earlier versions of XEmacs 21.
       ;; of XEmacs 21.  
142        'font-lock-constant-face        'font-lock-constant-face
143      c-label-face-name))      c-label-face-name))
144    
145  (defconst c-reference-face-name  (defconst c-reference-face-name
146    (if (and (c-face-name-p 'font-lock-reference-face)    (with-no-warnings
147             (eq font-lock-reference-face 'font-lock-reference-face))     (if (and (c-face-name-p 'font-lock-reference-face)
148        ;; This is considered obsolete in Emacs 20 and later, but it              (eq font-lock-reference-face 'font-lock-reference-face))
149        ;; still maps well to this use.  (Another reason to do this is         ;; This is considered obsolete in Emacs, but it still maps well
150        ;; to get unique faces for the test suite.)         ;; to this use.  (Another reason to do this is to get unique
151        'font-lock-reference-face         ;; faces for the test suite.)
152      c-label-face-name))         'font-lock-reference-face
153         c-label-face-name)))
154    
155  ;; This should not mapped to a face that also is used to fontify things  ;; This should not mapped to a face that also is used to fontify things
156  ;; that aren't comments or string literals.  ;; that aren't comments or string literals.
# Line 184  Line 172 
172           'font-lock-doc-markup-face           'font-lock-doc-markup-face
173      c-label-face-name))      c-label-face-name))
174    
175  (defconst c-invalid-face-name  (defconst c-negation-char-face-name
176    (if (c-face-name-p 'font-lock-warning-face)    (if (c-face-name-p 'font-lock-negation-char-face)
177        ;; Emacs >= 20 and XEmacs >= 21 has a font-lock-warning-face.        ;; Emacs 22 has a special face for negation chars.
178        'font-lock-warning-face        'font-lock-negation-char-face))
     ;; Otherwise we provide a face.  
     'c-invalid-face))  
   
 (unless (c-face-name-p c-invalid-face-name)  
   (defconst c-invalid-face 'c-invalid-face) ; Necessary in Emacs 19.  
   ;; This face should be called `c-invalid' for consistency with the  
   ;; rest of emacs, but as it's only used in very old versions of Emacs,  
   ;; we leave it unchanged (the face-alias mechanism doesn't exist in  
   ;; those old versions).  
   (defface c-invalid-face  
     '((((class color) (background light)) (:foreground "red1"))  
       (((class color)) (:foreground "hotpink"))  
       (t (:inverse-video t)))  
     "Face used to highlight invalid syntax."  
     :group 'c-fonts))  
   
 ;; To make hard spaces visible an inverted version of  
 ;; `c-invalid-face-name' is used.  Since font-lock in Emacs expands  
 ;; all face names in `font-lock-keywords' as variables we need to have  
 ;; a variable for it.  
 (defconst c-nonbreakable-space-face 'c-nonbreakable-space)  
179    
180  (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.  (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
181  (cc-bytecomp-defun face-property-instance) ; Only in XEmacs.  (cc-bytecomp-defun face-property-instance) ; Only in XEmacs.
# Line 216  Line 183 
183  (defun c-make-inverse-face (oldface newface)  (defun c-make-inverse-face (oldface newface)
184    ;; Emacs and XEmacs have completely different face manipulation    ;; Emacs and XEmacs have completely different face manipulation
185    ;; routines. :P    ;; routines. :P
   ;;  
   ;; This function does not do any hidden buffer changes  
186    (copy-face oldface newface)    (copy-face oldface newface)
187    (cond ((fboundp 'face-inverse-video-p)    (cond ((fboundp 'face-inverse-video-p)
188           ;; Emacs 20 and later.  This only looks at the inverse flag           ;; Emacs.  This only looks at the inverse flag in the current
189           ;; in the current frame.  Other display configurations might           ;; frame.  Other display configurations might be different,
190           ;; be different, but it can only show if the same Emacs has           ;; but it can only show if the same Emacs has frames on
191           ;; frames on e.g. a color and a monochrome display           ;; e.g. a color and a monochrome display simultaneously.
          ;; simultaneously.  
192           (unless (face-inverse-video-p oldface)           (unless (face-inverse-video-p oldface)
193             (invert-face newface)))             (invert-face newface)))
194          ((fboundp 'face-property-instance)          ((fboundp 'face-property-instance)
195           ;; XEmacs.  Same pitfall here.           ;; XEmacs.  Same pitfall here.
196           (unless (face-property-instance oldface 'reverse)           (unless (face-property-instance oldface 'reverse)
197             (invert-face newface)))             (invert-face newface)))))
         (t  
          ;; Emacs 19 has no inverse flag at all.  Just inverse the  
          ;; face and hope it wasn't inversed already.  
          (invert-face newface))))  
198    
199  (eval-and-compile  (eval-and-compile
200    ;; We need the following functions during compilation since they're    ;; We need the following functions during compilation since they're
# Line 247  Line 207 
207      ;; additional font-lock property, or else the font-lock package      ;; additional font-lock property, or else the font-lock package
208      ;; won't recognize it as fontified and might override it      ;; won't recognize it as fontified and might override it
209      ;; incorrectly.      ;; incorrectly.
210        ;;
211        ;; This function does a hidden buffer change.
212      (if (fboundp 'font-lock-set-face)      (if (fboundp 'font-lock-set-face)
213          ;; Note: This function has no docstring in XEmacs so it might be          ;; Note: This function has no docstring in XEmacs so it might be
214          ;; considered internal.          ;; considered internal.
# Line 255  Line 217 
217    
218    (defmacro c-remove-font-lock-face (from to)    (defmacro c-remove-font-lock-face (from to)
219      ;; This is the inverse of `c-put-font-lock-face'.      ;; This is the inverse of `c-put-font-lock-face'.
220        ;;
221        ;; This function does a hidden buffer change.
222      (if (fboundp 'font-lock-remove-face)      (if (fboundp 'font-lock-remove-face)
223          `(font-lock-remove-face ,from ,to)          `(font-lock-remove-face ,from ,to)
224        `(remove-text-properties ,from ,to '(face nil))))        `(remove-text-properties ,from ,to '(face nil))))
# Line 263  Line 227 
227      ;; Put `font-lock-string-face' on a string.  The surrounding      ;; Put `font-lock-string-face' on a string.  The surrounding
228      ;; quotes are included in Emacs but not in XEmacs.  The passed      ;; quotes are included in Emacs but not in XEmacs.  The passed
229      ;; region should include them.      ;; region should include them.
230        ;;
231        ;; This function does a hidden buffer change.
232      (if (featurep 'xemacs)      (if (featurep 'xemacs)
233          `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)          `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
234        `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))        `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
# Line 271  Line 237 
237      ;; Like `let', but additionally activates `c-record-type-identifiers'      ;; Like `let', but additionally activates `c-record-type-identifiers'
238      ;; and `c-record-ref-identifiers', and fontifies the recorded ranges      ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
239      ;; accordingly on exit.      ;; accordingly on exit.
240        ;;
241        ;; This function does hidden buffer changes.
242      `(let ((c-record-type-identifiers t)      `(let ((c-record-type-identifiers t)
243             c-record-ref-identifiers             c-record-ref-identifiers
244             ,@varlist)             ,@varlist)
245         (prog1 (progn ,@body)         (prog1 (progn ,@body)
246           (c-fontify-recorded-types-and-refs))))           (c-fontify-recorded-types-and-refs))))
247    (put 'c-fontify-types-and-refs 'lisp-indent-function 1)    (put 'c-fontify-types-and-refs 'lisp-indent-function 1)
   (eval-after-load "edebug" '(def-edebug-spec c-fontify-types-and-refs let*))  
248    
249    (defun c-skip-comments-and-strings (limit)    (defun c-skip-comments-and-strings (limit)
250      ;; If the point is within a region fontified as a comment or      ;; If the point is within a region fontified as a comment or
251      ;; string literal skip to the end of it or to LIMIT, whichever      ;; string literal skip to the end of it or to LIMIT, whichever
252      ;; comes first, and return t.  Otherwise return nil.  The match      ;; comes first, and return t.  Otherwise return nil.  The match
253      ;; data is not clobbered.      ;; data is not clobbered.
254        ;;
255        ;; This function might do hidden buffer changes.
256      (when (c-got-face-at (point) c-literal-faces)      (when (c-got-face-at (point) c-literal-faces)
257        (while (progn        (while (progn
258                 (goto-char (next-single-property-change                 (goto-char (next-single-property-change
# Line 292  Line 261 
261                      (c-got-face-at (point) c-literal-faces))))                      (c-got-face-at (point) c-literal-faces))))
262        t))        t))
263    
264      (defun c-make-syntactic-matcher (regexp)
265        ;; Returns a byte compiled function suitable for use in place of a
266        ;; regexp string in a `font-lock-keywords' matcher, except that
267        ;; only matches outside comments and string literals count.
268        ;;
269        ;; This function does not do any hidden buffer changes, but the
270        ;; generated functions will.  (They are however used in places
271        ;; covered by the font-lock context.)
272        (byte-compile
273         `(lambda (limit)
274            (let (res)
275              (while (and (setq res (re-search-forward ,regexp limit t))
276                          (progn
277                            (goto-char (match-beginning 0))
278                            (or (c-skip-comments-and-strings limit)
279                                (progn
280                                  (goto-char (match-end 0))
281                                  nil)))))
282              res))))
283    
284    (defun c-make-font-lock-search-function (regexp &rest highlights)    (defun c-make-font-lock-search-function (regexp &rest highlights)
285      ;; This function makes a byte compiled function that works much like      ;; This function makes a byte compiled function that works much like
286      ;; a matcher element in `font-lock-keywords'.  It cuts out a little      ;; a matcher element in `font-lock-keywords'.  It cuts out a little
# Line 315  Line 304 
304      ;; the anchored matcher forms.      ;; the anchored matcher forms.
305      ;;      ;;
306      ;; This function does not do any hidden buffer changes, but the      ;; This function does not do any hidden buffer changes, but the
307      ;; generated functions will.  They are however used in places      ;; generated functions will.  (They are however used in places
308      ;; covered by the font-lock context.      ;; covered by the font-lock context.)
309    
310      ;; Note: Replace `byte-compile' with `eval' to debug the generated      ;; Note: Replace `byte-compile' with `eval' to debug the generated
311      ;; lambda easier.      ;; lambda easier.
312      (byte-compile      (byte-compile
313       `(lambda (limit)       `(lambda (limit)
314          (let (-match-end-pos-          (let (;; The font-lock package in Emacs is known to clobber
               ;; The font-lock package in Emacs is known to clobber  
315                ;; `parse-sexp-lookup-properties' (when it exists).                ;; `parse-sexp-lookup-properties' (when it exists).
316                (parse-sexp-lookup-properties                (parse-sexp-lookup-properties
317                 (cc-eval-when-compile                 (cc-eval-when-compile
318                   (boundp 'parse-sexp-lookup-properties))))                   (boundp 'parse-sexp-lookup-properties))))
319            (while (re-search-forward ,regexp limit t)            (while (re-search-forward ,regexp limit t)
             (setq -match-end-pos- (point))  
320              (unless (progn              (unless (progn
321                        (goto-char (match-beginning 0))                        (goto-char (match-beginning 0))
322                        (c-skip-comments-and-strings limit))                        (c-skip-comments-and-strings limit))
323                (goto-char -match-end-pos-)                (goto-char (match-end 0))
324                ,@(mapcar                ,@(mapcar
325                   (lambda (highlight)                   (lambda (highlight)
326                     (if (integerp (car highlight))                     (if (integerp (car highlight))
327                         (progn                         (progn
328                           (unless (nth 2 highlight)                           (unless (eq (nth 2 highlight) t)
329                             (error                             (error
330                              "The override flag must currently be set in %s"                              "The override flag must currently be t in %s"
331                              highlight))                              highlight))
332                           (when (nth 3 highlight)                           (when (nth 3 highlight)
333                             (error                             (error
# Line 359  Line 346 
346                          (save-match-data ,(car highlight))                          (save-match-data ,(car highlight))
347                          ,(nth 2 highlight))))                          ,(nth 2 highlight))))
348                   highlights))))                   highlights))))
349          nil))))          nil)))
350    
351      (eval-after-load "edebug"
352        '(progn
353           (def-edebug-spec c-fontify-types-and-refs let*)
354           (def-edebug-spec c-make-syntactic-matcher t)
355           ;; If there are literal quoted or backquoted highlight specs in
356           ;; the call to `c-make-font-lock-search-function' then let's
357           ;; instrument the forms in them.
358           (def-edebug-spec c-make-font-lock-search-function
359             (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)))))
360    
361  (defun c-fontify-recorded-types-and-refs ()  (defun c-fontify-recorded-types-and-refs ()
362    ;; Converts the ranges recorded on `c-record-type-identifiers' and    ;; Convert the ranges recorded on `c-record-type-identifiers' and
363    ;; `c-record-ref-identifiers' to fontification.    ;; `c-record-ref-identifiers' to fontification.
364      ;;
365      ;; This function does hidden buffer changes.
366    (let (elem)    (let (elem)
367      (while (consp c-record-type-identifiers)      (while (consp c-record-type-identifiers)
368        (setq elem (car c-record-type-identifiers)        (setq elem (car c-record-type-identifiers)
# Line 388  stuff.  Used on level 1 and higher." Line 387  stuff.  Used on level 1 and higher."
387    
388    t `(,@(when (c-lang-const c-opt-cpp-prefix)    t `(,@(when (c-lang-const c-opt-cpp-prefix)
389            (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")            (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
390                   (ncle-depth (c-regexp-opt-depth noncontinued-line-end))                   (ncle-depth (regexp-opt-depth noncontinued-line-end))
391                   (sws-depth (c-lang-const c-syntactic-ws-depth)))                   (sws-depth (c-lang-const c-syntactic-ws-depth))
392                     (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
393    
394              `(;; The stuff after #error and #warning is a message, so              `(;; The stuff after #error and #warning is a message, so
395                ;; fontify it as a string.                ;; fontify it as a string.
396                (,(concat noncontinued-line-end                ,@(when (c-lang-const c-cpp-message-directives)
397                          (c-lang-const c-opt-cpp-prefix)                    (let* ((re (c-make-keywords-re nil
398                          "\\(error\\|warning\\)\\>\\s *\\(.*\\)$")                                 (c-lang-const c-cpp-message-directives)))
399                 ,(+ ncle-depth 2) font-lock-string-face)                           (re-depth (regexp-opt-depth re)))
400                        `((,(concat noncontinued-line-end
401                                    (c-lang-const c-opt-cpp-prefix)
402                                    re
403                                    "\\s +\\(.*\\)$")
404                           ,(+ ncle-depth re-depth 1) font-lock-string-face))))
405    
406                ;; Fontify filenames in #include <...> as strings.                ;; Fontify filenames in #include <...> as strings.
407                (,(concat noncontinued-line-end                ,@(when (c-lang-const c-cpp-include-directives)
408                          (c-lang-const c-opt-cpp-prefix)                    (let* ((re (c-make-keywords-re nil
409                          "\\(import\\|include\\)\\>"                                 (c-lang-const c-cpp-include-directives)))
410                          (c-lang-const c-syntactic-ws)                           (re-depth (regexp-opt-depth re)))
411                          "\\(<[^>\n\r]*>?\\)")                      `((,(concat noncontinued-line-end
412                 (,(+ ncle-depth sws-depth 2)                                  (c-lang-const c-opt-cpp-prefix)
413                  font-lock-string-face)                                  re
414                                    (c-lang-const c-syntactic-ws)
415                 ;; Use an anchored matcher to put paren syntax on the brackets.                                  "\\(<[^>\n\r]*>?\\)")
416                 (,(byte-compile                         (,(+ ncle-depth re-depth sws-depth 1)
417                    `(lambda (limit)                          font-lock-string-face)
418                       (let ((beg-pos  
419                              (match-beginning ,(+ ncle-depth sws-depth 2)))                         ;; Use an anchored matcher to put paren syntax
420                             (end-pos                         ;; on the brackets.
421                              (1- (match-end ,(+ ncle-depth sws-depth 2)))))                         (,(byte-compile
422                         (if (eq (char-after end-pos) ?>)                            `(lambda (limit)
423                             (progn                               (let ((beg (match-beginning
424                               (c-mark-<-as-paren beg-pos)                                           ,(+ ncle-depth re-depth sws-depth 1)))
425                               (c-mark->-as-paren end-pos))                                     (end (1- (match-end ,(+ ncle-depth re-depth
426                           (c-clear-char-property beg-pos 'syntax-table)))                                                             sws-depth 1)))))
427                       nil))))                                 (if (eq (char-after end) ?>)
428                                       (progn
429                                         (c-mark-<-as-paren beg)
430                                         (c-mark->-as-paren end))
431                                     (c-clear-char-property beg 'syntax-table)))
432                                 nil)))))))
433    
434                ;; #define.                ;; #define.
435                (,(c-make-font-lock-search-function                ,@(when (c-lang-const c-opt-cpp-macro-define)
436                   (concat                    `((,(c-make-font-lock-search-function
437                    noncontinued-line-end                         (concat
438                    (c-lang-const c-opt-cpp-prefix)                          noncontinued-line-end
439                    "define\\>"                          (c-lang-const c-opt-cpp-prefix)
440                    (c-lang-const c-syntactic-ws)                          (c-lang-const c-opt-cpp-macro-define)
441                    "\\(" (c-lang-const c-symbol-key) "\\)" ; 1 + ncle + sws                          (c-lang-const c-nonempty-syntactic-ws)
442                    (concat "\\("         ; 2 + ncle + sws + c-sym-key                          "\\(" (c-lang-const ; 1 + ncle + nsws
443                            ;; Macro with arguments - a "function".                                 c-symbol-key) "\\)"
444                            "\\(\(\\)"    ; 3 + ncle + sws + c-sym-key                          (concat "\\("   ; 2 + ncle + nsws + c-sym-key
445                            "\\|"                                  ;; Macro with arguments - a "function".
446                            ;; Macro without arguments - a "variable".                                  "\\(\(\\)" ; 3 + ncle + nsws + c-sym-key
447                            "\\([^\(]\\|$\\)"                                  "\\|"
448                            "\\)"))                                  ;; Macro without arguments - a "variable".
449                   `((if (match-beginning ,(+ 3 ncle-depth sws-depth                                  "\\([^\(]\\|$\\)"
450                                              (c-lang-const c-symbol-key-depth)))                                  "\\)"))
451                         ;; "Function".  Fontify the name and the arguments.                         `((if (match-beginning
452                         (save-restriction                                ,(+ 3 ncle-depth nsws-depth
453                           (c-put-font-lock-face                                    (c-lang-const c-symbol-key-depth)))
454                            (match-beginning ,(+ 1 ncle-depth sws-depth))  
455                            (match-end ,(+ 1 ncle-depth sws-depth))                               ;; "Function".  Fontify the name and the arguments.
456                            'font-lock-function-name-face)                               (save-restriction
457                           (goto-char (match-end                                 (c-put-font-lock-face
458                                       ,(+ 3 ncle-depth sws-depth                                  (match-beginning ,(+ 1 ncle-depth nsws-depth))
459                                           (c-lang-const c-symbol-key-depth))))                                  (match-end ,(+ 1 ncle-depth nsws-depth))
460                                    'font-lock-function-name-face)
461                           (narrow-to-region (point-min) limit)                                 (goto-char
462                           (while (and                                  (match-end
463                                   (progn                                   ,(+ 3 ncle-depth nsws-depth
464                                     (c-forward-syntactic-ws)                                       (c-lang-const c-symbol-key-depth))))
465                                     (looking-at c-symbol-key))  
466                                   (progn                                 (narrow-to-region (point-min) limit)
467                                     (c-put-font-lock-face                                 (while (and
468                                      (match-beginning 0) (match-end 0)                                         (progn
469                                      'font-lock-variable-name-face)                                           (c-forward-syntactic-ws)
470                                     (goto-char (match-end 0))                                           (looking-at c-symbol-key))
471                                     (c-forward-syntactic-ws)                                         (progn
472                                     (eq (char-after) ?,)))                                           (c-put-font-lock-face
473                             (forward-char)))                                            (match-beginning 0) (match-end 0)
474                                              'font-lock-variable-name-face)
475                       ;; "Variable".                                           (goto-char (match-end 0))
476                       (c-put-font-lock-face                                           (c-forward-syntactic-ws)
477                        (match-beginning ,(+ 1 ncle-depth sws-depth))                                           (eq (char-after) ?,)))
478                        (match-end ,(+ 1 ncle-depth sws-depth))                                   (forward-char)))
479                        'font-lock-variable-name-face)))))  
480                               ;; "Variable".
481                               (c-put-font-lock-face
482                                (match-beginning ,(+ 1 ncle-depth nsws-depth))
483                                (match-end ,(+ 1 ncle-depth nsws-depth))
484                                'font-lock-variable-name-face)))))))
485    
486                ;; Fontify cpp function names in preprocessor                ;; Fontify cpp function names in preprocessor
487                ;; expressions in #if and #elif.                ;; expressions in #if and #elif.
488                ,(when (c-lang-const c-cpp-defined-fns)                ,@(when (and (c-lang-const c-cpp-expr-directives)
489                   `(,(c-make-font-lock-search-function                             (c-lang-const c-cpp-expr-functions))
490                       (concat noncontinued-line-end                    (let ((ced-re (c-make-keywords-re t
491                               (c-lang-const c-opt-cpp-prefix)                                    (c-lang-const c-cpp-expr-directives)))
492                               "\\(if\\|elif\\)\\>" ; 1 + ncle-depth                          (cef-re (c-make-keywords-re t
493                               ;; Match the whole logical line to look                                    (c-lang-const c-cpp-expr-functions))))
494                               ;; for the functions in.                      `((,(c-make-font-lock-search-function
495                               "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")                           (concat noncontinued-line-end
496                       `((let ((limit (match-end 0)))                                   (c-lang-const c-opt-cpp-prefix)
497                           (while (re-search-forward                                   ced-re ; 1 + ncle-depth
498                                   ,(concat "\\<\\("                                   ;; Match the whole logical line to look
499                                            (c-regexp-opt                                   ;; for the functions in.
500                                             (c-lang-const c-cpp-defined-fns)                                   "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")
501                                             nil)                           `((let ((limit (match-end 0)))
502                                            "\\)\\>"                               (while (re-search-forward ,cef-re limit 'move)
503                                            "\\s *\(?")                                 (c-put-font-lock-face (match-beginning 1)
504                                   limit 'move)                                                       (match-end 1)
505                             (c-put-font-lock-face (match-beginning 1)                                                       c-preprocessor-face-name)))
506                                                   (match-end 1)                             (goto-char (match-end ,(1+ ncle-depth)))))))))
                                                  c-preprocessor-face-name)))  
                        (goto-char (match-end ,(1+ ncle-depth)))))))  
507    
508                ;; Fontify the directive names.                ;; Fontify the directive names.
509                (,(c-make-font-lock-search-function                (,(c-make-font-lock-search-function
# Line 500  stuff.  Used on level 1 and higher." Line 514  stuff.  Used on level 1 and higher."
514                           "\\)")                           "\\)")
515                   `(,(1+ ncle-depth) c-preprocessor-face-name t)))                   `(,(1+ ncle-depth) c-preprocessor-face-name t)))
516    
517                ;; fontify the n in ifndef                (eval . (list ,(c-make-syntactic-matcher
518                (,(concat noncontinued-line-end                                (concat noncontinued-line-end
519                          (c-lang-const c-opt-cpp-prefix)                                        (c-lang-const c-opt-cpp-prefix)
520                          "if\\(n\\)def\\>")                                        "if\\(n\\)def\\>"))
521                 ,(+ ncle-depth 1) font-lock-negation-char-face prepend)                              ,(+ ncle-depth 1)
522                                c-negation-char-face-name
523                                'append))
524                )))                )))
525    
526        ,@(when (c-major-mode-is 'pike-mode)        ,@(when (c-major-mode-is 'pike-mode)
527              ;; Recognize hashbangs in Pike.
528            `((eval . (list "\\`#![^\n\r]*"            `((eval . (list "\\`#![^\n\r]*"
529                            0 c-preprocessor-face-name))))                            0 c-preprocessor-face-name))))
530    
531        ;; Make hard spaces visible through an inverted `c-invalid-face-name'.        ;; Make hard spaces visible through an inverted `font-lock-warning-face'.
532        (eval . (list        (eval . (list
533                 "\240"                 "\240"
534                 0 (progn                 0 (progn
535                     (unless (c-face-name-p c-nonbreakable-space-face)                     (unless (c-face-name-p 'c-nonbreakable-space-face)
536                       (c-make-inverse-face c-invalid-face-name                       (c-make-inverse-face 'font-lock-warning-face
537                                            c-nonbreakable-space-face))                                            'c-nonbreakable-space-face))
538                     'c-nonbreakable-space-face)))                     ''c-nonbreakable-space-face)))
539        ))        ))
540    
541  (defun c-font-lock-invalid-string ()  (defun c-font-lock-invalid-string ()
542    ;; Assuming the point is after the opening character of a string,    ;; Assuming the point is after the opening character of a string,
543    ;; fontify that char with `c-invalid-face-name' if the string    ;; fontify that char with `font-lock-warning-face' if the string
544    ;; decidedly isn't terminated properly.    ;; decidedly isn't terminated properly.
545      ;;
546      ;; This function does hidden buffer changes.
547    (let ((start (1- (point))))    (let ((start (1- (point))))
548      (save-excursion      (save-excursion
549        (and (nth 3 (parse-partial-sexp start (c-point 'eol)))        (and (eq (elt (parse-partial-sexp start (c-point 'eol)) 8) start)
550             (if (c-major-mode-is '(c-mode c++-mode objc-mode pike-mode))             (if (integerp c-multiline-string-start-char)
551                   ;; There's no multiline string start char before the
552                   ;; string, so newlines aren't allowed.
553                   (not (eq (char-before start) c-multiline-string-start-char))
554                 ;; Multiline strings are allowed anywhere if
555                 ;; c-multiline-string-start-char is t.
556                 (not c-multiline-string-start-char))
557               (if c-string-escaped-newlines
558                 ;; There's no \ before the newline.                 ;; There's no \ before the newline.
559                 (not (eq (char-before (point)) ?\\))                 (not (eq (char-before (point)) ?\\))
560               ;; Quoted newlines aren't supported.               ;; Escaped newlines aren't supported.
561               t)               t)
562             (if (c-major-mode-is 'pike-mode)             (c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
                ;; There's no # before the string, so newlines  
                ;; aren't allowed.  
                (not (eq (char-before start) ?#))  
              t)  
            (c-put-font-lock-face start (1+ start) c-invalid-face-name)))))  
563    
564  (c-lang-defconst c-basic-matchers-before  (c-lang-defconst c-basic-matchers-before
565    "Font lock matchers for basic keywords, labels, references and various    "Font lock matchers for basic keywords, labels, references and various
# Line 566  casts and declarations are fontified.  U Line 587  casts and declarations are fontified.  U
587            (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))            (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
588              (if (c-major-mode-is 'pike-mode)              (if (c-major-mode-is 'pike-mode)
589                  ;; No symbol is a keyword after "->" in Pike.                  ;; No symbol is a keyword after "->" in Pike.
590                  `((eval . (list ,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)"                  `((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
591                                           "\\<\\(" re "\\)\\>")                                           "\\<\\(" re "\\)\\>")
592                                  3 c-constant-face-name)))                                  2 c-constant-face-name)))
593                `((eval . (list ,(concat "\\<\\(" re "\\)\\>")                `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
594                                1 c-constant-face-name))))))                                1 c-constant-face-name))))))
595    
596        ;; Fontify all keywords except the primitive types.        ;; Fontify all keywords except the primitive types.
597        ,(if (c-major-mode-is 'pike-mode)        ,(if (c-major-mode-is 'pike-mode)
598             ;; No symbol is a keyword after "->" in Pike.             ;; No symbol is a keyword after "->" in Pike.
599             `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)"             `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
600                        "\\<" (c-lang-const c-regular-keywords-regexp))                        "\\<" (c-lang-const c-regular-keywords-regexp))
601               3 font-lock-keyword-face)               2 font-lock-keyword-face)
602           `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))           `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
603             1 font-lock-keyword-face))             1 font-lock-keyword-face))
604    
# Line 596  casts and declarations are fontified.  U Line 617  casts and declarations are fontified.  U
617                    ;; Search for class identifiers preceded by ".".  The                    ;; Search for class identifiers preceded by ".".  The
618                    ;; anchored matcher takes it from there.                    ;; anchored matcher takes it from there.
619                    (concat (c-lang-const c-opt-identifier-concat-key)                    (concat (c-lang-const c-opt-identifier-concat-key)
620                            "[ \t\n\r\f\v]*"                            (c-lang-const c-simple-ws) "*"
621                            (concat "\\("                            (concat "\\("
622                                    "[" c-upper "][" (c-lang-const c-symbol-chars) "]*"                                    "[" c-upper "]"
623                                      "[" (c-lang-const c-symbol-chars) "]*"
624                                    "\\|"                                    "\\|"
625                                    "\\*"                                    "\\*"
626                                    "\\)"))                                    "\\)"))
# Line 612  casts and declarations are fontified.  U Line 634  casts and declarations are fontified.  U
634                                      (< (skip-chars-backward                                      (< (skip-chars-backward
635                                          ,(c-lang-const c-symbol-chars)) 0))                                          ,(c-lang-const c-symbol-chars)) 0))
636                                    (not (get-text-property (point) 'face)))                                    (not (get-text-property (point) 'face)))
637                          (c-put-font-lock-face (point) id-end c-reference-face-name)                          (c-put-font-lock-face (point) id-end
638                                                  c-reference-face-name)
639                          (c-backward-syntactic-ws)))                          (c-backward-syntactic-ws)))
640                      nil                      nil
641                      (goto-char (match-end 0)))))                      (goto-char (match-end 0)))))
642    
643              `((,(byte-compile              `((,(byte-compile
644                   ;; Must use a function here since we match longer than we                   ;; Must use a function here since we match longer than
645                   ;; want to move before doing a new search.  This is not                   ;; we want to move before doing a new search.  This is
646                   ;; necessary for XEmacs >= 20 since it restarts the search                   ;; not necessary for XEmacs since it restarts the
647                   ;; from the end of the first highlighted submatch (something                   ;; search from the end of the first highlighted
648                   ;; that causes problems in other places).                   ;; submatch (something that causes problems in other
649                     ;; places).
650                   `(lambda (limit)                   `(lambda (limit)
651                      (while (re-search-forward                      (while (re-search-forward
652                              ,(concat "\\(\\<" ; 1                              ,(concat "\\(\\<" ; 1
653                                       "\\(" (c-lang-const c-symbol-key) "\\)" ; 2                                       "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
654                                       "[ \t\n\r\f\v]*"                                       (c-lang-const c-simple-ws) "*"
655                                       (c-lang-const c-opt-identifier-concat-key)                                       (c-lang-const c-opt-identifier-concat-key)
656                                       "[ \t\n\r\f\v]*"                                       (c-lang-const c-simple-ws) "*"
657                                       "\\)"                                       "\\)"
658                                       "\\("                                       "\\("
659                                       (c-lang-const c-opt-after-id-concat-key)                                       (c-lang-const c-opt-after-id-concat-key)
# Line 660  casts and declarations are fontified.  U Line 684  casts and declarations are fontified.  U
684                    (if (> (point) limit) (goto-char limit)))))                    (if (> (point) limit) (goto-char limit)))))
685    
686              ;; The @interface/@implementation/@protocol directives.              ;; The @interface/@implementation/@protocol directives.
687              (,(concat "\\<"              ,(c-make-font-lock-search-function
688                        (c-regexp-opt                (concat "\\<"
689                          (regexp-opt
690                         '("@interface" "@implementation" "@protocol")                         '("@interface" "@implementation" "@protocol")
691                         t)                         t)
692                        "\\>")                        "\\>")
693               (,(byte-compile                '((c-fontify-types-and-refs
694                  (lambda (limit)                      (;; The font-lock package in Emacs is known to clobber
695                    (let (;; The font-lock package in Emacs is known to clobber                       ;; `parse-sexp-lookup-properties' (when it exists).
696                          ;; `parse-sexp-lookup-properties' (when it exists).                       (parse-sexp-lookup-properties
697                          (parse-sexp-lookup-properties                        (cc-eval-when-compile
698                           (cc-eval-when-compile                          (boundp 'parse-sexp-lookup-properties))))
699                             (boundp 'parse-sexp-lookup-properties))))                    (c-forward-objc-directive)
700                      (save-restriction                    nil)
701                        (narrow-to-region (point-min) limit)                  (goto-char (match-beginning 0))))))
                       (c-font-lock-objc-iip-decl)))  
                   nil))))))  
702    
703        ("\\(!\\)[^=]" 1 font-lock-negation-char-face)        (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name))
704        ))        ))
705    
706  (defun c-font-lock-complex-decl-prepare (limit)  (defun c-font-lock-complex-decl-prepare (limit)
707    ;; Called before any of the matchers in `c-complex-decl-matchers'.    ;; Called before any of the matchers in `c-complex-decl-matchers'.
708    ;; Nil is always returned.    ;; Nil is always returned.
709      ;;
710      ;; This function does hidden buffer changes.
711    
712    ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)    ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
713    
# Line 718  casts and declarations are fontified.  U Line 743  casts and declarations are fontified.  U
743    
744  (defun c-font-lock-<>-arglists (limit)  (defun c-font-lock-<>-arglists (limit)
745    ;; Fontify types and references in names containing angle bracket    ;; Fontify types and references in names containing angle bracket
746    ;; arglists from the point to LIMIT.  This will also fontify cases    ;; arglists from the point to LIMIT.  Note that
747    ;; like normal function calls on the form "foo (a < b, c > d)", but    ;; `c-font-lock-declarations' already has handled many of them.  Nil
748    ;; `c-font-lock-declarations' will undo that later.  Nil is always    ;; is always returned.
749    ;; returned.    ;;
750      ;; This function might do hidden buffer changes.
751    
752    (let (;; The font-lock package in Emacs is known to clobber    (let (;; The font-lock package in Emacs is known to clobber
753          ;; `parse-sexp-lookup-properties' (when it exists).          ;; `parse-sexp-lookup-properties' (when it exists).
754          (parse-sexp-lookup-properties          (parse-sexp-lookup-properties
755           (cc-eval-when-compile           (cc-eval-when-compile
756             (boundp 'parse-sexp-lookup-properties)))             (boundp 'parse-sexp-lookup-properties)))
757          id-start id-end pos kwd-sym)          (c-parse-and-markup-<>-arglists t)
758            c-restricted-<>-arglists
759            id-start id-end id-face pos kwd-sym)
760    
761      (while (and (< (point) limit)      (while (and (< (point) limit)
762                  (re-search-forward c-opt-<>-arglist-start limit t))                  (re-search-forward c-opt-<>-arglist-start limit t))
# Line 739  casts and declarations are fontified.  U Line 767  casts and declarations are fontified.  U
767    
768        (goto-char id-start)        (goto-char id-start)
769        (unless (c-skip-comments-and-strings limit)        (unless (c-skip-comments-and-strings limit)
770          (setq kwd-sym nil)          (setq kwd-sym nil
771          (if (or (not (eq (get-text-property id-start 'face)                c-restricted-<>-arglists nil
772                           'font-lock-keyword-face))                id-face (get-text-property id-start 'face))
773                  (when (looking-at c-opt-<>-sexp-key)  
774                    (setq kwd-sym (c-keyword-sym (match-string 1)))))          (if (cond
775                 ((eq id-face 'font-lock-type-face)
776                  ;; The identifier got the type face so it has already been
777                  ;; handled in `c-font-lock-declarations'.
778                  nil)
779    
780                 ((eq id-face 'font-lock-keyword-face)
781                  (when (looking-at c-opt-<>-sexp-key)
782                    ;; There's a special keyword before the "<" that tells
783                    ;; that it's an angle bracket arglist.
784                    (setq kwd-sym (c-keyword-sym (match-string 1)))))
785    
786                 (t
787                  ;; There's a normal identifier before the "<".  If we're not in
788                  ;; a declaration context then we set `c-restricted-<>-arglists'
789                  ;; to avoid recognizing templates in function calls like "foo (a
790                  ;; < b, c > d)".
791                  (c-backward-syntactic-ws)
792                  (when (and (memq (char-before) '(?\( ?,))
793                             (not (eq (get-text-property (1- (point)) 'c-type)
794                                      'c-decl-arg-start)))
795                    (setq c-restricted-<>-arglists t))
796                  t))
797    
798              (progn              (progn
799                (goto-char (1- pos))                (goto-char (1- pos))
800                ;; Check for comment/string both at the identifier and                ;; Check for comment/string both at the identifier and
801                ;; at the "<".                ;; at the "<".
802                (unless (c-skip-comments-and-strings limit)                (unless (c-skip-comments-and-strings limit)
803    
804                  (when (c-forward-<>-arglist (c-keyword-member kwd-sym                  (c-fontify-types-and-refs ()
805                                                                'c-<>-type-kwds)                    (when (c-forward-<>-arglist (c-keyword-member
806                                              t)                                                 kwd-sym 'c-<>-type-kwds))
807                    (when (and c-opt-identifier-concat-key                      (when (and c-opt-identifier-concat-key
808                               (not (get-text-property id-start 'face)))                                 (not (get-text-property id-start 'face)))
809                      (c-forward-syntactic-ws)                        (c-forward-syntactic-ws)
810                      (if (looking-at c-opt-identifier-concat-key)                        (if (looking-at c-opt-identifier-concat-key)
811                              (c-put-font-lock-face id-start id-end
812                                                    c-reference-face-name)
813                          (c-put-font-lock-face id-start id-end                          (c-put-font-lock-face id-start id-end
814                                                c-reference-face-name)                                                'font-lock-type-face)))))
                       (c-put-font-lock-face id-start id-end  
                                             'font-lock-type-face))))  
815    
816                  (goto-char pos)))                  (goto-char pos)))
817            (goto-char pos)))))            (goto-char pos)))))
# Line 773  casts and declarations are fontified.  U Line 824  casts and declarations are fontified.  U
824    ;; "bar" in "int foo = 17, bar;").  Stop at LIMIT.  If TYPES is    ;; "bar" in "int foo = 17, bar;").  Stop at LIMIT.  If TYPES is
825    ;; non-nil, fontify all identifiers as types.  Nil is always    ;; non-nil, fontify all identifiers as types.  Nil is always
826    ;; returned.    ;; returned.
827      ;;
828      ;; This function might do hidden buffer changes.
829    
830    ;;(message "c-font-lock-declarators from %s to %s" (point) limit)    ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
831    (c-fontify-types-and-refs    (c-fontify-types-and-refs
# Line 789  casts and declarations are fontified.  U Line 842  casts and declarations are fontified.  U
842              (let (got-identifier)              (let (got-identifier)
843                (setq paren-depth 0)                (setq paren-depth 0)
844                ;; Skip over type decl prefix operators.  (Note similar                ;; Skip over type decl prefix operators.  (Note similar
845                ;; code in `c-font-lock-declarations'.)                ;; code in `c-forward-decl-or-cast-1'.)
846                (while (and (looking-at c-type-decl-prefix-key)                (while (and (looking-at c-type-decl-prefix-key)
847                            (if (and (c-major-mode-is 'c++-mode)                            (if (and (c-major-mode-is 'c++-mode)
848                                     (match-beginning 2))                                     (match-beginning 2))
# Line 830  casts and declarations are fontified.  U Line 883  casts and declarations are fontified.  U
883    
884              (<= (point) limit)              (<= (point) limit)
885    
886                (progn
887                  (when (looking-at c-decl-hangon-key)
888                    (c-forward-keyword-clause 1))
889                  (<= (point) limit))
890    
891              ;; Search syntactically to the end of the declarator (";",              ;; Search syntactically to the end of the declarator (";",
892              ;; ",", a closen paren, eob etc) or to the beginning of an              ;; ",", a closen paren, eob etc) or to the beginning of an
893              ;; initializer or function prototype ("=" or "\\s\(").              ;; initializer or function prototype ("=" or "\\s\(").
# Line 883  casts and declarations are fontified.  U Line 941  casts and declarations are fontified.  U
941                               (looking-at "{"))                               (looking-at "{"))
942                          (c-safe (c-forward-sexp) t)                          (c-safe (c-forward-sexp) t)
943                        t)                        t)
944                        ;; FIXME: Should look for c-decl-end markers here;
945                        ;; we might go far into the following declarations
946                        ;; in e.g. ObjC mode (see e.g. methods-4.m).
947                      (c-syntactic-re-search-forward "[;,{]" limit 'move t)                      (c-syntactic-re-search-forward "[;,{]" limit 'move t)
948                      (backward-char)))                      (backward-char)))
949    
# Line 905  casts and declarations are fontified.  U Line 966  casts and declarations are fontified.  U
966          c-reference-face-name          c-reference-face-name
967          font-lock-keyword-face))          font-lock-keyword-face))
968    
 ;; Macro used inside `c-font-lock-declarations'.  It ought to be a  
 ;; defsubst or perhaps even a defun, but it contains lots of free  
 ;; variables that refer to things inside `c-font-lock-declarations'.  
 (defmacro c-fl-shift-type-backward (&optional short)  
   ;; `c-font-lock-declarations' can consume an arbitrary length list  
   ;; of types when parsing a declaration, which means that it  
   ;; sometimes consumes the identifier in the declaration as a type.  
   ;; This is used to "backtrack" and make the last type be treated  
   ;; as an identifier instead.  
   `(progn  
      ,(unless short  
         ;; These identifiers are bound only in the inner let.  
         '(setq identifier-type at-type  
                identifier-start type-start  
                identifier-end type-end))  
      (if (setq at-type (if (eq prev-at-type 'prefix)  
                            t  
                          prev-at-type))  
          (setq type-start prev-type-start  
                type-end prev-type-end)  
        (setq type-start start-pos  
              type-end start-pos))  
      ,(unless short  
         ;; These identifiers are bound only in the inner let.  
         '(setq start type-end  
                got-parens nil  
                got-identifier t  
                got-suffix t  
                got-suffix-after-parens t  
                paren-depth 0))))  
   
969  (defun c-font-lock-declarations (limit)  (defun c-font-lock-declarations (limit)
970    ;; Fontify all the declarations and casts from the point to LIMIT.    ;; Fontify all the declarations, casts and labels from the point to LIMIT.
971    ;; Assumes that strings and comments have been fontified already.    ;; Assumes that strings and comments have been fontified already.  Nil is
972    ;; Nil is always returned.    ;; always returned.
973    ;;    ;;
974    ;; This function can make hidden buffer changes, but the font-lock    ;; This function might do hidden buffer changes.
   ;; context covers that.  
975    
976    ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)    ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
977    
978    (save-restriction    (save-restriction
979      (let (start-pos      (let (;; The position where `c-find-decl-spots' stopped.
980            c-restricted-<>-arglists            start-pos
981            ;; Nonzero if the `c-decl-prefix-re' match is in an arglist context,            ;; 'decl if we're in an arglist containing declarations (but
982            ;; as opposed to a statement-level context.  The major difference is            ;; if `c-recognize-paren-inits' is set it might also be an
983            ;; that "," works as declaration delimiter in an arglist context,            ;; initializer arglist), '<> if the arglist is of angle
984            ;; whereas it only separates declarators in the same declaration in            ;; bracket type, 'arglist if it's some other arglist, or nil
985            ;; a statement context.  If it's nonzero then the value is the            ;; if not in an arglist at all.
986            ;; matched char, e.g. ?\( or ?,.            context
987            arglist-match            ;; The position of the next token after the closing paren of
988            ;; 'decl if we're in an arglist containing declarations (but if            ;; the last detected cast.
           ;; `c-recognize-paren-inits' is set it might also be an initializer  
           ;; arglist), '<> if the arglist is of angle bracket type, 'other if  
           ;; it's some other arglist, or nil if not in an arglist at all.  
           arglist-type  
           ;; Set to the result of `c-forward-type'.  
           at-type  
           ;; These record the start and end of the type or possible type found  
           ;; by `c-forward-type'.  `type-start' is at the start of the first  
           ;; type token, and `type-end' is at the start of the first token  
           ;; after the type (and after any specifiers).  
           type-start type-end  
           ;; These store `at-type', `type-start' and `type-end' of the  
           ;; identifier before the one in those variables.  The previous  
           ;; identifier might turn out to be the real type in a declaration if  
           ;; the last one has to be the declarator in it.  If `prev-at-type'  
           ;; is nil then the other variables have undefined values.  
           prev-at-type prev-type-start prev-type-end  
           ;; Whether we've found a declaration or a cast.  We might know this  
           ;; before we've found the type in it.  
           at-decl-or-cast  
           ;; Set when we need to back up to parse this as a declaration but  
           ;; not as a cast.  
           backup-if-not-cast  
           ;; Set if we've found a "typedef" specifier.  The identifiers in the  
           ;; declaration are then fontified as types.  
           at-typedef  
           ;; Set if we've found a specifier that can start a declaration where  
           ;; there's no type.  
           maybe-typeless  
           ;; The position of the next token after the closing paren of the  
           ;; last fontified cast.  
989            last-cast-end            last-cast-end
990            ;; The same for the currently investigated cast.            ;; The result from `c-forward-decl-or-cast-1'.
991            cast-end            decl-or-cast
992            ;; The maximum of the end positions of all the checked type decl            ;; The maximum of the end positions of all the checked type
993            ;; expressions in the successfully identified declarations.  The            ;; decl expressions in the successfully identified
994            ;; position might be either before or after the syntactic whitespace            ;; declarations.  The position might be either before or
995            ;; following the last token in the type decl expression.            ;; after the syntactic whitespace following the last token
996              ;; in the type decl expression.
997            (max-type-decl-end 0)            (max-type-decl-end 0)
998            ;; Same as `max-type-decl-*', but used when we're before            ;; Same as `max-type-decl-*', but used when we're before
999            ;; `token-pos'.            ;; `token-pos'.
1000            (max-type-decl-end-before-token 0)            (max-type-decl-end-before-token 0)
1001            ;; Allow recording of identifier ranges in `c-forward-type' etc for            ;; Set according to the context to direct the heuristics for
1002            ;; later fontification.  Not using `c-fontify-types-and-refs' here            ;; recognizing C++ templates.
1003            ;; since the ranges should be fontified selectively only when a            c-restricted-<>-arglists
1004            ;; declaration or cast has been successfully recognized.            ;; Turn on recording of identifier ranges in
1005            c-record-type-identifiers            ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
1006              ;; later fontification.
1007              (c-record-type-identifiers t)
1008            c-record-ref-identifiers            c-record-ref-identifiers
1009              ;; Make `c-forward-type' calls mark up template arglists if
1010              ;; it finds any.  That's necessary so that we later will
1011              ;; stop inside them to fontify types there.
1012              (c-parse-and-markup-<>-arglists t)
1013            ;; The font-lock package in Emacs is known to clobber            ;; The font-lock package in Emacs is known to clobber
1014            ;; `parse-sexp-lookup-properties' (when it exists).            ;; `parse-sexp-lookup-properties' (when it exists).
1015            (parse-sexp-lookup-properties            (parse-sexp-lookup-properties
# Line 1024  casts and declarations are fontified.  U Line 1029  casts and declarations are fontified.  U
1029        ;; "some_other_variable" as an identifier, and the latter will not        ;; "some_other_variable" as an identifier, and the latter will not
1030        ;; correct itself until the second line is changed.  To avoid that we        ;; correct itself until the second line is changed.  To avoid that we
1031        ;; narrow to the limit if the region to fontify is a single line.        ;; narrow to the limit if the region to fontify is a single line.
1032        (when (<= limit (c-point 'bonl))        (narrow-to-region
1033          (narrow-to-region         (point-min)
1034           (point-min)         (if (<= limit (c-point 'bonl))
1035           (save-excursion             (save-excursion
1036             ;; Narrow after any operator chars following the limit though, since               ;; Narrow after any operator chars following the limit though,
1037             ;; those characters can be useful in recognizing a declaration (in               ;; since those characters can be useful in recognizing a
1038             ;; particular the '{' that opens a function body after the header).               ;; declaration (in particular the '{' that opens a function body
1039             (goto-char limit)               ;; after the header).
1040             (skip-chars-forward c-nonsymbol-chars)               (goto-char limit)
1041             (point))))               (skip-chars-forward c-nonsymbol-chars)
1042                 (point))
1043             limit))
1044    
1045        (c-find-decl-spots        (c-find-decl-spots
1046         limit         limit
1047         c-identifier-start         c-decl-start-re
1048         c-font-lock-maybe-decl-faces         c-font-lock-maybe-decl-faces
1049    
1050         (lambda (match-pos inside-macro)         (lambda (match-pos inside-macro)
1051           (catch 'false-alarm           (setq start-pos (point))
1052             ;; Don't do anything more if we're looking at a keyword           (when
1053             ;; that can't start a declaration.            ;; The result of the form below is true when we don't recognize a
1054             (when (and (eq (get-text-property (point) 'face)            ;; declaration or cast.
1055                            'font-lock-keyword-face)            (if (and (eq (get-text-property (point) 'face)
1056                        (looking-at c-not-decl-init-keywords))                         'font-lock-keyword-face)
1057               (throw 'false-alarm t))                     (looking-at c-not-decl-init-keywords))
1058                  ;; Don't do anything more if we're looking at a keyword that
1059             ;; Set `arglist-match' and `arglist-type'.  Look for "<" for the                ;; can't start a declaration.
1060             ;; sake of C++-style template arglists.                t
1061             (setq arglist-match (char-before match-pos))  
1062             (if (memq arglist-match '(?\( ?, ?\[ ?<))              ;; Set `context'.  Look for "<" for the sake of C++-style template
1063                ;; arglists.
1064                 ;; Find out the type of the arglist.              (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<))
1065                 (if (<= match-pos (point-min))  
1066                     (setq arglist-type 'other)                  ;; Find out the type of the arglist.
1067                   (let ((type (c-get-char-property (1- match-pos) 'c-type)))                  (if (<= match-pos (point-min))
1068                     (cond ((eq type 'c-decl-arg-start)                      (setq context 'arglist)
1069                            ;; Got a cached hit in a declaration arglist.                    (let ((type (c-get-char-property (1- match-pos) 'c-type)))
1070                            (setq arglist-type 'decl))                      (cond ((eq type 'c-decl-arg-start)
1071                           ((or (eq type 'c-<>-arg-sep)                             ;; Got a cached hit in a declaration arglist.
1072                                (eq arglist-match ?<))                             (setq context 'decl))
1073                            ;; Inside an angle bracket arglist.                            ((or (eq type 'c-<>-arg-sep)
1074                            (setq arglist-type '<>))                                 (eq (char-before match-pos) ?<))
1075                           (type                             ;; Inside an angle bracket arglist.
1076                            ;; Got a cached hit in some other type of arglist.                             (setq context '<>))
1077                            (setq arglist-type 'other))                            (type
1078                           ((if inside-macro                             ;; Got a cached hit in some other type of arglist.
1079                                (< match-pos max-type-decl-end-before-token)                             (setq context 'arglist))
1080                              (< match-pos max-type-decl-end))                            ((if inside-macro
1081                            ;; The point is within the range of a previously                                 (< match-pos max-type-decl-end-before-token)
1082                            ;; encountered type decl expression, so the arglist                               (< match-pos max-type-decl-end))
1083                            ;; is probably one that contains declarations.                             ;; The point is within the range of a previously
1084                            ;; However, if `c-recognize-paren-inits' is set it                             ;; encountered type decl expression, so the arglist
1085                            ;; might also be an initializer arglist.                             ;; is probably one that contains declarations.
1086                            (setq arglist-type 'decl)                             ;; However, if `c-recognize-paren-inits' is set it
1087                            ;; The result of this check is cached with a char                             ;; might also be an initializer arglist.
1088                            ;; property on the match token, so that we can look                             (setq context 'decl)
1089                            ;; it up again when refontifying single lines in a                             ;; The result of this check is cached with a char
1090                            ;; multiline declaration.                             ;; property on the match token, so that we can look
1091                            (c-put-char-property (1- match-pos)                             ;; it up again when refontifying single lines in a
1092                                                 'c-type 'c-decl-arg-start))                             ;; multiline declaration.
1093                           (t                             (c-put-char-property (1- match-pos)
1094                            (setq arglist-type 'other)))))                                                  'c-type 'c-decl-arg-start))
1095                              (t
1096               (setq arglist-match nil                             (setq context 'arglist)))))
1097                     arglist-type nil))  
1098                  (setq context nil))
1099             (setq at-type nil  
1100                   at-decl-or-cast nil              ;; If we're in a normal arglist context we don't want to
1101                   backup-if-not-cast nil              ;; recognize commas in nested angle bracket arglists since
1102                   at-typedef nil              ;; those commas could be part of our own arglist.
1103                   maybe-typeless nil              (setq c-restricted-<>-arglists (and c-recognize-<>-arglists
1104                   c-record-type-identifiers t                                                  (eq context 'arglist))
1105                   c-record-ref-identifiers nil  
1106                   ;; `start-pos' is used below to point to the start of the                    ;; Now analyze the construct.
1107                   ;; first type, i.e. after any leading specifiers.  It might                    decl-or-cast (c-forward-decl-or-cast-1
1108                   ;; also point at the beginning of the preceding syntactic                                  match-pos context last-cast-end))
1109                   ;; whitespace.  
1110                   start-pos (point)              (if (not decl-or-cast)
1111                   ;; If we're in a normal arglist context we don't want to                  ;; False alarm.  Return t to go on to the next check.
1112                   ;; recognize commas in nested angle bracket arglists since                  t
1113                   ;; those commas could be part of our own arglist.  
1114                   c-restricted-<>-arglists                (if (eq decl-or-cast 'cast)
1115                   (and c-recognize-<>-arglists                    ;; Save the position after the previous cast so we can feed
1116                        (eq arglist-type 'other)))                    ;; it to `c-forward-decl-or-cast-1' in the next round.  That
1117                      ;; helps it discover cast chains like "(a) (b) c".
1118             (when (and c-restricted-<>-arglists                    (setq last-cast-end (point))
1119                        (/= arglist-match ?,))  
1120               ;; We're standing at the start of a normal arglist so remove any                  ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1121               ;; angle bracket arglists containing commas that's been                  ;; under the assumption that we're after the first type decl
1122               ;; recognized inside it by the preceding slightly opportunistic                  ;; expression in the declaration now.  That's not really true;
1123               ;; scan in `c-font-lock-<>-arglists'.                  ;; we could also be after a parenthesized initializer
1124               (while (and (c-syntactic-re-search-forward                  ;; expression in C++, but this is only used as a last resort
1125                            c-opt-<>-arglist-start-in-paren nil t t)                  ;; to slant ambiguous expression/declarations, and overall
1126                           (match-beginning 1))                  ;; it's worth the risk to occasionally fontify an expression
1127                 (backward-char)                  ;; as a declaration in an initializer expression compared to
1128                 (when (save-match-data                  ;; getting ambiguous things in normal function prototypes
1129                         (and (c-get-char-property (point) 'syntax-table)                  ;; fontified as expressions.
1130                              (not (c-forward-<>-arglist nil t))))                  (if inside-macro
1131                   (c-remove-font-lock-face (match-beginning 2) (match-end 2))))                      (when (> (point) max-type-decl-end-before-token)
1132               (goto-char start-pos))                        (setq max-type-decl-end-before-token (point)))
1133                      (when (> (point) max-type-decl-end)
1134             ;; Check for a type, but be prepared to skip over leading                      (setq max-type-decl-end (point))))
1135             ;; specifiers like "static".  Unknown symbols are treated as  
1136             ;; possible types, but they could also be specifiers disguised                  ;; Back up to the type to fontify the declarator(s).
1137             ;; through macros like __INLINE__, so we recognize both types and                  (goto-char (car decl-or-cast))
1138             ;; known specifiers after them too.  
1139             (while (let ((start (point))                  (let ((decl-list
1140                          (res (unless (eq at-type t)                         (if context
1141                                 ;; Don't look for a type if we already found a                             ;; Should normally not fontify a list of
1142                                 ;; positive one; we only loop for the                             ;; declarators inside an arglist, but the first
1143                                 ;; `c-specifier-key' check then.                             ;; argument in the ';' separated list of a "for"
1144                                 (c-forward-type))))                             ;; statement is an exception.
1145                               (when (eq (char-before match-pos) ?\()
1146                      (when res                               (save-excursion
1147                        ;; Found a known or possible type or a prefix of a known                                 (goto-char (1- match-pos))
1148                        ;; type.                                 (c-backward-syntactic-ws)
1149                                   (and (c-simple-skip-symbol-backward)
1150                        (when at-type                                      (looking-at c-paren-stmt-key))))
1151                          ;; Got two identifiers with nothing but whitespace                           t)))
1152                          ;; between them.  That can only happen in  
1153                          ;; declarations.                    ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1154                          (setq at-decl-or-cast t)                    ;; before the first declarator if it's a list.
1155                      ;; `c-font-lock-declarators' handles the rest.
1156                          (when (eq at-type 'found)                    (when decl-list
1157                            ;; If the previous identifier is a found type we                      (save-excursion
1158                            ;; record it as a real one; it might be some sort of                        (c-backward-syntactic-ws)
1159                            ;; alias for a prefix like "unsigned".                        (unless (bobp)
1160                            (save-excursion                          (c-put-char-property (1- (point)) 'c-type
1161                              (goto-char type-start)                                               (if (cdr decl-or-cast)
1162                              (let ((c-promote-possible-types t))                                                   'c-decl-type-start
1163                                (c-forward-type)))))                                                 'c-decl-id-start)))))
1164    
1165                        (setq prev-at-type at-type                    (c-font-lock-declarators
1166                              prev-type-start type-start                     (point-max) decl-list (cdr decl-or-cast))))
1167                              prev-type-end type-end  
1168                              at-type res                ;; A cast or declaration has been successfully identified, so do
1169                              type-start start                ;; all the fontification of types and refs that's been recorded.
1170                              type-end (point))                (c-fontify-recorded-types-and-refs)
1171                  nil))
1172                        ;; If the type isn't known we continue so that we'll  
1173                        ;; jump over all specifiers and type identifiers.  The            ;; It was a false alarm.  Check if we're in a label instead.
1174                        ;; reason to do this for a known type prefix is to make            (goto-char start-pos)
1175                        ;; things like "unsigned INT16" work.            (when (c-forward-label t match-pos nil)
1176                        (setq res (not (eq res t))))              ;; Can't use `c-fontify-types-and-refs' here since we
1177                ;; should use the label face.
1178                      (if (looking-at c-specifier-key)              (let (elem)
1179                          ;; Found a known specifier keyword.  The specifier                (while c-record-ref-identifiers
1180                          ;; keywords are restrictive, so we check for them                  (setq elem (car c-record-ref-identifiers)
1181                          ;; anywhere inside or around the type(s).  We thereby                        c-record-ref-identifiers (cdr c-record-ref-identifiers))
1182                          ;; avoid having special cases for specifiers like MSVC                  (c-put-font-lock-face (car elem) (cdr elem)
1183                          ;; '__declspec' which can come after the type.                                        c-label-face-name)))
1184                          (progn              ;; `c-forward-label' probably has added a `c-decl-end'
1185                            (setq at-decl-or-cast t)              ;; marker, so return t to `c-find-decl-spots' to signal
1186                            (let ((kwd-sym (c-keyword-sym (match-string 1))))              ;; that.
1187                              (when (c-keyword-member              t))))
                                    kwd-sym 'c-typedef-decl-kwds)  
                               (setq at-typedef t))  
                             (when (c-keyword-member  
                                    kwd-sym 'c-typeless-decl-kwds)  
                               (setq maybe-typeless t)))  
                           (c-forward-keyword-clause)  
                           ;; Move type-end forward if we've passed a type,  
                           ;; otherwise move start-pos forward.  
                           (if at-type  
                               (setq type-end (point))  
                             (setq start-pos (point))))  
   
                       res)))  
   
            (cond  
             ((eq at-type 'prefix)  
              ;; A prefix type is itself a primitive type when it's not  
              ;; followed by another type.  
              (setq at-type t))  
   
             ((not at-type)  
              ;; Got no type but set things up to continue anyway to handle the  
              ;; various cases when a declaration doesn't start with a type.  
              (setq type-end start-pos))  
   
             ((and (eq at-type 'maybe)  
                   (c-major-mode-is 'c++-mode))  
              ;; If it's C++ then check if the last "type" ends on the form  
              ;; "foo::foo" or "foo::~foo", i.e. if it's the name of a  
              ;; (con|de)structor.  
              (save-excursion  
                (let (name end-2 end-1)  
                  (goto-char type-end)  
                  (c-backward-syntactic-ws)  
                  (setq end-2 (point))  
                  (when (and  
                         (c-simple-skip-symbol-backward)  
                         (progn  
                           (setq name  
                                 (buffer-substring-no-properties (point) end-2))  
                           ;; Cheating in the handling of syntactic ws below.  
                           (< (skip-chars-backward ":~ \t\n\r\v\f") 0))  
                         (progn  
                           (setq end-1 (point))  
                           (c-simple-skip-symbol-backward))  
                         (>= (point) type-start)  
                         (equal (buffer-substring-no-properties (point) end-1)  
                                name))  
                    ;; It is a (con|de)structor name.  In that case the  
                    ;; declaration is typeless so zap out any preceding  
                    ;; identifier(s) that we might have taken as types.  
                    (goto-char type-start)  
                    (setq at-type nil  
                          prev-at-type nil  
                          type-end type-start))))))  
   
            ;; Check for and step over a type decl expression after the thing  
            ;; that is or might be a type.  This can't be skipped since we need  
            ;; the correct end position of the declarator for  
            ;; `max-type-decl-end-*'.  
            (let ((start (point)) (paren-depth 0) pos  
                  ;; True if there's a non-open-paren match of  
                  ;; `c-type-decl-prefix-key'.  
                  got-prefix  
                  ;; True if the declarator is surrounded by a parenthesis pair.  
                  got-parens  
                  ;; True if there is an identifier in the declarator.  
                  got-identifier  
                  ;; True if there's a non-close-paren match of  
                  ;; `c-type-decl-suffix-key'.  
                  got-suffix  
                  ;; True if there's a prefix or suffix match outside the  
                  ;; outermost paren pair that surrounds the declarator.  
                  got-prefix-before-parens  
                  got-suffix-after-parens  
                  ;; True if we've parsed the type decl to a token that  
                  ;; is known to end declarations in this context.  
                  at-decl-end  
                  ;; The earlier values of `at-type', `type-start' and  
                  ;; `type-end' if we've shifted the type backwards.  
                  identifier-type identifier-start identifier-end)  
              (goto-char type-end)  
   
              ;; Skip over type decl prefix operators.  (Note similar code in  
              ;; `c-font-lock-declarators'.)  
              (while (and (looking-at c-type-decl-prefix-key)  
                          (if (and (c-major-mode-is 'c++-mode)  
                                   (match-beginning 2))  
                              ;; If the second submatch matches in C++ then  
                              ;; we're looking at an identifier that's a prefix  
                              ;; only if it specifies a member pointer.  
                              (when (setq got-identifier (c-forward-name))  
                                (if (looking-at "\\(::\\)")  
                                    ;; We only check for a trailing "::" and  
                                    ;; let the "*" that should follow be  
                                    ;; matched in the next round.  
                                    (progn (setq got-identifier nil) t)  
                                  ;; It turned out to be the real identifier,  
                                  ;; so stop.  
                                  nil))  
                            t))  
                (if (eq (char-after) ?\()  
                    (progn  
                      (setq paren-depth (1+ paren-depth))  
                      (forward-char))  
                  (unless got-prefix-before-parens  
                    (setq got-prefix-before-parens (= paren-depth 0)))  
                  (setq got-prefix t)  
                  (goto-char (match-end 1)))  
                (c-forward-syntactic-ws))  
              (setq got-parens (> paren-depth 0))  
   
              ;; Skip over an identifier.  
              (or got-identifier  
                  (and (looking-at c-identifier-start)  
                       (setq got-identifier (c-forward-name))))  
   
              ;; Skip over type decl suffix operators.  
              (while (if (looking-at c-type-decl-suffix-key)  
                         (if (eq (char-after) ?\))  
                             (when (> paren-depth 0)  
                               (setq paren-depth (1- paren-depth))  
                               (forward-char)  
                               t)  
                           (when (if (save-match-data (looking-at "\\s\("))  
                                     (c-safe (c-forward-sexp 1) t)  
                                   (goto-char (match-end 1))  
                                   t)  
                             (unless got-suffix-after-parens  
                               (setq got-suffix-after-parens (= paren-depth 0)))  
                             (setq got-suffix t)))  
                       ;; No suffix matched.  We might have matched the  
                       ;; identifier as a type and the open paren of a function  
                       ;; arglist as a type decl prefix.  In that case we  
                       ;; should "backtrack": Reinterpret the last type as the  
                       ;; identifier, move out of the arglist and continue  
                       ;; searching for suffix operators.  
                       ;;  
                       ;; Do this even if there's no preceding type, to cope  
                       ;; with old style function declarations in K&R C,  
                       ;; (con|de)structors in C++ and `c-typeless-decl-kwds'  
                       ;; style declarations.  That isn't applicable in an  
                       ;; arglist context, though.  
                       (when (and (= paren-depth 1)  
                                  (not got-prefix-before-parens)  
                                  (not (eq at-type t))  
                                  (or prev-at-type  
                                      maybe-typeless  
                                      (when c-recognize-typeless-decls  
                                        (not arglist-type)))  
                                  (setq pos (c-up-list-forward (point)))  
                                  (eq (char-before pos) ?\)))  
                         (c-fl-shift-type-backward)  
                         (goto-char pos)  
                         t))  
                (c-forward-syntactic-ws))  
   
              (when (and maybe-typeless  
                         (not got-identifier)  
                         (not got-prefix)  
                         at-type  
                         (not (eq at-type t)))  
                ;; Have found no identifier but `c-typeless-decl-kwds' has  
                ;; matched so we know we're inside a declaration.  The  
                ;; preceding type must be the identifier instead.  
                (c-fl-shift-type-backward))  
   
              (setq  
               at-decl-or-cast  
               (catch 'at-decl-or-cast  
   
                 (when (> paren-depth 0)  
                   ;; Encountered something inside parens that isn't matched by  
                   ;; the `c-type-decl-*' regexps, so it's not a type decl  
                   ;; expression.  Try to skip out to the same paren depth to  
                   ;; not confuse the cast check below.  
                   (c-safe (goto-char (scan-lists (point) 1 paren-depth)))  
                   (throw 'at-decl-or-cast nil))  
   
                 (setq at-decl-end  
                       (looking-at (cond ((eq arglist-type '<>) "[,>]")  
                                         (arglist-type "[,\)]")  
                                         (t "[,;]"))))  
   
                 ;; Now we've collected info about various characteristics of  
                 ;; the construct we're looking at.  Below follows a decision  
                 ;; tree based on that.  It's ordered to check more certain  
                 ;; signs before less certain ones.  
   
                 (if got-identifier  
                     (progn  
   
                       (when (and (or at-type maybe-typeless)  
                                  (not (or got-prefix got-parens)))  
                         ;; Got another identifier directly after the type, so  
                         ;; it's a declaration.  
                         (throw 'at-decl-or-cast t))  
   
                       (when (and got-parens  
                                  (not got-prefix)  
                                  (not got-suffix-after-parens)  
                                  (or prev-at-type maybe-typeless))  
                         ;; Got a declaration of the form "foo bar (gnu);"  
                         ;; where we've recognized "bar" as the type and "gnu"  
                         ;; as the declarator.  In this case it's however more  
                         ;; likely that "bar" is the declarator and "gnu" a  
                         ;; function argument or initializer (if  
                         ;; `c-recognize-paren-inits' is set), since the parens  
                         ;; around "gnu" would be superfluous if it's a  
                         ;; declarator.  Shift the type one step backward.  
                         (c-fl-shift-type-backward)))  
   
                   ;; Found no identifier.  
   
                   (if prev-at-type  
                       (when (or (= (point) start)  
                                 (and got-suffix  
                                      (not got-prefix)  
                                      (not got-parens)))  
                         ;; Got two types after each other, so if this isn't a  
                         ;; cast then the latter probably is the identifier and  
                         ;; we should back up to the previous type.  
                         (setq backup-if-not-cast t)  
                         (throw 'at-decl-or-cast t))  
   
                     (when (eq at-type t)  
                       ;; If the type is known we know that there can't be any  
                       ;; identifier somewhere else, and it's only in  
                       ;; declarations in e.g. function prototypes and in casts  
                       ;; that the identifier may be left out.  
                       (throw 'at-decl-or-cast t))  
   
                     (when (= (point) start)  
                       ;; Only got a single identifier (parsed as a type so  
                       ;; far).  
                       (if (and  
                            ;; Check that the identifier isn't at the start of  
                            ;; an expression.  
                            at-decl-end  
                            (cond  
                             ((eq arglist-type 'decl)  
                              ;; Inside an arglist that contains declarations.  
                              ;; If K&R style declarations and parenthesis  
                              ;; style initializers aren't allowed then the  
                              ;; single identifier must be a type, else we  
                              ;; require that it's known or found (primitive  
                              ;; types are handled above).  
                              (or (and (not c-recognize-knr-p)  
                                       (not c-recognize-paren-inits))  
                                  (memq at-type '(known found))))  
                             ((eq arglist-type '<>)  
                              ;; Inside a template arglist.  Accept known and  
                              ;; found types; other identifiers could just as  
                              ;; well be constants in C++.  
                              (memq at-type '(known found)))))  
                           (throw 'at-decl-or-cast t)  
                         (throw 'at-decl-or-cast nil))))  
   
                   (if (and  
                        got-parens  
                        (not got-prefix)  
                        (not arglist-type)  
                        (not (eq at-type t))  
                        (or  
                         prev-at-type  
                         maybe-typeless  
                         (when c-recognize-typeless-decls  
                           (or (not got-suffix)  
                               (not (looking-at  
                                     c-after-suffixed-type-maybe-decl-key))))))  
                       ;; Got an empty paren pair and a preceding type that  
                       ;; probably really is the identifier.  Shift the type  
                       ;; backwards to make the last one the identifier.  This  
                       ;; is analogous to the "backtracking" done inside the  
                       ;; `c-type-decl-suffix-key' loop above.  
                       ;;  
                       ;; Exception: In addition to the conditions in that  
                       ;; "backtracking" code, do not shift backward if we're  
                       ;; not looking at either `c-after-suffixed-type-decl-key'  
                       ;; or "[;,]".  Since there's no preceding type, the  
                       ;; shift would mean that the declaration is typeless.  
                       ;; But if the regexp doesn't match then we will simply  
                       ;; fall through in the tests below and not recognize it  
                       ;; at all, so it's better to try it as an abstract  
                       ;; declarator instead.  
                       (c-fl-shift-type-backward)  
   
                     ;; Still no identifier.  
   
                     (when (and got-prefix (or got-parens got-suffix))  
                       ;; Require `got-prefix' together with either  
                       ;; `got-parens' or `got-suffix' to recognize it as an  
                       ;; abstract declarator: `got-parens' only is probably an  
                       ;; empty function call.  `got-suffix' only can build an  
                       ;; ordinary expression together with the preceding  
                       ;; identifier which we've taken as a type.  We could  
                       ;; actually accept on `got-prefix' only, but that can  
                       ;; easily occur temporarily while writing an expression  
                       ;; so we avoid that case anyway.  We could do a better  
                       ;; job if we knew the point when the fontification was  
                       ;; invoked.  
                       (throw 'at-decl-or-cast t))))  
   
                 (when at-decl-or-cast  
                   ;; By now we've located the type in the declaration that we  
                   ;; know we're in.  
                   (throw 'at-decl-or-cast t))  
   
                 (when (and got-identifier  
                            (not arglist-type)  
                            (looking-at c-after-suffixed-type-decl-key)  
                            (if (and got-parens  
                                     (not got-prefix)  
                                     (not got-suffix)  
                                     (not (eq at-type t)))  
                                ;; Shift the type backward in the case that  
                                ;; there's a single identifier inside parens.  
                                ;; That can only occur in K&R style function  
                                ;; declarations so it's more likely that it  
                                ;; really is a function call.  Therefore we  
                                ;; only do this after  
                                ;; `c-after-suffixed-type-decl-key' has  
                                ;; matched.  
                                (progn (c-fl-shift-type-backward) t)  
                              got-suffix-after-parens))  
                   ;; A declaration according to  
                   ;; `c-after-suffixed-type-decl-key'.  
                   (throw 'at-decl-or-cast t))  
   
                 (when (and (or got-prefix (not got-parens))  
                            (memq at-type '(t known)))  
                   ;; It's a declaration if a known type precedes it and it  
                   ;; can't be a function call.  
                   (throw 'at-decl-or-cast t))  
   
                 ;; If we get here we can't tell if this is a type decl or a  
                 ;; normal expression by looking at it alone.  (That's under  
                 ;; the assumption that normal expressions always can look like  
                 ;; type decl expressions, which isn't really true but the  
                 ;; cases where it doesn't hold are so uncommon (e.g. some  
                 ;; placements of "const" in C++) it's not worth the effort to  
                 ;; look for them.)  
   
                 (unless (or at-decl-end (looking-at "=[^=]"))  
                   ;; If this is a declaration it should end here or its  
                   ;; initializer(*) should start here, so check for allowed  
                   ;; separation tokens.  Note that this rule doesn't work  
                   ;; e.g. with a K&R arglist after a function header.  
                   ;;  
                   ;; *) Don't check for C++ style initializers using parens  
                   ;; since those already have been matched as suffixes.  
                   (throw 'at-decl-or-cast nil))  
   
                 ;; Below are tests that only should be applied when we're  
                 ;; certain to not have parsed halfway through an expression.  
   
                 (when (memq at-type '(t known))  
                   ;; The expression starts with a known type so treat it as a  
                   ;; declaration.  
                   (throw 'at-decl-or-cast t))  
   
                 (when (and (c-major-mode-is 'c++-mode)  
                            ;; In C++ we check if the identifier is a known  
                            ;; type, since (con|de)structors use the class name  
                            ;; as identifier.  We've always shifted over the  
                            ;; identifier as a type and then backed up again in  
                            ;; this case.  
                            identifier-type  
                            (or (memq identifier-type '(found known))  
                                (and (eq (char-after identifier-start) ?~)  
                                     ;; `at-type' probably won't be 'found for  
                                     ;; destructors since the "~" is then part  
                                     ;; of the type name being checked against  
                                     ;; the list of known types, so do a check  
                                     ;; without that operator.  
                                     (or (save-excursion  
                                           (goto-char (1+ identifier-start))  
                                           (c-forward-syntactic-ws)  
                                           (c-with-syntax-table  
                                               c-identifier-syntax-table  
                                             (looking-at c-known-type-key)))  
                                         (c-check-type (1+ identifier-start)  
                                                       identifier-end)))))  
                   (throw 'at-decl-or-cast t))  
   
                 (if got-identifier  
                     (progn  
                       (when (and got-prefix-before-parens  
                                  at-type  
                                  (or at-decl-end (looking-at "=[^=]"))  
                                  (not arglist-type)  
                                  (not got-suffix))  
                         ;; Got something like "foo * bar;".  Since we're not  
                         ;; inside an arglist it would be a meaningless  
                         ;; expression because the result isn't used.  We  
                         ;; therefore choose to recognize it as a declaration.  
                         ;; Do not allow a suffix since it could then be a  
                         ;; function call.  
                         (throw 'at-decl-or-cast t))  
   
                       (when (and (or got-suffix-after-parens  
                                      (looking-at "=[^=]"))  
                                  (eq at-type 'found)  
                                  (not (eq arglist-type 'other)))  
                         ;; Got something like "a (*b) (c);" or "a (b) = c;".  
                         ;; It could be an odd expression or it could be a  
                         ;; declaration.  Treat it as a declaration if "a" has  
                         ;; been used as a type somewhere else (if it's a known  
                         ;; type we won't get here).  
                         (throw 'at-decl-or-cast t)))  
   
                   (when (and arglist-type  
                              (or got-prefix  
                                  (and (eq arglist-type 'decl)  
                                       (not c-recognize-paren-inits)  
                                       (or got-parens got-suffix))))  
                     ;; Got a type followed by an abstract declarator.  If  
                     ;; `got-prefix' is set it's something like "a *" without  
                     ;; anything after it.  If `got-parens' or `got-suffix' is  
                     ;; set it's "a()", "a[]", "a()[]", or similar, which we  
                     ;; accept only if the context rules out expressions.  
                     (throw 'at-decl-or-cast t)))  
   
                 ;; If we had a complete symbol table here (which rules out  
                 ;; `c-found-types') we should return t due to the  
                 ;; disambiguation rule (in at least C++) that anything that  
                 ;; can be parsed as a declaration is a declaration.  Now we're  
                 ;; being more defensive and prefer to highlight things like  
                 ;; "foo (bar);" as a declaration only if we're inside an  
                 ;; arglist that contains declarations.  
                 (eq arglist-type 'decl))))  
   
            ;; Point is now after the type decl expression.  
   
            (cond  
             ;; Check for a cast.  
             ((save-excursion  
                (and  
                 c-cast-parens  
   
                 ;; Should be the first type/identifier in a cast paren.  
                 (memq arglist-match c-cast-parens)  
   
                 ;; The closing paren should follow.  
                 (progn  
                   (c-forward-syntactic-ws)  
                   (looking-at "\\s\)"))  
   
                 ;; There should be a primary expression after it.  
                 (let (pos)  
                   (forward-char)  
                   (c-forward-syntactic-ws)  
                   (setq cast-end (point))  
                   (and (looking-at c-primary-expr-regexp)  
                        (progn  
                          (setq pos (match-end 0))  
                          (or  
                           ;; Check if the expression begins with a prefix  
                           ;; keyword.  
                           (match-beginning 2)  
                           (if (match-beginning 1)  
                               ;; Expression begins with an ambiguous operator.  
                               ;; Treat it as a cast if it's a type decl or if  
                               ;; we've recognized the type somewhere else.  
                               (or at-decl-or-cast  
                                   (memq at-type '(t known found)))  
                             ;; Unless it's a keyword, it's the beginning of a  
                             ;; primary expression.  
                             (not (looking-at c-keywords-regexp)))))  
                        ;; If `c-primary-expr-regexp' matched a nonsymbol  
                        ;; token, check that it matched a whole one so that we  
                        ;; don't e.g. confuse the operator '-' with '->'.  It's  
                        ;; ok if it matches further, though, since it e.g. can  
                        ;; match the float '.5' while the operator regexp only  
                        ;; matches '.'.  
                        (or (not (looking-at c-nonsymbol-token-regexp))  
                            (<= (match-end 0) pos))))  
   
                 ;; There should either be a cast before it or something that  
                 ;; isn't an identifier or close paren.  
                 (/= match-pos 0)  
                 (progn  
                   (goto-char (1- match-pos))  
                   (or (eq (point) last-cast-end)  
                       (progn  
                         (c-backward-syntactic-ws)  
                         (if (< (skip-syntax-backward "w_") 0)  
                             ;; It's a symbol.  Accept it only if it's one of  
                             ;; the keywords that can precede an expression  
                             ;; (without surrounding parens).  
                             (looking-at c-simple-stmt-key)  
                           (and  
                            ;; Check that it isn't a close paren (block close  
                            ;; is ok, though).  
                            (not (memq (char-before) '(?\) ?\])))  
                            ;; Check that it isn't a nonsymbol identifier.  
                            (not (c-on-identifier)))))))))  
   
              ;; Handle the cast.  
              (setq last-cast-end cast-end)  
              (when (and at-type (not (eq at-type t)))  
                (let ((c-promote-possible-types t))  
                  (goto-char type-start)  
                  (c-forward-type))))  
   
             (at-decl-or-cast  
              ;; We're at a declaration.  Highlight the type and the following  
              ;; declarators.  
   
              (when backup-if-not-cast  
                (c-fl-shift-type-backward t))  
   
              (when (and (eq arglist-type 'decl) (looking-at ","))  
                ;; Make sure to propagate the `c-decl-arg-start' property to  
                ;; the next argument if it's set in this one, to cope with  
                ;; interactive refontification.  
                (c-put-char-property (point) 'c-type 'c-decl-arg-start))  
   
              ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'  
              ;; under the assumption that we're after the first type decl  
              ;; expression in the declaration now.  That's not really true; we  
              ;; could also be after a parenthesized initializer expression in  
              ;; C++, but this is only used as a last resort to slant ambiguous  
              ;; expression/declarations, and overall it's worth the risk to  
              ;; occasionally fontify an expression as a declaration in an  
              ;; initializer expression compared to getting ambiguous things in  
              ;; normal function prototypes fontified as expressions.  
              (if inside-macro  
                  (when (> (point) max-type-decl-end-before-token)  
                    (setq max-type-decl-end-before-token (point)))  
                (when (> (point) max-type-decl-end)  
                  (setq max-type-decl-end (point))))  
   
              (when (and at-type (not (eq at-type t)))  
                (let ((c-promote-possible-types t))  
                  (goto-char type-start)  
                  (c-forward-type)))  
   
              (goto-char type-end)  
   
              (let ((decl-list  
                     (if arglist-type  
                         ;; Should normally not fontify a list of declarators  
                         ;; inside an arglist, but the first argument in the  
                         ;; ';' separated list of a "for" statement is an  
                         ;; exception.  
                         (when (and (eq arglist-match ?\() (/= match-pos 0))  
                           (save-excursion  
                             (goto-char (1- match-pos))  
                             (c-backward-syntactic-ws)  
                             (and (c-simple-skip-symbol-backward)  
                                  (looking-at c-paren-stmt-key))))  
                       t)))  
   
                ;; Fix the `c-decl-id-start' or `c-decl-type-start' property  
                ;; before the first declarator if it's a list.  
                ;; `c-font-lock-declarators' handles the rest.  
                (when decl-list  
                  (save-excursion  
                    (c-backward-syntactic-ws)  
                    (unless (bobp)  
                      (c-put-char-property (1- (point)) 'c-type  
                                           (if at-typedef  
                                               'c-decl-type-start  
                                             'c-decl-id-start)))))  
   
                (c-font-lock-declarators (point-max) decl-list at-typedef)))  
   
             (t  
              ;; False alarm.  Skip the fontification done below.  
              (throw 'false-alarm t)))  
   
            ;; A cast or declaration has been successfully identified, so do  
            ;; all the fontification of types and refs that's been recorded by  
            ;; the calls to `c-forward-type' and `c-forward-name' above.  
            (c-fontify-recorded-types-and-refs)  
            nil)))  
1188    
1189        nil)))        nil)))
1190    
# Line 1794  on level 2 only and so aren't combined w Line 1224  on level 2 only and so aren't combined w
1224        ;; Fontify types preceded by `c-type-prefix-kwds' and the        ;; Fontify types preceded by `c-type-prefix-kwds' and the
1225        ;; identifiers in the declarations they might start.        ;; identifiers in the declarations they might start.
1226        ,@(when (c-lang-const c-type-prefix-kwds)        ,@(when (c-lang-const c-type-prefix-kwds)
1227            (let ((prefix-re (c-make-keywords-re nil            (let* ((prefix-re (c-make-keywords-re nil
1228                               (c-lang-const c-type-prefix-kwds))))                                (c-lang-const c-type-prefix-kwds)))
1229                     (type-match (+ 2
1230                                    (regexp-opt-depth prefix-re)
1231                                    (c-lang-const c-simple-ws-depth))))
1232              `((,(c-make-font-lock-search-function              `((,(c-make-font-lock-search-function
1233                   (concat "\\<\\(" prefix-re "\\)"                   (concat "\\<\\(" prefix-re "\\)" ; 1
1234                           "[ \t\n\r\f\v]+"                           (c-lang-const c-simple-ws) "+"
1235                           "\\(" (c-lang-const c-symbol-key) "\\)")                           (concat "\\("  ; 2 + prefix-re + c-simple-ws
1236                   `(,(+ (c-regexp-opt-depth prefix-re) 2)                                   (c-lang-const c-symbol-key)
1237                                     "\\)"))
1238                     `(,type-match
1239                     'font-lock-type-face t)                     'font-lock-type-face t)
1240                   '((c-font-lock-declarators limit t nil)                   `((c-font-lock-declarators limit t nil)
1241                     (save-match-data                     (save-match-data
1242                       (goto-char (match-end 2))                       (goto-char (match-end ,type-match))
1243                       (c-forward-syntactic-ws))                       (c-forward-syntactic-ws))
1244                     (goto-char (match-end 2))))))))                     (goto-char (match-end ,type-match))))))))
1245    
1246        ;; Fontify special declarations that lacks a type.        ;; Fontify special declarations that lacks a type.
1247        ,@(when (c-lang-const c-typeless-decl-kwds)        ,@(when (c-lang-const c-typeless-decl-kwds)
1248            `((,(c-make-font-lock-search-function            `((,(c-make-font-lock-search-function
1249                 (concat "\\<\\("                 (concat "\\<\\("
1250                         (c-regexp-opt (c-lang-const c-typeless-decl-kwds))                         (regexp-opt (c-lang-const c-typeless-decl-kwds))
1251                         "\\)\\>")                         "\\)\\>")
1252                 '((c-font-lock-declarators limit t nil)                 '((c-font-lock-declarators limit t nil)
1253                   (save-match-data                   (save-match-data
1254                     (goto-char (match-end 1))                     (goto-char (match-end 1))
1255                     (c-forward-syntactic-ws))                     (c-forward-syntactic-ws))
1256                   (goto-char (match-end 1)))))))                   (goto-char (match-end 1)))))))
1257        ))  
1258          ;; Fontify generic colon labels in languages that support them.
1259          ,@(when (c-lang-const c-recognize-colon-labels)
1260              `(c-font-lock-labels))))
1261    
1262  (c-lang-defconst c-complex-decl-matchers  (c-lang-defconst c-complex-decl-matchers
1263    "Complex font lock matchers for types and declarations.  Used on level    "Complex font lock matchers for types and declarations.  Used on level
# Line 1828  on level 2 only and so aren't combined w Line 1266  on level 2 only and so aren't combined w
1266    t `(;; Initialize some things before the search functions below.    t `(;; Initialize some things before the search functions below.
1267        c-font-lock-complex-decl-prepare        c-font-lock-complex-decl-prepare
1268    
       ;; Fontify angle bracket arglists like templates in C++.  
       ,@(when (c-lang-const c-recognize-<>-arglists)  
           `(c-font-lock-<>-arglists))  
   
1269        ,@(if (c-major-mode-is 'objc-mode)        ,@(if (c-major-mode-is 'objc-mode)
1270              ;; Fontify method declarations in Objective-C, but first              ;; Fontify method declarations in Objective-C, but first
1271              ;; we have to put the `c-decl-end' `c-type' property on              ;; we have to put the `c-decl-end' `c-type' property on
# Line 1847  on level 2 only and so aren't combined w Line 1281  on level 2 only and so aren't combined w
1281                                    nil)))                                    nil)))
1282                  '((c-put-char-property (1- (match-end 1))                  '((c-put-char-property (1- (match-end 1))
1283                                         'c-type 'c-decl-end)))                                         'c-type 'c-decl-end)))
1284                  c-font-lock-objc-methods))
1285    
1286                c-font-lock-objc-methods)        ;; Fontify all declarations, casts and normal labels.
   
           (when (c-lang-const c-opt-access-key)  
             `(,(c-make-font-lock-search-function  
                 (c-lang-const c-opt-access-key)  
                 '((c-put-char-property (1- (match-end 0))  
                                        'c-type 'c-decl-end))))))  
   
       ;; Fontify all declarations and casts.  
1287        c-font-lock-declarations        c-font-lock-declarations
1288    
1289          ;; Fontify angle bracket arglists like templates in C++.
1290          ,@(when (c-lang-const c-recognize-<>-arglists)
1291              `(c-font-lock-<>-arglists))
1292    
1293        ;; The first two rules here mostly find occurences that        ;; The first two rules here mostly find occurences that
1294        ;; `c-font-lock-declarations' has found already, but not        ;; `c-font-lock-declarations' has found already, but not
1295        ;; declarations containing blocks in the type (see note below).        ;; declarations containing blocks in the type (see note below).
# Line 1870  on level 2 only and so aren't combined w Line 1301  on level 2 only and so aren't combined w
1301                     (c-lang-const c-primitive-type-kwds))))                     (c-lang-const c-primitive-type-kwds))))
1302           (if (c-major-mode-is 'pike-mode)           (if (c-major-mode-is 'pike-mode)
1303               ;; No symbol is a keyword after "->" in Pike.               ;; No symbol is a keyword after "->" in Pike.
1304               `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)"               `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
1305                          "\\<\\(" re "\\)\\>")                          "\\<\\(" re "\\)\\>")
1306                 3 font-lock-type-face)                 2 font-lock-type-face)
1307             `(,(concat "\\<\\(" re "\\)\\>")             `(,(concat "\\<\\(" re "\\)\\>")
1308               1 'font-lock-type-face)))               1 'font-lock-type-face)))
1309    
# Line 1900  on level 2 only and so aren't combined w Line 1331  on level 2 only and so aren't combined w
1331                          (unless (c-skip-comments-and-strings limit)                          (unless (c-skip-comments-and-strings limit)
1332                            (c-forward-syntactic-ws)                            (c-forward-syntactic-ws)
1333                            ;; Handle prefix declaration specifiers.                            ;; Handle prefix declaration specifiers.
1334                            (when (looking-at c-specifier-key)                            (when (looking-at c-prefix-spec-kwds-re)
1335                              (c-forward-keyword-clause))                              (c-forward-keyword-clause 1))
1336                            ,(if (c-major-mode-is 'c++-mode)                            ,(if (c-major-mode-is 'c++-mode)
1337                                 `(when (and (c-forward-type)                                 `(when (and (c-forward-type)
1338                                             (eq (char-after) ?=))                                             (eq (char-after) ?=))
# Line 1949  on level 2 only and so aren't combined w Line 1380  on level 2 only and so aren't combined w
1380        ))        ))
1381    
1382  (defun c-font-lock-labels (limit)  (defun c-font-lock-labels (limit)
1383    ;; Fontify all the declarations from the point to LIMIT.  Assumes    ;; Fontify all statement labels from the point to LIMIT.  Assumes
1384    ;; that strings and comments have been fontified already.  Nil is    ;; that strings and comments have been fontified already.  Nil is
1385    ;; always returned.    ;; always returned.
1386    ;;    ;;
1387    ;; This function can make hidden buffer changes, but the font-lock    ;; Note: This function is only used on decoration level 2; this is
1388    ;; context covers that.    ;; taken care of directly by the gargantuan
1389      ;; `c-font-lock-declarations' on higher levels.
1390      ;;
1391      ;; This function might do hidden buffer changes.
1392    
1393    (let (continue-pos id-start    (let (continue-pos id-start
1394          ;; The font-lock package in Emacs is known to clobber          ;; The font-lock package in Emacs is known to clobber
# Line 2027  higher." Line 1461  higher."
1461                     (c-forward-syntactic-ws))                     (c-forward-syntactic-ws))
1462                   (goto-char (match-end 0)))))))                   (goto-char (match-end 0)))))))
1463    
1464        ;; Fontify labels in languages that supports them.          ;; Fontify labels after goto etc.
1465        ,@(when (c-lang-const c-label-key)          ,@(when (c-lang-const c-before-label-kwds)
1466              `(;; (Got three different interpretation levels here,
           `(;; Fontify labels after goto etc.  
             ;; (Got three different interpretation levels here,  
1467              ;; which makes it a bit complicated: 1) The backquote              ;; which makes it a bit complicated: 1) The backquote
1468              ;; stuff is expanded when compiled or loaded, 2) the              ;; stuff is expanded when compiled or loaded, 2) the
1469              ;; eval form is evaluated at font-lock setup (to              ;; eval form is evaluated at font-lock setup (to
# Line 2048  higher." Line 1480  higher."
1480                               "\\("      ; identifier-offset                               "\\("      ; identifier-offset
1481                               (c-lang-const c-symbol-key)                               (c-lang-const c-symbol-key)
1482                               "\\)")                               "\\)")
1483                      (list ,(+ (c-regexp-opt-depth c-before-label-re) 2)                      (list ,(+ (regexp-opt-depth c-before-label-re) 2)
1484                            c-label-face-name nil t))))                            c-label-face-name nil t))))))
   
             ;; Fontify normal labels.  
             c-font-lock-labels))  
1485    
1486        ;; Fontify the clauses after various keywords.        ;; Fontify the clauses after various keywords.
1487        ,@(when (or (c-lang-const c-type-list-kwds)        ,@(when (or (c-lang-const c-type-list-kwds)
# Line 2068  higher." Line 1497  higher."
1497                                   (c-lang-const c-paren-type-kwds)))                                   (c-lang-const c-paren-type-kwds)))
1498                         "\\)\\>")                         "\\)\\>")
1499                 '((c-fontify-types-and-refs ((c-promote-possible-types t))                 '((c-fontify-types-and-refs ((c-promote-possible-types t))
1500                     (c-forward-keyword-clause)                     (c-forward-keyword-clause 1)
1501                     (if (> (point) limit) (goto-char limit))))))))                     (if (> (point) limit) (goto-char limit))))))))
1502        ))        ))
1503    
# Line 2135  higher." Line 1564  higher."
1564    ;; to override, but we should otoh avoid clobbering a user setting.    ;; to override, but we should otoh avoid clobbering a user setting.
1565    ;; This heuristic for that isn't perfect, but I can't think of any    ;; This heuristic for that isn't perfect, but I can't think of any
1566    ;; better. /mast    ;; better. /mast
   ;;  
   ;; This function does not do any hidden buffer changes.  
1567    (when (and (boundp def-var)    (when (and (boundp def-var)
1568               (memq (symbol-value def-var)               (memq (symbol-value def-var)
1569                     (cons nil                     (cons nil
# Line 2193  need for `c-font-lock-extra-types'.") Line 1620  need for `c-font-lock-extra-types'.")
1620    ;;    ;;
1621    ;; As usual, C++ takes the prize in coming up with a hard to parse    ;; As usual, C++ takes the prize in coming up with a hard to parse
1622    ;; syntax. :P    ;; syntax. :P
1623      ;;
1624      ;; This function might do hidden buffer changes.
1625    
1626    (unless (c-skip-comments-and-strings limit)    (unless (c-skip-comments-and-strings limit)
1627      (save-excursion      (save-excursion
# Line 2338  need for `c++-font-lock-extra-types'.") Line 1767  need for `c++-font-lock-extra-types'.")
1767    
1768  ;;; Objective-C.  ;;; Objective-C.
1769    
 (defun c-font-lock-objc-iip-decl ()  
   ;; Assuming the point is after an "@interface", "@implementation",  
   ;; "@protocol" declaration, fontify all the types in the directive.  
   ;; Return t if the directive was fully recognized.  Point will then  
   ;; be at the end of it.  
   
   (c-fontify-types-and-refs  
       (start-char  
        (c-promote-possible-types t)  
        ;; Turn off recognition of angle bracket arglists while parsing  
        ;; types here since the protocol reference list might then be  
        ;; considered part of the preceding name or superclass-name.  
        c-recognize-<>-arglists)  
     (catch 'break  
   
       ;; Handle the name of the class itself.  
       (c-forward-syntactic-ws)  
       (unless (c-forward-type) (throw 'break nil))  
   
       ;; Look for ": superclass-name" or "( category-name )".  
       (when (looking-at "[:\(]")  
         (setq start-char (char-after))  
         (forward-char)  
         (c-forward-syntactic-ws)  
         (unless (c-forward-type) (throw 'break nil))  
         (when (eq start-char ?\()  
           (unless (eq (char-after) ?\)) (throw 'break nil))  
           (forward-char)  
           (c-forward-syntactic-ws)))  
   
       ;; Look for a protocol reference list.  
       (when (if (eq (char-after) ?<)  
                 (progn  
                   (setq c-recognize-<>-arglists t)  
                   (c-forward-<>-arglist t t))  
               t)  
         (c-put-char-property (1- (point)) 'c-type 'c-decl-end)  
         t))))  
   
1770  (defun c-font-lock-objc-method ()  (defun c-font-lock-objc-method ()
1771    ;; Assuming the point is after the + or - that starts an Objective-C    ;; Assuming the point is after the + or - that starts an Objective-C
1772    ;; method declaration, fontify it.  This must be done before normal    ;; method declaration, fontify it.  This must be done before normal
1773    ;; casts, declarations and labels are fontified since they will get    ;; casts, declarations and labels are fontified since they will get
1774    ;; false matches in these things.    ;; false matches in these things.
1775      ;;
1776      ;; This function might do hidden buffer changes.
1777    
1778    (c-fontify-types-and-refs    (c-fontify-types-and-refs
1779        ((first t)        ((first t)
# Line 2430  need for `c++-font-lock-extra-types'.") Line 1822  need for `c++-font-lock-extra-types'.")
1822  (defun c-font-lock-objc-methods (limit)  (defun c-font-lock-objc-methods (limit)
1823    ;; Fontify method declarations in Objective-C.  Nil is always    ;; Fontify method declarations in Objective-C.  Nil is always
1824    ;; returned.    ;; returned.
1825      ;;
1826      ;; This function might do hidden buffer changes.
1827    
1828    (let (;; The font-lock package in Emacs is known to clobber    (let (;; The font-lock package in Emacs is known to clobber
1829          ;; `parse-sexp-lookup-properties' (when it exists).          ;; `parse-sexp-lookup-properties' (when it exists).
# Line 2605  need for `pike-font-lock-extra-types'.") Line 1999  need for `pike-font-lock-extra-types'.")
1999    ;; Note that faces added through KEYWORDS should never replace the    ;; Note that faces added through KEYWORDS should never replace the
2000    ;; existing `c-doc-face-name' face since the existence of that face    ;; existing `c-doc-face-name' face since the existence of that face
2001    ;; is used as a flag in other code to skip comments.    ;; is used as a flag in other code to skip comments.
2002      ;;
2003      ;; This function might do hidden buffer changes.
2004    
2005    (let (comment-beg region-beg)    (let (comment-beg region-beg)
2006      (if (eq (get-text-property (point) 'face)      (if (eq (get-text-property (point) 'face)
# Line 2686  need for `pike-font-lock-extra-types'.") Line 2082  need for `pike-font-lock-extra-types'.")
2082    ;; between the point and LIMIT that only is fontified with    ;; between the point and LIMIT that only is fontified with
2083    ;; `c-doc-face-name'.  If a match is found then submatch 0 surrounds    ;; `c-doc-face-name'.  If a match is found then submatch 0 surrounds
2084    ;; the first char and t is returned, otherwise nil is returned.    ;; the first char and t is returned, otherwise nil is returned.
2085      ;;
2086      ;; This function might do hidden buffer changes.
2087    (let (start)    (let (start)
2088      (while (if (re-search-forward regexp limit t)      (while (if (re-search-forward regexp limit t)
2089                 (not (eq (get-text-property                 (not (eq (get-text-property
# Line 2697  need for `pike-font-lock-extra-types'.") Line 2095  need for `pike-font-lock-extra-types'.")
2095                                (copy-marker (1+ start))))                                (copy-marker (1+ start))))
2096        t)))        t)))
2097    
2098    ;; GtkDoc patterns contributed by Masatake YAMATO <jet@gyve.org>.
2099    
2100    (defconst gtkdoc-font-lock-doc-comments
2101      (let ((symbol "[a-zA-Z0-9_]+")
2102            (header "^ \\* "))
2103        `((,(concat header "\\("     symbol "\\):[ \t]*$")
2104           1 ,c-doc-markup-face-name prepend nil)
2105          (,(concat                  symbol     "()")
2106           0 ,c-doc-markup-face-name prepend nil)
2107          (,(concat header "\\(" "@" symbol "\\):")
2108           1 ,c-doc-markup-face-name prepend nil)
2109          (,(concat "[#%]" symbol)
2110           0 ,c-doc-markup-face-name prepend nil))
2111        ))
2112    
2113    (defconst gtkdoc-font-lock-doc-protection
2114      `(("< \\(public\\|private\\|protected\\) >"
2115         1 ,c-doc-markup-face-name prepend nil)))
2116    
2117    (defconst gtkdoc-font-lock-keywords
2118      `((,(lambda (limit)
2119            (c-font-lock-doc-comments "/\\*\\*$" limit
2120              gtkdoc-font-lock-doc-comments)
2121            (c-font-lock-doc-comments "/\\*< " limit
2122              gtkdoc-font-lock-doc-protection)
2123            ))))
2124    
2125    ;; Javadoc.
2126    
2127  (defconst javadoc-font-lock-doc-comments  (defconst javadoc-font-lock-doc-comments
2128    `(("{@[a-z]+[^}\n\r]*}"               ; "{@foo ...}" markup.    `(("{@[a-z]+[^}\n\r]*}"               ; "{@foo ...}" markup.
2129       0 ,c-doc-markup-face-name prepend nil)       0 ,c-doc-markup-face-name prepend nil)
2130      ("^\\(/\\*\\)?[ \t*]*\\(@[a-z]+\\)" ; "@foo ..." markup.      ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup.
2131       2 ,c-doc-markup-face-name prepend nil)       3 ,c-doc-markup-face-name prepend nil)
2132      (,(concat "</?\\sw"                 ; HTML tags.      (,(concat "</?\\sw"                 ; HTML tags.
2133                "\\("                "\\("
2134                (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"                (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"
# Line 2715  need for `pike-font-lock-extra-types'.") Line 2142  need for `pike-font-lock-extra-types'.")
2142      ;; allowed in non-markup use.      ;; allowed in non-markup use.
2143      (,(lambda (limit)      (,(lambda (limit)
2144          (c-find-invalid-doc-markup "[<>&]\\|{@" limit))          (c-find-invalid-doc-markup "[<>&]\\|{@" limit))
2145       0 ,c-invalid-face-name prepend nil)))       0 'font-lock-warning-face prepend nil)))
2146    
2147  (defconst javadoc-font-lock-keywords  (defconst javadoc-font-lock-keywords
2148    `((,(lambda (limit)    `((,(lambda (limit)
2149          (c-font-lock-doc-comments "/\\*\\*" limit          (c-font-lock-doc-comments "/\\*\\*" limit
2150            javadoc-font-lock-doc-comments)))))            javadoc-font-lock-doc-comments)))))
2151    
2152    ;; Pike autodoc.
2153    
2154  (defconst autodoc-decl-keywords  (defconst autodoc-decl-keywords
2155    ;; Adorned regexp matching the keywords that introduce declarations    ;; Adorned regexp matching the keywords that introduce declarations
2156    ;; in Pike Autodoc.    ;; in Pike Autodoc.
# Line 2736  need for `pike-font-lock-extra-types'.") Line 2165  need for `pike-font-lock-extra-types'.")
2165  (defun autodoc-font-lock-line-markup (limit)  (defun autodoc-font-lock-line-markup (limit)
2166    ;; Fontify all line oriented keywords between the point and LIMIT.    ;; Fontify all line oriented keywords between the point and LIMIT.
2167    ;; Nil is always returned.    ;; Nil is always returned.
2168      ;;
2169      ;; This function might do hidden buffer changes.
2170    
2171    (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("    (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("
2172                           c-current-comment-prefix                           c-current-comment-prefix
# Line 2765  need for `pike-font-lock-extra-types'.") Line 2196  need for `pike-font-lock-extra-types'.")
2196                       (and (eq (char-before) ?@)                       (and (eq (char-before) ?@)
2197                            (not (eobp))                            (not (eobp))
2198                            (progn (forward-char)                            (progn (forward-char)
2199                                   (skip-chars-forward " \t")                                   (skip-syntax-forward " ")
2200                                   (looking-at c-current-comment-prefix))))                                   (looking-at c-current-comment-prefix))))
2201                (goto-char (match-end 0))                (goto-char (match-end 0))
2202                (c-remove-font-lock-face pos (1- end))                (c-remove-font-lock-face pos (1- end))
# Line 2804  need for `pike-font-lock-extra-types'.") Line 2235  need for `pike-font-lock-extra-types'.")
2235                   (and (eq (char-before) ?@)                   (and (eq (char-before) ?@)
2236                        (not (eobp))                        (not (eobp))
2237                        (progn (forward-char)                        (progn (forward-char)
2238                               (skip-chars-forward " \t")                               (skip-syntax-forward " ")
2239                               (looking-at c-current-comment-prefix))))                               (looking-at c-current-comment-prefix))))
2240            (goto-char (match-end 0))))))            (goto-char (match-end 0))))))
2241    
# Line 2818  need for `pike-font-lock-extra-types'.") Line 2249  need for `pike-font-lock-extra-types'.")
2249      ;; Fontify remaining markup characters as invalid.      ;; Fontify remaining markup characters as invalid.
2250      (,(lambda (limit)      (,(lambda (limit)
2251          (c-find-invalid-doc-markup "@" limit))          (c-find-invalid-doc-markup "@" limit))
2252       0 ,c-invalid-face-name prepend nil)       0 'font-lock-warning-face prepend nil)
2253      ))      ))
2254    
2255  (defun autodoc-font-lock-keywords ()  (defun autodoc-font-lock-keywords ()
2256    ;; Note that we depend on that `c-current-comment-prefix' has got    ;; Note that we depend on that `c-current-comment-prefix' has got
2257    ;; its proper value here.    ;; its proper value here.
2258      ;;
2259      ;; This function might do hidden buffer changes.
2260    
2261    ;; The `c-type' text property with `c-decl-end' is used to mark the    ;; The `c-type' text property with `c-decl-end' is used to mark the
2262    ;; end of the `autodoc-decl-keywords' occurrences to fontify the    ;; end of the `autodoc-decl-keywords' occurrences to fontify the
# Line 2846  need for `pike-font-lock-extra-types'.") Line 2279  need for `pike-font-lock-extra-types'.")
2279       ',(eval-when-compile               ; Evaluate while compiling cc-fonts       ',(eval-when-compile               ; Evaluate while compiling cc-fonts
2280           (list           (list
2281            ;; Function names.            ;; Function names.
2282            '("^[ \t]*\\(func\\(tion\\)?\\)\\>[ \t]*\\(\\sw+\\)?"            '("^\\s *\\(func\\(tion\\)?\\)\\>\\s *\\(\\sw+\\)?"
2283              (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))              (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
2284            ;;            ;;
2285            ;; Variable names.            ;; Variable names.
2286            (cons            (cons
2287             (concat "\\<"             (concat "\\<"
2288                     (c-regexp-opt                     (regexp-opt
2289                      '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON"                      '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON"
2290                        "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE"                        "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE"
2291                        "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH"                        "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH"
# Line 2861  need for `pike-font-lock-extra-types'.") Line 2294  need for `pike-font-lock-extra-types'.")
2294    
2295            ;; Special file names.  (acm, 2002/7/22)            ;; Special file names.  (acm, 2002/7/22)
2296            ;; The following regexp was created by first evaluating this in GNU Emacs 21.1:            ;; The following regexp was created by first evaluating this in GNU Emacs 21.1:
2297            ;; (c-regexp-opt '("/dev/stdin" "/dev/stdout" "/dev/stderr" "/dev/fd/n" "/dev/pid"            ;; (regexp-opt '("/dev/stdin" "/dev/stdout" "/dev/stderr" "/dev/fd/n" "/dev/pid"
2298            ;;                 "/dev/ppid" "/dev/pgrpid" "/dev/user") 'words)            ;;                 "/dev/ppid" "/dev/pgrpid" "/dev/user") 'words)
2299            ;; , removing the "?:" from each "\\(?:" (for backward compatibility with older Emacsen)            ;; , removing the "?:" from each "\\(?:" (for backward compatibility with older Emacsen)
2300            ;; , replacing the "n" in "dev/fd/n" with "[0-9]+"            ;; , replacing the "n" in "dev/fd/n" with "[0-9]+"
# Line 2875  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ Line 2308  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2308              (1 font-lock-variable-name-face t)              (1 font-lock-variable-name-face t)
2309              (8 font-lock-variable-name-face t t))              (8 font-lock-variable-name-face t t))
2310            ;; Do the same (almost) with            ;; Do the same (almost) with
2311            ;; (c-regexp-opt '("/inet/tcp/lport/rhost/rport" "/inet/udp/lport/rhost/rport"            ;; (regexp-opt '("/inet/tcp/lport/rhost/rport" "/inet/udp/lport/rhost/rport"
2312            ;;                 "/inet/raw/lport/rhost/rport") 'words)            ;;                 "/inet/raw/lport/rhost/rport") 'words)
2313            ;; This cannot be combined with the above pattern, because the match number            ;; This cannot be combined with the above pattern, because the match number
2314            ;; for the (optional) closing \" would then exceed 9.            ;; for the (optional) closing \" would then exceed 9.
# Line 2886  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ Line 2319  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2319    
2320            ;; Keywords.            ;; Keywords.
2321            (concat "\\<"            (concat "\\<"
2322                    (c-regexp-opt                    (regexp-opt
2323                     '("BEGIN" "END" "break" "continue" "delete" "do" "else"                     '("BEGIN" "END" "break" "continue" "delete" "do" "else"
2324                       "exit" "for" "getline" "if" "in" "next" "nextfile"                       "exit" "for" "getline" "if" "in" "next" "nextfile"
2325                       "return" "while")                       "return" "while")
# Line 2896  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ Line 2329  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2329            `(eval . (list            `(eval . (list
2330                      ,(concat                      ,(concat
2331                        "\\<"                        "\\<"
2332                        (c-regexp-opt                        (regexp-opt
2333                         '("adump" "and" "asort" "atan2" "bindtextdomain" "close"                         '("adump" "and" "asort" "atan2" "bindtextdomain" "close"
2334                           "compl" "cos" "dcgettext" "exp" "extension" "fflush"                           "compl" "cos" "dcgettext" "exp" "extension" "fflush"
2335                           "gensub" "gsub" "index" "int" "length" "log" "lshift"                           "gensub" "gsub" "index" "int" "length" "log" "lshift"
# Line 2909  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ Line 2342  std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2342    
2343            ;; gawk debugging keywords.  (acm, 2002/7/21)            ;; gawk debugging keywords.  (acm, 2002/7/21)
2344            ;; (Removed, 2003/6/6.  These functions are now fontified as built-ins)            ;; (Removed, 2003/6/6.  These functions are now fontified as built-ins)
2345  ;;      (list (concat "\\<" (c-regexp-opt '("adump" "stopme") t) "\\>")  ;;      (list (concat "\\<" (regexp-opt '("adump" "stopme") t) "\\>")
2346  ;;         0 'font-lock-warning-face)  ;;         0 'font-lock-warning-face)
2347    
2348            ;; User defined functions with an apparent spurious space before the            ;; User defined functions with an apparent spurious space before the
2349            ;; opening parenthesis.  acm, 2002/5/30.            ;; opening parenthesis.  acm, 2002/5/30.
2350            `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "[ \t]"            `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "\\s "
2351                       c-awk-escaped-nls*-with-space* "(")                       c-awk-escaped-nls*-with-space* "(")
2352              (0 'font-lock-warning-face))              (0 'font-lock-warning-face))
2353    
2354            ;; Space after \ in what looks like an escaped newline.  2002/5/31            ;; Space after \ in what looks like an escaped newline.  2002/5/31
2355            '("\\\\[ \t]+$" 0 font-lock-warning-face t)            '("\\\\\\s +$" 0 font-lock-warning-face t)
2356    
2357            ;; Unbalanced string (") or regexp (/) delimiters.  2002/02/16.            ;; Unbalanced string (") or regexp (/) delimiters.  2002/02/16.
2358            '("\\s|" 0 font-lock-warning-face t nil)            '("\\s|" 0 font-lock-warning-face t nil)

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26