emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 5175053: Merge some of the differences from the sta


From: Stefan Monnier
Subject: [Emacs-diffs] master 5175053: Merge some of the differences from the standalone CC-mode.
Date: Mon, 01 Dec 2014 20:06:57 +0000

branch: master
commit 517505322a965a042d2d05385a25f7c13704e022
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    Merge some of the differences from the standalone CC-mode.
    
    The main change is to only use the `category' text-property only when
    available.  For that many calls are changed to use c-get-char-property,
    c-next-single-property-change, c-sc-scan-lists,
    c-sc-parse-partial-sexp, c-unmark-<->-as-paren.
    
    * lisp/progmodes/cc-align.el (c-lineup-respect-col-0): New function.
    
    * lisp/progmodes/cc-cmds.el (c-forward-into-nomenclature)
    (c-backward-into-nomenclature): Use cc-subword if subword-mode is
    not available.
    (c-beginning-of-defun, c-end-of-defun, c-mark-function)
    (c-indent-line-or-region): Use c-region-is-active-p.
    
    * lisp/progmodes/cc-defs.el (c-version): Bump up to 5.33.
    (c-use-category): New const.
    (c-next-single-property-change): New macro.
    (c-region-is-active-p): Prefer region-active-p when available.
    (c-search-backward-char-property): Fix old min/max typo; probably
    a copy/paste error.
    (c-mark-<-as-paren, c-mark->-as-paren, c-unmark-<->-as-paren):
    Turn them into macros that obey c-use-category.
    (c-sc-scan-lists-no-category+1+1, c-sc-scan-lists-no-category+1-1)
    (c-sc-scan-lists-no-category-1+1, c-sc-scan-lists-no-category-1-1)
    (c-sc-scan-lists, c-sc-parse-partial-sexp)
    (c-looking-at-non-alphnumspace): New macros.
    (c-sc-parse-partial-sexp-no-category): New function.
    (c-emacs-features): Add `category-properties' element.
    
    * lisp/progmodes/cc-engine.el (c-invalidate-state-cache, c-parse-state):
    Handle the case where categories are not available.
    (c-record-parse-state-state, c-replay-parse-state-state):
    Handle marker values.
    (c-before-change-check-<>-operators): Look for the `syntax-table'
    property rather than for the corresponding `category'.
    (c-looking-at-decl-block): Remove unused var
    `c-disallow-comma-in-<>-arglists'.
    (c-forward-<>-arglist-recur): Remove unused var
    `orig-record-found-types'.
    
    * lisp/progmodes/cc-langs.el (c-modified-constant): New lang var.
    (c-known-type-key): Don't make a list just to throw it away.
    
    * lisp/progmodes/cc-bytecomp.el (cc-bytecomp-unbound-variables)
    (cc-bytecomp-original-functions, cc-bytecomp-original-properties)
    (cc-bytecomp-loaded-files): Re-set each time the file is loaded.
    (cc-bytecomp-obsolete-var, cc-bytecomp-ignore-obsolete)
    (cc-bytecomp-obsolete-fun): Delete unused functions.
    
    * lisp/progmodes/cc-mode.el (c-just-done-before-change): New var.
    (c-basic-common-init): Initialize it.
    (c-common-init): Only use mode-require-final-newline when available.
    (c-before-change): Check and set c-just-done-before-change.
    (c-after-change): Re-set c-just-done-before-change.
    (c-advise-fl-for-region): New macro.
    (lazy-lock-defer-rest-after-change, lazy-lock-defer-line-after-change)
    (font-lock-after-change-function, jit-lock-after-change):
    Advise if needed.
---
 lisp/ChangeLog                |   62 ++++++++++-
 lisp/progmodes/cc-align.el    |   16 +++
 lisp/progmodes/cc-awk.el      |    4 +
 lisp/progmodes/cc-bytecomp.el |   40 ++-----
 lisp/progmodes/cc-cmds.el     |   38 +++++--
 lisp/progmodes/cc-defs.el     |  240 ++++++++++++++++++++++++++++++++++-------
 lisp/progmodes/cc-engine.el   |  230 +++++++++++++++++++++------------------
 lisp/progmodes/cc-fonts.el    |    9 +-
 lisp/progmodes/cc-guess.el    |    5 +
 lisp/progmodes/cc-langs.el    |   36 ++++--
 lisp/progmodes/cc-menus.el    |    6 +-
 lisp/progmodes/cc-mode.el     |  198 +++++++++++++++++++++-------------
 lisp/progmodes/cc-styles.el   |   22 +++--
 lisp/progmodes/cc-vars.el     |   11 ++-
 14 files changed, 627 insertions(+), 290 deletions(-)

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 762b248..e0b0ca6 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,7 +1,63 @@
-2014-12-01  Lars Magne Ingebrigtsen  <address@hidden>
+2014-12-01  Stefan Monnier  <address@hidden>
 
