SMIE: Reliably distinguish openers/closers in smie-prec2-levels
[bpt/emacs.git] / lisp / progmodes / cc-mode.el
index bd590d6..505a566 100644 (file)
@@ -1,24 +1,25 @@
 ;;; cc-mode.el --- major mode for editing C and similar languages
 
 ;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-;;   Free Software Foundation, Inc.
+;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+;;   2010  Free Software Foundation, Inc.
 
 ;; Authors:    2003- Alan Mackenzie
 ;;             1998- Martin Stjernholm
 ;;             1992-1999 Barry A. Warsaw
-;;             1987 Dave Detlefs and Stewart Clamen
+;;             1987 Dave Detlefs
+;;             1987 Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    a long, long, time ago. adapted from the original c-mode.el
-;; Keywords:   c languages oop
+;; Keywords:   c languages
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,9 +27,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with this program; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
+;; For Emacs < 22.2.
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
 (eval-when-compile
   (let ((load-path
         (if (and (boundp 'byte-compile-dest-file)
 (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
 (cc-bytecomp-defun set-keymap-parents) ; XEmacs
 (cc-bytecomp-defun run-mode-hooks)     ; Emacs 21.1
-(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1.
 
 ;; We set these variables during mode init, yet we don't require
 ;; font-lock.
 
 ;; Autoload directive for emacsen that doesn't have an older CC Mode
 ;; version in the dist.
-(autoload 'c-subword-mode "cc-subword"
+(autoload 'subword-mode "subword"
   "Mode enabling subword movement and editing keys." t)
 
 ;; Load cc-fonts first after font-lock is loaded, since it isn't
@@ -212,12 +214,12 @@ control).  See \"cc-mode.el\" for more info."
     ;; function is called from top-level forms that are evaluated
     ;; while cc-bytecomp is active when one does M-x eval-buffer.
     (cond
-     ;; XEmacs
-     ((cc-bytecomp-fboundp 'set-keymap-parents)
-      (set-keymap-parents map c-mode-base-map))
      ;; Emacs
      ((cc-bytecomp-fboundp 'set-keymap-parent)
       (set-keymap-parent map c-mode-base-map))
+     ;; XEmacs
+     ((cc-bytecomp-fboundp 'set-keymap-parents)
+      (set-keymap-parents map c-mode-base-map))
      ;; incompatible
      (t (error "CC Mode is incompatible with this version of Emacs")))
     map))
@@ -283,8 +285,9 @@ control).  See \"cc-mode.el\" for more info."
 
   ;; RMS says don't make these the default.
   ;; (April 2006): RMS has now approved these commands as defaults.
-  (define-key c-mode-base-map "\e\C-a"    'c-beginning-of-defun)
-  (define-key c-mode-base-map "\e\C-e"    'c-end-of-defun)
+  (unless (memq 'argumentative-bod-function c-emacs-features)
+    (define-key c-mode-base-map "\e\C-a"    'c-beginning-of-defun)
+    (define-key c-mode-base-map "\e\C-e"    'c-end-of-defun))
 
   (define-key c-mode-base-map "\C-c\C-n"  'c-forward-conditional)
   (define-key c-mode-base-map "\C-c\C-p"  'c-backward-conditional)
@@ -375,7 +378,7 @@ control).  See \"cc-mode.el\" for more info."
   ;; conflicts with OOBR
   ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
   ;; (define-key c-mode-base-map "\C-c\C-y"  'c-toggle-hungry-state)  Commented out by ACM, 2005-11-22.
-  (define-key c-mode-base-map "\C-c\C-w" 'c-subword-mode)
+  (define-key c-mode-base-map "\C-c\C-w" 'subword-mode)
   )
 
 ;; We don't require the outline package, but we configure it a bit anyway.
@@ -406,7 +409,7 @@ preferably use the `c-mode-menu' language constant directly."
 ;; temporary changes in some font lock support modes, causing extra
 ;; unnecessary work and font lock glitches due to interactions between
 ;; various text properties.
-;; 
+;;
 ;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any
 ;; more.
 
@@ -447,18 +450,18 @@ preferably use the `c-mode-menu' language constant directly."
                              end (point))))))))
 
 ;; c-maybe-stale-found-type records a place near the region being
-;; changed where an element of `found-types' might become stale.  It 
+;; changed where an element of `found-types' might become stale.  It
 ;; is set in c-before-change and is either nil, or has the form:
 ;;
 ;;   (c-decl-id-start "foo" 97 107  " (* ooka) " "o"), where
-;;   
+;;
 ;; o - `c-decl-id-start' is the c-type text property value at buffer
 ;;   pos 96.
-;; 
+;;
 ;; o - 97 107 is the region potentially containing the stale type -
 ;;   this is delimited by a non-nil c-type text property at 96 and
 ;;   either another one or a ";", "{", or "}" at 107.
-;; 
+;;
 ;; o - " (* ooka) " is the (before change) buffer portion containing
 ;;   the suspect type (here "ooka").
 ;;
@@ -513,9 +516,12 @@ that requires a literal mode spec at compile time."
   (make-local-variable 'fill-paragraph-function)
   (setq fill-paragraph-function 'c-fill-paragraph)
 
+  ;; Initialise the cache of brace pairs, and opening braces/brackets/parens.
+  (c-state-cache-init)
+
   (when (or c-recognize-<>-arglists
            (c-major-mode-is 'awk-mode)
-           (c-major-mode-is '(c-mode c++-mode objc-mode)))
+           (c-major-mode-is '(java-mode c-mode c++-mode objc-mode)))
     ;; We'll use the syntax-table text property to change the syntax
     ;; of some chars for this language, so do the necessary setup for
     ;; that.
@@ -534,19 +540,15 @@ that requires a literal mode spec at compile time."
       (make-local-variable 'lookup-syntax-properties)
       (setq lookup-syntax-properties t)))
 
-  ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky
+  ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
   ;; property on each character.
   (when (boundp 'text-property-default-nonsticky)
     (make-local-variable 'text-property-default-nonsticky)
-    (let ((elem (assq 'syntax-table text-property-default-nonsticky)))
-      (if elem
-         (setcdr elem t)
-       (setq text-property-default-nonsticky
-             (cons '(syntax-table . t)
-                   text-property-default-nonsticky))))
-    (setq text-property-default-nonsticky
-         (cons '(c-type . t)
-               text-property-default-nonsticky)))
+    (mapc (lambda (tprop)
+           (unless (assq tprop text-property-default-nonsticky)
+             (setq text-property-default-nonsticky
+                   (cons `(,tprop . t) text-property-default-nonsticky))))
+         '(syntax-table category c-type)))
 
   ;; In Emacs 21 and later it's possible to turn off the ad-hoc
   ;; heuristic that open parens in column 0 are defun starters.  Since
@@ -597,12 +599,14 @@ that requires a literal mode spec at compile time."
 
   ;; Install the functions that ensure that various internal caches
   ;; don't become invalid due to buffer changes.
-  (make-local-hook 'before-change-functions)
+  (when (featurep 'xemacs)
+    (make-local-hook 'before-change-functions)
+    (make-local-hook 'after-change-functions))
   (add-hook 'before-change-functions 'c-before-change nil t)
-  (make-local-hook 'after-change-functions)
   (add-hook 'after-change-functions 'c-after-change nil t)
   (set (make-local-variable 'font-lock-extend-after-change-region-function)
-       'c-extend-after-change-region)) ; Currently (2008-04), only used by AWK.
+       'c-extend-after-change-region)) ; Currently (2009-05) used by all
+                       ; lanaguages with #define (C, C++,; ObjC), and by AWK.
 
 (defun c-setup-doc-comment-style ()
   "Initialize the variables that depend on the value of `c-doc-comment-style'."
@@ -612,6 +616,15 @@ that requires a literal mode spec at compile time."
     (font-lock-mode 0)
     (font-lock-mode 1)))
 
+;; Buffer local variables defining the region to be fontified by a font lock
+;; after-change function.  They are set in c-after-change to
+;; after-change-function's BEG and END, and may be modified by a
+;; `c-before-font-lock-function'.
+(defvar c-new-BEG 0)
+(make-variable-buffer-local 'c-new-BEG)
+(defvar c-new-END 0)
+(make-variable-buffer-local 'c-new-END)
+
 (defun c-common-init (&optional mode)
   "Common initialization for all CC Mode modes.
 In addition to the work done by `c-basic-common-init' and
@@ -636,9 +649,13 @@ compatible with old code; callers should always specify it."
   ;; Starting a mode is a sort of "change".  So call the change functions...
   (save-restriction
     (widen)
+    (setq c-new-BEG (point-min))
+    (setq c-new-END (point-max))
     (save-excursion
-      (if c-get-state-before-change-function
-         (funcall c-get-state-before-change-function (point-min) (point-max)))
+      (if c-get-state-before-change-functions
+         (mapc (lambda (fn)
+                 (funcall fn (point-min) (point-max)))
+               c-get-state-before-change-functions))
       (if c-before-font-lock-function
          (funcall c-before-font-lock-function (point-min) (point-max)
                   (- (point-max) (point-min))))))
@@ -654,6 +671,50 @@ compatible with old code; callers should always specify it."
       (and (cdr rfn)
           (setq require-final-newline mode-require-final-newline)))))
 
+(defun c-count-cfss (lv-alist)
+  ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
+  ;; elements with the key `c-file-style' there are in it.
+  (let ((elt-ptr lv-alist) elt (cownt 0))
+    (while elt-ptr
+      (setq elt (car elt-ptr)
+           elt-ptr (cdr elt-ptr))
+      (when (eq (car elt) 'c-file-style)
+       (setq cownt (1+ cownt))))
+    cownt))
+                                                         
+(defun c-before-hack-hook ()
+  "Set the CC Mode style and \"offsets\" when in the buffer's local variables.
+They are set only when, respectively, the pseudo variables
+`c-file-style' and `c-file-offsets' are present in the list.
+
+This function is called from the hook `before-hack-local-variables-hook'."
+  (when c-buffer-is-cc-mode
+    (let ((mode-cons (assq 'mode file-local-variables-alist))
+         (stile (cdr (assq 'c-file-style file-local-variables-alist)))
+         (offsets (cdr (assq 'c-file-offsets file-local-variables-alist))))
+      (when mode-cons
+       (hack-one-local-variable (car mode-cons) (cdr mode-cons))
+       (setq file-local-variables-alist
+             (delq mode-cons file-local-variables-alist)))
+      (when stile
+       (or (stringp stile) (error "c-file-style is not a string"))
+       (if (boundp 'dir-local-variables-alist)
+           ;; Determine whether `c-file-style' was set in the file's local
+           ;; variables or in a .dir-locals.el (a directory setting).
+           (let ((cfs-in-file-and-dir-count
+                  (c-count-cfss file-local-variables-alist))
+                 (cfs-in-dir-count (c-count-cfss dir-local-variables-alist)))
+             (c-set-style stile
+                          (= cfs-in-file-and-dir-count cfs-in-dir-count)))
+         (c-set-style stile)))
+      (when offsets
+       (mapc
+        (lambda (langentry)
+          (let ((langelem (car langentry))
+                (offset (cdr langentry)))
+            (c-set-offset langelem offset)))
+        offsets)))))
+
 (defun c-remove-any-local-eval-or-mode-variables ()
   ;; If the buffer specifies `mode' or `eval' in its File Local Variable list
   ;; or on the first line, remove all occurrences.  See
@@ -713,8 +774,11 @@ Note that the style variables are always made local to the buffer."
   (when c-buffer-is-cc-mode
     (if (or c-file-style c-file-offsets)
        (c-make-styles-buffer-local t))
-    (and c-file-style
-        (c-set-style c-file-style))
+    (when c-file-style
+      (or (stringp c-file-style)
+         (error "c-file-style is not a string"))
+      (c-set-style c-file-style))
+
     (and c-file-offsets
         (mapc
          (lambda (langentry)
@@ -742,11 +806,13 @@ Note that the style variables are always made local to the buffer."
            (hack-local-variables))
          nil))))
 
-(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
+(if (boundp 'before-hack-local-variables-hook)
+    (add-hook 'before-hack-local-variables-hook 'c-before-hack-hook)
+  (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
 
 (defmacro c-run-mode-hooks (&rest hooks)
   ;; Emacs 21.1 has introduced a system with delayed mode hooks that
-  ;; require the use of the new function `run-mode-hooks'.
+  ;; requires the use of the new function `run-mode-hooks'.
   (if (cc-bytecomp-fboundp 'run-mode-hooks)
       `(run-mode-hooks ,@hooks)
     `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks))))
@@ -754,15 +820,6 @@ Note that the style variables are always made local to the buffer."
 \f
 ;;; Change hooks, linking with Font Lock.
 
-;; Buffer local variables defining the region to be fontified by a font lock
-;; after-change function.  They are set in c-after-change to
-;; after-change-function's BEG and END, and may be modified by a
-;; `c-before-font-lock-function'.
-(defvar c-new-BEG 0)
-(make-variable-buffer-local 'c-new-BEG)
-(defvar c-new-END 0)
-(make-variable-buffer-local 'c-new-END)
-
 ;; Buffer local variables recording Beginning/End-of-Macro position before a
 ;; change, when a macro straddles, respectively, the BEG or END (or both) of
 ;; the change region.  Otherwise these have the values BEG/END.
@@ -779,51 +836,64 @@ Note that the style variables are always made local to the buffer."
   ;; has already been widened, and match-data saved.  The return value is
   ;; meaningless.
   ;;
-  ;; This function is the C/C++/ObjC value of
-  ;; `c-get-state-before-change-function' and is called exclusively as a
+  ;; This function is in the C/C++/ObjC values of
+  ;; `c-get-state-before-change-functions' and is called exclusively as a
   ;; before change function.
   (goto-char beg)
   (c-beginning-of-macro)
   (setq c-old-BOM (point))
 
   (goto-char end)
-  (if (c-beginning-of-macro)
-    (c-end-of-macro))
+  (when (c-beginning-of-macro)
+    (c-end-of-macro)
+    (or (eobp) (forward-char)))         ; Over the terminating NL which may be marked
+                                ; with a c-cpp-delimiter category property
   (setq c-old-EOM (point)))
 
 (defun c-neutralize-CPP-line (beg end)
-  ;; BEG and END bound a preprocessor line.  Put a "punctuation" syntax-table
-  ;; property on syntactically obtrusive characters, ones which would interact
-  ;; syntactically with stuff outside the CPP line.
+  ;; BEG and END bound a region, typically a preprocessor line.  Put a
+  ;; "punctuation" syntax-table property on syntactically obtrusive
+  ;; characters, ones which would interact syntactically with stuff outside
+  ;; this region.
   ;;
   ;; These are unmatched string delimiters, or unmatched
   ;; parens/brackets/braces.  An unclosed comment is regarded as valid, NOT
   ;; obtrusive.
-  (let (s)
-    (while
-       (progn
-         (setq s (parse-partial-sexp beg end -1))
-         (cond
-          ((< (nth 0 s) 0)             ; found an unmated ),},]
-           (c-put-char-property (1- (point)) 'syntax-table '(1))
-           t)
-          ((nth 3 s)                   ; In a string
-           (c-put-char-property (nth 8 s) 'syntax-table '(1))
-           t)
-          ((> (nth 0 s) 0)             ; In a (,{,[
-           (c-put-char-property (nth 1 s) 'syntax-table '(1))
-           t)
-          (t nil))))))
-
-(defun c-neutralize-syntax-in-CPP (begg endd old-len)
-  ;; "Neutralize" every preprocessor line wholly or partially in the changed
-  ;; region.  "Restore" lines which were CPP lines before the change and are
-  ;; no longer so; these can be located from the Buffer local variables
-  ;; c-old-[EB]OM.
+  (save-excursion
+    (let (s)
+      (while
+         (progn
+           (setq s (parse-partial-sexp beg end -1))
+           (cond
+            ((< (nth 0 s) 0)           ; found an unmated ),},]
+             (c-put-char-property (1- (point)) 'syntax-table '(1))
+             t)
+            ((nth 3 s)                 ; In a string
+             (c-put-char-property (nth 8 s) 'syntax-table '(1))
+             t)
+            ((> (nth 0 s) 0)           ; In a (,{,[
+             (c-put-char-property (nth 1 s) 'syntax-table '(1))
+             t)
+            (t nil)))))))
+
+(defun c-neutralize-syntax-in-and-mark-CPP (begg endd old-len)
+  ;; (i) Extend the font lock region to cover all changed preprocessor
+  ;; regions; it does this by setting the variables `c-new-BEG' and
+  ;; `c-new-END' to the new boundaries.
   ;; 
+  ;; (ii) "Neutralize" every preprocessor line wholly or partially in the
+  ;; extended changed region.  "Restore" lines which were CPP lines before the
+  ;; change and are no longer so; these can be located from the Buffer local
+  ;; variables `c-old-BOM' and `c-old-EOM'.
+  ;;
+  ;; (iii) Mark every CPP construct by placing a `category' property value
+  ;; `c-cpp-delimiter' at its start and end.  The marked characters are the
+  ;; opening # and usually the terminating EOL, but sometimes the character
+  ;; before a comment/string delimiter.
+  ;;
   ;; That is, set syntax-table properties on characters that would otherwise
   ;; interact syntactically with those outside the CPP line(s).
-  ;; 
+  ;;
   ;; This function is called from an after-change function, BEGG ENDD and
   ;; OLD-LEN being the standard parameters.  It prepares the buffer for font
   ;; locking, hence must get called before `font-lock-after-change-function'.
@@ -833,35 +903,63 @@ Note that the style variables are always made local to the buffer."
   ;;
   ;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
   ;;
-  ;; This function might do invisible changes.
-  (c-save-buffer-state (limits mbeg+1 beg end)
-    ;; First calculate the region, possibly to be extended.
-    (setq beg (min begg c-old-BOM))
+  ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
+  ;;
+  ;; This function might make hidden buffer changes.
+  (c-save-buffer-state (limits)
+    ;; First determine the region, (c-new-BEG c-new-END), which will get font
+    ;; locked.  It might need "neutralizing".  This region may not start
+    ;; inside a string, comment, or macro.
+    (goto-char c-old-BOM)        ; already set to old start of macro or begg.
+    (setq c-new-BEG
+         (min c-new-BEG
+              (if (setq limits (c-state-literal-at (point)))
+                  (cdr limits)     ; go forward out of any string or comment.
+                (point))))
+
     (goto-char endd)
-    (when (c-beginning-of-macro)
-      (c-end-of-macro))
-    (setq end (max (+ (- c-old-EOM old-len) (- endd begg))
-                  (point)))
-    ;; Clear all old punctuation properties
-    (c-clear-char-property-with-value beg end 'syntax-table '(1))
-
-    (goto-char beg)
-    (while (and (< (point) end)
-               (search-forward-regexp c-anchored-cpp-prefix end t))
-      ;; If we've found a "#" inside a string/comment, ignore it.
-      (if (setq limits (c-literal-limits))
-         (goto-char (cdr limits))
-       (setq mbeg+1 (point))
-       (c-end-of-macro)          ; Do we need to go forward 1 char here?  No!
-       (c-neutralize-CPP-line mbeg+1 (point))))))
+    (if (setq limits (c-state-literal-at (point)))
+       (goto-char (car limits)))  ; go backward out of any string or comment.
+    (if (c-beginning-of-macro)
+       (c-end-of-macro))
+    (setq c-new-END (max c-new-END
+                        (+ (- c-old-EOM old-len) (- endd begg))
+                        (point)))
+
+    ;; Clear all old relevant properties.
+    (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
+    (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter)
+    ;; FIXME!!!  What about the "<" and ">" category properties?  2009-11-16
+
+    ;; Add needed properties to each CPP construct in the region.
+    (goto-char c-new-BEG)
+    (let ((pps-position c-new-BEG)  pps-state mbeg)
+      (while (and (< (point) c-new-END)
+                 (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
+       ;; If we've found a "#" inside a string/comment, ignore it.
+       (setq pps-state
+             (parse-partial-sexp pps-position (point) nil nil pps-state)
+             pps-position (point))
+       (unless (or (nth 3 pps-state)   ; in a string?
+                   (nth 4 pps-state))  ; in a comment?
+         (goto-char (match-beginning 0))
+         (setq mbeg (point))
+         (if (> (c-syntactic-end-of-macro) mbeg)
+             (progn
+               (c-neutralize-CPP-line mbeg (point))
+               (c-set-cpp-delimiters mbeg (point))
+               ;(setq pps-position (point))
+               )
+           (forward-line))           ; no infinite loop with, e.g., "#//"
+         )))))
 
 (defun c-before-change (beg end)
-  ;; Function to be put on `before-change-function'.  Primarily, this calls
-  ;; the language dependent `c-get-state-before-change-function'.  It is
+  ;; Function to be put on `before-change-functions'.  Primarily, this calls
+  ;; the language dependent `c-get-state-before-change-functions'.  It is
   ;; otherwise used only to remove stale entries from the `c-found-types'
   ;; cache, and to record entries which a `c-after-change' function might
   ;; confirm as stale.
-  ;; 
+  ;;
   ;; Note that this function must be FAST rather than accurate.  Note
   ;; also that it only has any effect when font locking is enabled.
   ;; We exploit this by checking for font-lock-*-face instead of doing
@@ -931,10 +1029,14 @@ Note that the style variables are always made local to the buffer."
                            (buffer-substring-no-properties type-pos term-pos)
                            (buffer-substring-no-properties beg end)))))))
 
+       ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
+       ;; larger than (beg end).
        (setq c-new-BEG beg
              c-new-END end)
-       (if c-get-state-before-change-function
-           (funcall c-get-state-before-change-function beg end))
+       (if c-get-state-before-change-functions
+           (mapc (lambda (fn)
+                   (funcall fn beg end))
+                 c-get-state-before-change-functions))
        ))))
 
 (defun c-after-change (beg end old-len)
@@ -968,6 +1070,14 @@ Note that the style variables are always made local to the buffer."
          (when (> beg end)
            (setq beg end)))
 
+       ;; C-y is capable of spuriously converting category properties
+       ;; c-</>-as-paren-syntax into hard syntax-table properties.  Remove
+       ;; these when it happens.
+       (c-clear-char-property-with-value beg end 'syntax-table
+                                         c-<-as-paren-syntax)
+       (c-clear-char-property-with-value beg end 'syntax-table
+                                         c->-as-paren-syntax)
+
        (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
        (c-invalidate-sws-region-after beg end)
        (c-invalidate-state-cache beg)
@@ -1001,11 +1111,10 @@ This does not load the font-lock package.  Use after
          nil nil
          ,c-identifier-syntax-modifications
          c-beginning-of-syntax
-         (font-lock-lines-before . 1)
          (font-lock-mark-block-function
           . c-mark-function)))
-
-  (make-local-hook 'font-lock-mode-hook)
+  (if (featurep 'xemacs)
+      (make-local-hook 'font-lock-mode-hook))
   (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
 
 (defun c-extend-after-change-region (beg end old-len)
@@ -1016,8 +1125,9 @@ This does not load the font-lock package.  Use after
   ;; font-lock-extend-after-change-region-function, is forced to use advice
   ;; instead.
   ;;
-  ;; Of the seven CC Mode languages, currently (2008-04) only AWK Mode makes
-  ;; non-null use of this function.
+  ;; Of the seven CC Mode languages, currently (2009-05) only C, C++, Objc
+  ;; (the languages with #define) and AWK Mode make non-null use of this
+  ;; function.
   (cons c-new-BEG c-new-END))
 
 \f
@@ -1054,8 +1164,8 @@ This does not load the font-lock package.  Use after
 ;; which could cause it to clobber user settings.  Later emacsen have
 ;; an append option, but it's not safe to use.
 
-;; The the extension ".C" is associated to C++ while the lowercase
-;; variant goes to C.  On case insensitive file systems, this means
+;; The extension ".C" is associated with C++ while the lowercase
+;; variant goes with C.  On case insensitive file systems, this means
 ;; that ".c" files also might open C++ mode if the C++ entry comes
 ;; first on `auto-mode-alist'.  Thus we try to ensure that ".C" comes
 ;; after ".c", and since `add-to-list' adds the entry first we have to
@@ -1072,6 +1182,11 @@ This does not load the font-lock package.  Use after
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.y\\(acc\\)?\\'" . c-mode))
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.lex\\'" . c-mode))
 
+;; Preprocessed files generated by C and C++ compilers.
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.i\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.ii\\'" . c++-mode))
+
+
 ;;;###autoload
 (defun c-mode ()
   "Major mode for editing K&R and ANSI C code.
@@ -1456,6 +1571,10 @@ Key bindings:
 (easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands"
                  (cons "AWK" (c-lang-const c-mode-menu awk)))
 
+;; (require 'cc-awk) brings these in.
+(defvar awk-mode-syntax-table)
+(declare-function c-awk-unstick-NL-prop "cc-awk" ())
+
 (defun awk-mode ()
   "Major mode for editing AWK code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from an