-       * net/shr.el (shr-dom-print): Fix up `shr-dom-print' after the
-       dom.el changes.
+       Merge some of the differences from the standalone CC-mode.
+       The main change is to only use the `category' text-property only when
+       available.  For that many calls are changed to use c-get-char-property,
+       c-next-single-property-change, c-sc-scan-lists,
+       c-sc-parse-partial-sexp, c-unmark-<->-as-paren.
+
+       * progmodes/cc-mode.el (c-just-done-before-change): New var.
+       (c-basic-common-init): Initialize it.
+       (c-common-init): Only use mode-require-final-newline when available.
+       (c-before-change): Check and set c-just-done-before-change.
+       (c-after-change): Re-set c-just-done-before-change.
+       (c-advise-fl-for-region): New macro.
+       (lazy-lock-defer-rest-after-change, lazy-lock-defer-line-after-change)
+       (font-lock-after-change-function, jit-lock-after-change):
+       Advise if needed.
+
+       * progmodes/cc-langs.el (c-modified-constant): New lang var.
+       (c-known-type-key): Don't make a list just to throw it away.
+
+       * progmodes/cc-engine.el (c-invalidate-state-cache, c-parse-state):
+       Handle the case where categories are not available.
+       (c-record-parse-state-state, c-replay-parse-state-state):
+       Handle marker values.
+       (c-before-change-check-<>-operators): Look for the `syntax-table'
+       property rather than for the corresponding `category'.
+       (c-looking-at-decl-block): Remove unused var
+       `c-disallow-comma-in-<>-arglists'.
+       (c-forward-<>-arglist-recur): Remove unused var
+       `orig-record-found-types'.
+
+       * progmodes/cc-defs.el (c-version): Bump up to 5.33.
+       (c-use-category): New const.
+       (c-next-single-property-change): New macro.
+       (c-region-is-active-p): Prefer region-active-p when available.
+       (c-search-backward-char-property): Fix old min/max typo; probably
+       a copy/paste error.
+       (c-mark-<-as-paren, c-mark->-as-paren, c-unmark-<->-as-paren):
+       Turn them into macros that obey c-use-category.
+       (c-sc-scan-lists-no-category+1+1, c-sc-scan-lists-no-category+1-1)
+       (c-sc-scan-lists-no-category-1+1, c-sc-scan-lists-no-category-1-1)
+       (c-sc-scan-lists, c-sc-parse-partial-sexp)
+       (c-looking-at-non-alphnumspace): New macros.
+       (c-sc-parse-partial-sexp-no-category): New function.
+       (c-emacs-features): Add `category-properties' element.
+
+       * progmodes/cc-cmds.el (c-forward-into-nomenclature)
+       (c-backward-into-nomenclature): Use cc-subword if subword-mode is
+       not available.
+       (c-beginning-of-defun, c-end-of-defun, c-mark-function)
+       (c-indent-line-or-region): Use c-region-is-active-p.
+
+       * progmodes/cc-bytecomp.el (cc-bytecomp-unbound-variables)
+       (cc-bytecomp-original-functions, cc-bytecomp-original-properties)
+       (cc-bytecomp-loaded-files): Re-set each time the file is loaded.
+       (cc-bytecomp-obsolete-var, cc-bytecomp-ignore-obsolete)
+       (cc-bytecomp-obsolete-fun): Delete unused functions.
+
+       * progmodes/cc-align.el (c-lineup-respect-col-0): New function.
 
 2014-12-01  Stefan Monnier  <address@hidden>
 
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 05d796c..5800dc9 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -1229,6 +1229,18 @@ Works with: Any syntactic symbol."
     (back-to-indentation)
     (vector (current-column))))
 
+(defun c-lineup-respect-col-0 (langelem)
+  "If the current line starts at column 0, return [0].  Otherwise return nil.
+
+This can be used for comments (in conjunction with, say,
+`c-lineup-comment'), to keep comments already at column 0
+anchored there, but reindent other comments."
+  (save-excursion
+    (back-to-indentation)
+    (if (eq (current-column) 0)
+       [0]
+      nil)))
+
 
 (defun c-snug-do-while (syntax pos)
   "Dynamically calculate brace hanginess for do-while statements.
@@ -1333,4 +1345,8 @@ For other semicolon contexts, no determination is made."
 
 (cc-provide 'cc-align)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-align.el ends here
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index d57d601..2fcd0fd 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -1146,4 +1146,8 @@ comment at the start of cc-engine.el for more info."
 
 (cc-provide 'cc-awk)                   ; Changed from 'awk-mode, ACM 2002/5/21
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; awk-mode.el ends here
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index 1936627..2db5a10 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -65,8 +65,7 @@
 ;; elsewhere in the load path.
 ;;
 ;; To suppress byte compiler warnings, use the macros
-;; `cc-bytecomp-defun', `cc-bytecomp-defvar',
-;; `cc-bytecomp-obsolete-fun', and `cc-bytecomp-obsolete-var'.
+;; `cc-bytecomp-defun' and `cc-bytecomp-defvar'.
 ;;
 ;; This file is not used at all after the package has been byte
 ;; compiled.  It is however necessary when running uncompiled.
@@ -78,6 +77,12 @@
 (defvar cc-bytecomp-original-functions nil)
 (defvar cc-bytecomp-original-properties nil)
 (defvar cc-bytecomp-loaded-files nil)
+
+(setq cc-bytecomp-unbound-variables nil)
+(setq cc-bytecomp-original-functions nil)
+(setq cc-bytecomp-original-properties nil)
+(setq cc-bytecomp-loaded-files nil)
+
 (defvar cc-bytecomp-environment-set nil)
 
 (defmacro cc-bytecomp-debug-msg (&rest args)
@@ -370,33 +375,6 @@ the file.  Don't use outside `eval-when-compile'."
       "cc-bytecomp-put: Bound property %s for %s to %s"
       ,propname ,symbol ,value)))
 
-(defmacro cc-bytecomp-obsolete-var (symbol)
-  "Suppress warnings that the given symbol is an obsolete variable.
-Don't use within `eval-when-compile'."
-  `(eval-when-compile
-     (if (get ',symbol 'byte-obsolete-variable)
-        (cc-bytecomp-put ',symbol 'byte-obsolete-variable nil)
-       ;; This avoids a superfluous compiler warning
-       ;; about calling `get' for effect.
-       t)))
-
-(defun cc-bytecomp-ignore-obsolete (form)
-  ;; Wraps a call to `byte-compile-obsolete' that suppresses the warning.
-  (let ((byte-compile-warnings byte-compile-warnings))
-    (byte-compile-disable-warning 'obsolete)
-    (byte-compile-obsolete form)))
-
-(defmacro cc-bytecomp-obsolete-fun (symbol)
-  "Suppress warnings that the given symbol is an obsolete function.
-Don't use within `eval-when-compile'."
-  `(eval-when-compile
-     (if (eq (get ',symbol 'byte-compile) 'byte-compile-obsolete)
-        (cc-bytecomp-put ',symbol 'byte-compile
-                         'cc-bytecomp-ignore-obsolete)
-       ;; This avoids a superfluous compiler warning
-       ;; about calling `get' for effect.
-       t)))
-
 (defmacro cc-bytecomp-boundp (symbol)
   "Return non-nil if the given symbol is bound as a variable outside
 the compilation.  This is the same as using `boundp' but additionally
@@ -423,4 +401,8 @@ exclude any functions that have been bound during 
compilation with
 
 (provide 'cc-bytecomp)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-bytecomp.el ends here
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 50cdd78..55b676b 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1308,16 +1308,28 @@ keyword on the line, the keyword is not inserted inside 
a literal, and
 (defun c-forward-into-nomenclature (&optional arg)
   "Compatibility alias for `c-forward-subword'."
   (interactive "p")
-  (require 'subword)
-  (subword-forward arg))
-(make-obsolete 'c-forward-into-nomenclature 'subword-forward "23.2")
+  (if (fboundp 'subword-mode)
+      (progn
+        (require 'subword)
+        (subword-forward arg))
+    (require 'cc-subword)
+    (c-forward-subword arg)))
+(make-obsolete 'c-forward-into-nomenclature
+               (if (fboundp 'subword-mode) 'subword-forward 'c-forward-subword)
+               "23.2")
 
 (defun c-backward-into-nomenclature (&optional arg)
   "Compatibility alias for `c-backward-subword'."
   (interactive "p")
-  (require 'subword)
-  (subword-backward arg))
-(make-obsolete 'c-backward-into-nomenclature 'subword-backward "23.2")
+  (if (fboundp 'subword-mode)
+      (progn
+        (require 'subword)
+        (subword-backward arg))
+    (require 'cc-subword)
+    (c-backward-subword arg)))
+(make-obsolete
+ 'c-backward-into-nomenclature
+ (if (fboundp 'subword-mode) 'subword-backward 'c-backward-subword) "23.2")
 
 (defun c-scope-operator ()
   "Insert a double colon scope operator at point.
@@ -1585,7 +1597,7 @@ defun."
 
   (or (not (eq this-command 'c-beginning-of-defun))
       (eq last-command 'c-beginning-of-defun)
-      (and transient-mark-mode mark-active)
+      (c-region-is-active-p)
       (push-mark))
 
   (c-save-buffer-state
@@ -1709,7 +1721,7 @@ the open-parenthesis that starts a defun; see 
`beginning-of-defun'."
 
   (or (not (eq this-command 'c-end-of-defun))
       (eq last-command 'c-end-of-defun)
-      (and transient-mark-mode mark-active)
+      (c-region-is-active-p)
       (push-mark))
 
   (c-save-buffer-state
@@ -1813,7 +1825,7 @@ with a brace block."
              (looking-at c-symbol-key))
            (match-string-no-properties 0))
 
-          ((looking-at "DEFUN\\_>")
+          ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs!
            ;; DEFUN ("file-name-directory", Ffile_name_directory, 
Sfile_name_directory, ...) ==> Ffile_name_directory
            ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START 
LENGTH) ==> POSIX::STREAM-LOCK
            (down-list 1)
@@ -2006,7 +2018,7 @@ function does not require the declaration to contain a 
brace block."
                   (eq last-command 'c-mark-function)))
             (push-mark-p (and (eq this-command 'c-mark-function)
                               (not extend-region-p)
-                              (not (and transient-mark-mode mark-active)))))
+                              (not (c-region-is-active-p)))))
        (if push-mark-p (push-mark (point)))
        (if extend-region-p
            (progn
@@ -3343,7 +3355,7 @@ Otherwise, with a prefix argument, rigidly reindent the 
expression
 starting on the current line.
 Otherwise reindent just the current line."
   (interactive
-   (list current-prefix-arg (use-region-p)))
+   (list current-prefix-arg (c-region-is-active-p)))
   (if region
       (c-indent-region (region-beginning) (region-end))
     (c-indent-command arg)))
@@ -4732,4 +4744,8 @@ normally bound to C-o.  See `c-context-line-break' for 
the details."
 
 (cc-provide 'cc-cmds)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-cmds.el ends here
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 1d8b8ab..46cb2f9 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -64,15 +64,14 @@
          (not (fboundp 'push)))
       (cc-load "cc-fix")))
 
-; (eval-after-load "font-lock"  ; 2006-07-09.  font-lock is now preloaded
-;   '
-(if (and (featurep 'xemacs)    ; There is now (2005/12) code in GNU Emacs CVS
-                               ; to make the call to f-l-c-k throw an error.
-        (not (featurep 'cc-fix)) ; only load the file once.
-        (let (font-lock-keywords)
-          (font-lock-compile-keywords '("\\<\\>"))
-          font-lock-keywords))     ; did the previous call foul this up?
-    (load "cc-fix")) ;)
+(when (featurep 'xemacs) ; There is now (2005/12) code in GNU Emacs CVS
+                        ; to make the call to f-l-c-k throw an error.
+  (eval-after-load "font-lock"
+    '(if (and (not (featurep 'cc-fix)) ; only load the file once.
+             (let (font-lock-keywords)
+               (font-lock-compile-keywords '("\\<\\>"))
+               font-lock-keywords)) ; did the previous call foul this up?
+         (load "cc-fix"))))
 
 ;; The above takes care of the delayed loading, but this is necessary
 ;; to ensure correct byte compilation.
@@ -94,7 +93,7 @@
 
 ;;; Variables also used at compile time.
 
-(defconst c-version "5.32.5"
+(defconst c-version "5.33"
   "CC Mode version number.")
 
 (defconst c-version-sym (intern c-version))
@@ -336,16 +335,42 @@ to it is returned.  This function does not modify the 
point or the mark."
          (t (error "Unknown buffer position requested: %s" position))))
        (point))))
 
+(eval-and-compile
+  ;; Constant to decide at compilation time whether to use category
+  ;; properties.  Currently (2010-03) they're available only on GNU Emacs.
+  (defconst c-use-category
+    (with-temp-buffer
+      (let ((parse-sexp-lookup-properties t)
+           (lookup-syntax-properties t))
+        (set-syntax-table (make-syntax-table))
+        (insert "<()>")
+        (put-text-property (point-min) (1+ (point-min))
+                          'category 'c-<-as-paren-syntax)
+        (put-text-property (+ 3 (point-min)) (+ 4 (point-min))
+                          'category 'c->-as-paren-syntax)
+        (goto-char (point-min))
+        (forward-sexp)
+        (= (point) (+ 4 (point-min)))))))
+
+(defvar c-use-extents)
+
+(defmacro c-next-single-property-change (position prop &optional object limit)
+  ;; See the doc string for either of the defuns expanded to.
+  (if (and c-use-extents
+          (fboundp 'next-single-char-property-change))
+      ;; XEmacs >= 2005-01-25
+      `(next-single-char-property-change ,position ,prop ,object ,limit)
+    ;; Emacs and earlier XEmacs
+    `(next-single-property-change ,position ,prop ,object ,limit)))
+
 (defmacro c-region-is-active-p ()
   ;; Return t when the region is active.  The determination of region
   ;; activeness is different in both Emacs and XEmacs.
-  ;; FIXME? Emacs has region-active-p since 23.1, so maybe this test
-  ;; should be updated.
-  (if (cc-bytecomp-boundp 'mark-active)
-      ;; Emacs.
-      'mark-active
-    ;; XEmacs.
-    '(region-active-p)))
+  (if (cc-bytecomp-fboundp 'region-active-p)
+      ;; XEmacs.
+      '(region-active-p)
+    ;; Old Emacs.
+    'mark-active))
 
 (defmacro c-set-region-active (activate)
   ;; Activate the region if ACTIVE is non-nil, deactivate it
@@ -1061,8 +1086,8 @@ nil; point is then left undefined."
      (while
         (and
          (< place ,(or limit '(point-max)))
-         (not (equal (get-text-property place ,property) ,value)))
-       (setq place (next-single-property-change
+         (not (equal (c-get-char-property place ,property) ,value)))
+       (setq place (c-next-single-property-change
                    place ,property nil ,(or limit '(point-max)))))
      (when (< place ,(or limit '(point-max)))
        (goto-char place)
@@ -1080,10 +1105,15 @@ point is then left undefined."
      (while
         (and
          (> place ,(or limit '(point-min)))
-         (not (equal (get-text-property (1- place) ,property) ,value)))
-       (setq place (previous-single-property-change
+         (not (equal (c-get-char-property (1- place) ,property) ,value)))
+       (setq place (,(if (and c-use-extents
+                             (fboundp 'previous-single-char-property-change))
+                        ;; XEmacs > 2005-01-25.
+                        'previous-single-char-property-change
+                      ;; Emacs and earlier XEmacs.
+                      'previous-single-property-change)
                    place ,property nil ,(or limit '(point-min)))))
-     (when (> place ,(or limit '(point-max)))
+     (when (> place ,(or limit '(point-min)))
        (goto-char place)
        (search-backward-regexp ".")    ; to set the match-data.
        (point))))
@@ -1100,9 +1130,9 @@ been put there by c-put-char-property.  POINT remains 
unchanged."
              (and
               (< place to)
               (not (equal (get-text-property place property) value)))
-           (setq place (next-single-property-change place property nil to)))
+           (setq place (c-next-single-property-change place property nil to)))
          (< place to))
-      (setq end-place (next-single-property-change place property nil to))
+      (setq end-place (c-next-single-property-change place property nil to))
       (remove-text-properties place end-place (cons property nil))
       ;; Do we have to do anything with stickiness here?
       (setq place end-place))))
@@ -1119,7 +1149,7 @@ been put there by c-put-char-property.  POINT remains 
unchanged."
                        (if (equal (extent-property ext -property-) val)
                            (delete-extent ext)))
                      nil ,from ,to ,value nil -property-))
-  ;; Gnu Emacs
+    ;; GNU Emacs
     `(c-clear-char-property-with-value-function ,from ,to ,property ,value)))
 
 ;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text.
@@ -1203,36 +1233,43 @@ been put there by c-put-char-property.  POINT remains 
unchanged."
     (if (< (point) start)
        (goto-char (point-max)))))
 
-(defsubst c-mark-<-as-paren (pos)
+(defmacro c-mark-<-as-paren (pos)
   ;; Mark the "<" character at POS as a template opener using the
-  ;; `syntax-table' property via the `category' property.
+  ;; `syntax-table' property either directly (XEmacs) or via a `category'
+  ;; property (GNU Emacs).
   ;;
   ;; This function does a hidden buffer change.  Note that we use
   ;; indirection through the `category' text property.  This allows us to
   ;; toggle the property in all template brackets simultaneously and
   ;; cheaply.  We use this, for instance, in `c-parse-state'.
-  (c-put-char-property pos 'category 'c-<-as-paren-syntax))
+  (if c-use-category
+      `(c-put-char-property ,pos 'category 'c-<-as-paren-syntax)
+    `(c-put-char-property ,pos 'syntax-table c-<-as-paren-syntax)))
 
-(defsubst c-mark->-as-paren (pos)
+
+(defmacro c-mark->-as-paren (pos)
   ;; Mark the ">" character at POS as an sexp list closer using the
-  ;; syntax-table property.
+  ;; `syntax-table' property either directly (XEmacs) or via a `category'
+  ;; property (GNU Emacs).
   ;;
   ;; This function does a hidden buffer change.  Note that we use
   ;; indirection through the `category' text property.  This allows us to
   ;; toggle the property in all template brackets simultaneously and
   ;; cheaply.  We use this, for instance, in `c-parse-state'.
-  (c-put-char-property pos 'category 'c->-as-paren-syntax))
-
-(defsubst c-unmark-<->-as-paren (pos)
-  ;; Unmark the "<" or "<" character at POS as an sexp list opener using
-  ;; the syntax-table property indirectly through the `category' text
-  ;; property.
+  (if c-use-category
+      `(c-put-char-property ,pos 'category 'c->-as-paren-syntax)
+    `(c-put-char-property ,pos 'syntax-table c->-as-paren-syntax)))
+
+(defmacro c-unmark-<->-as-paren (pos)
+  ;; Unmark the "<" or "<" character at POS as an sexp list opener using the
+  ;; `syntax-table' property either directly or indirectly through a
+  ;; `category' text property.
   ;;
-  ;; This function does a hidden buffer change.  Note that we use
+  ;; This function does a hidden buffer change.  Note that we try to use
   ;; indirection through the `category' text property.  This allows us to
   ;; toggle the property in all template brackets simultaneously and
   ;; cheaply.  We use this, for instance, in `c-parse-state'.
-  (c-clear-char-property pos 'category))
+  `(c-clear-char-property ,pos ,(if c-use-category ''category ''syntax-table)))
 
 (defsubst c-suppress-<->-as-parens ()
   ;; Suppress the syntactic effect of all marked < and > as parens.  Note
@@ -1313,6 +1350,124 @@ been put there by c-put-char-property.  POINT remains 
unchanged."
         (widen)
         (c-set-cpp-delimiters ,beg ,end)))))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; The following macros are to be used only in `c-parse-state' and its
+;; subroutines.  Their main purpose is to simplify the handling of C++/Java
+;; template delimiters and CPP macros.  In GNU Emacs, this is done slickly by
+;; the judicious use of 'category properties.  These don't exist in XEmacs.
+;;
+;; Note: in the following macros, there is no special handling for parentheses
+;; inside CPP constructs.  That is because CPPs are always syntactically
+;; balanced, thanks to `c-neutralize-CPP-line' in cc-mode.el.
+(defmacro c-sc-scan-lists-no-category+1+1 (from)
+  ;; Do a (scan-lists FROM 1 1).  Any finishing position which either (i) is
+  ;; determined by and angle bracket; or (ii) is inside a macro whose start
+  ;; isn't POINT-MACRO-START doesn't count as a finishing position.
+  `(let ((here (point))
+        (pos (scan-lists ,from 1 1)))
+     (while (eq (char-before pos) ?>)
+       (setq pos (scan-lists pos 1 1)))
+     pos))
+
+(defmacro c-sc-scan-lists-no-category+1-1 (from)
+  ;; Do a (scan-lists FROM 1 -1).  Any finishing position which either (i) is
+  ;; determined by an angle bracket; or (ii) is inside a macro whose start
+  ;; isn't POINT-MACRO-START doesn't count as a finishing position.
+  `(let ((here (point))
+        (pos (scan-lists ,from 1 -1)))
+     (while (eq (char-before pos) ?<)
+       (setq pos (scan-lists pos 1 1))
+       (setq pos (scan-lists pos 1 -1)))
+     pos))
+
+(defmacro c-sc-scan-lists-no-category-1+1 (from)
+  ;; Do a (scan-lists FROM -1 1).  Any finishing position which either (i) is
+  ;; determined by and angle bracket; or (ii) is inside a macro whose start
+  ;; isn't POINT-MACRO-START doesn't count as a finishing position.
+  `(let ((here (point))
+        (pos (scan-lists ,from -1 1)))
+     (while (eq (char-after pos) ?<)
+       (setq pos (scan-lists pos -1 1)))
+     pos))
+
+(defmacro c-sc-scan-lists-no-category-1-1 (from)
+  ;; Do a (scan-lists FROM -1 -1).  Any finishing position which either (i) is
+  ;; determined by and angle bracket; or (ii) is inside a macro whose start
+  ;; isn't POINT-MACRO-START doesn't count as a finishing position.
+  `(let ((here (point))
+        (pos (scan-lists ,from -1 -1)))
+     (while (eq (char-after pos) ?>)
+       (setq pos (scan-lists pos -1 1))
+       (setq pos (scan-lists pos -1 -1)))
+     pos))
+
+(defmacro c-sc-scan-lists (from count depth)
+  (if c-use-category
+      `(scan-lists ,from ,count ,depth)
+    (cond
+     ((and (eq count 1) (eq depth 1))
+      `(c-sc-scan-lists-no-category+1+1 ,from))
+     ((and (eq count 1) (eq depth -1))
+      `(c-sc-scan-lists-no-category+1-1 ,from))
+     ((and (eq count -1) (eq depth 1))
+      `(c-sc-scan-lists-no-category-1+1 ,from))
+     ((and (eq count -1) (eq depth -1))
+      `(c-sc-scan-lists-no-category-1-1 ,from))
+     (t (error "Invalid parameter(s) to c-sc-scan-lists")))))
+
+
+(defun c-sc-parse-partial-sexp-no-category (from to targetdepth stopbefore
+                                                oldstate)
+  ;; Do a parse-partial-sexp using the supplied arguments, disregarding
+  ;; template/generic delimiters < > and disregarding macros other than the
+  ;; one at POINT-MACRO-START.
+  ;;
+  ;; NOTE that STOPBEFORE must be nil.  TARGETDEPTH should be one less than
+  ;; the depth in OLDSTATE.  This function is thus a SPECIAL PURPOSE variation
+  ;; on parse-partial-sexp, designed for calling from
+  ;; `c-remove-stale-state-cache'.
+  ;;
+  ;; Any finishing position which is determined by an angle bracket delimiter
+  ;; doesn't count as a finishing position.
+  ;;
+  ;; Note there is no special handling of CPP constructs here, since these are
+  ;; always syntactically balanced (thanks to `c-neutralize-CPP-line').
+  (let ((state
+        (parse-partial-sexp from to targetdepth stopbefore oldstate)))
+    (while
+       (and (< (point) to)
+            ;; We must have hit targetdepth.
+            (or (eq (char-before) ?<)
+                (eq (char-before) ?>)))
+      (setcar state
+             (if (memq (char-before) '(?> ?\) ?\} ?\]))
+                 (1+ (car state))
+               (1- (car state))))
+      (setq state
+           (parse-partial-sexp (point) to targetdepth stopbefore oldstate)))
+    state))
+
+(defmacro c-sc-parse-partial-sexp (from to &optional targetdepth stopbefore
+                                       oldstate)
+  (if c-use-category
+      `(parse-partial-sexp ,from ,to ,targetdepth ,stopbefore ,oldstate)
+    `(c-sc-parse-partial-sexp-no-category ,from ,to ,targetdepth ,stopbefore
+                                         ,oldstate)))
+
+
+(defvar c-emacs-features)
+
+(defmacro c-looking-at-non-alphnumspace ()
+  "Are we looking at a character which isn't alphanumeric or space?"
+  (if (memq 'gen-comment-delim c-emacs-features)
+      `(looking-at
+"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)")
+    `(or (looking-at
+"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\)"
+        (let ((prop (c-get-char-property (point) 'syntax-table)))
+          (eq prop '(14)))))))         ; '(14) is generic comment delimiter.
+
+
 (defsubst c-intersect-lists (list alist)
   ;; return the element of ALIST that matches the first element found
   ;; in LIST.  Uses assq.
@@ -1614,6 +1769,9 @@ non-nil, a caret is prepended to invert the set."
                               (not (end-of-defun))))
          (setq list (cons 'argumentative-bod-function list))))
 
+    ;; Record whether the `category' text property works.
+    (if c-use-category (setq list (cons 'category-properties list)))
+
     (let ((buf (generate-new-buffer " test"))
          parse-sexp-lookup-properties
          parse-sexp-ignore-comments
@@ -1719,6 +1877,8 @@ might be present:
                    in the buffer with the 'syntax-table property.  It's
                    always set - CC Mode no longer works in emacsen without
                    this feature.
+'category-properties Syntax routines can add a level of indirection to text
+                   properties using the 'category property.
 'gen-comment-delim  Generic comment delimiters work
                    (i.e. the syntax class `!').
 'gen-string-delim   Generic string delimiters work
@@ -2277,4 +2437,8 @@ fallback definition for all modes, to break the cycle).")
 
 (cc-provide 'cc-defs)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-defs.el ends here
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index a388b42..a24cb3d 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -534,7 +534,7 @@ comment at the start of cc-engine.el for more info."
     (while (progn
             (when (eq (get-text-property (point) 'c-type) value)
               (c-clear-char-property (point) 'c-type))
-            (goto-char (next-single-property-change (point) 'c-type nil to))
+            (goto-char (c-next-single-property-change (point) 'c-type nil to))
             (< (point) to)))))
 
 
@@ -1723,7 +1723,7 @@ comment at the start of cc-engine.el for more info."
          ;; the cases when the marked rung is complete.
          ;; (`next-single-property-change' is certain to move at least one
          ;; step forward.)
-         (setq rung-pos (1- (next-single-property-change
+         (setq rung-pos (1- (c-next-single-property-change
                              rung-is-marked 'c-is-sws nil rung-end-pos)))
        ;; Got no marked rung here.  Since the simple ws might have started
        ;; inside a line comment or cpp directive we must set `rung-pos' as
@@ -1739,7 +1739,7 @@ comment at the start of cc-engine.el for more info."
 
                  ;; The following search is the main reason that `c-in-sws'
                  ;; and `c-is-sws' aren't combined to one property.
-                 (goto-char (next-single-property-change
+                 (goto-char (c-next-single-property-change
                              (point) 'c-in-sws nil (point-max)))
                  (unless (get-text-property (point) 'c-is-sws)
                    ;; If the `c-in-sws' region extended past the last
@@ -1861,7 +1861,7 @@ comment at the start of cc-engine.el for more info."
          ;; possible since we can't be in the ending ws of a line comment or
          ;; cpp directive now.
          (if (setq rung-is-marked next-rung-is-marked)
-             (setq rung-pos (1- (next-single-property-change
+             (setq rung-pos (1- (c-next-single-property-change
                                  rung-is-marked 'c-is-sws nil rung-end-pos)))
            (setq rung-pos next-rung-pos))
          (setq safe-start t)))
@@ -1939,7 +1939,7 @@ comment at the start of cc-engine.el for more info."
                  (unless (get-text-property (point) 'c-is-sws)
                    ;; If the `c-in-sws' region extended past the first
                    ;; `c-is-sws' char we have to go forward a bit.
-                   (goto-char (next-single-property-change
+                   (goto-char (c-next-single-property-change
                                (point) 'c-is-sws)))
 
                  (c-debug-sws-msg
@@ -2547,7 +2547,7 @@ comment at the start of cc-engine.el for more info."
        (setq pos here+)
        (c-safe
          (while
-             (setq ren+1 (scan-lists pos 1 1)) ; might signal
+             (setq ren+1 (c-sc-scan-lists pos 1 1)) ; might signal
            (setq lonely-rens (cons ren+1 lonely-rens)
                  pos ren+1)))))
 
@@ -2559,7 +2559,7 @@ comment at the start of cc-engine.el for more info."
       (c-safe
        (while
            (and lonely-rens            ; actual values aren't used.
-                (setq pa (scan-lists pos -1 1)))
+                (setq pa (c-sc-scan-lists pos -1 1)))
          (setq pos pa)
          (setq lonely-rens (cdr lonely-rens)))))
     pos))
@@ -2715,8 +2715,8 @@ comment at the start of cc-engine.el for more info."
              (progn
                (c-safe
                  (while
-                     (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; 
might signal
-                          (setq bra (scan-lists ce -1 1)) ; back past (/[/{; 
might signal
+                     (and (setq ce (c-sc-scan-lists bra -1 -1)) ; back past 
)/]/}; might signal
+                          (setq bra (c-sc-scan-lists ce -1 1)) ; back past 
(/[/{; might signal
                           (or (> bra here) ;(> ce here)
                               (and
                                (< ce here)
@@ -2768,7 +2768,7 @@ comment at the start of cc-engine.el for more info."
                     (not (c-beginning-of-macro))))
          (setq c-state-cache
                (cons (cons (1- bra+1)
-                           (scan-lists bra+1 1 1))
+                           (c-sc-scan-lists bra+1 1 1))
                      (if (consp (car c-state-cache))
                          (cdr c-state-cache)
                        c-state-cache)))
@@ -2818,9 +2818,9 @@ comment at the start of cc-engine.el for more info."
              ;; are no more b/b/p's to scan.
              (c-safe
                (while t
-                 (setq pa+1 (scan-lists ren+1 1 -1) ; Into (/{/[; might signal
+                 (setq pa+1 (c-sc-scan-lists ren+1 1 -1) ; Into (/{/[; might 
signal
                        paren+1s (cons pa+1 paren+1s))
-                 (setq ren+1 (scan-lists pa+1 1 1)) ; Out of )/}/]; might 
signal
+                 (setq ren+1 (c-sc-scan-lists pa+1 1 1)) ; Out of )/}/]; might 
signal
                  (if (and (eq (char-before pa+1) ?{)) ; Check for a macro 
later.
                      (setq bra+1 pa+1))
                  (setcar paren+1s ren+1)))
@@ -2844,7 +2844,7 @@ comment at the start of cc-engine.el for more info."
                ;; finished - we just need to check for having found an
                ;; unmatched )/}/], which we ignore.  Such a )/}/] can't be in a
                ;; macro, due the action of `c-neutralize-syntax-in-CPP'.
-               (c-safe (setq ren+1 (scan-lists ren+1 1 1)))))) ; acts as loop 
control.
+               (c-safe (setq ren+1 (c-sc-scan-lists ren+1 1 1)))))) ; acts as 
loop control.
 
        ;; Record the final, innermost, brace-pair if there is one.
        (c-state-push-any-brace-pair bra+1 macro-start-or-here)
@@ -2947,7 +2947,7 @@ comment at the start of cc-engine.el for more info."
        ;; The next loop jumps forward out of a nested level of parens each
        ;; time round; the corresponding elements in `c-state-cache' are
        ;; removed.  `pos' is just after the brace-pair or the open paren at
-       ;; (car c-state-cache).  There can be no open parens/braces/brackets
+       ;; (car c-state-cache).  There can be no open parens/braces/brackets
        ;; between `start-point'/`start-point-actual-macro-start' and HERE,
        ;; due to the interface spec to this function.
        (setq pos (if (and start-point-actual-macro-end
@@ -2971,7 +2971,7 @@ comment at the start of cc-engine.el for more info."
 
          ;; Scan!
          (setq pps-state
-               (parse-partial-sexp
+               (c-sc-parse-partial-sexp
                 (point) (if (< (point) pps-point) pps-point here)
                 target-depth
                 nil pps-state))
@@ -3002,9 +3002,10 @@ comment at the start of cc-engine.el for more info."
             )))
 
        (if (< (point) pps-point)
-           (setq pps-state (parse-partial-sexp (point) pps-point
-                                               nil nil ; TARGETDEPTH, 
STOPBEFORE
-                                               pps-state)))
+           (setq pps-state (c-sc-parse-partial-sexp
+                            (point) pps-point
+                            nil nil ; TARGETDEPTH, STOPBEFORE
+                            pps-state)))
 
        ;; If the last paren pair we moved out of was actually a brace pair,
        ;; insert it into `c-state-cache'.
@@ -3125,12 +3126,15 @@ comment at the start of cc-engine.el for more info."
        (save-restriction
          (narrow-to-region here-bol (point-max))
          (setq pos here-lit-start)
-         (c-safe (while (setq pa (scan-lists pos -1 1))
+         (c-safe (while (setq pa (c-sc-scan-lists pos -1 1))
                    (setq pos pa))))    ; might signal
        nil))                           ; for the cond
 
-     ((setq ren (c-safe-scan-lists pos -1 -1 too-far-back))
-       ;; CASE 3: After a }/)/] before `here''s BOL.
+     ((save-restriction
+        (narrow-to-region too-far-back (point-max))
+        (setq ren (c-safe (c-sc-scan-lists pos -1 -1))))
+
+      ;; CASE 3: After a }/)/] before `here''s BOL.
       (list (1+ ren) (and dropped-cons pos) nil)) ; Return value
 
      (t
@@ -3352,15 +3356,19 @@ comment at the start of cc-engine.el for more info."
   ;; of all parens in preprocessor constructs, except for any such construct
   ;; containing point.  We can then call `c-invalidate-state-cache-1' without
   ;; worrying further about macros and template delimiters.
-  (c-with-<->-as-parens-suppressed
-   (if (and c-state-old-cpp-beg
-           (< c-state-old-cpp-beg here))
-       (c-with-all-but-one-cpps-commented-out
-       c-state-old-cpp-beg
-       (min c-state-old-cpp-end here)
-       (c-invalidate-state-cache-1 here))
-     (c-with-cpps-commented-out
-      (c-invalidate-state-cache-1 here)))))
+  (if (eval-when-compile (memq 'category-properties c-emacs-features))
+      ;; Emacs
+      (c-with-<->-as-parens-suppressed
+       (if (and c-state-old-cpp-beg
+               (< c-state-old-cpp-beg here))
+          (c-with-all-but-one-cpps-commented-out
+           c-state-old-cpp-beg
+           (min c-state-old-cpp-end here)
+           (c-invalidate-state-cache-1 here))
+        (c-with-cpps-commented-out
+         (c-invalidate-state-cache-1 here))))
+    ;; XEmacs
+    (c-invalidate-state-cache-1 here)))
 
 (defmacro c-state-maybe-marker (place marker)
   ;; If PLACE is non-nil, return a marker marking it, otherwise nil.
@@ -3388,13 +3396,17 @@ comment at the start of cc-engine.el for more info."
     ;; FIXME!!! Put in a `condition-case' here to protect the integrity of the
     ;; subsystem.
     (prog1
-       (c-with-<->-as-parens-suppressed
-        (if (and here-cpp-beg (> here-cpp-end here-cpp-beg))
-            (c-with-all-but-one-cpps-commented-out
-             here-cpp-beg here-cpp-end
-             (c-parse-state-1))
-          (c-with-cpps-commented-out
-           (c-parse-state-1))))
+       (if (eval-when-compile (memq 'category-properties c-emacs-features))
+           ;; Emacs
+           (c-with-<->-as-parens-suppressed
+            (if (and here-cpp-beg (> here-cpp-end here-cpp-beg))
+                (c-with-all-but-one-cpps-commented-out
+                 here-cpp-beg here-cpp-end
+                 (c-parse-state-1))
+              (c-with-cpps-commented-out
+               (c-parse-state-1))))
+         ;; XEmacs
+         (c-parse-state-1))
       (setq c-state-old-cpp-beg
            (c-state-maybe-marker here-cpp-beg c-state-old-cpp-beg-marker)
            c-state-old-cpp-end
@@ -3417,9 +3429,9 @@ comment at the start of cc-engine.el for more info."
         (lambda (arg)
           (let ((val (symbol-value arg)))
             (cons arg
-                  (if (consp val)
-                      (copy-tree val)
-                    val))))
+                  (cond ((consp val) (copy-tree val))
+                        ((markerp val) (copy-marker val))
+                        (t val)))))
         '(c-state-cache
           c-state-cache-good-pos
           c-state-nonlit-pos-cache
@@ -3439,7 +3451,11 @@ comment at the start of cc-engine.el for more info."
    (concat "(setq "
     (mapconcat
      (lambda (arg)
-       (format "%s %s%s" (car arg) (if (atom (cdr arg)) "" "'") (cdr arg)))
+       (format "%s %s%s" (car arg)
+              (if (atom (cdr arg)) "" "'")
+              (if (markerp (cdr arg))
+                  (format "(copy-marker %s)" (marker-position (cdr arg)))
+                (cdr arg))))
      c-parse-state-state "  ")
     ")")))
 
@@ -4783,7 +4799,7 @@ comment at the start of cc-engine.el for more info."
      (unless cfd-prop-match
        (save-excursion
         (while (progn
-                 (goto-char (next-single-property-change
+                 (goto-char (c-next-single-property-change
                              (point) 'c-type nil cfd-limit))
                  (and (< (point) cfd-limit)
                       (not (eq (c-get-char-property (1- (point)) 'c-type)
@@ -4823,7 +4839,7 @@ comment at the start of cc-engine.el for more info."
               ;; Pseudo match inside a comment or string literal.  Skip out
               ;; of comments and string literals.
               (while (progn
-                       (goto-char (next-single-property-change
+                       (goto-char (c-next-single-property-change
                                    (point) 'face nil cfd-limit))
                        (and (< (point) cfd-limit)
                             (c-got-face-at (point) c-literal-faces))))
@@ -5012,7 +5028,7 @@ comment at the start of cc-engine.el for more info."
         (save-excursion
           (goto-char cfd-start-pos)
           (while (progn
-                   (goto-char (next-single-property-change
+                   (goto-char (c-next-single-property-change
                                (point) 'face nil cfd-limit))
                    (and (< (point) cfd-limit)
                         (c-got-face-at (point) c-literal-faces))))
@@ -5432,8 +5448,8 @@ comment at the start of cc-engine.el for more info."
        (c-go-list-forward))
       (when (equal (c-get-char-property (1- (point)) 'syntax-table)
                   c->-as-paren-syntax) ; should always be true.
-       (c-clear-char-property (1- (point)) 'category))
-      (c-clear-char-property pos 'category))))
+       (c-unmark-<->-as-paren (1- (point))))
+      (c-unmark-<->-as-paren pos))))
 
 (defun c-clear->-pair-props (&optional pos)
   ;; POS (default point) is at a > character.  If it is marked with
@@ -5449,8 +5465,8 @@ comment at the start of cc-engine.el for more info."
        (c-go-up-list-backward))
       (when (equal (c-get-char-property (point) 'syntax-table)
                        c-<-as-paren-syntax) ; should always be true.
-       (c-clear-char-property (point) 'category))
-      (c-clear-char-property pos 'category))))
+       (c-unmark-<->-as-paren (point)))
+      (c-unmark-<->-as-paren pos))))
 
 (defun c-clear-<>-pair-props (&optional pos)
   ;; POS (default point) is at a < or > character.  If it has an
@@ -5539,9 +5555,10 @@ comment at the start of cc-engine.el for more info."
       (c-syntactic-skip-backward "^;{}" (c-determine-limit 512))
       (setq new-beg (point))
 
-      ;; Remove the syntax-table properties from each pertinent <...> pair.
-      ;; Firsly, the ones with the < before beg and > after beg.
-      (while (c-search-forward-char-property 'category 'c-<-as-paren-syntax 
beg)
+      ;; Remove the syntax-table/category properties from each pertinent <...>
+      ;; pair.  Firsly, the ones with the < before beg and > after beg.
+      (while
+         (c-search-forward-char-property 'syntax-table c-<-as-paren-syntax beg)
        (if (c-clear-<-pair-props-if-match-after beg (1- (point)))
            (setq need-new-beg t)))
 
@@ -5552,7 +5569,7 @@ comment at the start of cc-engine.el for more info."
 
       ;; Remove syntax-table properties from the remaining pertinent <...>
       ;; pairs, those with a > after end and < before end.
-      (while (c-search-backward-char-property 'category 'c->-as-paren-syntax 
end)
+      (while (c-search-backward-char-property 'syntax-table 
c->-as-paren-syntax end)
        (if (c-clear->-pair-props-if-match-before end)
            (setq need-new-end t)))
 
@@ -5934,32 +5951,31 @@ comment at the start of cc-engine.el for more info."
        (while (and
                (progn
                  (c-forward-syntactic-ws)
-                 (let ((orig-record-found-types c-record-found-types))
-                   (when (or (and c-record-type-identifiers all-types)
-                             (c-major-mode-is 'java-mode))
-                     ;; All encountered identifiers are types, so set the
-                     ;; promote flag and parse the type.
-                     (progn
-                       (c-forward-syntactic-ws)
-                       (if (looking-at "\\?")
-                           (forward-char)
-                         (when (looking-at c-identifier-start)
-                           (let ((c-promote-possible-types t)
-                                 (c-record-found-types t))
-                             (c-forward-type))))
-
-                       (c-forward-syntactic-ws)
-
-                       (when (or (looking-at "extends")
-                                 (looking-at "super"))
-                         (forward-word)
-                         (c-forward-syntactic-ws)
+                 (when (or (and c-record-type-identifiers all-types)
+                           (c-major-mode-is 'java-mode))
+                   ;; All encountered identifiers are types, so set the
+                   ;; promote flag and parse the type.
+                   (progn
+                     (c-forward-syntactic-ws)
+                     (if (looking-at "\\?")
+                         (forward-char)
+                       (when (looking-at c-identifier-start)
                          (let ((c-promote-possible-types t)
                                (c-record-found-types t))
-                           (c-forward-type)
-                           (c-forward-syntactic-ws))))))
+                           (c-forward-type))))
+
+                     (c-forward-syntactic-ws)
+
+                     (when (or (looking-at "extends")
+                               (looking-at "super"))
+                       (forward-word)
+                       (c-forward-syntactic-ws)
+                       (let ((c-promote-possible-types t)
+                             (c-record-found-types t))
+                         (c-forward-type)
+                         (c-forward-syntactic-ws)))))
 
-                 (setq pos (point))    ; e.g. first token inside the '<'
+                 (setq pos (point))    ; e.g. first token inside the '<'
 
                  ;; Note: These regexps exploit the match order in \| so
                  ;; that "<>" is matched by "<" rather than "[^>:-]>".
@@ -6049,7 +6065,7 @@ comment at the start of cc-engine.el for more info."
                       (or (and (eq (char-before) ?&)
                                (not (eq (char-after) ?&)))
                           (eq (char-before) ?,)))
-                 ;; Just another argument.      Record the position.  The
+                 ;; Just another argument.  Record the position.  The
                  ;; type check stuff that made us stop at it is at
                  ;; the top of the loop.
                  (setq arg-start-pos (cons (point) arg-start-pos)))
@@ -6472,13 +6488,14 @@ comment at the start of cc-engine.el for more info."
             (setq res nil)))))
 
     (when res
-      ;; Skip trailing type modifiers. If any are found we know it's
+      ;; Skip trailing type modifiers.  If any are found we know it's
       ;; a type.
       (when c-opt-type-modifier-key
        (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
          (goto-char (match-end 1))
          (c-forward-syntactic-ws)
          (setq res t)))
+
       ;; Step over any type suffix operator.  Do not let the existence
       ;; of these alter the classification of the found type, since
       ;; these operators typically are allowed in normal expressions
@@ -6560,7 +6577,7 @@ comment at the start of cc-engine.el for more info."
        (progn (c-forward-syntactic-ws) t)
        (if (looking-at "(")
           (c-go-list-forward)
-         t)))
+        t)))
 
 (defmacro c-pull-open-brace (ps)
   ;; Pull the next open brace from PS (which has the form of paren-state),
@@ -7147,7 +7164,7 @@ comment at the start of cc-engine.el for more info."
 
         ;; 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
+        ;; tree based on that.  It's ordered to check more certain
         ;; signs before less certain ones.
 
         (if got-identifier
@@ -7233,7 +7250,7 @@ comment at the start of cc-engine.el for more info."
                    at-decl-end
                    (cond
                     ((eq context 'decl)
-                     ;; Inside an arglist that contains declarations.  If K&R
+                     ;; 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
@@ -7266,7 +7283,7 @@ comment at the start of cc-engine.el for more info."
                                    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
+              ;; the last one the identifier.  This is analogous to the
               ;; "backtracking" done inside the `c-type-decl-suffix-key' loop
               ;; above.
               ;;
@@ -7274,7 +7291,7 @@ comment at the start of cc-engine.el for more info."
               ;; "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
+              ;; 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.
@@ -7413,7 +7430,7 @@ comment at the start of cc-engine.el for more info."
                          (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
+                ;; 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))
@@ -7424,7 +7441,7 @@ comment at the start of cc-engine.el for more info."
                          (eq at-type 'found)
                          (not (eq context 'arglist)))
                 ;; Got something like "a (*b) (c);" or "a (b) = c;".  It could
-                ;; be an odd expression or it could be a declaration.  Treat
+                ;; 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)))
@@ -7435,7 +7452,7 @@ comment at the start of cc-engine.el for more info."
                          (and (eq context 'decl)
                               (not c-recognize-paren-inits)
                               (or got-parens got-suffix))))
-            ;; Got a type followed by an abstract declarator.  If `got-prefix'
+            ;; 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
@@ -8105,7 +8122,7 @@ comment at the start of cc-engine.el for more info."
                            (c-forward-token-2))
                          (eq (char-after) ?\))))))
 
-                   ;; ...Yes.  We've identified the function's argument list.
+                   ;; ...Yes.  We've identified the function's argument list.
                    (throw 'knr
                           (progn (goto-char after-rparen)
                                  (c-forward-syntactic-ws)
@@ -8432,10 +8449,7 @@ comment at the start of cc-engine.el for more info."
     (when (and c-recognize-<>-arglists
               (eq (char-before) ?>))
       ;; Could be at the end of a template arglist.
-      (let ((c-parse-and-markup-<>-arglists t)
-           (c-disallow-comma-in-<>-arglists
-            (and containing-sexp
-                 (not (eq (char-after containing-sexp) ?{)))))
+      (let ((c-parse-and-markup-<>-arglists t))
        (while (and
                (c-backward-<>-arglist nil limit)
                (progn
@@ -8698,7 +8712,7 @@ comment at the start of cc-engine.el for more info."
         (goto-char containing-sexp)
         (if (c-looking-at-inexpr-block next-containing next-containing)
             ;; We're in an in-expression block of some kind.  Do not
-            ;; check nesting.  We deliberately set the limit to the
+            ;; check nesting.  We deliberately set the limit to the
             ;; containing sexp, so that c-looking-at-inexpr-block
             ;; doesn't check for an identifier before it.
             (setq containing-sexp nil)
@@ -9460,15 +9474,15 @@ comment at the start of cc-engine.el for more info."
      ;;annotations.
      ((and (c-major-mode-is 'java-mode)
           (setq placeholder (point))
-            (c-beginning-of-statement-1)
-            (progn
-              (while (and (c-forward-annotation)
-                          (< (point) placeholder))
-                (c-forward-syntactic-ws))
-              t)
-            (prog1
-                (>= (point) placeholder)
-              (goto-char placeholder)))
+          (c-beginning-of-statement-1)
+          (progn
+            (while (and (c-forward-annotation)
+                        (< (point) placeholder))
+              (c-forward-syntactic-ws))
+            t)
+          (prog1
+              (>= (point) placeholder)
+            (goto-char placeholder)))
        (c-beginning-of-statement-1 containing-sexp)
        (c-add-syntax 'annotation-var-cont (point)))
 
@@ -9519,7 +9533,7 @@ comment at the start of cc-engine.el for more info."
        ((indent-point (point))
         (case-fold-search nil)
         open-paren-in-column-0-is-defun-start
-        ;; A whole ugly bunch of various temporary variables.  Have
+        ;; A whole ugly bunch of various temporary variables.  Have
         ;; to declare them here since it's not possible to declare
         ;; a variable with only the scope of a cond test and the
         ;; following result clauses, and most of this function is a
@@ -10431,7 +10445,7 @@ comment at the start of cc-engine.el for more info."
                             paren-state))
 
         ;; CASE 7B: Looking at the opening brace of an
-        ;; in-expression block or brace list.  C.f. cases 4, 16A
+        ;; in-expression block or brace list.  C.f. cases 4, 16A
         ;; and 17E.
         ((and (eq char-after-ip ?{)
               (progn
@@ -10553,7 +10567,7 @@ comment at the start of cc-engine.el for more info."
          )))
 
        ;; CASE 9: we are inside a brace-list
-       ((and (not (c-major-mode-is 'awk-mode)) ; Maybe this isn't needed (ACM, 
2002/3/29)
+       ((and (not (c-major-mode-is 'awk-mode))  ; Maybe this isn't needed 
(ACM, 2002/3/29)
             (setq special-brace-list
                   (or (and c-special-brace-lists ;;;; ALWAYS NIL FOR AWK!!
                            (save-excursion
@@ -10767,9 +10781,9 @@ comment at the start of cc-engine.el for more info."
         ))
 
        ;; CASE 19: line is an expression, not a statement, and is directly
-       ;; contained by a template delimiter.   Most likely, we are in a
+       ;; contained by a template delimiter.  Most likely, we are in a
        ;; template arglist within a statement.  This case is based on CASE
-       ;; 7.   At some point in the future, we may wish to create more
+       ;; 7.  At some point in the future, we may wish to create more
        ;; syntactic symbols such as `template-intro',
        ;; `template-cont-nonempty', etc., and distinguish between them as we
        ;; do for `arglist-intro' etc. (2009-12-07).
@@ -11105,7 +11119,7 @@ Cannot combine absolute offsets %S and %S in `add' 
method"
   ;;
   ;; This function might do hidden buffer changes.
   (let* ((symbol (c-langelem-sym langelem))
-        (match  (assq symbol c-offsets-alist))
+        (match (assq symbol c-offsets-alist))
         (offset (cdr-safe match)))
     (if match
        (setq offset (c-evaluate-offset offset langelem symbol))
@@ -11176,4 +11190,8 @@ Cannot combine absolute offsets %S and %S in `add' 
method"
 
 (cc-provide 'cc-engine)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-engine.el ends here
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 8035c18..448e764 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -266,7 +266,7 @@
     ;; This function might do hidden buffer changes.
     (when (c-got-face-at (point) c-literal-faces)
       (while (progn
-              (goto-char (next-single-property-change
+              (goto-char (c-next-single-property-change
                           (point) 'face nil limit))
               (and (< (point) limit)
                    (c-got-face-at (point) c-literal-faces))))
@@ -559,8 +559,7 @@ stuff.  Used on level 1 and higher."
                                   (progn
                                     (c-mark-<-as-paren beg)
                                     (c-mark->-as-paren end))
-                                ;; (c-clear-char-property beg 'syntax-table)
-                                (c-clear-char-property beg 'category)))
+                                (c-unmark-<->-as-paren beg)))
                             nil)))))))
 
              ;; #define.
@@ -2702,4 +2701,8 @@ need for `pike-font-lock-extra-types'.")
 ;; 2006-07-10:  awk-font-lock-keywords has been moved back to cc-awk.el.
 (cc-provide 'cc-fonts)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-fonts.el ends here
diff --git a/lisp/progmodes/cc-guess.el b/lisp/progmodes/cc-guess.el
index f46ae0f..4c07744 100644
--- a/lisp/progmodes/cc-guess.el
+++ b/lisp/progmodes/cc-guess.el
@@ -572,4 +572,9 @@ WITH-NAME is asked to the user."
 
 
 (cc-provide 'cc-guess)
+
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-guess.el ends here
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 68b2d62..375725e 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -577,9 +577,18 @@ EOL terminated statements."
   (c c++ objc) t)
 (c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields))
 
+(c-lang-defconst c-modified-constant
+  "Regexp that matches a \"modified\" constant literal such as \"L'a'\",
+a \"long character\".  In particular, this recognizes forms of constant
+which `c-backward-sexp' needs to be called twice to move backwards over."
+  t nil
+  (c c++ objc) "L'\\([^\\'\t\f\n\r]\\|\\\\.\\)'")
+;; FIXME!!!  Extend this to cover strings, if needed.  2008-04-11
+(c-lang-defvar c-modified-constant (c-lang-const c-modified-constant))
+
 (c-lang-defconst c-symbol-start
   "Regexp that matches the start of a symbol, i.e. any identifier or
-keyword.  It's unspecified how far it matches. Does not contain a \\|
+keyword.  It's unspecified how far it matches.  Does not contain a \\|
 operator at the top level."
   t    (concat "[" c-alpha "_]")
   java (concat "[" c-alpha "address@hidden")
@@ -1144,7 +1153,8 @@ operators."
   c++  (append '("&" "<%" "%>" "<:" ":>" "%:" "%:%:")
               (c-lang-const c-other-op-syntax-tokens))
   objc (append '("#" "##"              ; Used by cpp.
-                "+" "-") (c-lang-const c-other-op-syntax-tokens))
+                "+" "-")
+               (c-lang-const c-other-op-syntax-tokens))
   idl  (append '("#" "##")             ; Used by cpp.
               (c-lang-const c-other-op-syntax-tokens))
   pike (append '("..")
@@ -2996,17 +3006,15 @@ is in effect or not."
          (when (boundp (c-mode-symbol "font-lock-extra-types"))
            (c-mode-var "font-lock-extra-types")))
         (regexp-strings
-         (apply 'nconc
-                (mapcar (lambda (re)
-                   (when (string-match "[][.*+?^$\\]" re)
-                     (list re)))
-                 extra-types)))
+         (delq nil (mapcar (lambda (re)
+                             (when (string-match "[][.*+?^$\\]" re)
+                               re))
+                           extra-types)))
         (plain-strings
-         (apply 'nconc
-                (mapcar (lambda (re)
-                   (unless (string-match "[][.*+?^$\\]" re)
-                     (list re)))
-                 extra-types))))
+         (delq nil (mapcar (lambda (re)
+                             (unless (string-match "[][.*+?^$\\]" re)
+                               re))
+                           extra-types))))
     (concat "\\<\\("
            (c-concat-separated
             (append (list (c-make-keywords-re nil
@@ -3350,4 +3358,8 @@ evaluated and should not be quoted."
 
 (cc-provide 'cc-langs)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-langs.el ends here
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el
index 735c2cb..ae26e9b 100644
--- a/lisp/progmodes/cc-menus.el
+++ b/lisp/progmodes/cc-menus.el
@@ -269,7 +269,7 @@ nested angle brackets constructs."
        "\\("                                 ; method name which gets captured
                                              ; into index
          "[" c-alpha "_]"
-         "[" c-alnum "_]*"
+        "[" c-alnum "_]*"
        "\\)"
        "[ \t\n\r]*"
        ;; An argument list that contains zero or more arguments.
@@ -521,4 +521,8 @@ Example:
 
 (cc-provide 'cc-menus)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-menus.el ends here
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index cb138d5..4b8e41f 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -471,6 +471,14 @@ preferably use the `c-mode-menu' language constant 
directly."
 (defvar c-maybe-stale-found-type nil)
 (make-variable-buffer-local 'c-maybe-stale-found-type)
 
+(defvar c-just-done-before-change nil)
+(make-variable-buffer-local 'c-just-done-before-change)
+;; This variable is set to t by `c-before-change' and to nil by
+;; `c-after-change'.  It is used to detect a spurious invocation of
+;; `before-change-functions' directly following on from a correct one.  This
+;; happens in some Emacsen, for example when `basic-save-buffer' does (insert
+;; ?\n) when `require-final-newline' is non-nil.
+
 (defun c-basic-common-init (mode default-style)
   "Do the necessary initialization for the syntax handling routines
 and the line breaking/filling code.  Intended to be used by other
@@ -541,10 +549,11 @@ that requires a literal mode spec at compile time."
   ;; 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)
     (mapc (lambda (tprop)
            (unless (assq tprop text-property-default-nonsticky)
-             (set (make-local-variable 'text-property-default-nonsticky)
-                   (cons `(,tprop . t) 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
@@ -604,10 +613,12 @@ that requires a literal mode spec at compile time."
     (make-local-hook 'before-change-functions)
     (make-local-hook 'after-change-functions))
   (add-hook 'before-change-functions 'c-before-change nil t)
+  (setq c-just-done-before-change nil)
   (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 (2009-05) used by all
-                       ; languages with #define (C, C++,; ObjC), and by AWK.
+  (when (boundp 'font-lock-extend-after-change-region-function)
+    (set (make-local-variable 'font-lock-extend-after-change-region-function)
+         'c-extend-after-change-region))) ; Currently (2009-05) used by all
+                          ; languages 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'."
@@ -668,9 +679,11 @@ compatible with old code; callers should always specify 
it."
         (or (c-cpp-define-name) (c-defun-name))))
   (let ((rfn (assq mode c-require-final-newline)))
     (when rfn
-      (and (cdr rfn)
-          (set (make-local-variable 'require-final-newline)
-                mode-require-final-newline)))))
+      (if (boundp 'mode-require-final-newline)
+          (and (cdr rfn)
+               (set (make-local-variable 'require-final-newline)
+                    mode-require-final-newline))
+        (set (make-local-variable 'require-final-newline) (cdr rfn))))))
 
 (defun c-count-cfss (lv-alist)
   ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
@@ -947,7 +960,11 @@ Note that the style variables are always made local to the 
buffer."
          c-new-END (min (cdr new-bounds) (c-determine-+ve-limit 500 endd)))
     ;; 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)
+
+    ;; CPP "comment" markers:
+    (if (eval-when-compile (memq 'category-properties c-emacs-features));Emacs.
+       (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.
@@ -966,8 +983,10 @@ Note that the style variables are always made local to the 
buffer."
          (setq mbeg (point))
          (if (> (c-syntactic-end-of-macro) mbeg)
              (progn
-               (c-neutralize-CPP-line mbeg (point))
-               (c-set-cpp-delimiters mbeg (point)))
+               (c-neutralize-CPP-line mbeg (point)) ; "punctuation" properties
+               (if (eval-when-compile
+                      (memq 'category-properties c-emacs-features)) ;Emacs.
+                   (c-set-cpp-delimiters mbeg (point)))) ; "comment" markers
            (forward-line))           ; no infinite loop with, e.g., "#//"
          )))))
 
@@ -987,64 +1006,71 @@ Note that the style variables are always made local to 
the buffer."
   ;; it/them from the cache.  Don't worry about being inside a string
   ;; or a comment - "wrongly" removing a symbol from `c-found-types'
   ;; isn't critical.
-  (setq c-maybe-stale-found-type nil)
-  (save-restriction
-    (save-match-data
-      (widen)
-      (save-excursion
-       ;; Are we inserting/deleting stuff in the middle of an identifier?
-       (c-unfind-enclosing-token beg)
-       (c-unfind-enclosing-token end)
-       ;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
-       (when (< beg end)
-         (c-unfind-coalesced-tokens beg end))
-       ;; Are we (potentially) disrupting the syntactic context which
-       ;; makes a type a type?  E.g. by inserting stuff after "foo" in
-       ;; "foo bar;", or before "foo" in "typedef foo *bar;"?
-       ;;
-       ;; We search for appropriate c-type properties "near" the change.
-       ;; First, find an appropriate boundary for this property search.
-       (let (lim
-             type type-pos
-             marked-id term-pos
-             (end1
-              (or (and (eq (get-text-property end 'face) 
'font-lock-comment-face)
-                       (previous-single-property-change end 'face))
-                  end)))
-         (when (>= end1 beg) ; Don't hassle about changes entirely in comments.
-           ;; Find a limit for the search for a `c-type' property
-           (while
-               (and (/= (skip-chars-backward "^;{}") 0)
-                    (> (point) (point-min))
-                    (memq (c-get-char-property (1- (point)) 'face)
-                          '(font-lock-comment-face font-lock-string-face))))
-           (setq lim (max (point-min) (1- (point))))
-
-           ;; Look for the latest `c-type' property before end1
-           (when (and (> end1 (point-min))
-                      (setq type-pos
-                            (if (get-text-property (1- end1) 'c-type)
-                                end1
-                              (previous-single-property-change end1 'c-type 
nil lim))))
-             (setq type (get-text-property (max (1- type-pos) lim) 'c-type))
-
-             (when (memq type '(c-decl-id-start c-decl-type-start))
-               ;; Get the identifier, if any, that the property is on.
-               (goto-char (1- type-pos))
-               (setq marked-id
-                     (when (looking-at "\\(\\sw\\|\\s_\\)")
-                       (c-beginning-of-current-token)
-                       (buffer-substring-no-properties (point) type-pos)))
-
-               (goto-char end1)
-               (skip-chars-forward "^;{}") ; FIXME!!!  loop for comment, maybe
-               (setq lim (point))
-               (setq term-pos
-                     (or (next-single-property-change end 'c-type nil lim) 
lim))
-               (setq c-maybe-stale-found-type
-                     (list type marked-id
-                           type-pos term-pos
-                           (buffer-substring-no-properties type-pos term-pos)
+  (unless c-just-done-before-change  ; Guard against a spurious second
+                             ; invocation of before-change-functions.
+    (setq c-just-done-before-change t)
+    (setq c-maybe-stale-found-type nil)
+    (save-restriction
+      (save-match-data
+       (widen)
+       (save-excursion
+         ;; Are we inserting/deleting stuff in the middle of an identifier?
+         (c-unfind-enclosing-token beg)
+         (c-unfind-enclosing-token end)
+         ;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
+         (when (< beg end)
+           (c-unfind-coalesced-tokens beg end))
+         ;; Are we (potentially) disrupting the syntactic context which
+         ;; makes a type a type?  E.g. by inserting stuff after "foo" in
+         ;; "foo bar;", or before "foo" in "typedef foo *bar;"?
+         ;;
+         ;; We search for appropriate c-type properties "near" the change.
+         ;; First, find an appropriate boundary for this property search.
+         (let (lim
+               type type-pos
+               marked-id term-pos
+               (end1
+                (or (and (eq (get-text-property end 'face)
+                             'font-lock-comment-face)
+                         (previous-single-property-change end 'face))
+                    end)))
+           (when (>= end1 beg) ; Don't hassle about changes entirely in 
comments.
+             ;; Find a limit for the search for a `c-type' property
+             (while
+                 (and (/= (skip-chars-backward "^;{}") 0)
+                      (> (point) (point-min))
+                      (memq (c-get-char-property (1- (point)) 'face)
+                            '(font-lock-comment-face font-lock-string-face))))
+             (setq lim (max (point-min) (1- (point))))
+
+             ;; Look for the latest `c-type' property before end1
+             (when (and (> end1 (point-min))
+                        (setq type-pos
+                              (if (get-text-property (1- end1) 'c-type)
+                                  end1
+                                (previous-single-property-change end1 'c-type
+                                                                 nil lim))))
+               (setq type (get-text-property (max (1- type-pos) lim) 'c-type))
+
+               (when (memq type '(c-decl-id-start c-decl-type-start))
+                 ;; Get the identifier, if any, that the property is on.
+                 (goto-char (1- type-pos))
+                 (setq marked-id
+                       (when (looking-at "\\(\\sw\\|\\s_\\)")
+                         (c-beginning-of-current-token)
+                         (buffer-substring-no-properties (point) type-pos)))
+
+                 (goto-char end1)
+                 (skip-chars-forward "^;{}") ;FIXME!!! loop for comment, maybe
+                 (setq lim (point))
+                 (setq term-pos
+                       (or (c-next-single-property-change end 'c-type nil lim)
+                           lim))
+                 (setq c-maybe-stale-found-type
+                       (list type marked-id
+                             type-pos term-pos
+                             (buffer-substring-no-properties type-pos
+                                                             term-pos)
                              (buffer-substring-no-properties beg end)))))))
 
          (if c-get-state-before-change-functions
@@ -1055,7 +1081,7 @@ Note that the style variables are always made local to 
the buffer."
          )))
     ;; The following must be done here rather than in `c-after-change' because
     ;; newly inserted parens would foul up the invalidation algorithm.
-  (c-invalidate-state-cache beg))
+    (c-invalidate-state-cache beg)))
 
 (defvar c-in-after-change-fontification nil)
 (make-variable-buffer-local 'c-in-after-change-fontification)
@@ -1076,6 +1102,7 @@ Note that the style variables are always made local to 
the buffer."
   ;; This calls the language variable c-before-font-lock-functions, if non nil.
   ;; This typically sets `syntax-table' properties.
 
+  (setq c-just-done-before-change nil)
   (c-save-buffer-state (case-fold-search open-paren-in-column-0-is-defun-start)
     ;; When `combine-after-change-calls' is used we might get calls
     ;; with regions outside the current narrowing.  This has been
@@ -1096,11 +1123,12 @@ Note that the style variables are always made local to 
the buffer."
        ;; C-y is capable of spuriously converting category properties
        ;; c-</>-as-paren-syntax and c-cpp-delimiter 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-clear-char-property-with-value beg end 'syntax-table nil)
+       (when (eval-when-compile (memq 'category-properties c-emacs-features))
+         (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-clear-char-property-with-value beg end 'syntax-table nil))
 
        (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
        (c-invalidate-sws-region-after beg end)
@@ -1238,6 +1266,7 @@ This function is called from `c-common-init', once per 
mode initialization."
       (make-local-hook 'font-lock-mode-hook))
   (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
 
+;; Emacs 22 and later.
 (defun c-extend-after-change-region (_beg _end _old-len)
   "Extend the region to be fontified, if necessary."
   ;; Note: the parameters are ignored here.  This somewhat indirect
@@ -1251,6 +1280,21 @@ This function is called from `c-common-init', once per 
mode initialization."
   ;; function.
   (cons c-new-BEG c-new-END))
 
+;; Emacs < 22 and XEmacs
+(defmacro c-advise-fl-for-region (function)
+  `(defadvice ,function (before get-awk-region activate)
+     ;; Make sure that any string/regexp is completely font-locked.
+     (when c-buffer-is-cc-mode
+       (save-excursion
+        (ad-set-arg 1 c-new-END)   ; end
+        (ad-set-arg 0 c-new-BEG)))))   ; beg
+
+(unless (boundp 'font-lock-extend-after-change-region-function)
+  (c-advise-fl-for-region font-lock-after-change-function)
+  (c-advise-fl-for-region jit-lock-after-change)
+  (c-advise-fl-for-region lazy-lock-defer-rest-after-change)
+  (c-advise-fl-for-region lazy-lock-defer-line-after-change))
+
 ;; Connect up to `electric-indent-mode' (Emacs 24.4 and later).
 (defun c-electric-indent-mode-hook ()
   ;; Emacs has en/disabled `electric-indent-mode'.  Propagate this through to
@@ -1779,4 +1823,8 @@ Key bindings:
 
 (cc-provide 'cc-mode)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-mode.el ends here
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index 337ef92..793a6ea 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -165,8 +165,8 @@
      (c-offsets-alist . ((topmost-intro        . 0)
                         (substatement         . +)
                         (substatement-open    . 0)
-                         (case-label           . +)
-                         (access-label         . -)
+                        (case-label           . +)
+                        (access-label         . -)
                         (inclass              . +)
                         (inline-open          . 0))))
     ("linux"
@@ -209,15 +209,15 @@
      (c-offsets-alist . ((inline-open . 0)
                         (topmost-intro-cont    . +)
                         (statement-block-intro . +)
-                        (knr-argdecl-intro     . 5)
+                        (knr-argdecl-intro     . 5)
                         (substatement-open     . +)
                         (substatement-label    . +)
-                        (label                 . +)
-                        (statement-case-open   . +)
-                        (statement-cont        . +)
-                        (arglist-intro  . c-lineup-arglist-intro-after-paren)
-                        (arglist-close  . c-lineup-arglist)
-                        (access-label   . 0)
+                        (label                 . +)
+                        (statement-case-open   . +)
+                        (statement-cont        . +)
+                        (arglist-intro  . c-lineup-arglist-intro-after-paren)
+                        (arglist-close  . c-lineup-arglist)
+                        (access-label   . 0)
                         (inher-cont     . c-lineup-java-inher)
                         (func-decl-cont . c-lineup-java-throws))))
 
@@ -663,4 +663,8 @@ DEFAULT-STYLE has the same format as `c-default-style'."
 
 (cc-provide 'cc-styles)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-styles.el ends here
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index ac8dbfc..635e382 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -271,12 +271,13 @@ nil."
   :group 'c)
 ;;;###autoload(put 'c-basic-offset 'safe-local-variable 'integerp)
 
+
 (defcustom c-tab-always-indent t
   "*Controls the operation of the TAB key.
 If t, hitting TAB always just indents the current line.  If nil, hitting
 TAB indents the current line if point is at the left margin or in the
 line's indentation, otherwise it inserts a `real' tab character \(see
-note\).         If some other value (not nil or t), then tab is inserted only
+note\).  If some other value (not nil or t), then tab is inserted only
 within literals \(comments and strings), but the line is always
 reindented.
 
@@ -540,7 +541,7 @@ variable in a mode hook."
                  (const :format "IDL   " idl-mode) (regexp :format "%v"))
            (cons :format "%v"
                  (const :format "Pike  " pike-mode) (regexp :format "%v"))
-            (cons :format "%v"
+           (cons :format "%v"
                  (const :format "AWK   " awk-mode) (regexp :format "%v")))
           (cons :format "    %v"
                 (const :format "Other " other) (regexp :format "%v"))))
@@ -1175,7 +1176,7 @@ can always override the use of `c-default-style' by 
making calls to
        (objc-method-args-cont . c-lineup-ObjC-method-args)
        ;; Anchor pos: At the method start (always at boi).
        (objc-method-call-cont . (c-lineup-ObjC-method-call-colons
-                               c-lineup-ObjC-method-call +))
+                               c-lineup-ObjC-method-call +))
        ;; Anchor pos: At the open bracket.
        (extern-lang-open      . 0)
        (namespace-open        . 0)
@@ -1771,4 +1772,8 @@ It treats escaped EOLs as whitespace.")
 
 (cc-provide 'cc-vars)
 
+;;; Local Variables:
+;;; indent-tabs-mode: t
+;;; tab-width: 8
+;;; End:
 ;;; cc-vars.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]