]> code.delx.au - gnu-emacs/commitdiff
Update to version 5.28.
authorGerd Moellmann <gerd@gnu.org>
Wed, 21 Mar 2001 12:59:36 +0000 (12:59 +0000)
committerGerd Moellmann <gerd@gnu.org>
Wed, 21 Mar 2001 12:59:36 +0000 (12:59 +0000)
12 files changed:
lisp/ChangeLog
lisp/progmodes/cc-align.el
lisp/progmodes/cc-bytecomp.el [new file with mode: 0644]
lisp/progmodes/cc-cmds.el
lisp/progmodes/cc-compat.el
lisp/progmodes/cc-defs.el
lisp/progmodes/cc-engine.el
lisp/progmodes/cc-langs.el
lisp/progmodes/cc-menus.el
lisp/progmodes/cc-mode.el
lisp/progmodes/cc-styles.el
lisp/progmodes/cc-vars.el

index e094f5cc0b25d37930f23ddb7cff7708bc7e0d97..5473ab98fd78747560649665476c93faa10dd1a3 100644 (file)
@@ -6,6 +6,372 @@
        * mail/sendmail.el (sendmail-send-it): Don't parse Resent-*
        headers.  Always invoke sendmail with option -t.
 
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * Release of cc-mode 5.28.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-mode.el, cc-vars.el (c-common-init, c-default-style):
+       Removed the hardcoded switch to "java" style in Java mode.
+       It's instead taken care of by the default value for
+       c-default-style.
+
+       * cc-mode.texi: Updated the mentions of the "java" style
+       special case for Java mode.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-align.el (c-lineup-math): Fix bug where lineup was
+       triggered by equal signs in string literals.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-fill-paragraph): Fixed bug in the paragraph
+       limit detection when at the ends of the buffer.
+
+       * cc-engine.el (c-guess-basic-syntax): Removed bogus check for
+       "for" statement clause in case 7F; a better one is done
+       earlier in case 7D anyway.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-guess-fill-prefix): Improved the heuristics
+       somewhat more and did a small optimization.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-beginning-of-statement, c-end-of-statement):
+       Use the limit argument only to limit the syntactic context
+       search, not to limit the actual movement.
+
+       * cc-cmds.el (c-beginning-of-statement): Move by sentence
+       inside multiline strings, just like in comments.  Also various
+       fixes to the paragraph and comment prefix recognition, block
+       comment ender handling etc.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-fill-paragraph): Take more care to preserve
+       the relative position of the point.
+
+       * cc-cmds.el (c-electric-continued-statement): New function to
+       use as abbrev hook to reindent for keywords such as "else"
+       that continues an earlier statement.
+
+       * cc-menus.el (cc-imenu-c++-generic-expression): Treat structs
+       like classes.
+
+       * cc-mode.el (c-mode, c++-mode, java-mode, objc-mode)
+       (pike-mode): Populate the default abbrev tables to reindent for
+       keywords such as "else" that can continue earlier statements.
+       Abbrev mode is therefore turned on by default now.  (Note that
+       this doesn't apply to idl-mode, since IDL afaik doesn't have
+       statements at all.)
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-inside-bracelist-p): Fix for handling
+       bracelists where the declaration contains template arguments.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-comment-indent): Use
+       `c-get-syntactic-indentation' to correctly calculate the
+       syntactic indentation.  Fixes bug with lineup functions that
+       return vectors.
+
+       * cc-engine.el (c-get-syntactic-indentation): Split the
+       indentation sum calculation from `c-indent-line' to a separate
+       function.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-beginning-of-statement, c-comment-indent):
+       Fixed places where it was assumed that preprocessor directives
+       have to start in column zero.
+
+       * cc-engine.el (c-beginning-of-member-init-list): Handle C++
+       template arguments after a class identifier properly.
+
+       * cc-engine.el (c-guess-basic-syntax): Treat initializer brace
+       lists for `new Foo[]' constructs in Java as expressions and
+       not top level definition brace lists on the top level, so that
+       they'll get indented consistently with the same type of
+       expression in a normal block.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-fill-paragraph): The kludge that checks
+       whether the adaptive filling package fails to keep the comment
+       prefix is now kludged further to check for filladapt-mode
+       which doesn't have that problem. This is really icky, but it's
+       the only way that works with the current misfeatures/bugs in
+       both adaptive-fill-mode and filladapt-mode.
+
+       * cc-cmds.el (c-fill-paragraph): Made the way the paragraph
+       around point is recognized more robust.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el, cc-engine.el, cc-lobotomy.el (c-state-cache)
+       (c-in-literal-cache, c-auto-fill-prefix, c-lit-limits)
+       (c-lit-type): Fixed all internal variables used dynamically so
+       that they are always bound.
+
+       * cc-cmds.el, cc-engine.el: Improved recovery of syntactic
+       errors:
+
+       (c-indent-region): Fixed reporting of syntactic errors so that
+       the region is fully reindented even when an error occurs.  The
+       last syntactic error is printed afterwards.  Also cleanup up a
+       whole lot of code that tried to optimize indentation of whole
+       sexps but in reality accomplishes nothing.
+
+       (c-indent-sexp): Use c-indent-region.
+
+       (c-parsing-error): Changed this variable to hold the message
+       for any syntactic error that is discovered.
+
+       (c-parse-state): Search backward from point instead of the bod
+       position when the latter is invalid.  This makes CC Mode
+       recover faster when there are unbalanced close braces.
+
+       (c-backward-to-start-of-if): Use c-parsing-error to report
+       dangling "else" clauses instead of throwing an error, and fall
+       back to a reasonable position.
+
+       (c-indent-line): Added argument to avoid reporting syntactic
+       errors.
+
+       (c-show-syntactic-information): Don't report any syntactic
+       errors.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-beginning-of-statement): Fixed bugs with
+       paragraph recognition when moving by sentence in literals.
+
+       * cc-langs.el (c-Java-javadoc-paragraph-start): Modified
+       paragraph start regexp for javadoc to recognize javadoc markup
+       in general instead of a specific set of keywords, to be more
+       future-safe.
+
+       (c-Pike-pikedoc-paragraph-start)
+       (c-Pike-pikedoc-paragraph-separate): New regexps to recognize
+       pikedoc markup.
+
+       * cc-mode.el: Fixed initialization and use of
+       c-current-comment-prefix.
+
+       (pike-mode): Initialize paragraph settings pikedoc
+       recognition.
+
+       * cc-vars.el (c-default-style): Made a nicer Customize widget.
+
+       (c-comment-prefix-regexp): Made it possible to use an
+       association list on this to specify mode specific regexps.
+       The default value now use a special regexp in Pike mode to
+       recognize pikedoc markup.
+
+       (c-current-comment-prefix): New variable containing the actual
+       regexp from c-comment-prefix-regexp for the current buffer.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-electric-brace): Fixed check for special brace
+       lists: We can't look at the syntax, since a brace list can get
+       recognized as a plain statement-cont.
+
+       * cc-engine.el (c-guess-basic-syntax): Fixed bug where a
+       special brace list opener broken over two lines got recognized
+       as a statement on the second line.  Case 9A changed.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-electric-brace): Fixed bug in c-state-cache
+       adjustment after line is reindented.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-defs.el (c-point): Added optional argument for position
+       to use instead of the current point.
+
+       * cc-defs.el, cc-engine.el (c-add-class-syntax): Do not add
+       the in-expression block symbols when the construct starts at
+       boi, to avoid the extra level of indentation in that case.
+       Cases 4, 16A and 17E affected.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el: Use `indent-according-to-mode' instead of direct
+       calls to `c-indent-line', to adhere better to Emacs
+       conventions.
+
+       * cc-engine.el (c-indent-line): Use the syntax already bound
+       to `c-syntactic-context', if there is any.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-get-offset): Fixed bug where the indentation
+       wasn't added up correctly when a lineup function returned nil.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-collect-line-comments): Fixed bug where
+       empty lines were ignored when collecting line comments
+       backwards.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-align.el (c-lineup-dont-change): Return an absolute
+       indentation column to work correctly in the case when several
+       syntactic elements are processed for the same line.
+
+       * cc-engine.el, cc-styles.el, cc-vars.el (c-evaluate-offset)
+       (c-get-offset, c-indent-line, c-valid-offset, c-read-offset)
+       (c-set-offset): Added absolute indentation column settings by
+       using the vector type.
+
+       * cc-mode.texi: Documented the new vector setting for offsets.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el, cc-vars.el (c-electric-paren, c-cleanup-list):
+       Implemented two new cleanups `space-before-funcall' and
+       `compact-empty-funcall'.
+
+       * cc-mode.texi: Documented the two new cleanups
+       space-before-funcall and compact-empty-funcall on
+       c-cleanup-list.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-defs.el (c-paren-re, c-identifier-re): Two new macros for
+       helping building regexps.
+
+       * cc-engine.el (c-on-identifier): New function for detecting
+       identifiers.  It takes keywords into account.
+
+       * cc-langs.el, cc-mode.el: Added regexps for complete keyword
+       lists.  `c-keywords' is set to a regexp matching all keywords
+       in the current language.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-beginning-of-statement-1): Added '#' to the
+       list of characters to skip backwards over at the beginning of
+       a statement, since it can precede string literals in Pike.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-guess-fill-prefix): Fixed bug with prefix
+       recognition when standing on the last line in a C++ comment
+       with nothing but whitespace after the prefix.
+
+       * cc-engine.el (c-backward-to-start-of-if): Fixed bug when
+       given no limit argument.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-inside-bracelist-p): Fixed brace list
+       recognition for the `[]= operator symbol in Pike.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-bytecomp.el (cc-eval-when-compile): New macro that works
+       around a bug in `eval-when-compile' in the byte compiler.
+
+       * cc-engine.el (c-forward-token-1): Fixed bug with return
+       value when count is zero and there's no token start within the
+       limit.
+
+       (c-guess-basic-syntax): Don't add 'comment-intro to lines with
+       "prefix comments", i.e. comments which are followed by code on
+       the same line.
+
+       * cc-mode-19.el: Fixes so that checks that must be done at
+       compile time also are done then.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-defs.el: Make sure cc-mode-19 is loaded both at compile
+       time and at runtime, and only when it's needed.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       Major cleanup for less error prone and more warning free
+       compilation, including some fixes for bugs due to different
+       compilation orders. Thanks to Martin Buchholz for providing
+       the basis for all this.
+
+       * cc-bytecomp.el: New file that provides some byte compilation
+       features: It ensures that files always are loaded from the
+       current source directory during compilation, and it provides a
+       set of macros to turn off specific compiler warnings for
+       specific symbols.  (It's not CC Mode specific in any way.)
+
+       Fixed a nearly acyclic dependency tree (both runtime and
+       compile-time) between all files.
+
+       * cc-defs.el: Separated all macros before the inline functions,
+       to ensure correct compilation.
+
+       * cc-defs.el, cc-engine.el: Moved c-beginning-of-macro to from
+       cc-defs.el to cc-engine.el and made it a function instead.
+
+       * cc-mode-19.el: Patch the byte compiler in Emacs 19 not to warn
+       about char-after.
+
+       * cc-vars.el: Cope even when there isn't a custom package
+       containing defcustom available.
+
+       * cc-make.el: Removed since it's no longer necessary.
+
+       README: Updated installation instructions.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el, cc-langs.el, cc-mode.el: Moved around things to
+       improve the modularity: Moved all mode init stuff from
+       cc-langs.el to cc-mode.el, including the keymap
+       initialization; cc-langs now only contains the various
+       variables for configuring the language syntax.
+
+       * cc-engine.el, cc-styles.el (c-evaluate-offset,
+       c-get-offset): Moved from cc-styles to cc-engine since file
+       dependency analysis suggests they belong there (which also
+       makes more sense).  Thanks to Martin Buchholz for doing the
+       analysis.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-fn-region-is-active-p): New function that
+       wraps the corresponding macro, for use in places that aren't
+       compiled.  Thanks to Martin Buchholz for pointing out this.
+
+       * cc-langs.el (c-mode-menu): Use c-fn-region-is-active-p. 
+
+       * cc-mode.el (c-prepare-bug-report-hooks): Hook variable to
+       add things to the bug report.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-guess-fill-prefix): Fixed bug where the
+       returned prefix could contain a newline when the search for a
+       good prefix line failed.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-cmds.el (c-toggle-auto-state, c-toggle-hungry-state)
+       (c-toggle-auto-hungry-state): Made the argument optional, as
+       the documentation says it is.
+
+2000-03-21  Martin Stjernholm  <bug-cc-mode@gnu.org>
+
+       * cc-engine.el (c-guess-basic-syntax): Don't treat the Pike
+       multiline string syntax, #"...", as a cpp macro.
+
 2001-03-21  Paul Eggert  <eggert@twinsun.com>
 
        * international/mule-cmds.el (set-locale-environment): Set
index 8bb69e387c880a74770eaa7cd81e3fb0e9756ee4..c5c8786085c9dcdd21800ca4661fb3a9fa67e28d 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-align.el --- custom indentation functions for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-engine)
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
+(cc-require 'cc-langs)
+(cc-require 'cc-engine)
 
 \f
 ;; Standard indentation line-ups
@@ -254,9 +257,9 @@ if (n > 0)                 if (n > 0)
 <--> c-basic-offset            m+=n; n=0;
                            }
 
-The block may be surrounded by any kind of parenthesis characters.
-nil is returned if the line doesn't start with a one line block, which
-makes the function usable in list expressions.
+The block may use any kind of parenthesis character.  nil is returned
+if the line doesn't start with a one line block, which makes the
+function usable in list expressions.
 
 Work with: Almost all syntactic symbols, but most useful on *-open."
   (save-excursion
@@ -279,9 +282,9 @@ int *foo[] = {           int *foo[] = {
                                  }
                              <--> c-basic-offset
 
-The block may be surrounded by any kind of parenthesis characters.
-nil is returned if the line doesn't start with a multi line block,
-which makes the function usable in list expressions.
+The block may use any kind of parenthesis character.  nil is returned
+if the line doesn't start with a multi line block, which makes the
+function usable in list expressions.
 
 Work with: Almost all syntactic symbols, but most useful on *-open."
   (save-excursion
@@ -295,7 +298,7 @@ Work with: Almost all syntactic symbols, but most useful on *-open."
 
 (defun c-lineup-C-comments (langelem)
   "Line up C block comment continuation lines.
-Various heuristics are used to handle most of the common comment
+Various heuristics are used to handle many of the common comment
 styles.  Some examples:
 
 /*          /**         /*         /* text      /*          /**
@@ -322,7 +325,7 @@ Works with: The `c' syntactic symbol."
   (save-excursion
     (let* ((here (point))
           (prefixlen (progn (back-to-indentation)
-                            (if (looking-at c-comment-prefix-regexp)
+                            (if (looking-at c-current-comment-prefix)
                                 (- (match-end 0) (point))
                               0)))
           (starterlen (save-excursion
@@ -369,11 +372,11 @@ Works with: The `c' syntactic symbol."
          ;; line has a nonempty comment prefix, align with it.
          ;; Otherwise, align with the previous nonempty line, but
          ;; align the comment ender with the starter.
-         (when (or (not (looking-at c-comment-prefix-regexp))
+         (when (or (not (looking-at c-current-comment-prefix))
                    (eq (match-beginning 0) (match-end 0)))
            (goto-char here)
            (back-to-indentation)
-           (if (looking-at (concat "\\(" c-comment-prefix-regexp "\\)\\*/"))
+           (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/"))
                (goto-char (cdr langelem))
              (while (and (zerop (forward-line -1))
                          (looking-at "^[ \t]*$")))
@@ -392,19 +395,13 @@ line, that alignment is preserved.
 Works with: comment-intro."
   (save-excursion
     (back-to-indentation)
-    ;; this highly kludgiforous flag prevents the mapcar over
-    ;; c-syntactic-context from entering an infinite loop
-    (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag))
-         (col (current-column)))
+    (let ((col (current-column)))
       (cond
-       (recurse-prevention-flag 0)
        ;; CASE 1: preserve aligned comments
        ((save-excursion
          (and (c-forward-comment -1)
               (= col (current-column))))
-       ;; we have to subtract out all other indentation
-       (- col (apply '+ (mapcar 'c-get-offset
-                                c-syntactic-context))))
+       (vector col))                   ; Return an absolute column.
        ;; indent as specified by c-comment-only-line-offset
        ((not (bolp))
        (or (car-safe c-comment-only-line-offset)
@@ -446,7 +443,10 @@ Works with: statement-cont."
   (save-excursion
     (let ((equalp (save-excursion
                    (goto-char (c-point 'boi))
-                   (skip-chars-forward "^=" (c-point 'eol))
+                   (let ((eol (c-point 'eol)))
+                     (c-forward-token-1 0 t eol)
+                     (while (and (not (eq (char-after) ?=))
+                                 (= (c-forward-token-1 1 t eol) 0))))
                    (and (eq (char-after) ?=)
                         (- (point) (c-point 'boi)))))
          (langelem-col (c-langelem-col langelem))
@@ -616,7 +616,7 @@ inextern-lang, innamespace."
 Works with: Any syntactic symbol."
   (save-excursion
     (back-to-indentation)
-    (- (current-column) (c-langelem-col langelem))))
+    (vector (current-column))))
 
 \f
 (defun c-snug-do-while (syntax pos)
@@ -718,5 +718,5 @@ For other semicolon contexts, no determination is made."
       nil)))
 
 \f
-(provide 'cc-align)
+(cc-provide 'cc-align)
 ;;; cc-align.el ends here
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
new file mode 100644 (file)
index 0000000..1d2e44e
--- /dev/null
@@ -0,0 +1,290 @@
+;;; cc-bytecomp.el --- Compile time setup for proper compilation
+
+;; Copyright (C) 2000, 01 Free Software Foundation, Inc.
+
+;; Author:     Martin Stjernholm
+;; Maintainer: bug-cc-mode@gnu.org
+;; Created:    15-Jul-2000
+;; Version:    See cc-mode.el
+;; Keywords:   c languages oop
+
+;; This program 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 2 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This file is used to ensure that the CC Mode files are correctly
+;; compiled regardless the environment (e.g. if an older CC Mode with
+;; outdated macros are loaded during compilation).  It also provides
+;; features to defeat the compiler warnings for selected symbols.
+
+\f
+(defvar cc-bytecomp-unbound-variables nil)
+(defvar cc-bytecomp-original-functions nil)
+(defvar cc-bytecomp-original-properties nil)
+(defvar cc-bytecomp-load-depth 0)
+(defvar cc-bytecomp-loaded-files nil)
+(defvar cc-bytecomp-environment-set nil)
+
+(put 'cc-eval-when-compile 'lisp-indent-hook 0)
+(defmacro cc-eval-when-compile (&rest body)
+  "Like `progn', but evaluates the body at compile time.
+The result of the body appears to the compiler as a quoted constant.
+
+This variant works around what looks like a bug in
+`eval-when-compile': During byte compilation it byte compiles its
+contents before evaluating it.  That can cause forms to be compiled in
+situations they aren't intended to be compiled.  See cc-bytecomp.el
+for further discussion."
+  ;;
+  ;; Example: It's not possible to defsubst a primitive, e.g. the
+  ;; following will produce an error (in any emacs flavor), since
+  ;; `nthcdr' is a primitive function that's handled specially by the
+  ;; byte compiler and thus can't be redefined:
+  ;;
+  ;;     (defsubst nthcdr (val) val)
+  ;;
+  ;; `defsubst', like `defmacro', needs to be evaluated at compile
+  ;; time, so this will produce an error during byte compilation.
+  ;;
+  ;; CC Mode occasionally needs to do things like this for cross-emacs
+  ;; compatibility (although we try to avoid it since it results in
+  ;; byte code that isn't compatible between emacsen).  It therefore
+  ;; uses the following to conditionally do a `defsubst':
+  ;;
+  ;;     (eval-when-compile
+  ;;       (if (not (fboundp 'foo))
+  ;;           (defsubst foo ...)))
+  ;;
+  ;; But `eval-when-compile' byte compiles its contents and _then_
+  ;; evaluates it (in all current emacs versions, up to and including
+  ;; Emacs 20.6 and XEmacs 21.1 as of this writing).  So this will
+  ;; still produce an error, since the byte compiler will get to the
+  ;; defsubst anyway.  That's arguably a bug because the point with
+  ;; `eval-when-compile' is that it should evaluate rather than
+  ;; compile its contents.
+  `(eval-when-compile (eval '(progn ,@body))))
+
+(defun cc-bytecomp-setup-environment ()
+  ;; Eval'ed during compilation to setup variables, functions etc
+  ;; declared with `cc-bytecomp-defvar' et al.
+  (if (= cc-bytecomp-load-depth 0)
+      (let (p)
+       (if cc-bytecomp-environment-set
+           (error "Byte compilation environment already set - \
+perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
+       (setq p cc-bytecomp-unbound-variables)
+       (while p
+         (if (not (boundp (car p)))
+             (progn
+               (eval `(defvar ,(car p)))
+               (set (car p) 'cc-bytecomp-ignore)))
+         (setq p (cdr p)))
+       (setq p cc-bytecomp-original-functions)
+       (while p
+         (let ((fun (car (car p)))
+               (temp-macro (car (cdr (car p)))))
+           (if temp-macro
+               (eval `(defmacro ,fun ,@temp-macro))
+             (fset fun 'cc-bytecomp-ignore)))
+         (setq p (cdr p)))
+       (setq p cc-bytecomp-original-properties)
+       (while p
+         (let ((sym (car (car (car p))))
+               (prop (cdr (car (car p))))
+               (tempdef (car (cdr (car p)))))
+           (put sym prop tempdef))
+         (setq p (cdr p)))
+       (setq cc-bytecomp-environment-set t))))
+
+(defun cc-bytecomp-restore-environment ()
+  ;; Eval'ed during compilation to restore variables, functions etc
+  ;; declared with `cc-bytecomp-defvar' et al.
+  (if (= cc-bytecomp-load-depth 0)
+      (let (p)
+       (setq p cc-bytecomp-unbound-variables)
+       (while p
+         (let ((var (car p)))
+           (if (and (boundp var)
+                    (eq var 'cc-bytecomp-ignore))
+               (makunbound var)))
+         (setq p (cdr p)))
+       (setq p cc-bytecomp-original-functions)
+       (while p
+         (let ((fun (car (car p)))
+               (def (car (cdr (cdr (car p))))))
+           (if (and (fboundp fun)
+                    (eq (symbol-function fun) 'cc-bytecomp-ignore))
+               (if (eq def 'unbound)
+                   (fmakunbound fun)
+                 (fset fun def))))
+         (setq p (cdr p)))
+       (setq p cc-bytecomp-original-properties)
+       (while p
+         (let ((sym (car (car (car p))))
+               (prop (cdr (car (car p))))
+               (tempdef (car (cdr (car p))))
+               (origdef (cdr (cdr (car p)))))
+           (if (eq (get sym prop) tempdef)
+               (put sym prop origdef)))
+         (setq p (cdr p)))
+       (setq cc-bytecomp-environment-set nil))))
+
+(defun cc-bytecomp-load (cc-part)
+  ;; Eval'ed during compilation to load a CC Mode file from the source
+  ;; directory (assuming it's the same as the compiled file
+  ;; destination dir).
+  (if (and (boundp 'byte-compile-dest-file)
+          (stringp byte-compile-dest-file))
+      (progn
+       (cc-bytecomp-restore-environment)
+       (let ((cc-bytecomp-load-depth (1+ cc-bytecomp-load-depth))
+             (load-path
+              (cons (file-name-directory byte-compile-dest-file)
+                    load-path))
+             (cc-file (concat cc-part ".el")))
+         (if (member cc-file cc-bytecomp-loaded-files)
+             ()
+           (setq cc-bytecomp-loaded-files
+                 (cons cc-file cc-bytecomp-loaded-files))
+           (load cc-file nil t t)))
+       (cc-bytecomp-setup-environment)
+       t)))
+
+(defmacro cc-require (cc-part)
+  "Force loading of the corresponding .el file in the current
+directory during compilation, but compile in a `require'.  Don't use
+within `eval-when-compile'.
+
+Having cyclic cc-require's will result in infinite recursion.  That's
+somewhat intentional."
+  `(progn
+     (cc-eval-when-compile (cc-bytecomp-load (symbol-name ,cc-part)))
+     (require ,cc-part)))
+
+(defmacro cc-provide (feature)
+  "A replacement for the `provide' form that restores the environment
+after the compilation.  Don't use within `eval-when-compile'."
+  `(progn
+     (eval-when-compile (cc-bytecomp-restore-environment))
+     (provide ,feature)))
+
+(defmacro cc-load (cc-part)
+  "Force loading of the corresponding .el file in the current
+directory during compilation.  Don't use outside `eval-when-compile'
+or `eval-and-compile'.
+
+Having cyclic cc-load's will result in infinite recursion.  That's
+somewhat intentional."
+  `(or (and (featurep 'cc-bytecomp)
+           (cc-bytecomp-load ,cc-part))
+       (load ,cc-part nil t nil)))
+
+(defun cc-bytecomp-is-compiling ()
+  "Return non-nil if eval'ed during compilation.  Don't use outside
+`eval-when-compile'."
+  (and (boundp 'byte-compile-dest-file)
+       (stringp byte-compile-dest-file)))
+
+(defmacro cc-bytecomp-defvar (var)
+  "Binds the symbol as a variable during compilation of the file,
+to silence the byte compiler.  Don't use within `eval-when-compile'."
+  `(eval-when-compile
+     (if (boundp ',var)
+        nil
+       (if (not (memq ',var cc-bytecomp-unbound-variables))
+          (setq cc-bytecomp-unbound-variables
+                (cons ',var cc-bytecomp-unbound-variables)))
+       (if (and (cc-bytecomp-is-compiling)
+               (= cc-bytecomp-load-depth 0))
+          (progn
+            (defvar ,var)
+            (set ',var 'cc-bytecomp-ignore))))))
+
+(defmacro cc-bytecomp-defun (fun)
+  "Bind the symbol as a function during compilation of the file,
+to silence the byte compiler.  Don't use within `eval-when-compile'."
+  `(eval-when-compile
+     (if (not (assq ',fun cc-bytecomp-original-functions))
+        (setq cc-bytecomp-original-functions
+              (cons (list ',fun
+                          nil
+                          (if (fboundp ',fun)
+                              (symbol-function ',fun)
+                            'unbound))
+                    cc-bytecomp-original-functions)))
+     (if (and (cc-bytecomp-is-compiling)
+             (= cc-bytecomp-load-depth 0)
+             (not (fboundp ',fun)))
+        (fset ',fun 'cc-bytecomp-ignore))))
+
+(put 'cc-bytecomp-defmacro 'lisp-indent-function 'defun)
+(defmacro cc-bytecomp-defmacro (fun &rest temp-macro)
+  "Bind the symbol as a macro during compilation (and evaluation) of the
+file.  Don't use outside `eval-when-compile'."
+  `(progn
+     (if (not (assq ',fun cc-bytecomp-original-functions))
+        (setq cc-bytecomp-original-functions
+              (cons (list ',fun
+                          ',temp-macro
+                          (if (fboundp ',fun)
+                              (symbol-function ',fun)
+                            'unbound))
+                    cc-bytecomp-original-functions)))
+     (defmacro ,fun ,@temp-macro)))
+
+(defmacro cc-bytecomp-put (symbol propname value)
+  "Set a property on a symbol during compilation (and evaluation) of
+the file.  Don't use outside `eval-when-compile'."
+  `(cc-eval-when-compile
+     (if (not (assoc (cons ,symbol ,propname) cc-bytecomp-original-properties))
+        (setq cc-bytecomp-original-properties
+              (cons (cons (cons ,symbol ,propname)
+                          (cons ,value (get ,symbol ,propname)))
+                    cc-bytecomp-original-properties)))
+     (put ,symbol ,propname ,value)))
+
+(defmacro cc-bytecomp-obsolete-var (symbol)
+  "Suppress warnings about 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))))
+
+(defun cc-bytecomp-ignore-obsolete (form)
+  ;; Wraps a call to `byte-compile-obsolete' that suppresses the warning.
+  (let ((byte-compile-warnings
+        (delq 'obsolete (append byte-compile-warnings nil))))
+    (byte-compile-obsolete form)))
+
+(defmacro cc-bytecomp-obsolete-fun (symbol)
+  "Suppress warnings about 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))))
+
+;; Override ourselves with a version loaded from source if we're
+;; compiling, like cc-require does for all the other files.
+(if (and (cc-bytecomp-is-compiling)
+        (= cc-bytecomp-load-depth 0))
+    (let ((load-path
+          (cons (file-name-directory byte-compile-dest-file) load-path))
+         (cc-bytecomp-load-depth 1))
+      (load "cc-bytecomp.el" nil t t)))
+
+\f
+(provide 'cc-bytecomp)
index cc5c3b9f9cece60b1ac5213a7c666cb88ab1b332..ae905c08d8673faf249bbf100079c8c43eaa82d5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-cmds.el --- user level commands for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-engine)
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
+(cc-require 'cc-langs)
+(cc-require 'cc-engine)
+
+;; Silence the compiler.
+(cc-bytecomp-defvar delete-key-deletes-forward) ; XEmacs 20+
+(cc-bytecomp-defun delete-forward-p)   ; XEmacs 21+
+(cc-bytecomp-obsolete-fun insert-and-inherit) ; Marked obsolete in XEmacs 19
+(cc-bytecomp-defvar filladapt-mode)    ; c-fill-paragraph contains a kludge
+                                       ; which looks at this.
 
 \f
 (defun c-calculate-state (arg prevstate)
     (> arg 0)))
 
 ;; Auto-newline and hungry-delete
-(defun c-toggle-auto-state (arg)
+(defun c-toggle-auto-state (&optional arg)
   "Toggle auto-newline feature.
-Optional numeric ARG, if supplied turns on auto-newline when positive,
-turns it off when negative, and just toggles it when zero.
+Optional numeric ARG, if supplied, turns on auto-newline when
+positive, turns it off when negative, and just toggles it when zero or
+left out.
 
 When the auto-newline feature is enabled (as evidenced by the `/a' or
 `/ah' on the modeline after the mode name) newlines are automatically
@@ -64,10 +75,11 @@ and colon."
   (c-update-modeline)
   (c-keep-region-active))
 
-(defun c-toggle-hungry-state (arg)
+(defun c-toggle-hungry-state (&optional arg)
   "Toggle hungry-delete-key feature.
-Optional numeric ARG, if supplied turns on hungry-delete when positive,
-turns it off when negative, and just toggles it when zero.
+Optional numeric ARG, if supplied, turns on hungry-delete when
+positive, turns it off when negative, and just toggles it when zero or
+left out.
 
 When the hungry-delete-key feature is enabled (as evidenced by the
 `/h' or `/ah' on the modeline after the mode name) the delete key
@@ -77,11 +89,11 @@ gobbles all preceding whitespace in one fell swoop."
   (c-update-modeline)
   (c-keep-region-active))
 
-(defun c-toggle-auto-hungry-state (arg)
+(defun c-toggle-auto-hungry-state (&optional arg)
   "Toggle auto-newline and hungry-delete-key features.
-Optional numeric ARG, if supplied turns on auto-newline and
+Optional numeric ARG, if supplied, turns on auto-newline and
 hungry-delete when positive, turns them off when negative, and just
-toggles them when zero.
+toggles them when zero or left out.
 
 See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
   (interactive "P")
@@ -258,9 +270,6 @@ This function does various newline cleanups based on the value of
        ;; Do not try to insert newlines around a special (Pike-style)
        ;; brace list.
        (if (and c-special-brace-lists
-                (c-intersect-lists '(brace-list-open brace-list-close
-                                     brace-list-intro brace-entry-open)
-                                   syntax)
                 (save-excursion
                   (c-safe (if (= (char-before) ?{)
                               (forward-char -1)
@@ -278,9 +287,12 @@ This function does various newline cleanups based on the value of
        (if (memq 'before newlines)
            ;; we leave the newline we've put in there before,
            ;; but we need to re-indent the line above
-           (let ((pos (- (point-max) (point)))
+           (let (old-ind
+                 (old-point-max (point-max))
+                 (pos (- (point-max) (point)))
                  (here (point)))
              (forward-line -1)
+             (setq old-ind (c-point 'boi))
              (let ((c-state-cache (c-whack-state (point) c-state-cache)))
                ;; we may need to update the cache. this should
                ;; still be faster than recalculating the state
@@ -296,9 +308,9 @@ This function does various newline cleanups based on the value of
                        (setq c-state-cache
                              (c-hack-state (point) 'open c-state-cache)))))
                (if c-syntactic-indentation
-                   (c-indent-line)))
-             (setq c-state-cache (c-adjust-state (c-point 'bol) here
-                                                 (- (point) (c-point 'bol))
+                   (indent-according-to-mode)))
+             (setq c-state-cache (c-adjust-state (c-point 'bol) old-point-max
+                                                 (- (c-point 'boi) old-ind)
                                                  c-state-cache))
              (goto-char (- (point-max) pos))
              ;; if the buffer has changed due to the indentation, we
@@ -327,17 +339,19 @@ This function does various newline cleanups based on the value of
                  (setq syntax (c-guess-basic-syntax))
                ;; gotta punt. this requires some horrible kludgery
                (beginning-of-line)
-               (makunbound 'c-state-cache)
-               (setq c-state-cache (c-parse-state)
+               (setq c-state-cache nil
+                     c-state-cache (c-parse-state)
                      syntax nil))))
          )
-       ;; now adjust the line's indentation. don't update the state
-       ;; cache since c-guess-basic-syntax isn't called when the
-       ;; syntax is passed to c-indent-line
-       (let* ((here (point)))
-         (c-indent-line syntax)
-         (setq c-state-cache (c-adjust-state (c-point 'bol) here
-                                             (- (c-point 'boi) (c-point 'bol))
+       ;; Now adjust the line's indentation.  Don't update the state
+       ;; cache since c-guess-basic-syntax isn't called when
+       ;; c-syntactic-context is set.
+       (let* ((old-ind (c-point 'boi))
+              (old-point-max (point-max))
+              (c-syntactic-context syntax))
+         (indent-according-to-mode)
+         (setq c-state-cache (c-adjust-state (c-point 'bol) old-point-max
+                                             (- (c-point 'boi) old-ind)
                                              c-state-cache)))
        ;; Do all appropriate clean ups
        (let ((here (point))
@@ -396,7 +410,7 @@ This function does various newline cleanups based on the value of
              (let* ((bufpos (- (point) 2))
                     (which (if (eq (char-after bufpos) ?{) 'open 'close))
                     (c-state-cache (c-hack-state bufpos which c-state-cache)))
-               (c-indent-line))))
+               (indent-according-to-mode))))
        ;; blink the paren
        (and (eq last-command-char ?\})
             old-blink-paren
@@ -432,7 +446,7 @@ If a numeric ARG is supplied, point is inside a literal, or
         (c-echo-syntactic-information-p nil))
     (self-insert-command (prefix-numeric-value arg))
     (if indentp
-       (c-indent-line))))
+       (indent-according-to-mode))))
 
 (defun c-electric-star (arg)
   "Insert a star character.
@@ -455,9 +469,8 @@ If a numeric ARG is supplied, point is inside a literal, or
                 (forward-char -1))
             (skip-chars-backward " \t")
             (bolp)))
-      ;; shut this up
-      (let (c-echo-syntactic-information-p)
-       (c-indent-line))
+      (let (c-echo-syntactic-information-p) ; shut this up
+       (indent-according-to-mode))
     ))
 
 (defun c-electric-semi&comma (arg)
@@ -490,7 +503,7 @@ following brace lists and semicolons following defuns."
       ;; turned on
       (if (not c-auto-newline)
          (if c-syntactic-indentation
-             (c-indent-line))
+             (indent-according-to-mode))
        ;; clean ups
        (let ((pos (- (point-max) (point))))
          (if (and (or (and
@@ -509,7 +522,7 @@ following brace lists and semicolons following defuns."
          (goto-char (- (point-max) pos)))
        ;; re-indent line
        (if c-syntactic-indentation
-           (c-indent-line))
+           (indent-according-to-mode))
        ;; check to see if a newline should be added
        (let ((criteria c-hanging-semi&comma-criteria)
              answer add-newline-p)
@@ -524,7 +537,7 @@ following brace lists and semicolons following defuns."
              ))
          (if add-newline-p
              (progn (newline)
-                    (c-indent-line)))
+                    (indent-according-to-mode)))
          )))))
 
 (defun c-electric-colon (arg)
@@ -587,7 +600,8 @@ value of `c-cleanup-list'."
                                     c-hanging-colons-alist))))
       ;; indent the current line if it's done syntactically.
       (if c-syntactic-indentation
-         (c-indent-line syntax))
+         (let ((c-syntactic-context syntax))
+           (indent-according-to-mode)))
       ;; does a newline go before the colon?  Watch out for already
       ;; non-hung colons.  However, we don't unhang them because that
       ;; would be a cleanup (and anti-social).
@@ -599,14 +613,14 @@ value of `c-cleanup-list'."
          (let ((pos (- (point-max) (point))))
            (forward-char -1)
            (newline)
-           (c-indent-line)
+           (indent-according-to-mode)
            (goto-char (- (point-max) pos))))
       ;; does a newline go after the colon?
       (if (and (memq 'after (cdr-safe newlines))
               (not is-scope-op))
          (progn
            (newline)
-           (c-indent-line)))
+           (indent-according-to-mode)))
       )))
 
 (defun c-electric-lt-gt (arg)
@@ -625,14 +639,13 @@ will not be re-indented."
        (c-echo-syntactic-information-p nil))
     (self-insert-command (prefix-numeric-value arg))
     (if indentp
-       (c-indent-line))))
+       (indent-according-to-mode))))
 
 (defun c-electric-paren (arg)
   "Insert a parenthesis.
 
-If the auto-newline feature is turned on, as evidenced by the \"/a\"
-or \"/ah\" string on the mode line, some newline cleanups are done if
-appropriate; see the variable `c-cleanup-list'.
+Some newline cleanups are done if appropriate; see the variable
+`c-cleanup-list'.
 
 Also, the line is re-indented unless a numeric ARG is supplied, there
 are non-whitespace characters present on the line after the
@@ -642,7 +655,6 @@ parenthesis, the parenthesis is inserted inside a literal, or
   (let (;; shut this up
        (c-echo-syntactic-information-p nil))
     (if (or arg
-           (not (looking-at "[ \t]*$"))
            (c-in-literal (c-point 'bod)))
        (self-insert-command (prefix-numeric-value arg))
       ;; do some special stuff with the character
@@ -652,43 +664,86 @@ parenthesis, the parenthesis is inserted inside a literal, or
             (old-blink-paren blink-paren-function)
             blink-paren-function)
        (self-insert-command (prefix-numeric-value arg))
-       (if c-syntactic-indentation
-           (c-indent-line))
-       (when c-auto-newline
-         ;; Do all appropriate clean ups
-         (let ((here (point))
-               (pos (- (point-max) (point)))
-               mbeg mend)
-           ;; clean up brace-elseif-brace
-           (if (and (memq 'brace-elseif-brace c-cleanup-list)
-                    (eq last-command-char ?\()
-                    (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*("
-                                        nil t)
-                    (save-excursion
-                      (setq mbeg (match-beginning 0)
-                            mend (match-end 0))
-                      (= mend here))
-                    (not (c-in-literal)))
-               (progn
-                 (delete-region mbeg mend)
-                 (insert "} else if (")))
-           ;; clean up brace-catch-brace
-           (if (and (memq 'brace-catch-brace c-cleanup-list)
-                    (eq last-command-char ?\()
-                    (re-search-backward "}[ \t\n]*catch[ \t\n]*(" nil t)
-                    (save-excursion
-                      (setq mbeg (match-beginning 0)
-                            mend (match-end 0))
-                      (= mend here))
-                    (not (c-in-literal)))
-               (progn
-                 (delete-region mbeg mend)
-                 (insert "} catch (")))
-           (goto-char (- (point-max) pos))
-           ))
+       (when (looking-at "[ \t]*$")
+         (if c-syntactic-indentation
+             (indent-according-to-mode))
+         (when c-auto-newline
+           ;; Do all appropriate clean ups
+           (let ((here (point))
+                 (pos (- (point-max) (point)))
+                 mbeg mend)
+             ;; clean up brace-elseif-brace
+             (if (and (memq 'brace-elseif-brace c-cleanup-list)
+                      (eq last-command-char ?\()
+                      (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*("
+                                          nil t)
+                      (save-excursion
+                        (setq mbeg (match-beginning 0)
+                              mend (match-end 0))
+                        (= mend here))
+                      (not (c-in-literal)))
+                 (progn
+                   (delete-region mbeg mend)
+                   (insert "} else if (")))
+             ;; clean up brace-catch-brace
+             (if (and (memq 'brace-catch-brace c-cleanup-list)
+                      (eq last-command-char ?\()
+                      (re-search-backward "}[ \t\n]*catch[ \t\n]*(" nil t)
+                      (save-excursion
+                        (setq mbeg (match-beginning 0)
+                              mend (match-end 0))
+                        (= mend here))
+                      (not (c-in-literal)))
+                 (progn
+                   (delete-region mbeg mend)
+                   (insert "} catch (")))
+             (goto-char (- (point-max) pos))
+             )))
+       (let (beg (end (1- (point))))
+         (cond ((and (memq 'space-before-funcall c-cleanup-list)
+                     (eq last-command-char ?\()
+                     (save-excursion
+                       (backward-char)
+                       (skip-chars-backward " \t")
+                       (setq beg (point))
+                       (c-on-identifier)))
+                (save-excursion
+                  (delete-region beg end)
+                  (goto-char beg)
+                  (insert " ")))
+               ((and (memq 'compact-empty-funcall c-cleanup-list)
+                     (eq last-command-char ?\))
+                     (save-excursion
+                       (c-safe (backward-char 2))
+                       (when (looking-at "()")
+                         (setq end (point))
+                         (skip-chars-backward " \t")
+                         (setq beg (point))
+                         (c-on-identifier))))
+                (delete-region beg end))))
        (if old-blink-paren
            (funcall old-blink-paren))))))
 
+(defun c-electric-continued-statement ()
+  "Reindent the current line if appropriate.
+
+This function is used to reindent the line after a keyword which
+continues an earlier statement is typed, e.g. an \"else\" or the
+\"while\" in a do-while block.
+
+The line is reindented if there is nothing but whitespace before the
+keyword on the line, the keyword is not inserted inside a literal, and
+`c-syntactic-indentation' is non-nil."
+  (let (;; shut this up
+       (c-echo-syntactic-information-p nil))
+    (when (and c-syntactic-indentation
+              (not (eq last-command-char ?_))
+              (= (save-excursion
+                   (skip-syntax-backward "w")
+                   (point))
+                 (c-point 'boi))
+              (not (c-in-literal (c-point 'bod))))
+      (indent-according-to-mode))))
 
 \f
 ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
@@ -792,14 +847,13 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
 With prefix arg, go back N - 1 statements.  If already at the
 beginning of a statement then go to the beginning of the closest
 preceding one, moving into nested blocks if necessary (use
-\\[backward-sexp] to skip over a block).  If within a comment, or next
-to a comment (only whitespace between), move by sentences instead of
-statements.
+\\[backward-sexp] to skip over a block).  If within or next to a
+comment or multiline string, move by sentences instead of statements.
 
 When called from a program, this function takes 3 optional args: the
 repetition count, a buffer position limit which is the farthest back
-to search, and a flag saying whether to do sentence motion when in a
-comment."
+to search for the syntactic context, and a flag saying whether to do
+sentence motion in or near comments and multiline strings."
   (interactive (list (prefix-numeric-value current-prefix-arg)
                     nil t))
   (let* ((count (or count 1))
@@ -812,48 +866,85 @@ comment."
          (save-excursion
            ;; Find the comment next to point if we're not in one.
            (if (> count 0)
-               (setq range (if (c-forward-comment -1)
-                               (cons (point)
-                                     (progn (c-forward-comment 1) (point)))))
-             (skip-chars-forward " \t\n")
-             (setq range (point))
-             (setq range (if (c-forward-comment 1)
-                             (cons range (point))
-                           nil)))
+               (if (c-forward-comment -1)
+                   (setq range (cons (point)
+                                     (progn (c-forward-comment 1) (point))))
+                 (skip-chars-backward " \t\n\r\f")
+                 (setq range (point))
+                 (setq range
+                       (if (eq (char-before) ?\")
+                           (c-safe (c-backward-sexp 1)
+                                   (cons (point) range)))))
+             ;; skip-syntax-* doesn't count \n as whitespace..
+             (skip-chars-forward " \t\n\r\f")
+             (if (eq (char-after) ?\")
+                 (setq range (cons (point)
+                                   (progn
+                                     (c-forward-sexp 1)
+                                     (point))))
+               (setq range (point))
+               (setq range (if (c-forward-comment 1)
+                               (cons range (point))
+                             nil))))
            (setq range (c-collect-line-comments range))))
       (if (and (< count 0) (= here (point-max)))
          ;; Special case because eob might be in a literal.
          (setq range nil))
       (if range
          (if (and sentence-flag
-                  (/= (char-syntax (char-after (car range))) ?\"))
+                  (or (/= (char-syntax (char-after (car range))) ?\")
+                      ;; Only visit a string if it spans more than one line.
+                      (save-excursion
+                        (goto-char (car range))
+                        (skip-chars-forward "^\n" (cdr range))
+                        (< (point) (cdr range)))))
              (let* ((lit-type (c-literal-type range))
-                    (beg (save-excursion
-                           (goto-char (car range))
-                           (looking-at (if (eq lit-type 'c)
-                                           comment-start-skip
-                                         (concat "\\("
-                                                 c-comment-prefix-regexp
-                                                 "\\)[ \t]*")))
-                           (goto-char (match-end 0))
-                           (point)))
-                    (end (save-excursion
-                           (goto-char (- (cdr range)
-                                         (if (eq lit-type 'c) 2 1)))
-                           (point))))
-               ;; move by sentence, but not past the limit of the literal
+                    (line-prefix (concat "[ \t]*\\("
+                                         c-current-comment-prefix
+                                         "\\)[ \t]*"))
+                    (beg (if (eq lit-type 'string)
+                             (1+ (car range))
+                           (save-excursion
+                             (goto-char (car range))
+                             (max (progn
+                                    (looking-at comment-start-skip)
+                                    (match-end 0))
+                                  (progn
+                                    (looking-at line-prefix)
+                                    (match-end 0))))))
+                    (end (- (cdr range) (if (eq lit-type 'c) 2 1)))
+                    (beg-of-para (if (eq lit-type 'string)
+                                     (lambda ())
+                                   (lambda ()
+                                     (beginning-of-line)
+                                     (if (looking-at line-prefix)
+                                         (goto-char (match-end 0)))))))
                (save-restriction
-                 (narrow-to-region beg end)
+                 ;; Move by sentence, but not past the limit of the
+                 ;; literal, narrowed to the appropriate
+                 ;; paragraph(s).
+                 (narrow-to-region (save-excursion
+                                     (let ((pos (min here end)))
+                                       (goto-char pos)
+                                       (forward-paragraph -1)
+                                       (if (looking-at paragraph-separate)
+                                           (forward-line))
+                                       (when (> (point) beg)
+                                         (funcall beg-of-para)
+                                         (when (>= (point) pos)
+                                           (forward-paragraph -2)
+                                           (funcall beg-of-para)))
+                                       (max (point) beg)))
+                                   end)
                  (c-safe (forward-sentence (if (< count 0) 1 -1)))
                  (if (and (memq lit-type '(c c++))
                           ;; Check if we stopped due to a comment
                           ;; prefix and not a sentence end.
-                          (/= (point) beg)
+                          (/= (point) (point-min))
+                          (/= (point) (point-max))
                           (save-excursion
                             (beginning-of-line)
-                            (looking-at (concat "[ \t]*\\("
-                                                c-comment-prefix-regexp
-                                                "\\)[ \t]*")))
+                            (looking-at line-prefix))
                           (>= (point) (match-beginning 0))
                           (/= (match-beginning 1) (match-end 1))
                           (or (< (point) (match-end 0))
@@ -883,16 +974,22 @@ comment."
                          ;; comment ender, stop before it.  Stop after
                          ;; the ender if there's either nothing or
                          ;; newlines between.
-                         (when (and (eq lit-type 'c) (eq (point) end))
+                         (when (and (eq lit-type 'c)
+                                    (eq (point) (point-max)))
                            (widen)
-                           (skip-chars-backward " \t")
-                           (when (or (eq (point) end) (bolp))
+                           (when (or (= (skip-chars-backward " \t") 0)
+                                     (eq (point) (point-max))
+                                     (bolp))
                              (goto-char (cdr range)))))
-                     (when (and (eq (point) beg) (looking-at "[ \t]*$"))
+                     (when (and (eq (point) (point-min))
+                                (looking-at "[ \t]*$"))
                        ;; Stop before instead of after the comment
                        ;; starter if nothing follows it.
                        (widen)
-                       (goto-char (car range))))))
+                       (goto-char (car range))
+                       (if (and (eq lit-type 'string) (/= (point) here))
+                           (setq count (1+ count)
+                                 range nil))))))
                ;; See if we should escape the literal.
                (if (> count 0)
                    (if (< (point) here)
@@ -915,15 +1012,19 @@ comment."
                ;; Stop before `{' and after `;', `{', `}' and `};'
                ;; when not followed by `}' or `)', but on the other
                ;; side of the syntactic ws.  Move by sexps and move
-               ;; into parens.  Also stop before `#' when it's first
+               ;; into parens.  Also stop before `#' when it's at boi
                ;; on a line.
-               (let ((comment-pos (not sentence-flag))
+               (let ((literal-pos (not sentence-flag))
                      (large-enough (- (point-max)))
                      last last-below-line)
                  (catch 'done
                    (while t
                      (setq last (point))
-                     (when (and (looking-at "{\\|^#") (/= here last))
+                     (when (and (or (eq (char-after) ?\{)
+                                    (and (eq (char-after) ?#)
+                                         (eq (point) (c-point 'boi)))
+                                    )
+                                (/= here last))
                        (unless (and c-special-brace-lists
                                     (eq (char-after) ?{)
                                     (c-looking-at-special-brace-list))
@@ -932,13 +1033,13 @@ comment."
                                   (not (eq last-below-line here)))
                              (goto-char last-below-line))
                          (throw 'done t)))
-                     (if comment-pos
+                     (if literal-pos
                          (c-forward-comment large-enough)
                        (when (c-forward-comment -1)
                          ;; Record position of first comment.
                          (save-excursion
                            (c-forward-comment 1)
-                           (setq comment-pos (point)))
+                           (setq literal-pos (point)))
                          (c-forward-comment large-enough)))
                      (unless last-below-line
                        (if (save-excursion
@@ -963,40 +1064,48 @@ comment."
                                 (goto-char last)
                                 (throw 'done t))))
                            ((= (char-syntax (char-after)) ?\")
-                            (forward-char)
-                            (c-backward-sexp))
+                            (let ((end (point)))
+                              (forward-char)
+                              (c-backward-sexp)
+                              (save-excursion
+                                (skip-chars-forward "^\n" end)
+                                (when (< (point) end)
+                                  ;; Break at multiline string.
+                                  (setq literal-pos (1+ end))
+                                  (throw 'done t)))))
                            (t (skip-syntax-backward "w_")) ; Speedup only.
                            )))
-                 (if (and (numberp comment-pos)
-                          (< (point) comment-pos))
-                     ;; We jumped over a comment that should be investigated.
-                     (goto-char comment-pos)
+                 (if (and (numberp literal-pos)
+                          (< (point) literal-pos))
+                     ;; We jumped over a comment or string that
+                     ;; should be investigated.
+                     (goto-char literal-pos)
                    (setq count (1- count))))
              (error
               (goto-char (point-min))
               (setq count 0)))
          (condition-case nil
-             ;; Stop before `{', `}', and `#' when it's first on a
+             ;; Stop before `{', `}', and `#' when it's at boi on a
              ;; line, but on the other side of the syntactic ws, and
              ;; after `;', `}' and `};'.  Only stop before `{' if at
              ;; top level or inside braces, though.  Move by sexps
              ;; and move into parens.  Also stop at eol of lines
-             ;; starting with `#'.
-             (let ((comment-pos (not sentence-flag))
+             ;; with `#' at the boi.
+             (let ((literal-pos (not sentence-flag))
                    (large-enough (point-max))
                    last)
                (catch 'done
                  (while t
                    (setq last (point))
-                   (if comment-pos
+                   (if literal-pos
                        (c-forward-comment large-enough)
                      (if (progn
                            (skip-chars-forward " \t\n\r\f")
                            ;; Record position of first comment.
-                           (setq comment-pos (point))
+                           (setq literal-pos (point))
                            (c-forward-comment 1))
                          (c-forward-comment large-enough)
-                       (setq comment-pos nil)))
+                       (setq literal-pos nil)))
                    (cond ((and (eq (char-after) ?{)
                                (not (and c-special-brace-lists
                                          (c-looking-at-special-brace-list)))
@@ -1017,7 +1126,8 @@ comment."
                                (/= here last))
                           (goto-char last)
                           (throw 'done t))
-                         ((looking-at "^#")
+                         ((and (eq (char-after) ?#)
+                               (= (point) (c-point 'boi)))
                           (if (= here last)
                               (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)
                                   (goto-char (point-max)))
@@ -1027,15 +1137,22 @@ comment."
                           (goto-char (match-end 0))
                           (throw 'done t))
                          ((= (char-syntax (char-after)) ?\")
-                          (c-forward-sexp))
+                          (let ((beg (point)))
+                            (c-forward-sexp)
+                            (save-excursion
+                              (skip-chars-backward "^\n" beg)
+                              (when (> (point) beg)
+                                ;; Break at multiline string.
+                                (setq literal-pos beg)
+                                (throw 'done t)))))
                          (t
                           (forward-char 1)
                           (skip-syntax-forward "w_")) ; Speedup only.
                          )))
-               (if (and (numberp comment-pos)
-                        (> (point) comment-pos))
+               (if (and (numberp literal-pos)
+                        (> (point) literal-pos))
                    ;; We jumped over a comment that should be investigated.
-                   (goto-char comment-pos)
+                   (goto-char literal-pos)
                  (setq count (1+ count))))
            (error
             (goto-char (point-max))
@@ -1044,23 +1161,20 @@ comment."
       ;; If we haven't moved we're near a buffer limit.
       (when (and (not (zerop count)) (= (point) here))
        (goto-char (if (> count 0) (point-min) (point-max)))
-       (setq count 0)))
-    ;; its possible we've been left up-buf of lim
-    (if lim (goto-char (max (point) lim))))
+       (setq count 0))))
   (c-keep-region-active))
 
 (defun c-end-of-statement (&optional count lim sentence-flag)
   "Go to the end of the innermost C statement.
 With prefix arg, go forward N - 1 statements.  Move forward to the end
 of the next statement if already at end, and move into nested blocks
-\(use \\[forward-sexp] to skip over a block).  If within a comment, or
-next to a comment (only whitespace between), move by sentences instead
-of statements.
+\(use \\[forward-sexp] to skip over a block).  If within or next to a
+comment or multiline string, move by sentences instead of statements.
 
 When called from a program, this function takes 3 optional args: the
 repetition count, a buffer position limit which is the farthest back
-to search, and a flag saying whether to do sentence motion when in a
-comment."
+to search for the syntactic context, and a flag saying whether to do
+sentence motion in or near comments and multiline strings."
   (interactive (list (prefix-numeric-value current-prefix-arg)
                     nil t))
   (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
@@ -1107,8 +1221,8 @@ comment."
          (search-forward "}")
          (1+ (current-column)))
         ;; CASE 2: 2 spaces after #endif
-        ((or (looking-at "^#[ \t]*endif[ \t]*")
-             (looking-at "^#[ \t]*else[ \t]*"))
+        ((or (looking-at "[ \t]*#[ \t]*endif[ \t]*")
+             (looking-at "[ \t]*#[ \t]*else[ \t]*"))
          7)
         ;; CASE 3: when c-indent-comments-syntactically-p is t,
         ;; calculate the offset according to c-offsets-alist.
@@ -1127,8 +1241,7 @@ comment."
            ;; to ignore any anchoring as specified by
            ;; c-comment-only-line-offset since it doesn't apply here.
            (if (save-excursion
-                 (beginning-of-line)
-                 (skip-chars-forward " \t")
+                 (back-to-indentation)
                  (eolp))
                (c-add-syntax 'comment-intro))
            (let ((c-comment-only-line-offset
@@ -1136,7 +1249,7 @@ comment."
                       c-comment-only-line-offset
                     (cons c-comment-only-line-offset
                           c-comment-only-line-offset))))
-             (apply '+ (mapcar 'c-get-offset syntax)))))
+             (c-get-syntactic-indentation syntax))))
         ;; CASE 4: If previous line is a comment-only line, use its
         ;; indentation if it's greater than comment-column.  Leave at
         ;; least one space between the comment and the last nonblank
@@ -1346,7 +1459,7 @@ relative indentation among the lines of the expression is preserved.
   (let ((bod (c-point 'bod))
        (indent-function
         (if c-syntactic-indentation
-            (symbol-function 'c-indent-line)
+            (symbol-function 'indent-according-to-mode)
           (lambda ()
             (let ((steps (cond ((not current-prefix-arg) 1)
                                ((equal current-prefix-arg '(4)) -1)
@@ -1357,8 +1470,15 @@ relative indentation among the lines of the expression is preserved.
        ;; If c-syntactic-indentation and got arg, always indent this
        ;; line as C and shift remaining lines of expression the same
        ;; amount.
-       (let ((shift-amt (c-indent-line))
+       (let ((shift-amt (save-excursion
+                          (back-to-indentation)
+                          (current-column)))
              beg end)
+         (c-indent-line)
+         (setq shift-amt (- (save-excursion
+                              (back-to-indentation)
+                              (current-column))
+                            shift-amt))
          (save-excursion
            (if (eq c-tab-always-indent t)
                (beginning-of-line))
@@ -1369,7 +1489,7 @@ relative indentation among the lines of the expression is preserved.
            (forward-line 1)
            (setq beg (point)))
          (if (> end beg)
-             (indent-code-rigidly beg end (- shift-amt) "#")))
+             (indent-code-rigidly beg end shift-amt "#")))
       ;; Else use c-tab-always-indent to determine behavior.
       (cond
        ;; CASE 1: indent when at column zero or in lines indentation,
@@ -1392,57 +1512,39 @@ relative indentation among the lines of the expression is preserved.
        )))))
 
 (defun c-indent-exp (&optional shutup-p)
-  "Indent each line in balanced expression following point syntactically.
-Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
+  "Indent each line in the balanced expression following point syntactically.
+If optional SHUTUP-P is non-nil, no errors are signalled if no
+balanced expression is found."
   (interactive "*P")
   (let ((here (point-marker))
-       end progress-p)
+       end)
     (set-marker-insertion-type here t)
     (unwind-protect
-       (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
-             (start (progn
+       (let ((start (progn
                       ;; try to be smarter about finding the range of
                       ;; lines to indent. skip all following
-                      ;; whitespace. failing that, try to find any
-                      ;; opening brace on the current line
+                      ;; whitespace, then try to find any
+                      ;; opening paren on the current line
                       (skip-chars-forward " \t\n")
-                      (if (memq (char-after) '(?\( ?\[ ?\{))
-                          (point)
-                        (let ((state (parse-partial-sexp (point)
-                                                         (c-point 'eol))))
-                          (and (nth 1 state)
-                               (goto-char (nth 1 state))
-                               (memq (char-after) '(?\( ?\[ ?\{))
-                               (point)))))))
+                      (save-restriction
+                        (narrow-to-region (point-min) (c-point 'eol))
+                        (c-safe (1- (scan-lists (point) 1 -1)))))))
          ;; find balanced expression end
          (setq end (and (c-safe (progn (c-forward-sexp 1) t))
-                        (point-marker)))
+                        (point)))
          ;; sanity check
-         (and (not start)
-              (not shutup-p)
-              (error "Cannot find start of balanced expression to indent."))
-         (and (not end)
-              (not shutup-p)
-              (error "Cannot find end of balanced expression to indent."))
-         (c-progress-init start end 'c-indent-exp)
-         (setq progress-p t)
-         (goto-char start)
-         (beginning-of-line)
-         (while (< (point) end)
-           (if (not (looking-at "[ \t]*$"))
-               (c-indent-line))
-           (c-progress-update)
-           (forward-line 1)))
-      ;; make sure marker is deleted
-      (and end
-          (set-marker end nil))
-      (and progress-p
-          (c-progress-fini 'c-indent-exp))
+         (if (not start)
+            (unless shutup-p
+              (error "Cannot find start of balanced expression to indent"))
+           (if (not end)
+               (unless shutup-p
+                 (error "Cannot find end of balanced expression to indent"))
+             (c-indent-region start end))))
       (goto-char here)
       (set-marker here nil))))
 
 (defun c-indent-defun ()
-  "Re-indents the current top-level function def, struct or class declaration
+  "Indent the current top-level function def, struct or class declaration
 syntactically."
   (interactive "*")
   (let ((here (point-marker))
@@ -1467,96 +1569,37 @@ syntactically."
       (goto-char here)
       (set-marker here nil))))
 
-(defun c-indent-region (start end)
-  ;; Indent every line whose first char is between START and END inclusive.
+(defun c-indent-region (start end &optional quiet)
+  "Indent every line whose first char is between START and END inclusive.
+Be silent about syntactic errors if the optional argument QUIET is non-nil."
   (save-excursion
     (goto-char start)
     ;; Advance to first nonblank line.
     (skip-chars-forward " \t\n")
     (beginning-of-line)
-    (let (endmark)
-      (unwind-protect
-         (let ((c-tab-always-indent t)
-               ;; shut up any echo msgs on indiv lines
-               (c-echo-syntactic-information-p nil)
-               fence)
-           (c-progress-init start end 'c-indent-region)
-           (setq endmark (copy-marker end))
-           (while (and (bolp)
-                       (not (eobp))
-                       (< (point) endmark))
-             ;; update progress
-             (c-progress-update)
-             ;; Indent one line as with TAB.
-             (let (nextline sexpend sexpbeg)
-               ;; skip blank lines
-               (skip-chars-forward " \t\n")
-               (beginning-of-line)
-               ;; indent the current line
-               (c-indent-line)
-               (setq fence (point))
-               (if (save-excursion
-                     (beginning-of-line)
-                     (looking-at "[ \t]*#"))
-                   (forward-line 1)
-                 (save-excursion
-                   ;; Find beginning of following line.
-                   (setq nextline (c-point 'bonl))
-                   ;; Find first beginning-of-sexp for sexp extending past
-                   ;; this line.
-                   (beginning-of-line)
-                   (while (< (point) nextline)
-                     (condition-case nil
-                         (progn
-                           (c-forward-sexp 1)
-                           (setq sexpend (point)))
-                       (error (setq sexpend nil)
-                              (goto-char nextline)))
-                     (c-forward-syntactic-ws))
-                   (if sexpend
-                       (progn
-                         ;; make sure the sexp we found really starts on the
-                         ;; current line and extends past it
-                         (goto-char sexpend)
-                         (setq sexpend (point-marker))
-                         (c-safe (c-backward-sexp 1))
-                         (setq sexpbeg (point))))
-                   (if (and sexpbeg (< sexpbeg fence))
-                       (setq sexpbeg fence)))
-                 ;; Since we move by sexps we might have missed
-                 ;; comment-only lines.
-                 (if sexpbeg
-                     (save-excursion
-                       (while (progn
-                                (forward-line 1)
-                                (skip-chars-forward " \t")
-                                (< (point) sexpbeg))
-                         (if (looking-at c-comment-start-regexp)
-                             (setq sexpbeg (c-point 'bol))))))
-                 ;; If that sexp ends within the region, indent it all at
-                 ;; once, fast.
-                 (condition-case nil
-                     (if (and sexpend
-                              (> sexpend nextline)
-                              (<= sexpend endmark))
-                         (progn
-                           (goto-char sexpbeg)
-                           (c-indent-exp 'shutup)
-                           (c-progress-update)
-                           (goto-char sexpend)))
-                   (error
-                    (goto-char sexpbeg)
-                    (c-indent-line)))
-                 ;; Move to following line and try again.
-                 (and sexpend
-                      (markerp sexpend)
-                      (set-marker sexpend nil))
-                 (forward-line 1)
-                 (setq fence (point))))))
-       (set-marker endmark nil)
-       (c-progress-fini 'c-indent-region)
-       (c-echo-parsing-error)
-       ))))
+    (setq c-parsing-error
+         (or (let ((endmark (copy-marker end))
+                   (c-parsing-error nil)
+                   ;; shut up any echo msgs on indiv lines
+                   (c-echo-syntactic-information-p nil))
+               (unwind-protect
+                   (progn
+                     (c-progress-init start end 'c-indent-region)
+                     (while (and (bolp)
+                                 (not (eobp))
+                                 (< (point) endmark))
+                       ;; update progress
+                       (c-progress-update)
+                       ;; skip blank lines
+                       (skip-chars-forward " \t\n")
+                       (beginning-of-line)
+                       ;; indent the current line
+                       (c-indent-line nil t)
+                       (forward-line)))
+                 (set-marker endmark nil)
+                 (c-progress-fini 'c-indent-region))
+               (c-echo-parsing-error quiet))
+             c-parsing-error))))
 
 (defun c-mark-function ()
   "Put mark at end of current top-level defun, point at beginning."
@@ -1582,10 +1625,10 @@ syntactically."
                      (c-backward-syntactic-ws)
                      (skip-chars-backward ";")
                      (point))
-                   (cdar state)))
+                   (cdr (car state))))
            (progn
              (setq eod (point))
-             (goto-char (caar state))
+             (goto-char (car (car state)))
              (c-beginning-of-statement-1))
          (if (= ?{ (save-excursion
                      (c-end-of-statement-1)
@@ -1613,13 +1656,18 @@ syntactically."
     (push-mark here)
     (push-mark eod nil t)))
 
+(defun c-fn-region-is-active-p ()
+  ;; Function version of the macro for use in places that aren't
+  ;; compiled, e.g. in the menus.
+  (c-region-is-active-p))
+
 (defun c-indent-line-or-region ()
   "When the region is active, indent it.  Otherwise indent the current line."
   ;; Emacs has a variable called mark-active, XEmacs uses region-active-p
   (interactive)
   (if (c-region-is-active-p)
       (c-indent-region (region-beginning) (region-end))
-    (c-indent-command)))
+    (indent-according-to-mode)))
 
 \f
 ;; for progress reporting
@@ -1632,7 +1680,7 @@ syntactically."
    ;; Start the progress update messages.  If this Emacs doesn't have
    ;; a built-in timer, just be dumb about it.
    ((not (fboundp 'current-time))
-    (message "indenting region... (this may take a while)"))
+    (message "Indenting region... (this may take a while)"))
    ;; If progress has already been initialized, do nothing. otherwise
    ;; initialize the counter with a vector of:
    ;;     [start end lastsec context]
@@ -1643,7 +1691,7 @@ syntactically."
                                      (point-marker))
                                    (nth 1 (current-time))
                                    context))
-      (message "indenting region..."))
+      (message "Indenting region..."))
    ))
 
 (defun c-progress-update ()
@@ -1658,7 +1706,7 @@ syntactically."
       ;; what's the right value?
       (if (< c-progress-interval (- now lastsecs))
          (progn
-           (message "indenting region... (%d%% complete)"
+           (message "Indenting region... (%d%% complete)"
                     (/ (* 100 (- (point) start)) (- end start)))
            (aset c-progress-info 2 now)))
       )))
@@ -1672,7 +1720,7 @@ syntactically."
        (progn
          (set-marker (aref c-progress-info 1) nil)
          (setq c-progress-info nil)
-         (message "indenting region...done")))))
+         (message "Indenting region... done")))))
 
 
 \f
@@ -1748,6 +1796,10 @@ command to conveniently insert and align the necessary backslashes."
 \f
 ;;; Line breaking and paragraph filling.
 
+(defvar c-auto-fill-prefix t)
+(defvar c-lit-limits nil)
+(defvar c-lit-type nil)
+
 ;; The filling code is based on a simple theory; leave the intricacies
 ;; of the text handling to the currently active mode for that
 ;; (e.g. adaptive-fill-mode or filladapt-mode) and do as little as
@@ -1772,12 +1824,12 @@ command to conveniently insert and align the necessary backslashes."
   ;; function also uses the value of point in some heuristics.
   (let* ((here (point))
         (prefix-regexp (concat "[ \t]*\\("
-                               c-comment-prefix-regexp
+                               c-current-comment-prefix
                                "\\)[ \t]*"))
         (comment-start-regexp (if (eq lit-type 'c++)
                                   prefix-regexp
                                 comment-start-skip))
-        prefix-line comment-prefix res)
+        prefix-line comment-prefix res comment-text-end)
     (cond
      (fill-prefix
       (setq res (cons fill-prefix
@@ -1796,7 +1848,8 @@ command to conveniently insert and align the necessary backslashes."
      ((eq lit-type 'c++)
       (save-excursion
        ;; Set fallback for comment-prefix if none is found.
-       (setq comment-prefix "// ")
+       (setq comment-prefix "// "
+             comment-text-end (cdr lit-limits))
        (beginning-of-line)
        (if (> (point) (car lit-limits))
            ;; The current line is not the comment starter, so the
@@ -1847,6 +1900,7 @@ command to conveniently insert and align the necessary backslashes."
                  )))))
      (t
       (save-excursion
+       (setq comment-text-end (- (cdr lit-limits) 2))
        (beginning-of-line)
        (if (and (> (point) (car lit-limits))
                 (not (and (looking-at "[ \t]*\\*/")
@@ -1868,7 +1922,7 @@ command to conveniently insert and align the necessary backslashes."
              ;; The comment is either one line or the next line
              ;; contains just the comment ender.  Also, if point is
              ;; on the comment opener line and the following line is
-             ;; empty or doesn't match c-comment-prefix-regexp we
+             ;; empty or doesn't match c-current-comment-prefix we
              ;; assume that this is in fact a not yet closed one line
              ;; comment, so we shouldn't look for the comment prefix
              ;; on the next line.  In these cases we have no
@@ -1910,7 +1964,7 @@ command to conveniently insert and align the necessary backslashes."
                                ;; "" or ends with whitespace.
                                (insert "x\n" comment-prefix ?x)
                                (setq tmp-post (point-marker))
-                               (c-indent-line)
+                               (indent-according-to-mode)
                                (goto-char (1- tmp-post))
                                (cons (buffer-substring-no-properties
                                         (c-point 'bol) (point))
@@ -1931,37 +1985,56 @@ command to conveniently insert and align the necessary backslashes."
                 (test-line
                  (lambda ()
                    (when (and (looking-at prefix-regexp)
-                              (< (match-end 0) (1- (cdr lit-limits))))
+                              (<= (match-end 0) comment-text-end))
+                     (unless (eq (match-end 0) (c-point 'eol))
+                       ;; The match is fine if there's text after it.
+                       (throw 'found (cons (buffer-substring-no-properties
+                                            (match-beginning 0) (match-end 0))
+                                           (progn (goto-char (match-end 0))
+                                                  (current-column)))))
                      (unless fb-string
+                       ;; This match is better than nothing, so let's
+                       ;; remember it in case nothing better is found
+                       ;; on another line.
                        (setq fb-string (buffer-substring-no-properties
                                         (match-beginning 0) (match-end 0))
                              fb-endpos (match-end 0)))
-                     (unless (eq (match-end 0) (c-point 'eol))
-                       (throw 'found t))
                      t))))
-           (if (catch 'found
+           (or (catch 'found
                  ;; Search for a line which has text after the prefix
                  ;; so that we get the proper amount of whitespace
                  ;; after it.  We start with the current line, then
                  ;; search backwards, then forwards.
                  (goto-char prefix-line)
                  (when (and (funcall test-line)
-                            (/= (match-end 1) (match-end 0)))
+                            (or (/= (match-end 1) (match-end 0))
+                                ;; The whitespace is sucked up by the
+                                ;; first [ \t]* glob if the prefix is empty.
+                                (and (= (match-beginning 1) (match-end 1))
+                                     (/= (match-beginning 0) (match-end 0)))))
                    ;; If the current line doesn't have text but do
                    ;; have whitespace after the prefix, we'll use it.
-                   (throw 'found t))
-                 (while (and (zerop (forward-line -1))
-                             (> (point) (car lit-limits)))
-                   (funcall test-line))
+                   (throw 'found (cons fb-string
+                                       (progn (goto-char fb-endpos)
+                                              (current-column)))))
+                 (if (eq lit-type 'c++)
+                     ;; For line comments we can search up to and
+                     ;; including the first line.
+                     (while (and (zerop (forward-line -1))
+                                 (>= (point) (car lit-limits)))
+                       (funcall test-line))
+                   ;; For block comments we must stop before the
+                   ;; block starter.
+                   (while (and (zerop (forward-line -1))
+                               (> (point) (car lit-limits)))
+                     (funcall test-line)))
                  (goto-char prefix-line)
                  (while (and (zerop (forward-line 1))
                              (< (point) (cdr lit-limits)))
                    (funcall test-line))
+                 (goto-char prefix-line)
                  nil)
-               ;; A good line with text after the prefix was found.
-               (cons (buffer-substring-no-properties (point) (match-end 0))
-                     (progn (goto-char (match-end 0)) (current-column)))
-             (if fb-string
+               (when fb-string
                  ;; A good line wasn't found, but at least we have a
                  ;; fallback that matches the comment prefix regexp.
                  (cond ((string-match "\\s \\'" fb-string)
@@ -1997,13 +2070,14 @@ command to conveniently insert and align the necessary backslashes."
                                        (c-point 'bol)
                                        (point))
                                       (current-column)))
-                            (delete-region tmp (point)))))
+                            (delete-region tmp (point))
+                            (set-buffer-modified-p buffer-modified))))
                        (t
                         ;; Last resort: Just add a single space after
                         ;; the prefix.
                         (cons (concat fb-string " ")
                               (progn (goto-char fb-endpos)
-                                     (1+ (current-column))))))
+                                     (1+ (current-column)))))))
                ;; The line doesn't match the comment prefix regexp.
                (if comment-prefix
                    ;; We have a fallback for line comments that we must use.
@@ -2016,7 +2090,7 @@ command to conveniently insert and align the necessary backslashes."
                  ;; comment where the lines doesn't have any comment
                  ;; prefix at all and we should just fill it as
                  ;; normal text.
-                 '("" . 0)))))))
+                 '("" . 0))))))
     ))
 
 (defun c-fill-paragraph (&optional arg)
@@ -2043,193 +2117,240 @@ Optional prefix ARG means justify paragraph as well."
   (let (lit-limits lit-type fill
        ;; beg and end limits the region to be filled.  end is a marker.
        beg end
-       ;; tmp-pre and tmp-post marks strings that are temporarily
+       ;; tmp-pre and tmp-post mark strings that are temporarily
        ;; inserted at the start and end of the region.  tmp-pre is a
        ;; cons of the positions of the prepended string.  tmp-post is
        ;; a marker pointing to the single character of the appended
        ;; string.
        tmp-pre tmp-post
-       hang-ender-stuck)
+       ;; If hang-ender-stuck isn't nil, the comment ender is
+       ;; hanging.  In that case it's set to the number of spaces
+       ;; that should be between the text and the ender.
+       hang-ender-stuck
+       (here (point)))
     ;; Restore point on undo.  It's necessary since we do a lot of
     ;; hidden inserts and deletes below that should be as transparent
     ;; as possible.
     (if (and buffer-undo-list (not (eq buffer-undo-list t)))
        (setq buffer-undo-list (cons (point) buffer-undo-list)))
+    (save-restriction
+      ;; Widen to catch comment limits correctly.
+      (widen)
+      (setq lit-limits (c-collect-line-comments (c-literal-limits nil t))
+           lit-type (c-literal-type lit-limits)))
     (save-excursion
-      (save-restriction
-       ;; Widen to catch comment limits correctly.
-       (widen)
-       (setq lit-limits (c-collect-line-comments (c-literal-limits nil t))
-             lit-type (c-literal-type lit-limits)))
-      (forward-paragraph)
-      (setq end (point-marker))
-      (backward-paragraph)
+      (unless (c-safe (backward-char)
+                     (forward-paragraph)
+                     (>= (point) here))
+       (goto-char here)
+       (forward-paragraph))
+      (setq end (point-marker)))
+    (save-excursion
+      (unless (c-safe (forward-char)
+                     (backward-paragraph)
+                     (<= (point) here))
+       (goto-char here)
+       (backward-paragraph))
       (setq beg (point)))
-    (when (and (>= (point) beg) (<= (point) end))
-      (unwind-protect
-         (progn
-           (cond
-            ((eq lit-type 'c++)        ; Line comment.
-             (save-excursion
-               ;; Fill to the comment or paragraph end, whichever
-               ;; comes first.
-               (set-marker end (min end (cdr lit-limits)))
-               (when (<= beg (car lit-limits))
-                 ;; The region to be filled includes the comment
-                 ;; starter, so we must check it.
-                 (goto-char (car lit-limits))
-                 (back-to-indentation)
-                 (if (eq (point) (car lit-limits))
-                     ;; Include the first line in the fill.
-                     (setq beg (c-point 'bol))
-                   ;; The first line contains code before the
-                   ;; comment.  We must fake a line that doesn't.
-                   (setq tmp-pre t)))
-               ))
-            ((eq lit-type 'c)          ; Block comment.
-             (save-excursion
-               (when (>= end (cdr lit-limits))
-                 ;; The region to be filled includes the comment ender.
-                 (goto-char (cdr lit-limits))
-                 (beginning-of-line)
-                 (if (and (looking-at (concat "[ \t]*\\("
-                                              c-comment-prefix-regexp
-                                              "\\)\\*/"))
-                          (eq (cdr lit-limits) (match-end 0)))
-                     ;; Leave the comment ender on its own line.
-                     (set-marker end (point))
-                   ;; The comment ender should hang.  Replace all
-                   ;; cruft between it and the last word with a 'x'
-                   ;; and include it in the fill.  We'll change it
-                   ;; back to a space afterwards.
-                   (let ((ender-start (progn
-                                        (goto-char (cdr lit-limits))
-                                        (skip-syntax-backward "^w ")
-                                        (point)))
-                         spaces)
-                     (goto-char (cdr lit-limits))
-                     (setq tmp-post (point-marker))
-                     (insert ?\n)
-                     (set-marker end (point))
-                     (forward-line -1)
-                     (if (and (looking-at (concat "[ \t]*\\(\\("
-                                                  c-comment-prefix-regexp
-                                                  "\\)[ \t]*\\)"))
-                              (eq ender-start (match-end 0)))
-                         ;; The comment ender is prefixed by nothing
-                         ;; but a comment line prefix.  Remove it
-                         ;; along with surrounding ws.
-                         (setq spaces (- (match-end 1) (match-end 2)))
-                       (goto-char ender-start))
-                     (skip-chars-backward " \t\r\n")
-                     (when (/= (point) ender-start)
-                       ;; Keep one or two spaces between the text and
-                       ;; the ender, depending on how many there are now.
-                       (unless spaces (setq spaces (- ender-start (point))))
-                       (setq spaces (max (min spaces 2) 1))
-                       ; Insert the filler first to keep marks right.
-                       (insert (make-string spaces ?x))
-                       (delete-region (point) (+ ender-start spaces))
-                       (setq hang-ender-stuck spaces)))))
-               (when (<= beg (car lit-limits))
-                 ;; The region to be filled includes the comment starter.
-                 (goto-char (car lit-limits))
-                 (if (looking-at (concat "\\(" comment-start-skip "\\)$"))
-                     ;; Begin filling with the next line.
-                     (setq beg (c-point 'bonl))
-                   ;; Fake the fill prefix in the first line.
-                   (setq tmp-pre t)))
-               ))
-            ((eq lit-type 'string)     ; String.
-             (save-excursion
-               (when (>= end (cdr lit-limits))
-                 (goto-char (1- (cdr lit-limits)))
-                 (setq tmp-post (point-marker))
-                 (insert ?\n)
-                 (set-marker end (point)))
-               (when (<= beg (car lit-limits))
-                 (goto-char (1+ (car lit-limits)))
-                 (setq beg (if (looking-at "\\\\$")
-                               ;; Leave the start line if it's
-                               ;; nothing but an escaped newline.
-                               (1+ (match-end 0))
-                             (point))))))
-            (t (setq beg nil)))
-           (when tmp-pre
-             ;; Temporarily insert the fill prefix after the comment
-             ;; starter so that the first line looks like any other
-             ;; comment line in the narrowed region.
-             (setq fill (c-guess-fill-prefix lit-limits lit-type))
-             (unless (string-match (concat "\\`[ \t]*\\("
-                                           c-comment-prefix-regexp
-                                           "\\)[ \t]*\\'")
-                                   (car fill))
-               ;; Oops, the prefix doesn't match the comment prefix
-               ;; regexp.  This could produce very confusing
-               ;; results with adaptive fill packages together with
-               ;; the insert prefix magic below, since the prefix
-               ;; often doesn't appear at all.  So let's warn about
-               ;; it.
-               (message "\
-Warning: `c-comment-prefix-regexp' doesn't match the comment prefix %S"
-                        (car fill)))
-             ;; Find the right spot on the line, break it, insert
-             ;; the fill prefix and make sure we're back in the
-             ;; same column by temporarily prefixing the first word
-             ;; with a number of 'x'.
+    (unwind-protect
+       (progn
+         (cond
+          ((eq lit-type 'c++)          ; Line comment.
+           (save-excursion
+             ;; Fill to the comment or paragraph end, whichever
+             ;; comes first.
+             (set-marker end (min end (cdr lit-limits)))
+             (when (<= beg (car lit-limits))
+               ;; The region to be filled includes the comment
+               ;; starter, so we must check it.
+               (goto-char (car lit-limits))
+               (back-to-indentation)
+               (if (eq (point) (car lit-limits))
+                   ;; Include the first line in the fill.
+                   (setq beg (c-point 'bol))
+                 ;; The first line contains code before the
+                 ;; comment.  We must fake a line that doesn't.
+                 (setq tmp-pre t)))
+             ))
+          ((eq lit-type 'c)            ; Block comment.
+           (when (>= end (cdr lit-limits))
+             ;; The region to be filled includes the comment ender.
+             (unless (save-excursion
+                       (goto-char (cdr lit-limits))
+                       (beginning-of-line)
+                       (and (looking-at (concat "[ \t]*\\("
+                                                c-current-comment-prefix
+                                                "\\)\\*/"))
+                            (eq (cdr lit-limits) (match-end 0))
+                            ;; Leave the comment ender on its own line.
+                            (set-marker end (point))))
+               ;; The comment ender should hang.  Replace all cruft
+               ;; between it and the last word with one or two 'x'
+               ;; and include it in the fill.  We'll change them back
+               ;; spaces afterwards.
+               (let* ((ender-start (save-excursion
+                                     (goto-char (cdr lit-limits))
+                                     (skip-syntax-backward "^w ")
+                                     (point)))
+                      (point-rel (- ender-start here))
+                      spaces)
+                 (save-excursion
+                   (goto-char (cdr lit-limits))
+                   (setq tmp-post (point-marker))
+                   (insert ?\n)
+                   (set-marker end (point))
+                   (forward-line -1)
+                   (if (and (looking-at (concat "[ \t]*\\(\\("
+                                                c-current-comment-prefix
+                                                "\\)[ \t]*\\)"))
+                            (eq ender-start (match-end 0)))
+                       ;; The comment ender is prefixed by nothing
+                       ;; but a comment line prefix.  Remove it
+                       ;; along with surrounding ws.
+                       (setq spaces (- (match-end 1) (match-end 2)))
+                     (goto-char ender-start))
+                   (skip-chars-backward " \t\r\n")
+                   (if (/= (point) ender-start)
+                       (progn
+                         (if (<= here (point))
+                             ;; Don't adjust point below if it's
+                             ;; before the string we replace.
+                             (setq point-rel -1))
+                         ;; Keep one or two spaces between the text and
+                         ;; the ender, depending on how many there are now.
+                         (unless spaces (setq spaces (- ender-start (point))))
+                         (setq spaces (max (min spaces 2) 1))
+                         ;; Insert the filler first to keep marks right.
+                         (insert (make-string spaces ?x))
+                         (delete-region (point) (+ ender-start spaces))
+                         (setq hang-ender-stuck spaces)
+                         (setq point-rel
+                               (and (>= point-rel 0)
+                                    (- (point) (min point-rel spaces)))))
+                     (setq point-rel nil)))
+                 (if point-rel
+                     ;; Point was in the middle of the string we
+                     ;; replaced above, so put it back in the same
+                     ;; relative position, counting from the end.
+                     (goto-char point-rel))
+                 )))
+           (when (<= beg (car lit-limits))
+             ;; The region to be filled includes the comment starter.
              (save-excursion
                (goto-char (car lit-limits))
-               (if (looking-at (if (eq lit-type 'c++)
-                                   c-comment-prefix-regexp
-                                 comment-start-skip))
-                   (goto-char (match-end 0))
-                 (forward-char 2)
-                 (skip-chars-forward " \t"))
-               (while (< (current-column) (cdr fill)) (forward-char 1))
-               (let ((col (current-column)))
-                 (setq beg (1+ (point))
-                       tmp-pre (list (point)))
-                 (unwind-protect
-                     (progn
-                       (insert ?\n (car fill))
-                       (insert (make-string (- col (current-column)) ?x)))
-                   (setcdr tmp-pre (point))))))
-           (when beg
-             (let ((fill-paragraph-function
-                    ;; Avoid infinite recursion.
-                    (if (not (eq fill-paragraph-function 'c-fill-paragraph))
-                        fill-paragraph-function))
-                   (fill-prefix
-                    (or fill-prefix
-                        (when (and (eq lit-type 'c++)
-                                   (not (string-match
-                                         "\\`[ \t]*//"
-                                         (or (fill-context-prefix beg end)
-                                             ""))))
-                          ;; Kludge: If the function that adapts the
-                          ;; fill prefix doesn't produce the required
-                          ;; comment starter for line comments, then
-                          ;; force it by setting fill-prefix.
-                          (car (or fill (c-guess-fill-prefix
-                                         lit-limits lit-type)))))))
-               ;; Preparations finally done!  Now we can call the
-               ;; real fill function.
-               (save-restriction
-                 (narrow-to-region beg end)
-                 (fill-paragraph arg)))))
-       (when (consp tmp-pre)
-         (delete-region (car tmp-pre) (cdr tmp-pre)))
-       (when tmp-post
-         (save-excursion
-           (goto-char tmp-post)
-           (delete-char 1)
-           (when hang-ender-stuck
-             (skip-syntax-backward "^w ")
-             (forward-char (- hang-ender-stuck))
-             (insert (make-string hang-ender-stuck ?\ ))
-             (delete-char hang-ender-stuck))
-           (set-marker tmp-post nil)))))
-    (set-marker end nil))
+               (if (looking-at (concat "\\(" comment-start-skip "\\)$"))
+                   ;; Begin filling with the next line.
+                   (setq beg (c-point 'bonl))
+                 ;; Fake the fill prefix in the first line.
+                 (setq tmp-pre t)))))
+          ((eq lit-type 'string)       ; String.
+           (save-excursion
+             (when (>= end (cdr lit-limits))
+               (goto-char (1- (cdr lit-limits)))
+               (setq tmp-post (point-marker))
+               (insert ?\n)
+               (set-marker end (point)))
+             (when (<= beg (car lit-limits))
+               (goto-char (1+ (car lit-limits)))
+               (setq beg (if (looking-at "\\\\$")
+                             ;; Leave the start line if it's
+                             ;; nothing but an escaped newline.
+                             (1+ (match-end 0))
+                           (point))))))
+          (t (setq beg nil)))
+         (when tmp-pre
+           ;; Temporarily insert the fill prefix after the comment
+           ;; starter so that the first line looks like any other
+           ;; comment line in the narrowed region.
+           (setq fill (c-guess-fill-prefix lit-limits lit-type))
+           (unless (string-match (concat "\\`[ \t]*\\("
+                                         c-current-comment-prefix
+                                         "\\)[ \t]*\\'")
+                                 (car fill))
+             ;; Oops, the prefix doesn't match the comment prefix
+             ;; regexp.  This could produce very confusing
+             ;; results with adaptive fill packages together with
+             ;; the insert prefix magic below, since the prefix
+             ;; often doesn't appear at all.  So let's warn about
+             ;; it.
+             (message "\
+Warning: Regexp from `c-comment-prefix-regexp' doesn't match the comment prefix %S"
+                      (car fill)))
+           ;; Find the right spot on the line, break it, insert
+           ;; the fill prefix and make sure we're back in the
+           ;; same column by temporarily prefixing the first word
+           ;; with a number of 'x'.
+           (save-excursion
+             (goto-char (car lit-limits))
+             (if (looking-at (if (eq lit-type 'c++)
+                                 c-comment-prefix-regexp
+                               comment-start-skip))
+                 (goto-char (match-end 0))
+               (forward-char 2)
+               (skip-chars-forward " \t"))
+             (while (< (current-column) (cdr fill)) (forward-char 1))
+             (let ((col (current-column)))
+               (setq beg (1+ (point))
+                     tmp-pre (list (point)))
+               (unwind-protect
+                   (progn
+                     (insert ?\n (car fill))
+                     (insert (make-string (- col (current-column)) ?x)))
+                 (setcdr tmp-pre (point))))))
+         (when beg
+           (let ((fill-paragraph-function
+                  ;; Avoid infinite recursion.
+                  (if (not (eq fill-paragraph-function 'c-fill-paragraph))
+                      fill-paragraph-function))
+                 (fill-prefix
+                  (or fill-prefix
+                      ;; Kludge: If the function that adapts the fill prefix
+                      ;; doesn't produce the required comment starter for line
+                      ;; comments, then force it by setting fill-prefix.
+                      (when (and (eq lit-type 'c++)
+                                 ;; Kludge the kludge: filladapt-mode doesn't
+                                 ;; have this problem, but it doesn't override
+                                 ;; fill-context-prefix currently (version
+                                 ;; 2.12).
+                                 (not (and (boundp 'filladapt-mode)
+                                           filladapt-mode))
+                                 (not (string-match
+                                       "\\`[ \t]*//"
+                                       (or (fill-context-prefix beg end)
+                                           ""))))
+                        (car (or fill (c-guess-fill-prefix
+                                       lit-limits lit-type))))))
+                 (point-rel (cond ((< here beg) (- here beg))
+                                  ((> here end) (- here end)))))
+             ;; Preparations finally done!  Now we can call the
+             ;; real fill function.
+             (save-restriction
+               (narrow-to-region beg end)
+               (fill-paragraph arg))
+             (if point-rel
+                 ;; Restore point if it was outside the region.
+                 (if (< point-rel 0)
+                     (goto-char (+ beg point-rel))
+                   (goto-char (+ end point-rel))))
+             )))
+      (when (consp tmp-pre)
+       (delete-region (car tmp-pre) (cdr tmp-pre)))
+      (when tmp-post
+       (save-excursion
+         (goto-char tmp-post)
+         (delete-char 1))
+       (when hang-ender-stuck
+         ;; Preserve point even if it's in the middle of the string
+         ;; we replace; save-excursion doesn't work in that case.
+         (setq here (point))
+         (goto-char tmp-post)
+         (skip-syntax-backward "^w ")
+         (forward-char (- hang-ender-stuck))
+         (insert (make-string hang-ender-stuck ?\ ))
+         (delete-char hang-ender-stuck)
+         (goto-char here))
+       (set-marker tmp-post nil))
+      (set-marker end nil)))
   ;; Always return t.  This has the effect that if filling isn't done
   ;; above, it isn't done at all, and it's therefore effectively
   ;; disabled in normal code.
@@ -2267,9 +2388,9 @@ If a fill prefix is specified, it overrides all the above."
           (if soft (insert-and-inherit ?\n) (newline 1))))
        ;; Already know the literal type and limits when called from
        ;; c-context-line-break.
-       (c-lit-limits (if (boundp 'c-lit-limits) c-lit-limits))
-       (c-lit-type (if (boundp 'c-lit-type) c-lit-type)))
-    (when (boundp 'c-auto-fill-prefix)
+       (c-lit-limits c-lit-limits)
+       (c-lit-type c-lit-type))
+    (when (not (eq c-auto-fill-prefix t))
       ;; Called from do-auto-fill.
       (unless c-lit-limits
        (setq c-lit-limits (c-literal-limits nil nil t)))
@@ -2325,7 +2446,7 @@ If a fill prefix is specified, it overrides all the above."
                 (if (save-excursion
                       (back-to-indentation)
                       (> (point) (car c-lit-limits))
-                      (looking-at c-comment-prefix-regexp))
+                      (looking-at c-current-comment-prefix))
                     (progn
                       ;; Skip forward past the fill prefix in case
                       ;; we're standing in it.
@@ -2390,13 +2511,14 @@ If a fill prefix is specified, it overrides all the above."
 
 ;; advice for indent-new-comment-line for older Emacsen
 (unless (boundp 'comment-line-break-function)
+  (defvar c-inside-line-break-advice nil)
   (defadvice indent-new-comment-line (around c-line-break-advice
                                             activate preactivate)
     "Call `c-indent-new-comment-line' if in CC Mode."
-    (if (or (boundp 'c-inside-line-break-advice)
+    (if (or c-inside-line-break-advice
            (not c-buffer-is-cc-mode))
        ad-do-it
-      (let (c-inside-line-break-advice)
+      (let ((c-inside-line-break-advice t))
        (c-indent-new-comment-line (ad-get-arg 0))))))
 
 (defun c-context-line-break ()
@@ -2431,8 +2553,8 @@ C++-style line comment doesn't count as inside the comment, though."
                                      (= (forward-line -1) 0))))
                   (current-column))))
        (indent-to col))
-      (c-indent-line))))
+      (indent-according-to-mode))))
 
 \f
-(provide 'cc-cmds)
+(cc-provide 'cc-cmds)
 ;;; cc-cmds.el ends here
index 98ba4bea3f6de0a61d074eddeabc780766eb84c7..887cf4bfc118dcd97dca004c6336995e971d0540 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
@@ -23,8 +23,8 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
 ;;
 ;; (require 'cc-compat)
 ;; (c-set-style "BOCM")
+;;
+;; This file is completely unsupported!  Although it has been patched
+;; superficially to keep pace with the rest of CC Mode, it hasn't been
+;; tested for a long time.
 
 ;;; Code:
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-styles)
-(require 'cc-engine)
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
+(cc-require 'cc-styles)
+(cc-require 'cc-engine)
 
 \f
 ;; In case c-mode.el isn't loaded
@@ -154,5 +160,5 @@ This is in addition to c-continued-statement-offset.")
   (+ c-continued-statement-offset c-continued-brace-offset))
 
 \f
-(provide 'cc-compat)
+(cc-provide 'cc-compat)
 ;;; cc-compat.el ends here
index d7213d034694a9cc4d2ef5d5e8d1a13ef653ef65..b17cbdd5900c693719199d10ef680ee234d7d837 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-defs.el --- compile time definitions for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-;; Get all the necessary compile time definitions.
-(require 'custom)
-(require 'derived)                     ;only necessary in Emacs 20
+(eval-when-compile
+  (let ((load-path
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
+          load-path)))
+    (require 'cc-bytecomp)))
 
-;; cc-mode-19.el contains compatibility macros that should be compiled
-;; in if needed.
-(if (or (not (fboundp 'functionp))
-       (not (condition-case nil
-                (progn (char-before) t)
-              (error nil)))
-       (not (condition-case nil
-                (progn (char-after) t)
-              (error nil)))
-       (not (fboundp 'when))
-       (not (fboundp 'unless)))
-    (require 'cc-mode-19))
+;; cc-mode-19.el contains compatibility macros that should be used if
+;; needed.
+(eval-and-compile
+  (if (or (not (fboundp 'functionp))
+         (not (condition-case nil
+                  (progn (eval '(char-before)) t)
+                (error nil)))
+         (not (condition-case nil
+                  (progn (eval '(char-after)) t)
+                (error nil)))
+         (not (fboundp 'when))
+         (not (fboundp 'unless)))
+      (cc-load "cc-mode-19")))
+
+;; Silence the compiler.
+(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el
+(cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs
+(cc-bytecomp-defun region-active-p)    ; XEmacs
+(cc-bytecomp-defvar zmacs-region-stays)        ; XEmacs
+(cc-bytecomp-defvar zmacs-regions)     ; XEmacs
+(cc-bytecomp-defvar mark-active)       ; Emacs
+(cc-bytecomp-defun scan-lists)         ; 5 args in XEmacs, 3 in Emacs
+(require 'derived)                     ; Only necessary in Emacs
 
 \f
-(defmacro c-point (position)
-  ;; Returns the value of point at certain commonly referenced POSITIONs.
-  ;; POSITION can be one of the following symbols:
+;;; Macros.
+
+;;; Helpers for building regexps.
+(defmacro c-paren-re (re)
+  `(concat "\\(" ,re "\\)"))
+(defmacro c-identifier-re (re)
+  `(concat "\\<\\(" ,re "\\)\\>[^_]"))
+
+(defmacro c-point (position &optional point)
+  ;; Returns the value of certain commonly referenced POSITIONs
+  ;; relative to POINT.  The current point is used if POINT isn't
+  ;; specified.  POSITION can be one of the following symbols:
   ;; 
   ;; bol  -- beginning of line
   ;; eol  -- end of line
@@ -63,6 +87,7 @@
   ;; 
   ;; This function does not modify point or mark.
   `(save-excursion
+     ,(if point `(goto-char ,point))
      ,(if (and (eq (car-safe position) 'quote)
               (symbolp (eval position)))
          (let ((position (eval position)))
            (t (error "unknown buffer position requested: %s" position)))))
      (point)))
 
-\f
 (defmacro c-safe (&rest body)
   ;; safely execute BODY, return nil if an error occurred
   `(condition-case nil
        (progn ,@body)
      (error nil)))
 
+(defmacro c-forward-sexp (&optional arg)
+  ;; like forward-sexp except
+  ;;   1. this is much stripped down from the XEmacs version
+  ;;   2. this cannot be used as a command, so we're insulated from
+  ;;      XEmacs' losing efforts to make forward-sexp more user
+  ;;      friendly
+  ;;   3. Preserves the semantics most of CC Mode is based on
+  (or arg (setq arg 1))
+  `(goto-char (or (scan-sexps (point) ,arg)
+                 ,(if (numberp arg)
+                      (if (> arg 0) `(point-max) `(point-min))
+                    `(if (> ,arg 0) (point-max) (point-min))))))
+
+(defmacro c-backward-sexp (&optional arg)
+  ;; See c-forward-sexp and reverse directions
+  (or arg (setq arg 1))
+  `(c-forward-sexp ,(if (numberp arg) (- arg) `(- ,arg))))
+
+(defmacro c-add-syntax (symbol &optional relpos)
+  ;; a simple macro to append the syntax in symbol to the syntax list.
+  ;; try to increase performance by using this macro
+  `(setq syntax (cons (cons ,symbol ,relpos) syntax)))
+
+(defmacro c-add-class-syntax (symbol classkey)
+  ;; The inclass and class-close syntactic symbols are added in
+  ;; several places and some work is needed to fix everything.
+  ;; Therefore it's collected here.  This is a macro mostly because
+  ;; c-add-syntax doesn't work otherwise.
+  `(save-restriction
+     (widen)
+     (let ((symbol ,symbol)
+          (classkey ,classkey)
+          inexpr)
+       (goto-char (aref classkey 1))
+       (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
+          (c-add-syntax symbol (point))
+        (c-add-syntax symbol (aref classkey 0))
+        (if (and c-inexpr-class-key
+                 (setq inexpr (c-looking-at-inexpr-block))
+                 (/= (cdr inexpr) (c-point 'boi (cdr inexpr))))
+            (c-add-syntax 'inexpr-class))))))
+
+(defmacro c-update-modeline ()
+  ;; set the c-auto-hungry-string for the correct designation on the modeline
+  `(progn
+     (setq c-auto-hungry-string
+          (if c-auto-newline
+              (if c-hungry-delete-key "/ah" "/a")
+            (if c-hungry-delete-key "/h" nil)))
+     (force-mode-line-update)))
+
+(defmacro c-with-syntax-table (table &rest code)
+  ;; Temporarily switches to the specified syntax table in a failsafe
+  ;; way to execute code.
+  `(let ((c-with-syntax-table-orig-table (syntax-table)))
+     (unwind-protect
+        (progn
+          (set-syntax-table ,table)
+          ,@code)
+       (set-syntax-table c-with-syntax-table-orig-table))))
+(put 'c-with-syntax-table 'lisp-indent-function 1)
+
+;;; Inline functions.
+
+;; Note: All these after the macros, to be on safe side in avoiding
+;; bugs where macros are defined too late.  These bugs often only show
+;; when the files are compiled in a certain order within the same
+;; session.
+
 (defsubst c-beginning-of-defun-1 ()
   ;; Wrapper around beginning-of-defun.
   ;;
     (if (< (point) start)
        (goto-char (point-max)))))
 
-(defmacro c-forward-sexp (&optional arg)
-  ;; like forward-sexp except
-  ;;   1. this is much stripped down from the XEmacs version
-  ;;   2. this cannot be used as a command, so we're insulated from
-  ;;      XEmacs' losing efforts to make forward-sexp more user
-  ;;      friendly
-  ;;   3. Preserves the semantics most of CC Mode is based on
-  (or arg (setq arg 1))
-  `(goto-char (or (scan-sexps (point) ,arg)
-                 ,(if (numberp arg)
-                      (if (> arg 0) `(point-max) `(point-min))
-                    `(if (> ,arg 0) (point-max) (point-min))))))
-
-(defmacro c-backward-sexp (&optional arg)
-  ;; See c-forward-sexp and reverse directions
-  (or arg (setq arg 1))
-  `(c-forward-sexp ,(if (numberp arg) (- arg) `(- ,arg))))
-
-(defsubst c-beginning-of-macro (&optional lim)
-  ;; Go to the beginning of a cpp macro definition.  Leaves point at
-  ;; the beginning of the macro and returns t if in a cpp macro
-  ;; definition, otherwise returns nil and leaves point unchanged.
-  ;; `lim' is currently ignored, but the interface requires it.
-  (let ((here (point)))
-    (beginning-of-line)
-    (while (eq (char-before (1- (point))) ?\\)
-      (forward-line -1))
-    (back-to-indentation)
-    (if (and (<= (point) here)
-            (eq (char-after) ?#))
-       t
-      (goto-char here)
-      nil)))
-
 (defsubst c-forward-comment (count)
   ;; Insulation from various idiosyncrasies in implementations of
-  ;; `forward-comment'.  Note: Some emacsen considers incorrectly that
-  ;; any line comment ending with a backslash continues to the next
-  ;; line.  I can't think of any way to work around that in a reliable
-  ;; way without changing the buffer though.  Suggestions welcome. ;)
+  ;; `forward-comment'.
+  ;;
+  ;; Note: Some emacsen considers incorrectly that any line comment
+  ;; ending with a backslash continues to the next line.  I can't
+  ;; think of any way to work around that in a reliable way without
+  ;; changing the buffer though.  Suggestions welcome. ;)
+  ;;
+  ;; Another note: When moving backwards over a block comment, there's
+  ;; a bug in forward-comment that can make it stop at "/*" inside a
+  ;; line comment.  Haven't yet found a reasonably cheap way to kludge
+  ;; around that one either. :\
   (let ((here (point)))
     (if (>= count 0)
        (when (forward-comment count)
-         ;; Emacs includes the ending newline in a b-style
-         ;; (c++) comment, but XEmacs don't.  We depend on the
-         ;; Emacs behavior (which also is symmetric).
+         ;; Emacs includes the ending newline in a b-style (c++)
+         ;; comment, but XEmacs doesn't.  We depend on the Emacs
+         ;; behavior (which also is symmetric).
          (if (and (eolp) (nth 7 (parse-partial-sexp here (point))))
              (condition-case nil (forward-char 1)))
          t)
        (if (forward-comment count)
            (if (eolp) (forward-comment -1) t))))))
 
-(defmacro c-add-syntax (symbol &optional relpos)
-  ;; a simple macro to append the syntax in symbol to the syntax list.
-  ;; try to increase performance by using this macro
-  `(setq syntax (cons (cons ,symbol ,relpos) syntax)))
-
-(defmacro c-add-class-syntax (symbol classkey)
-  ;; The inclass and class-close syntactic symbols are added in
-  ;; several places and some work is needed to fix everything.
-  ;; Therefore it's collected here.
-  `(save-restriction
-     (widen)
-     (let ((symbol ,symbol)
-          (classkey ,classkey))
-       (goto-char (aref classkey 1))
-       (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
-          (c-add-syntax symbol (point))
-        (c-add-syntax symbol (aref classkey 0))
-        (if (and c-inexpr-class-key (c-looking-at-inexpr-block))
-            (c-add-syntax 'inexpr-class))))))
-
 (defsubst c-intersect-lists (list alist)
   ;; return the element of ALIST that matches the first element found
   ;; in LIST.  Uses assq.
          ))
     0))
 
-(defmacro c-update-modeline ()
-  ;; set the c-auto-hungry-string for the correct designation on the modeline
-  `(progn
-     (setq c-auto-hungry-string
-          (if c-auto-newline
-              (if c-hungry-delete-key "/ah" "/a")
-            (if c-hungry-delete-key "/h" nil)))
-     (force-mode-line-update)))
-
 (defsubst c-keep-region-active ()
   ;; Do whatever is necessary to keep the region active in XEmacs.
-  ;; Ignore byte-compiler warnings you might see.  This is not needed
-  ;; for Emacs.
+  ;; This is not needed for Emacs.
   (and (boundp 'zmacs-region-stays)
        (setq zmacs-region-stays t)))
 
 (defsubst c-major-mode-is (mode)
   (eq (derived-mode-class major-mode) mode))
 
-(defmacro c-with-syntax-table (table &rest code)
-  ;; Temporarily switches to the specified syntax table in a failsafe
-  ;; way to execute code.
-  `(let ((c-with-syntax-table-orig-table (syntax-table)))
-     (unwind-protect
-        (progn
-          (set-syntax-table ,table)
-          ,@code)
-       (set-syntax-table c-with-syntax-table-orig-table))))
-(put 'c-with-syntax-table 'lisp-indent-function 1)
-
 \f
-(provide 'cc-defs)
+(cc-provide 'cc-defs)
 ;;; cc-defs.el ends here
index a2ed75e15203e75306fad064b0707ad34972727e..50613a21ad445f7e04db41facfb833cc94579168 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-engine.el --- core syntax guessing engine for CC mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-langs)
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
+(cc-require 'cc-langs)
+
+;; Silence the compiler.
+(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
 
 \f
+(defvar c-state-cache nil)
+(defvar c-in-literal-cache t)
+
 ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
 ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1.  A
 ;; better way should be implemented, but this will at least shut up
     ;; We always want to skip over the non-whitespace modifier
     ;; characters that can start a statement.
     (let ((lim (point)))
-      (skip-chars-backward "-+!*&~@` \t\n" (c-point 'boi))
+      (skip-chars-backward "-+!*&~@`# \t\n" (c-point 'boi))
       (skip-chars-forward " \t\n" lim))))
 
 (defun c-end-of-statement-1 ()
     crossedp))
 
 \f
+(defun c-beginning-of-macro (&optional lim)
+  ;; Go to the beginning of a cpp macro definition.  Leaves point at
+  ;; the beginning of the macro and returns t if in a cpp macro
+  ;; definition, otherwise returns nil and leaves point unchanged.
+  ;; `lim' is currently ignored, but the interface requires it.
+  (let ((here (point)))
+    (beginning-of-line)
+    (while (eq (char-before (1- (point))) ?\\)
+      (forward-line -1))
+    (back-to-indentation)
+    (if (and (<= (point) here)
+            (eq (char-after) ?#))
+       t
+      (goto-char here)
+      nil)))
+
 ;; Skipping of "syntactic whitespace", defined as lexical whitespace,
 ;; C and C++ style comments, and preprocessor directives.  Search no
 ;; farther back or forward than optional LIM.  If LIM is omitted,
                         '(?w ?_ ?\" ?\\ ?/ ?')))
          (last (point))
          (prev (point)))
-      (if (/= (point)
-             (progn (c-forward-syntactic-ws) (point)))
-         ;; Skip whitespace.  Count this as a move if we did in fact
-         ;; move and aren't out of bounds.
-         (or (eobp)
-             (and lim (> (point) lim))
-             (setq count (max (1- count) 0))))
-      (if (and (= count 0)
-              (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
-                       (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
-                  (eobp)))
-         ;; If count is zero we should jump if in the middle of a
-         ;; token or if there is whitespace between point and the
-         ;; following token beginning.
-         (setq count 1))
-      ;; Avoid having the limit tests inside the loop.
       (save-restriction
        (if lim (narrow-to-region (point-min) lim))
+       (if (/= (point)
+               (progn (c-forward-syntactic-ws) (point)))
+           ;; Skip whitespace.  Count this as a move if we did in fact
+           ;; move and aren't out of bounds.
+           (or (eobp)
+               (setq count (max (1- count) 0))))
+       (if (and (= count 0)
+                (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
+                         (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
+                    (eobp)))
+           ;; If count is zero we should jump if in the middle of a
+           ;; token or if there is whitespace between point and the
+           ;; following token beginning.
+           (setq count 1))
        (if (eobp)
            (goto-char last)
+         ;; Avoid having the limit tests inside the loop.
          (condition-case nil
              (while (> count 0)
                (setq prev last
          ;; token or if there is whitespace between point and the
          ;; following token beginning.
          (setq count 1))
-      ;; Avoid having the limit tests inside the loop.
       (save-restriction
        (if lim (narrow-to-region lim (point-max)))
        (or (bobp)
            (progn
+             ;; Avoid having the limit tests inside the loop.
              (condition-case nil
                  (while (progn
                           (setq last (point))
 (defun c-in-literal (&optional lim)
   ;; Determine if point is in a C++ literal. we cache the last point
   ;; calculated if the cache is enabled
-  (if (and (boundp 'c-in-literal-cache)
-          c-in-literal-cache
+  (if (and (vectorp c-in-literal-cache)
           (= (point) (aref c-in-literal-cache 0)))
       (aref c-in-literal-cache 1)
     (let ((rtn (save-excursion
                    ((c-beginning-of-macro lim) 'pound)
                    (t nil))))))
       ;; cache this result if the cache is enabled
-      (and (boundp 'c-in-literal-cache)
-          (setq c-in-literal-cache (vector (point) rtn)))
+      (if (not c-in-literal-cache)
+         (setq c-in-literal-cache (vector (point) rtn)))
       rtn)))
 
 ;; XEmacs has a built-in function that should make this much quicker.
                                 (looking-at "//")))
            (let ((col (current-column))
                  (beg (point))
+                 (bopl (c-point 'bopl))
                  (end (cdr range)))
+             ;; Got to take care in the backward direction to handle
+             ;; comments which are preceded by code.
              (while (and (c-forward-comment -1)
+                         (>= (point) bopl)
                          (looking-at "//")
                          (= col (current-column)))
-               (setq beg (point)))
+               (setq beg (point)
+                     bopl (c-point 'bopl)))
              (goto-char end)
              (while (and (progn (skip-chars-forward " \t")
                                 (looking-at "//"))
   ;; earlier in the file and point.
   ;;
   ;; if there's a state cache, return it
-  (setq c-parsing-error nil)
-  (if (boundp 'c-state-cache) c-state-cache
+  (if c-state-cache c-state-cache
     (let* (at-bob
           (pos (save-excursion
                  ;; go back 2 bods, but ignore any bogus positions
           (here (save-excursion
                   ;;(skip-chars-forward " \t}")
                   (point)))
-          (last-bod pos) (last-pos pos)
+          (last-bod here) (last-pos pos)
           placeholder state sexp-end)
       ;; cache last bod position
       (while (catch 'backup-bod
                       (while t
                         (setq last-bod (c-safe (scan-lists last-bod -1 1)))
                         (if (not last-bod)
-                            (progn
+                            (save-excursion
                               ;; bogus, but what can we do here?
-                              (setq c-parsing-error (1- placeholder))
+                              (goto-char placeholder)
+                              (beginning-of-line)
+                              (setq c-parsing-error
+                                    (format "\
+Unbalanced close brace at line %d" (1+ (count-lines 1 (point)))))
                               (throw 'backup-bod nil))
                           (setq at-bob (= last-bod (point-min))
                                 pos last-bod)
@@ -910,13 +940,11 @@ brace."
 (defun c-backward-to-start-of-if (&optional lim)
   ;; Move to the start of the last "unbalanced" if and return t.  If
   ;; none is found, and we are looking at an if clause, nil is
-  ;; returned.  If none is found and we are looking at an else clause,
-  ;; an error is thrown.
+  ;; returned.
   (let ((if-level 1)
        (here (c-point 'bol))
        (case-fold-search nil)
-       (lim (or (and (>= (point) lim)
-                     lim)
+       (lim (or (and lim (>= (point) lim) lim)
                 (c-point 'bod)))
        (at-if (looking-at "if\\b[^_]")))
     (catch 'orphan-if
@@ -926,10 +954,13 @@ brace."
        (condition-case nil
            (c-backward-sexp 1)
          (error
-          (if at-if
-              (throw 'orphan-if nil)
-            (error "No matching `if' found for `else' on line %d."
-                   (1+ (count-lines 1 here))))))
+          (unless at-if
+            (goto-char here)
+            (c-beginning-of-statement-1)
+            (setq c-parsing-error
+                  (format "No matching `if' found for `else' on line %d"
+                          (1+ (count-lines 1 here))))
+            (throw 'orphan-if nil))))
        (cond
         ((looking-at "else\\b[^_]")
          (setq if-level (1+ if-level)))
@@ -937,7 +968,7 @@ brace."
          ;; check for else if... skip over
          (let ((here (point)))
            (c-safe (c-forward-sexp -1))
-           (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
+           (if (looking-at "\\<else\\>[ \t]+\\<if\\>[^_]")
                nil
              (setq if-level (1- if-level))
              (goto-char here))))
@@ -952,9 +983,11 @@ brace."
   ;; statements in parentheses. No error checking is performed.
   (c-forward-sexp (cond
                   ;; else if()
-                  ((looking-at "\\<else\\>[ \t]+\\<if\\>") 3)
+                  ((looking-at "\\<else\\>[ \t]+\\<if\\>\\([^_]\\|$\\)") 3)
                   ;; do, else, try, finally
-                  ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1)
+                  ((looking-at
+                    "\\<\\(do\\|else\\|try\\|finally\\)\\>\\([^_]\\|$\\)")
+                   1)
                   ;; for, if, while, switch, catch, synchronized, foreach
                   (t 2))))
 
@@ -991,25 +1024,31 @@ brace."
   (if (eq (char-after) ?,)
       (forward-char 1)
     (c-backward-syntactic-ws limit))
-  (while (and (< limit (point))
-             (eq (char-before) ?,))
-    ;; this will catch member inits with multiple
-    ;; line arglists
-    (forward-char -1)
-    (c-backward-syntactic-ws)
-    (if (eq (char-before) ?\))
-       (c-backward-sexp 2)
-      (c-backward-sexp 1))
-    ;; Skip backwards over a fully::qualified::name.
-    (c-backward-syntactic-ws limit)
-    (while (and (eq (char-before) ?:)
-               (save-excursion
-                 (forward-char -1)
-                 (eq (char-before) ?:)))
-      (backward-char 2)
-      (c-backward-sexp 1))
-    ;; now continue checking
-    (c-backward-syntactic-ws limit))
+  (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+                          c++-template-syntax-table
+                        (syntax-table))
+    (while (and (< limit (point))
+               (eq (char-before) ?,))
+      ;; this will catch member inits with multiple
+      ;; line arglists
+      (forward-char -1)
+      (c-backward-syntactic-ws)
+      (if (eq (char-before) ?\))
+         (c-backward-sexp 2)
+       (c-backward-sexp 1))
+      ;; Skip over any template arg to the class.
+      (if (eq (char-after) ?<)
+         (c-backward-sexp 1))
+      ;; Skip backwards over a fully::qualified::name.
+      (c-backward-syntactic-ws limit)
+      (while (and (eq (char-before) ?:)
+                 (save-excursion
+                   (forward-char -1)
+                   (eq (char-before) ?:)))
+       (backward-char 2)
+       (c-backward-sexp 1))
+      ;; now continue checking
+      (c-backward-syntactic-ws limit)))
   (and (< limit (point))
        (eq (char-before) ?:)))
 
@@ -1160,7 +1199,8 @@ brace."
   ;; return the buffer position of the beginning of the brace list
   ;; statement if we're inside a brace list, otherwise return nil.
   ;; CONTAINING-SEXP is the buffer pos of the innermost containing
-  ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
+  ;; paren.  BRACE-STATE is the remainder of the state of enclosing
+  ;; braces
   ;;
   ;; N.B.: This algorithm can potentially get confused by cpp macros
   ;; places in inconvenient locations.  Its a trade-off we make for
@@ -1213,7 +1253,7 @@ brace."
               (while (eq braceassignp 'dontknow)
                 (setq braceassignp
                       (cond ((/= (c-backward-token-1 1 t lim) 0) nil)
-                            ((looking-at "new\\>") t)
+                            ((looking-at "new\\>[^_]") t)
                             ((looking-at "\\sw\\|\\s_\\|[.[]")
                              ;; Carry on looking if this is an
                              ;; identifier (may contain "." in Java)
@@ -1238,22 +1278,29 @@ brace."
                              (cond
                               ;; Check for operator =
                               ((looking-at "operator\\>") nil)
-                              ;; Check for `<opchar>= (Pike)
-                              ((eq (char-after) ?`) nil)
+                              ;; Check for `<opchar>= in Pike.
+                              ((and (c-major-mode-is 'pike-mode)
+                                    (or (eq (char-after) ?`)
+                                        ;; Special case for Pikes
+                                        ;; `[]=, since '[' is not in
+                                        ;; the punctuation class.
+                                        (and (eq (char-after) ?\[)
+                                             (eq (char-before) ?`))))
+                               nil)
                               ((looking-at "\\s.") 'maybe)
                               ;; make sure we're not in a C++ template
                               ;; argument assignment
-                              ((save-excursion
-                                 (let ((here (point))
-                                       (pos< (progn
-                                               (skip-chars-backward "^<")
-                                               (point))))
-                                   (and (c-major-mode-is 'c++-mode)
-                                        (eq (char-before) ?<)
-                                        (not (c-crosses-statement-barrier-p
-                                              pos< here))
-                                        (not (c-in-literal))
-                                        )))
+                              ((and (c-major-mode-is 'c++-mode)
+                                    (save-excursion
+                                      (let ((here (point))
+                                            (pos< (progn
+                                                    (skip-chars-backward "^<>")
+                                                    (point))))
+                                        (and (eq (char-before) ?<)
+                                             (not (c-crosses-statement-barrier-p
+                                                   pos< here))
+                                             (not (c-in-literal))
+                                             ))))
                                nil)
                               (t t))))))
               (if (and (eq braceassignp 'dontknow)
@@ -1394,6 +1441,28 @@ brace."
             (if (>= (point) lim)
                 (c-looking-at-inexpr-block lim))))))))
 
+(defun c-on-identifier ()
+  ;; Returns non-nil if we're on or directly after an identifier.
+  (if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_))
+         (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
+      (save-excursion
+       (skip-syntax-backward "w_")
+       (not (looking-at c-keywords)))
+    (if (c-major-mode-is 'pike-mode)
+       ;; Handle the `<operator> syntax in Pike.
+       (save-excursion
+         (if (eq (char-after) ?\`) (forward-char))
+         (skip-chars-backward "!%&*+\\-/<=>^|~")
+         (let ((pos (point)))
+           (cond ((memq (char-before) '(?\) ?\]))
+                  (c-safe (backward-char 2)))
+                 ((memq (char-before) '(?\( ?\[))
+                  (c-safe (backward-char 1))))
+           (if (not (looking-at "()\\|\\[]"))
+               (goto-char pos)))
+         (and (eq (char-before) ?\`)
+              (looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
+
 \f
 (defun c-most-enclosing-brace (state)
   ;; return the bufpos of the most enclosing brace that hasn't been
@@ -1562,8 +1631,10 @@ brace."
                                'inline-open
                              'lambda-intro-cont)))
          (goto-char (cdr placeholder))
-         (c-add-syntax tmpsymbol (c-point 'boi))
-         (c-add-syntax (car placeholder)))
+         (back-to-indentation)
+         (c-add-syntax tmpsymbol (point))
+         (unless (eq (point) (cdr placeholder))
+           (c-add-syntax (car placeholder))))
         ;; CASE 5: Line is at top level.
         ((null containing-sexp)
          (cond
@@ -1602,12 +1673,7 @@ brace."
                ;; to go through much chicanery to ignore the cache.
                ;; But of course, there may not be!  BLECH!  BOGUS!
                (let ((decl
-                      (if (boundp 'c-state-cache)
-                          (let ((old-cache c-state-cache))
-                            (prog2
-                                (makunbound 'c-state-cache)
-                                (c-search-uplist-for-classkey (c-parse-state))
-                              (setq c-state-cache old-cache)))
+                      (let ((c-state-cache nil))
                         (c-search-uplist-for-classkey (c-parse-state))
                         )))
                  (and decl
@@ -1625,20 +1691,38 @@ brace."
                           (c-forward-syntactic-ws indent-point)))
                (setq placeholder (c-point 'boi))
                (or (consp special-brace-list)
-                   (and (or (looking-at "enum[ \t\n]+")
-                            (save-excursion
+                   (and (or (save-excursion
                               (goto-char indent-point)
+                              (setq tmpsymbol nil)
                               (while (and (> (point) placeholder)
                                           (= (c-backward-token-1 1 t) 0)
-                                          (/= (char-after) ?=)))
-                              (eq (char-after) ?=)))
+                                          (/= (char-after) ?=))
+                                (if (and (not tmpsymbol)
+                                         (looking-at "new\\>[^_]"))
+                                    (setq tmpsymbol 'topmost-intro-cont)))
+                              (eq (char-after) ?=))
+                            (looking-at "enum[ \t\n]+"))
                         (save-excursion
                           (while (and (< (point) indent-point)
                                       (= (c-forward-token-1 1 t) 0)
                                       (not (memq (char-after) '(?\; ?\()))))
                           (not (memq (char-after) '(?\; ?\()))
                           ))))
-             (c-add-syntax 'brace-list-open placeholder))
+             (if (and (c-major-mode-is 'java-mode)
+                      (eq tmpsymbol 'topmost-intro-cont))
+                 ;; We're in Java and have found that the open brace
+                 ;; belongs to a "new Foo[]" initialization list,
+                 ;; which means the brace list is part of an
+                 ;; expression and not a top level definition.  We
+                 ;; therefore treat it as any topmost continuation
+                 ;; even though the semantically correct symbol still
+                 ;; is brace-list-open, on the same grounds as in
+                 ;; case 10B.2.
+                 (progn
+                   (c-beginning-of-statement-1 lim)
+                   (c-forward-syntactic-ws)
+                   (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+               (c-add-syntax 'brace-list-open placeholder)))
             ;; CASE 5A.4: inline defun open
             ((and inclass-p (not inenclosing-p))
              (c-add-syntax 'inline-open)
@@ -2042,14 +2126,10 @@ brace."
           ;; opening paren.  This case includes multi-line
           ;; mathematical paren groupings, but we could be on a
           ;; for-list continuation line
-          ((and (save-excursion
-                  (goto-char (1+ containing-sexp))
-                  (skip-chars-forward " \t")
-                  (not (eolp)))
-                (save-excursion
-                  (c-beginning-of-statement-1 lim)
-                  (skip-chars-backward " \t([")
-                  (<= (point) containing-sexp)))
+          ((save-excursion
+             (goto-char (1+ containing-sexp))
+             (skip-chars-forward " \t")
+             (not (eolp)))
            (goto-char containing-sexp)
            (setq placeholder (c-point 'boi))
            (when (and (c-safe (backward-up-list 1) t)
@@ -2102,8 +2182,10 @@ brace."
                 (eq char-after-ip (car (cdr special-brace-list))))
            (goto-char (car (car special-brace-list)))
            (skip-chars-backward " \t")
-           (if (bolp)
-               (setq syntax (c-guess-basic-syntax))
+           (if (and (bolp)
+                    (assoc 'statement-cont
+                           (setq placeholder (c-guess-basic-syntax))))
+               (setq syntax placeholder)
              (c-beginning-of-statement-1 lim)
              (c-forward-token-1 0)
              (if (looking-at "typedef\\>") (c-forward-token-1 1))
@@ -2151,7 +2233,7 @@ brace."
              (c-add-syntax 'brace-list-intro (c-point 'boi))
              )                         ; end CASE 9C
             ;; CASE 9D: this is just a later brace-list-entry or
-            ;; brace-entry-open 
+            ;; brace-entry-open
             (t (if (or (eq char-after-ip ?{)
                        (and c-special-brace-lists
                             (save-excursion
@@ -2346,8 +2428,10 @@ brace."
              (if (= containing-sexp (point))
                  (c-add-syntax tmpsymbol (point))
                (goto-char (cdr placeholder))
-               (c-add-syntax tmpsymbol (c-point 'boi))
-               (c-add-syntax (car placeholder))))
+               (back-to-indentation)
+               (c-add-syntax tmpsymbol (point))
+               (if (/= (point) (cdr placeholder))
+                   (c-add-syntax (car placeholder)))))
             ;; CASE 16B: does this close an inline or a function in
             ;; an extern block or namespace?
             ((progn
@@ -2480,8 +2564,10 @@ brace."
              (if (= containing-sexp (point))
                  (c-add-syntax block-intro (point))
                (goto-char (cdr placeholder))
-               (c-add-syntax block-intro (c-point 'boi))
-               (c-add-syntax (car placeholder))))
+               (back-to-indentation)
+               (c-add-syntax block-intro (point))
+               (if (/= (point) (cdr placeholder))
+                   (c-add-syntax (car placeholder)))))
            (if (eq char-after-ip ?{)
                (c-add-syntax 'block-open)))
           ;; CASE 17F: first statement in an inline, or first
@@ -2533,7 +2619,8 @@ brace."
        (skip-chars-forward " \t")
        (cond
         ;; are we looking at a comment only line?
-        ((looking-at c-comment-start-regexp)
+        ((and (looking-at c-comment-start-regexp)
+              (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
          (c-add-syntax 'comment-intro))
         ;; we might want to give additional offset to friends (in C++).
         ((and (c-major-mode-is 'c++-mode)
@@ -2544,17 +2631,17 @@ brace."
               (= (save-excursion
                    (c-beginning-of-macro lim)
                    (setq placeholder (point)))
-                 (c-point 'boi)))
+                 (c-point 'boi))
+              (not (and (c-major-mode-is 'pike-mode)
+                        (eq (char-after (1+ placeholder)) ?\"))))
          (c-add-syntax 'cpp-macro)))
        ;; return the syntax
        syntax))))
 
 \f
-(defun c-echo-parsing-error ()
-  (if (not c-parsing-error)
-      nil
-    (message "unbalanced close brace at bufpos %d -- INDENTATION IS SUSPECT!"
-            c-parsing-error)
+(defun c-echo-parsing-error (&optional quiet)
+  (when (and c-parsing-error (not quiet))
+    (message "%s" c-parsing-error)
     (ding))
   c-parsing-error)
 
@@ -2573,21 +2660,99 @@ brace."
       (if (> (- (point-max) pos) (point))
          (goto-char (- (point-max) pos))))))
 
-(defun c-indent-line (&optional syntax)
-  ;; Indent the current line as C/C++/ObjC code, if
+(defun c-evaluate-offset (offset langelem symbol)
+  ;; offset can be a number, a function, a variable, a list, or one of
+  ;; the symbols + or -
+  (cond
+   ((eq offset '+)         c-basic-offset)
+   ((eq offset '-)         (- c-basic-offset))
+   ((eq offset '++)        (* 2 c-basic-offset))
+   ((eq offset '--)        (* 2 (- c-basic-offset)))
+   ((eq offset '*)         (/ c-basic-offset 2))
+   ((eq offset '/)         (/ (- c-basic-offset) 2))
+   ((numberp offset)       offset)
+   ((functionp offset)     (c-evaluate-offset
+                           (funcall offset langelem) langelem symbol))
+   ((vectorp offset)       offset)
+   ((null offset)          nil)
+   ((listp offset)
+    (let (done)
+      (while (and (not done) offset)
+       (setq done (c-evaluate-offset (car offset) langelem symbol)
+             offset (cdr offset)))
+      (if (not done)
+         (if c-strict-syntax-p
+             (error "No offset found for syntactic symbol %s" symbol))
+       done)))
+   (t (symbol-value offset))
+   ))
+
+(defun c-get-offset (langelem)
+  ;; Get offset from LANGELEM which is a cons cell of the form:
+  ;; (SYMBOL . RELPOS).  The symbol is matched against
+  ;; c-offsets-alist and the offset found there is either returned,
+  ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
+  ;; the offset is simply returned.
+  (let* ((symbol (car langelem))
+        (relpos (cdr langelem))
+        (match  (assq symbol c-offsets-alist))
+        (offset (cdr-safe match)))
+    (if (not match)
+       (if c-strict-syntax-p
+           (error "No offset found for syntactic symbol %s" symbol)
+         (setq offset 0
+               relpos 0))
+      (setq offset (c-evaluate-offset offset langelem symbol)))
+    (if (vectorp offset)
+       offset
+      (+ (if (and relpos
+                 (< relpos (c-point 'bol)))
+            (save-excursion
+              (goto-char relpos)
+              (current-column))
+          0)
+        (or (and (numberp offset) offset)
+            (and (symbolp offset) (symbol-value offset))
+            0)))
+    ))
+
+(defun c-get-syntactic-indentation (langelems)
+  ;; Apply c-get-offset to a list of langelem cells to get the total
+  ;; syntactic indentation.  Special treatment is needed for vectors
+  ;; containing absolute columns.
+  (let ((indent 0))
+    (catch 'done
+      (while langelems
+       (let ((res (c-get-offset (car langelems))))
+         (if (vectorp res)
+             (throw 'done (elt res 0))
+           (setq indent (+ indent res)
+                 langelems (cdr langelems)))))
+      indent)))
+
+(defun c-indent-line (&optional syntax quiet)
+  ;; Indent the current line according to the syntactic context, if
   ;; c-syntactic-indentation is non-nil.  Optional SYNTAX is the
-  ;; syntactic information for the current line.  Returns the amount
-  ;; of indentation change (in columns).
+  ;; syntactic information for the current line.  Be silent about
+  ;; syntactic errors if the optional argument QUIET is non-nil.
+  ;; Returns the amount of indentation change (in columns).
   (let (shift-amt)
     (if c-syntactic-indentation
-       (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
-              (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context))))
-         (and c-echo-syntactic-information-p
-              (not (c-echo-parsing-error))
-              (message "syntax: %s, indent= %d" c-syntactic-context indent))
-         (setq shift-amt (- indent (current-indentation)))
-         (c-shift-line-indentation shift-amt)
-         (run-hooks 'c-special-indent-hook))
+       (setq c-parsing-error
+             (or (let* ((c-parsing-error nil)
+                        (c-syntactic-context (or syntax
+                                                 c-syntactic-context
+                                                 (c-guess-basic-syntax)))
+                        (indent (c-get-syntactic-indentation c-syntactic-context)))
+                   (and (not (c-echo-parsing-error quiet))
+                        c-echo-syntactic-information-p
+                        (message "syntax: %s, indent: %d"
+                                 c-syntactic-context indent))
+                   (setq shift-amt (- indent (current-indentation)))
+                   (c-shift-line-indentation shift-amt)
+                   (run-hooks 'c-special-indent-hook)
+                   c-parsing-error)
+                 c-parsing-error))
       (let ((indent 0))
        (save-excursion
          (while (and (= (forward-line -1) 0)
@@ -2606,8 +2771,7 @@ With universal argument, inserts the analysis as a comment on that line."
   (interactive "P")
   (let ((syntax (c-guess-basic-syntax)))
     (if (not (consp arg))
-       (if (not (c-echo-parsing-error))
-           (message "syntactic analysis: %s" syntax))
+       (message "syntactic analysis: %s" syntax)
       (indent-for-comment)
       (insert (format "%s" syntax))
       ))
@@ -2625,5 +2789,5 @@ With universal argument, inserts the analysis as a comment on that line."
        (forward-line)))))
 
 \f
-(provide 'cc-engine)
+(cc-provide 'cc-engine)
 ;;; cc-engine.el ends here
index 98620b733177f4540689ad0e291520c6076cdf78..8bd60ff8d4a2ab80230609cfe8da3f8fa4468b30 100644 (file)
@@ -1,7 +1,6 @@
-;;; cc-langs.el --- specific language support for CC Mode
+;;; cc-langs.el --- language specific settings for CC Mode
 
-;; Copyright (C) 1985,1987,1992,1993,1994,1995,1996,1997,1998,2000
-;;     Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-styles)
+    (require 'cc-bytecomp)))
 
-;; Pull in some other packages.
-(eval-when-compile
-  (condition-case nil
-      ;; Not required and only needed during compilation to shut up
-      ;; the compiler.
-      (require 'outline)
-    (error nil)))
-;; menu support for both XEmacs and Emacs.  If you don't have easymenu
-;; with your version of Emacs, you are incompatible!
-(require 'easymenu)
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
 
 \f
 (defvar c-buffer-is-cc-mode nil
@@ -65,9 +54,6 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 ;; Regular expressions and other values which must be parameterized on
 ;; a per-language basis.
 
-;; Keywords defining protection levels
-(defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>")
-
 ;; Regex describing a `symbol' in all languages.  We cannot use just
 ;; `word' syntax class since `_' cannot be in word class.  Putting
 ;; underscore in word class breaks forward word movement behavior that
@@ -78,40 +64,219 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 ;; definition of a symbol as being Unicode.  I know so little about
 ;; I18N (except how to sound cool and say I18N :-) that I'm willing to
 ;; punt on this for now.
-
 (defconst c-symbol-key "[_a-zA-Z]\\(\\w\\|\\s_\\)*")
 
-\f
-;; keywords introducing class definitions.  language specific
-(defconst c-C-class-key "\\(struct\\|union\\)")
-(defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
-(defconst c-IDL-class-key "\\(interface\\|struct\\|union\\|valuetype\\)")
-(defconst c-C-extra-toplevel-key "\\(extern\\)")
-(defconst c-C++-extra-toplevel-key "\\(extern\\|namespace\\)")
-(defconst c-IDL-extra-toplevel-key "\\(module\\)")
+;; HELPME: Many of the following keyword lists are more or less bogus
+;; for some languages (notably ObjC and IDL).  The effects of the
+;; erroneous values in the language handling is miniscule since these
+;; constants are not used very much (yet, anyway) in the actual syntax
+;; detection code, but I'd still appreciate help to get them correct.
+
+;; Primitive type keywords.
+(defconst c-C-primitive-type-kwds
+  "char\\|double\\|float\\|int\\|long\\|short\\|signed\\|unsigned\\|void")
+(defconst c-C++-primitive-type-kwds c-C-primitive-type-kwds)
+(defconst c-ObjC-primitive-type-kwds c-C-primitive-type-kwds)
+(defconst c-Java-primitive-type-kwds
+  "boolean\\|byte\\|char\\|double\\|float\\|int\\|long\\|short\\|void")
+(defconst c-IDL-primitive-type-kwds c-C-primitive-type-kwds)
+(defconst c-Pike-primitive-type-kwds
+  (concat "constant\\|float\\|int\\|mapping\\|multiset\\|object\\|"
+         "program\\|string\\|void"))
+
+;; Declaration specifier keywords.
+(defconst c-C-specifier-kwds
+  "auto\\|const\\|extern\\|register\\|static\\|volatile")
+(defconst c-C++-specifier-kwds
+  (concat c-C-specifier-kwds "\\|friend\\|inline\\|virtual"))
+(defconst c-ObjC-specifier-kwds c-C++-specifier-kwds)
+(defconst c-Java-specifier-kwds
+  ;; Note: `const' is not used, but it's still a reserved keyword.
+  (concat "abstract\\|const\\|final\\|native\\|private\\|protected\\|"
+         "public\\|static\\|synchronized\\|transient\\|volatile"))
+(defconst c-IDL-specifier-kwds c-C++-specifier-kwds)
+(defconst c-Pike-specifier-kwds
+  (concat "final\\|inline\\|local\\|nomask\\|optional\\|private\\|"
+         "protected\\|static\\|variant"))
+
+;; Class/struct declaration keywords.
+(defconst c-C-class-kwds "struct\\|union")
+(defconst c-C++-class-kwds (concat c-C-class-kwds "\\|class"))
+(defconst c-ObjC-class-kwds "interface\\|implementation")
+(defconst c-Java-class-kwds "class\\|interface")
+(defconst c-IDL-class-kwds
+  (concat c-C++-class-kwds "\\|interface\\|valuetype"))
+(defconst c-Pike-class-kwds "class")
+
+;; Keywords introducing other declaration-level blocks.
+(defconst c-C-extra-toplevel-kwds "extern")
+(defconst c-C++-extra-toplevel-kwds
+  (concat c-C-extra-toplevel-kwds "\\|namespace"))
+;;(defconst c-ObjC-extra-toplevel-kwds nil)
+;;(defconst c-Java-extra-toplevel-kwds nil)
+(defconst c-IDL-extra-toplevel-kwds "module")
+;;(defconst c-Pike-extra-toplevel-kwds nil)
+
+;; Keywords introducing other declaration-level constructs.
+(defconst c-C-other-decl-kwds "enum\\|typedef")
+(defconst c-C++-other-decl-kwds (concat c-C-other-decl-kwds "\\|template"))
+;;(defconst c-ObjC-other-decl-kwds nil)
+(defconst c-Java-other-decl-kwds "import\\|package")
+;;(defconst c-IDL-other-decl-kwds nil)
+(defconst c-Pike-other-decl-kwds "import\\|inherit")
+
+;; Keywords that occur in declaration-level constructs.
+;;(defconst c-C-decl-level-kwds nil)
+;;(defconst c-C++-decl-level-kwds nil)
+;;(defconst c-ObjC-decl-level-kwds nil)
+(defconst c-Java-decl-level-kwds "extends\\|implements\\|throws")
+;;(defconst c-IDL-decl-level-kwds nil)
+;;(defconst c-Pike-decl-level-kwds nil)
+
+;; Protection label keywords in classes.
+;;(defconst c-C-protection-kwds nil)
+(defconst c-C++-protection-kwds "private\\|protected\\|public")
+(defconst c-ObjC-protection-kwds c-C++-protection-kwds)
+;;(defconst c-Java-protection-kwds nil)
+;;(defconst c-IDL-protection-kwds nil)
+;;(defconst c-Pike-protection-kwds nil)
+
+;; Statement keywords followed directly by a block.
+(defconst c-C-block-stmt-1-kwds "do\\|else")
+(defconst c-C++-block-stmt-1-kwds
+  (concat c-C-block-stmt-1-kwds "\\|asm\\|try"))
+(defconst c-ObjC-block-stmt-1-kwds c-C++-block-stmt-1-kwds)
+(defconst c-Java-block-stmt-1-kwds
+  (concat c-C-block-stmt-1-kwds "\\|finally\\|try"))
+;;(defconst c-IDL-block-stmt-1-kwds nil)
+(defconst c-Pike-block-stmt-1-kwds c-C-block-stmt-1-kwds)
+
+;; Statement keywords followed by a paren sexp and then by a block.
+(defconst c-C-block-stmt-2-kwds "for\\|if\\|switch\\|while")
+(defconst c-C++-block-stmt-2-kwds (concat c-C-block-stmt-2-kwds "\\|catch"))
+(defconst c-ObjC-block-stmt-2-kwds c-C++-block-stmt-2-kwds)
+(defconst c-Java-block-stmt-2-kwds
+  (concat c-C++-block-stmt-2-kwds "\\|synchronized"))
+;;(defconst c-IDL-block-stmt-2-kwds nil)
+(defconst c-Pike-block-stmt-2-kwds c-C-block-stmt-2-kwds)
+
+;; Statement keywords followed by an expression or nothing.
+(defconst c-C-simple-stmt-kwds "break\\|continue\\|goto\\|return")
+(defconst c-C++-simple-stmt-kwds c-C-simple-stmt-kwds)
+(defconst c-ObjC-simple-stmt-kwds c-C-simple-stmt-kwds)
+(defconst c-Java-simple-stmt-kwds
+  ;; Note: `goto' is not a valid statement, but the keyword is still reserved.
+  (concat c-C-simple-stmt-kwds "\\|throw"))
+;;(defconst c-IDL-simple-stmt-kwds nil)
+(defconst c-Pike-simple-stmt-kwds "break\\|continue\\|return")
+
+;; Keywords introducing labels in blocks.
+(defconst c-C-label-kwds "case\\|default")
+(defconst c-C++-label-kwds c-C-label-kwds)
+(defconst c-ObjC-label-kwds c-C-label-kwds)
+(defconst c-Java-label-kwds c-C-label-kwds)
+;;(defconst c-IDL-label-kwds nil)
+(defconst c-Pike-label-kwds c-C-label-kwds)
+
+;; Keywords that can occur anywhere in expressions.
+(defconst c-C-expr-kwds "sizeof")
+(defconst c-C++-expr-kwds
+  (concat c-C-expr-kwds "\\|delete\\|new\\|operator\\|this\\|throw"))
+(defconst c-ObjC-expr-kwds c-C-expr-kwds)
+(defconst c-Java-expr-kwds "instanceof\\|new\\|super\\|this")
+;;(defconst c-IDL-expr-kwds nil)
+(defconst c-Pike-expr-kwds
+  (concat c-C-expr-kwds "\\|catch\\|class\\|gauge\\|lambda\\|predef"))
+
+;; All keywords.
+(defconst c-C-keywords
+  (concat c-C-primitive-type-kwds "\\|" c-C-specifier-kwds
+         "\\|" c-C-class-kwds "\\|" c-C-extra-toplevel-kwds
+         "\\|" c-C-other-decl-kwds
+         ;; "\\|" c-C-decl-level-kwds "\\|" c-C-protection-kwds
+         "\\|" c-C-block-stmt-1-kwds "\\|" c-C-block-stmt-2-kwds
+         "\\|" c-C-simple-stmt-kwds "\\|" c-C-label-kwds
+         "\\|" c-C-expr-kwds))
+(defconst c-C++-keywords
+  (concat c-C++-primitive-type-kwds "\\|" c-C++-specifier-kwds
+         "\\|" c-C++-class-kwds "\\|" c-C++-extra-toplevel-kwds
+         "\\|" c-C++-other-decl-kwds
+         ;; "\\|" c-C++-decl-level-kwds
+         "\\|" c-C++-protection-kwds
+         "\\|" c-C++-block-stmt-1-kwds "\\|" c-C++-block-stmt-2-kwds
+         "\\|" c-C++-simple-stmt-kwds "\\|" c-C++-label-kwds
+         "\\|" c-C++-expr-kwds))
+(defconst c-ObjC-keywords
+  (concat c-ObjC-primitive-type-kwds "\\|" c-ObjC-specifier-kwds
+         "\\|" c-ObjC-class-kwds
+         ;; "\\|" c-ObjC-extra-toplevel-kwds
+         ;; "\\|" c-ObjC-other-decl-kwds "\\|" c-ObjC-decl-level-kwds
+         "\\|" c-ObjC-protection-kwds
+         "\\|" c-ObjC-block-stmt-1-kwds "\\|" c-ObjC-block-stmt-2-kwds
+         "\\|" c-ObjC-simple-stmt-kwds "\\|" c-ObjC-label-kwds
+         "\\|" c-ObjC-expr-kwds))
+(defconst c-Java-keywords
+  (concat c-Java-primitive-type-kwds "\\|" c-Java-specifier-kwds
+         "\\|" c-Java-class-kwds
+         ;; "\\|" c-Java-extra-toplevel-kwds
+         "\\|" c-Java-other-decl-kwds "\\|" c-Java-decl-level-kwds
+         ;; "\\|" c-Java-protection-kwds
+         "\\|" c-Java-block-stmt-1-kwds "\\|" c-Java-block-stmt-2-kwds
+         "\\|" c-Java-simple-stmt-kwds "\\|" c-Java-label-kwds
+         "\\|" c-Java-expr-kwds))
+(defconst c-IDL-keywords
+  (concat c-IDL-primitive-type-kwds "\\|" c-IDL-specifier-kwds
+         "\\|" c-IDL-class-kwds "\\|" c-IDL-extra-toplevel-kwds
+         ;; "\\|" c-IDL-other-decl-kwds "\\|" c-IDL-decl-level-kwds
+         ;; "\\|" c-IDL-protection-kwds
+         ;; "\\|" c-IDL-block-stmt-1-kwds "\\|" c-IDL-block-stmt-2-kwds
+         ;; "\\|" c-IDL-simple-stmt-kwds "\\|" c-IDL-label-kwds
+         ;; "\\|" c-IDL-expr-kwds)
+         ))
+(defconst c-Pike-keywords
+  (concat c-Pike-primitive-type-kwds "\\|" c-Pike-specifier-kwds
+         "\\|" c-Pike-class-kwds
+         ;; "\\|" c-Pike-extra-toplevel-kwds
+         "\\|" c-Pike-other-decl-kwds
+         ;; "\\|" c-Pike-decl-level-kwds "\\|" c-Pike-protection-kwds
+         "\\|" c-Pike-block-stmt-1-kwds "\\|" c-Pike-block-stmt-2-kwds
+         "\\|" c-Pike-simple-stmt-kwds "\\|" c-Pike-label-kwds
+         "\\|" c-Pike-expr-kwds))
+
+(defvar c-keywords nil)
+(make-variable-buffer-local 'c-keywords)
+
+;; Keywords defining protection levels
+(defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>")
 
+;; Regexps introducing class definitions.
+(defconst c-C-class-key (c-paren-re c-C-class-kwds))
+(defconst c-C++-class-key (c-paren-re c-C++-class-kwds))
+(defconst c-IDL-class-key (c-paren-re c-IDL-class-kwds))
 (defconst c-ObjC-class-key
   (concat
-   "@\\(interface\\|implementation\\)\\s +"
+   "@\\(" c-ObjC-class-kwds "\\)\\s +"
    c-symbol-key                                ;name of the class
    "\\(\\s *:\\s *" c-symbol-key "\\)?"        ;maybe followed by the superclass
    "\\(\\s *<[^>]+>\\)?"               ;and maybe the adopted protocols list
    ))
-
 (defconst c-Java-class-key
   (concat
    "\\(" c-protection-key "\\s +\\)?"
-   "\\(interface\\|class\\)\\s +"
+   "\\(" c-Java-class-kwds "\\)\\s +"
    c-symbol-key                                      ;name of the class
    "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass
    ;;"\\(\\s *implements *[^{]+{\\)?"        ;maybe the adopted protocols list
    ))
-
-(defconst c-Pike-class-key "class")
+(defconst c-Pike-class-key (c-paren-re c-Pike-class-kwds))
 
 (defvar c-class-key c-C-class-key)
 (make-variable-buffer-local 'c-class-key)
 
+(defconst c-C-extra-toplevel-key (c-paren-re c-C-extra-toplevel-kwds))
+(defconst c-C++-extra-toplevel-key (c-paren-re c-C++-extra-toplevel-kwds))
+(defconst c-IDL-extra-toplevel-key (c-paren-re c-IDL-extra-toplevel-kwds))
+
 (defvar c-extra-toplevel-key c-C-extra-toplevel-key)
 (make-variable-buffer-local 'c-extra-toplevel-key)
 
@@ -121,17 +286,16 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 (defvar c-bitfield-key nil)
 (make-variable-buffer-local 'c-bitfield-key)
 
-\f
 ;; regexp describing access protection clauses.  language specific
 (defvar c-access-key nil)
 (make-variable-buffer-local 'c-access-key)
-(defconst c-C++-access-key (concat c-protection-key "[ \t]*:"))
-(defconst c-IDL-access-key nil)
+(defconst c-C++-access-key
+  (concat "\\<\\(" c-C++-protection-kwds "\\)\\>[ \t]*:"))
+;;(defconst c-IDL-access-key nil)
 (defconst c-ObjC-access-key (concat "@" c-protection-key))
-(defconst c-Java-access-key nil)
-(defconst c-Pike-access-key nil)
+;;(defconst c-Java-access-key nil)
+;;(defconst c-Pike-access-key nil)
 
-\f
 ;; keywords introducing conditional blocks
 (defconst c-C-conditional-key nil)
 (defconst c-C++-conditional-key nil)
@@ -143,8 +307,8 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 (let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch")
       (exc-kws "\\|try\\|catch")
       (thr-kws "\\|finally\\|synchronized")
-      (front   "\\b\\(")
-      (back    "\\)\\b[^_]"))
+      (front   "\\<\\(")
+      (back    "\\)\\>[^_]"))
   (setq c-C-conditional-key (concat front all-kws back)
        c-C++-conditional-key (concat front all-kws exc-kws back)
        ;; c-IDL-conditional-key is nil.
@@ -155,7 +319,6 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 (defvar c-conditional-key c-C-conditional-key)
 (make-variable-buffer-local 'c-conditional-key)
 
-\f
 ;; keywords describing method definition introductions
 (defvar c-method-key nil)
 (make-variable-buffer-local 'c-method-key)
@@ -168,8 +331,6 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
    ;; since it is considered the end of //-comments.
    "[ \t\n]*" c-symbol-key))
 
-
-\f
 ;; comment starter definitions for various languages.  language specific
 (defconst c-C++-comment-start-regexp "/[/*]")
 (defconst c-C-comment-start-regexp c-C++-comment-start-regexp)
@@ -182,8 +343,6 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 (defvar c-comment-start-regexp c-C++-comment-start-regexp)
 (make-variable-buffer-local 'c-comment-start-regexp)
 
-
-\f
 ;; Regexp describing a switch's case or default label for all languages
 (defconst c-switch-label-key "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):")
 ;; Regexp describing any label.
@@ -215,15 +374,18 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
 (defconst c-Java-defun-prompt-regexp
   "^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()\7f=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*")
 
-;; Regexp describing regexp to append to paragraph-start
+;; Regexp to append to paragraph-start.
 (defvar c-append-paragraph-start "$")
 (make-variable-buffer-local 'c-append-paragraph-start)
 (defconst c-Java-javadoc-paragraph-start
-  (concat "\\("
-         "@\\(author\\|deprecated\\|exception\\|param\\|return\\|"
-         "s\\(e\\(e\\|rial\\(\\|Data\\|Field\\)\\)\\|ince\\)\\|"
-         "throws\\|version\\)"
-         "\\|$\\)"))
+  "\\(@[a-zA-Z]+\\>\\|$\\)")
+(defconst c-Pike-pikedoc-paragraph-start
+  "\\(@[a-zA-Z]+\\>\\([^{]\\|$\\)\\|$\\)")
+
+;; Regexp to append to paragraph-separate.
+(defvar c-append-paragraph-separate "$")
+(make-variable-buffer-local 'c-append-paragraph-separate)
+(defconst c-Pike-pikedoc-paragraph-separate c-Pike-pikedoc-paragraph-start)
 
 ;; Regexp that starts lambda constructs.
 (defvar c-lambda-key nil)
@@ -250,175 +412,8 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
                                       (?\[ . ?\])
                                       (?< . ?>)))
 
-
-\f
-;; internal state variables
-
-;; Internal state of hungry delete key feature
-(defvar c-hungry-delete-key nil)
-(make-variable-buffer-local 'c-hungry-delete-key)
-
-;; Internal state of auto newline feature.
-(defvar c-auto-newline nil)
-(make-variable-buffer-local 'c-auto-newline)
-
-;; Internal auto-newline/hungry-delete designation string for mode line.
-(defvar c-auto-hungry-string nil)
-(make-variable-buffer-local 'c-auto-hungry-string)
-
-;; Non-nil means K&R style argument declarations are valid.
-(defvar c-recognize-knr-p t)
-(make-variable-buffer-local 'c-recognize-knr-p)
-
-
 \f
-(defun c-common-init ()
-  ;; Common initializations for all modes.
-  ;; these variables should always be buffer local; they do not affect
-  ;; indentation style.
-  (make-local-variable 'require-final-newline)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (make-local-variable 'indent-line-function)
-  (make-local-variable 'indent-region-function)
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (make-local-variable 'normal-auto-fill-function)
-  (make-local-variable 'comment-start)
-  (make-local-variable 'comment-end)
-  (make-local-variable 'comment-column)
-  (make-local-variable 'comment-start-skip)
-  (make-local-variable 'comment-multi-line)
-  (make-local-variable 'paragraph-start)
-  (make-local-variable 'paragraph-separate)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (make-local-variable 'adaptive-fill-mode)
-  (make-local-variable 'adaptive-fill-regexp)
-  (make-local-variable 'imenu-generic-expression) ;set in the mode functions
-  ;; X/Emacs 20 only
-  (and (boundp 'comment-line-break-function)
-       (progn
-        (make-local-variable 'comment-line-break-function)
-        (setq comment-line-break-function
-              'c-indent-new-comment-line)))
-  ;; now set their values
-  (setq require-final-newline t
-       parse-sexp-ignore-comments t
-       indent-line-function 'c-indent-line
-       indent-region-function 'c-indent-region
-       outline-regexp "[^#\n\^M]"
-       outline-level 'c-outline-level
-       normal-auto-fill-function 'c-do-auto-fill
-       comment-column 32
-       comment-start-skip "/\\*+ *\\|//+ *"
-       comment-multi-line t)
-  ;; now set the mode style based on c-default-style
-  (let ((style (if (stringp c-default-style)
-                  (if (c-major-mode-is 'java-mode)
-                      "java"
-                    c-default-style)
-                (or (cdr (assq major-mode c-default-style))
-                    (cdr (assq 'other c-default-style))
-                    "gnu"))))
-    ;; Override style variables if `c-old-style-variable-behavior' is
-    ;; set.  Also override if we are using global style variables,
-    ;; have already initialized a style once, and are switching to a
-    ;; different style.  (It's doubtful whether this is desirable, but
-    ;; the whole situation with nonlocal style variables is a bit
-    ;; awkward.  It's at least the most compatible way with the old
-    ;; style init procedure.)
-    (c-set-style style (not (or c-old-style-variable-behavior
-                               (and (not c-style-variables-are-local-p)
-                                    c-indentation-style
-                                    (not (string-equal c-indentation-style
-                                                       style)))))))
-  ;; Fix things up for paragraph recognition and filling inside
-  ;; comments by using c-comment-prefix-regexp in the relevant places.
-  ;; We use adaptive filling for this to make it possible to use
-  ;; filladapt or some other fancy package.
-  (let ((comment-line-prefix
-        (concat "[ \t]*\\(" c-comment-prefix-regexp "\\)?[ \t]*")))
-    (setq paragraph-start (concat comment-line-prefix
-                                 c-append-paragraph-start
-                                 "\\|"
-                                 page-delimiter)
-         paragraph-separate (concat comment-line-prefix "$"
-                                    "\\|"
-                                    page-delimiter)
-         paragraph-ignore-fill-prefix t
-         adaptive-fill-mode t
-         adaptive-fill-regexp
-         (concat comment-line-prefix
-                 (if adaptive-fill-regexp
-                     (concat "\\(" adaptive-fill-regexp "\\)")
-                   "")))
-    (when (boundp 'adaptive-fill-first-line-regexp)
-      ;; XEmacs (20.x) adaptive fill mode doesn't have this.
-      (make-local-variable 'adaptive-fill-first-line-regexp)
-      (setq adaptive-fill-first-line-regexp
-           (concat "\\`" comment-line-prefix
-                   ;; Maybe we should incorporate the old value here,
-                   ;; but then we have to do all sorts of kludges to
-                   ;; deal with the \` and \' it probably contains.
-                   "\\'"))))
-  ;; we have to do something special for c-offsets-alist so that the
-  ;; buffer local value has its own alist structure.
-  (setq c-offsets-alist (copy-alist c-offsets-alist))
-  ;; setup the comment indent variable in a Emacs version portable way
-  ;; ignore any byte compiler warnings you might get here
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'c-comment-indent)
-  ;; add menus to menubar
-  (easy-menu-add (c-mode-menu mode-name))
-  ;; put auto-hungry designators onto minor-mode-alist, but only once
-  (or (assq 'c-auto-hungry-string minor-mode-alist)
-      (setq minor-mode-alist
-           (cons '(c-auto-hungry-string c-auto-hungry-string)
-                 minor-mode-alist)))
-  )
-
-
-(defun c-postprocess-file-styles ()
-  "Function that post processes relevant file local variables.
-Currently, this function simply applies any style and offset settings
-found in the file's Local Variable list.  It first applies any style
-setting found in `c-file-style', then it applies any offset settings
-it finds in `c-file-offsets'.
-
-Note that the style variables are always made local to the buffer."
-  ;; apply file styles and offsets
-  (if (or c-file-style c-file-offsets)
-      (c-make-styles-buffer-local t))
-  (and c-file-style
-       (c-set-style c-file-style))
-  (and c-file-offsets
-       (mapcar
-       (function
-        (lambda (langentry)
-          (let ((langelem (car langentry))
-                (offset (cdr langentry)))
-            (c-set-offset langelem offset)
-            )))
-       c-file-offsets)))
-
-(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
-
-\f
-(defvar c-mode-base-map ()
-  "Keymap shared by all CC Mode related modes.")
-
-;; Common routines
-(defun c-make-inherited-keymap ()
-  (let ((map (make-sparse-keymap)))
-    (cond
-     ;; XEmacs 19 & 20
-     ((fboundp 'set-keymap-parents)
-      (set-keymap-parents map c-mode-base-map))
-     ;; Emacs 19
-     ((fboundp 'set-keymap-parent)
-      (set-keymap-parent map c-mode-base-map))
-     ;; incompatible
-     (t (error "CC Mode is incompatible with this version of Emacs")))
-    map))
+;; Syntax tables.
 
 (defun c-populate-syntax-table (table)
   ;; Populate the syntax TABLE
@@ -453,132 +448,6 @@ Note that the style variables are always made local to the buffer."
   ;; Give CR the same syntax as newline, for selective-display
   (modify-syntax-entry ?\^m "> b" table))
 
-
-(if c-mode-base-map
-    nil
-  ;; TBD: should we even worry about naming this keymap. My vote: no,
-  ;; because Emacs and XEmacs do it differently.
-  (setq c-mode-base-map (make-sparse-keymap))
-  ;; put standard keybindings into MAP
-  ;; the following mappings correspond more or less directly to BOCM
-  (define-key c-mode-base-map "{"         'c-electric-brace)
-  (define-key c-mode-base-map "}"         'c-electric-brace)
-  (define-key c-mode-base-map ";"         'c-electric-semi&comma)
-  (define-key c-mode-base-map "#"         'c-electric-pound)
-  (define-key c-mode-base-map ":"         'c-electric-colon)
-  (define-key c-mode-base-map "("         'c-electric-paren)
-  (define-key c-mode-base-map ")"         'c-electric-paren)
-  ;; Separate M-BS from C-M-h.  The former should remain
-  ;; backward-kill-word.
-  (define-key c-mode-base-map [(control meta h)] 'c-mark-function)
-  (define-key c-mode-base-map "\e\C-q"    'c-indent-exp)
-  (substitute-key-definition 'backward-sentence
-                            'c-beginning-of-statement
-                            c-mode-base-map global-map)
-  (substitute-key-definition 'forward-sentence
-                            'c-end-of-statement
-                            c-mode-base-map global-map)
-  (substitute-key-definition 'indent-new-comment-line
-                            'c-indent-new-comment-line
-                            c-mode-base-map global-map)
-  ;; RMS says don't make these the default.
-;;  (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)
-  (define-key c-mode-base-map "\C-c\C-u"  'c-up-conditional)
-  (substitute-key-definition 'indent-for-tab-command
-                            'c-indent-command
-                            c-mode-base-map global-map)
-  ;; It doesn't suffice to put c-fill-paragraph on
-  ;; fill-paragraph-function due to the way it works.
-  (substitute-key-definition 'fill-paragraph 'c-fill-paragraph
-                            c-mode-base-map global-map)
-  ;; In XEmacs the default fill function is called
-  ;; fill-paragraph-or-region.
-  (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
-                            c-mode-base-map global-map)
-  ;; Caution!  Enter here at your own risk.  We are trying to support
-  ;; several behaviors and it gets disgusting. :-(
-  ;;
-  (if (boundp 'delete-key-deletes-forward)
-      (progn
-       ;; In XEmacs 20 it is possible to sanely define both backward
-       ;; and forward deletion behavior under X separately (TTYs are
-       ;; forever beyond hope, but who cares?  XEmacs 20 does the
-       ;; right thing with these too).
-       (define-key c-mode-base-map [delete]    'c-electric-delete)
-       (define-key c-mode-base-map [backspace] 'c-electric-backspace))
-    ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
-    ;; backwards deletion behavior to DEL, which both Delete and
-    ;; Backspace get translated to.  There's no way to separate this
-    ;; behavior in a clean way, so deal with it!  Besides, it's been
-    ;; this way since the dawn of BOCM.
-    (define-key c-mode-base-map "\177" 'c-electric-backspace))
-  ;; these are new keybindings, with no counterpart to BOCM
-  (define-key c-mode-base-map ","         'c-electric-semi&comma)
-  (define-key c-mode-base-map "*"         'c-electric-star)
-  (define-key c-mode-base-map "/"         'c-electric-slash)
-  (define-key c-mode-base-map "\C-c\C-q"  'c-indent-defun)
-  (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
-  ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
-  (define-key c-mode-base-map "\C-c\C-a"  'c-toggle-auto-state)
-  (define-key c-mode-base-map "\C-c\C-b"  'c-submit-bug-report)
-  (define-key c-mode-base-map "\C-c\C-c"  'comment-region)
-  (define-key c-mode-base-map "\C-c\C-d"  'c-toggle-hungry-state)
-  (define-key c-mode-base-map "\C-c\C-o"  'c-set-offset)
-  (define-key c-mode-base-map "\C-c\C-s"  'c-show-syntactic-information)
-  (define-key c-mode-base-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
-  (define-key c-mode-base-map "\C-c."     'c-set-style)
-  ;; conflicts with OOBR
-  ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
-  )
-
-(defvar c-c-menu nil)
-(defvar c-c++-menu nil)
-(defvar c-objc-menu nil)
-(defvar c-java-menu nil)
-(defvar c-pike-menu nil)
-
-(defun c-mode-menu (modestr)
-  (let ((m
-        '(["Comment Out Region"     comment-region (c-region-is-active-p)]
-          ["Uncomment Region"
-           (comment-region (region-beginning) (region-end) '(4))
-           (c-region-is-active-p)]
-          ["Fill Comment Paragraph" c-fill-paragraph t]
-          "---"
-          ["Indent Expression"      c-indent-exp
-           (memq (char-after) '(?\( ?\[ ?\{))]
-          ["Indent Line or Region"  c-indent-line-or-region t]
-          ["Up Conditional"         c-up-conditional t]
-          ["Backward Conditional"   c-backward-conditional t]
-          ["Forward Conditional"    c-forward-conditional t]
-          ["Backward Statement"     c-beginning-of-statement t]
-          ["Forward Statement"      c-end-of-statement t]
-          "---"
-          ["Macro Expand Region"    c-macro-expand (c-region-is-active-p)]
-          ["Backslashify"           c-backslash-region (c-region-is-active-p)]
-          )))
-    (cons modestr m)))
-
-
-\f
-;; Support for C
-
-(defvar c-mode-abbrev-table nil
-  "Abbreviation table used in c-mode buffers.")
-(define-abbrev-table 'c-mode-abbrev-table ())
-
-(defvar c-mode-map ()
-  "Keymap used in c-mode buffers.")
-(if c-mode-map
-    nil
-  (setq c-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for C
-  (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
-  )
-
 ;;;###autoload
 (defvar c-mode-syntax-table nil
   "Syntax table used in c-mode buffers.")
@@ -587,27 +456,6 @@ Note that the style variables are always made local to the buffer."
   (setq c-mode-syntax-table (make-syntax-table))
   (c-populate-syntax-table c-mode-syntax-table))
 
-(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
-                 (c-mode-menu "C"))
-
-\f
-;; Support for C++
-
-(defvar c++-mode-abbrev-table nil
-  "Abbreviation table used in c++-mode buffers.")
-(define-abbrev-table 'c++-mode-abbrev-table ())
-
-(defvar c++-mode-map ()
-  "Keymap used in c++-mode buffers.")
-(if c++-mode-map
-    nil
-  (setq c++-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for C++
-  (define-key c++-mode-map "\C-c\C-e" 'c-macro-expand)
-  (define-key c++-mode-map "\C-c:"    'c-scope-operator)
-  (define-key c++-mode-map "<"        'c-electric-lt-gt)
-  (define-key c++-mode-map ">"        'c-electric-lt-gt))
-
 ;;;###autoload
 (defvar c++-mode-syntax-table nil
   "Syntax table used in c++-mode buffers.")
@@ -635,24 +483,6 @@ are parsed.")
   (modify-syntax-entry ?< "(>" c++-template-syntax-table)
   (modify-syntax-entry ?> ")<" c++-template-syntax-table))
 
-(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
-                 (c-mode-menu "C++"))
-
-\f
-;; Support for Objective-C
-
-(defvar objc-mode-abbrev-table nil
-  "Abbreviation table used in objc-mode buffers.")
-(define-abbrev-table 'objc-mode-abbrev-table ())
-
-(defvar objc-mode-map ()
-  "Keymap used in objc-mode buffers.")
-(if objc-mode-map
-    nil
-  (setq objc-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for Objective-C
-  (define-key objc-mode-map "\C-c\C-e" 'c-macro-expand))
-
 ;;;###autoload
 (defvar objc-mode-syntax-table nil
   "Syntax table used in objc-mode buffers.")
@@ -663,24 +493,6 @@ are parsed.")
   ;; add extra Objective-C only syntax
   (modify-syntax-entry ?@ "_" objc-mode-syntax-table))
 
-(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
-                 (c-mode-menu "ObjC"))
-
-\f
-;; Support for Java
-
-(defvar java-mode-abbrev-table nil
-  "Abbreviation table used in java-mode buffers.")
-(define-abbrev-table 'java-mode-abbrev-table ())
-
-(defvar java-mode-map ()
-  "Keymap used in java-mode buffers.")
-(if java-mode-map
-    nil
-  (setq java-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for Java
-  )
-
 ;;;###autoload
 (defvar java-mode-syntax-table nil
   "Syntax table used in java-mode buffers.")
@@ -689,24 +501,6 @@ are parsed.")
   (setq java-mode-syntax-table (make-syntax-table))
   (c-populate-syntax-table java-mode-syntax-table))
 
-(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
-                 (c-mode-menu "Java"))
-
-\f
-;; Support for CORBA's IDL language
-
-(defvar idl-mode-abbrev-table nil
-  "Abbreviation table used in idl-mode buffers.")
-(define-abbrev-table 'idl-mode-abbrev-table ())
-
-(defvar idl-mode-map ()
-  "Keymap used in idl-mode buffers.")
-(if idl-mode-map
-    nil
-  (setq idl-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for IDL
-  )
-
 ;;;###autoload
 (defvar idl-mode-syntax-table nil
   "Syntax table used in idl-mode buffers.")
@@ -715,24 +509,6 @@ are parsed.")
   (setq idl-mode-syntax-table (make-syntax-table))
   (c-populate-syntax-table idl-mode-syntax-table))
 
-(easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands"
-                 (c-mode-menu "IDL"))
-
-\f
-;; Support for Pike
-
-(defvar pike-mode-abbrev-table nil
-  "Abbreviation table used in pike-mode buffers.")
-(define-abbrev-table 'pike-mode-abbrev-table ())
-
-(defvar pike-mode-map ()
-  "Keymap used in pike-mode buffers.")
-(if pike-mode-map
-    nil
-  (setq pike-mode-map (c-make-inherited-keymap))
-  ;; additional bindings
-  (define-key pike-mode-map "\C-c\C-e" 'c-macro-expand))
-
 ;;;###autoload
 (defvar pike-mode-syntax-table nil
   "Syntax table used in pike-mode buffers.")
@@ -742,10 +518,25 @@ are parsed.")
   (c-populate-syntax-table pike-mode-syntax-table)
   (modify-syntax-entry ?@ "." pike-mode-syntax-table))
 
-(easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands"
-                 (c-mode-menu "Pike"))
+\f
+;; internal state variables
+
+;; Internal state of hungry delete key feature
+(defvar c-hungry-delete-key nil)
+(make-variable-buffer-local 'c-hungry-delete-key)
+
+;; Internal state of auto newline feature.
+(defvar c-auto-newline nil)
+(make-variable-buffer-local 'c-auto-newline)
 
+;; Internal auto-newline/hungry-delete designation string for mode line.
+(defvar c-auto-hungry-string nil)
+(make-variable-buffer-local 'c-auto-hungry-string)
+
+;; Non-nil means K&R style argument declarations are valid.
+(defvar c-recognize-knr-p t)
+(make-variable-buffer-local 'c-recognize-knr-p)
 
 \f
-(provide 'cc-langs)
+(cc-provide 'cc-langs)
 ;;; cc-langs.el ends here
index 3cd67c67bdb70b84ac6fae0cdb711b26ab95b2f9..5179f952530ca4b896d9e920b7ad110d6ed13d19 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-menus.el --- imenu support for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
+    (require 'cc-bytecomp)))
 
-;; Dummy definitions to shut up the compiler in case imenu doesn't exist.
-(eval-when-compile
-  (defvar imenu-generic-expression)
-  (defvar imenu-case-fold-search))
-(or (fboundp 'imenu-progress-message)
-    (defun imenu-progress-message (&rest args) nil))
+;; Try to pull in imenu if it exists.
+(condition-case nil
+    (require 'imenu)
+  (error nil))
 
-;; Try to pull in imenu.
-(eval-and-compile
-  (condition-case nil
-      (require 'imenu)
-    (error nil)))
+;; The things referenced in imenu, which we don't require.
+(cc-bytecomp-defvar imenu-case-fold-search)
+(cc-bytecomp-defvar imenu-generic-expression)
+(cc-bytecomp-defun imenu-progress-message)
 
 \f
 ;; imenu integration
@@ -134,13 +130,13 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
      ,(concat
          "^"                                  ; beginning of line is required
          "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>'
-         "class[ \t]+"
+         "\\(class\\|struct\\)[ \t]+"
          "\\("                                ; the string we want to get
          "[a-zA-Z0-9_]+"                      ; class name
-         "\\(<[^>]+>\\)?"                     ; possibly explicitely specialized
+         "\\(<[^>]+>\\)?"                     ; possibly explicitly specialized
          "\\)"
          "[ \t\n]*[:{]"
-         ) 2))
+         ) 3))
   "Imenu generic expression for C++ mode.  See `imenu-generic-expression'.")
  
 (defvar cc-imenu-c-generic-expression
@@ -414,5 +410,5 @@ Example:
        imenu-case-fold-search nil))
 
 \f
-(provide 'cc-menus)
+(cc-provide 'cc-menus)
 ;;; cc-menus.el ends here
index a3750bf082bf7901014d6adf52a2df2e9d72fc0b..a7e35a9c185a88ab75223ae278da423465f4dc43 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-mode.el --- major mode for editing C, C++, Objective-C, and Java code
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; Created:    a long, long, time ago. adapted from the original c-mode.el
 ;; Keywords:   c languages oop
 
-(defconst c-version "5.27"
-  "CC Mode version number.")
-
-;; NOTE: Read the commentary below for the right way to submit bug reports!
-;; NOTE: See the accompanying texinfo manual for details on using this mode!
-
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+(defconst c-version "5.28"
+  "CC Mode version number.")
+
+;; NOTE: Read the commentary below for the right way to submit bug reports!
+;; NOTE: See the accompanying texinfo manual for details on using this mode!
+
 ;;; Commentary:
 
 ;; This package provides GNU Emacs major modes for editing C, C++,
@@ -64,9 +64,8 @@
 ;; gnu.emacs.bug) as well as bug-cc-mode@gnu.org, which directly
 ;; contacts the CC Mode maintainers.  Questions can sent to
 ;; help-gnu-emacs@gnu.org (mirrored as gnu.emacs.help) and/or
-;; bug-cc-mode@gnu.org.  Please use bug-cc-mode@gnu.org instead.
-;; Please do not send bugs or questions to our personal accounts; we
-;; reserve the right to ignore such email!
+;; bug-cc-mode@gnu.org.  Please do not send bugs or questions to our
+;; personal accounts; we reserve the right to ignore such email!
 
 ;; Many, many thanks go out to all the folks on the beta test list.
 ;; Without their patience, testing, insight, code contributions, and
 
 (eval-when-compile
   (let ((load-path
-        ;; Try to make sure the source directory is at the front of
-        ;; load-path when we load cc-defs.
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            ;; byte-compile-current-file is set by the byte compiler
-            ;; to the full path to this file.
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    ;; Load our version of cc-defs unconditionally, since an older
-    ;; version might very well be dumped in or already loaded.  This
-    ;; way we ensure that the code is compiled with the correct macros
-    ;; and defsubsts.  The same problem affects the subpackages that's
-    ;; require'd below, but that doesn't harm the compiler; it can
-    ;; only cause some bogus warnings.
-    (load "cc-defs" nil t)))
-
-(require 'cc-defs) ; Not meaningless; this passes on require's from cc-defs.
-(require 'cc-menus)
-(require 'cc-vars)
-(require 'cc-styles)
-(require 'cc-langs)
-(require 'cc-engine)
-(require 'cc-align)
-(require 'cc-cmds)
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+(cc-require 'cc-menus)
+(cc-require 'cc-vars)
+(cc-require 'cc-langs)
+(cc-require 'cc-styles)
+(cc-require 'cc-engine)
+(cc-require 'cc-cmds)
+(cc-require 'cc-align)
+
+;; Silence the compiler.
+(cc-bytecomp-defvar comment-line-break-function) ; (X)Emacs 20+
+(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 20+
+(cc-bytecomp-defun set-keymap-parents) ; XEmacs
+
+;; Menu support for both XEmacs and Emacs.  If you don't have easymenu
+;; with your version of Emacs, you are incompatible!
+(require 'easymenu)
 
 \f
 ;; Other modes and packages which depend on CC Mode should do the
     ))
 
 \f
+;; Common routines
+(defvar c-mode-base-map ()
+  "Keymap shared by all CC Mode related modes.")
+
+(defun c-make-inherited-keymap ()
+  (let ((map (make-sparse-keymap)))
+    (cond
+     ;; XEmacs 19 & 20
+     ((fboundp 'set-keymap-parents)
+      (set-keymap-parents map c-mode-base-map))
+     ;; Emacs 19
+     ((fboundp 'set-keymap-parent)
+      (set-keymap-parent map c-mode-base-map))
+     ;; incompatible
+     (t (error "CC Mode is incompatible with this version of Emacs")))
+    map))
+
+(if c-mode-base-map
+    nil
+  ;; TBD: should we even worry about naming this keymap. My vote: no,
+  ;; because Emacs and XEmacs do it differently.
+  (setq c-mode-base-map (make-sparse-keymap))
+  ;; put standard keybindings into MAP
+  ;; the following mappings correspond more or less directly to BOCM
+  (define-key c-mode-base-map "{"         'c-electric-brace)
+  (define-key c-mode-base-map "}"         'c-electric-brace)
+  (define-key c-mode-base-map ";"         'c-electric-semi&comma)
+  (define-key c-mode-base-map "#"         'c-electric-pound)
+  (define-key c-mode-base-map ":"         'c-electric-colon)
+  (define-key c-mode-base-map "("         'c-electric-paren)
+  (define-key c-mode-base-map ")"         'c-electric-paren)
+  ;; Separate M-BS from C-M-h.  The former should remain
+  ;; backward-kill-word.
+  (define-key c-mode-base-map [(control meta h)] 'c-mark-function)
+  (define-key c-mode-base-map "\e\C-q"    'c-indent-exp)
+  (substitute-key-definition 'backward-sentence
+                            'c-beginning-of-statement
+                            c-mode-base-map global-map)
+  (substitute-key-definition 'forward-sentence
+                            'c-end-of-statement
+                            c-mode-base-map global-map)
+  (substitute-key-definition 'indent-new-comment-line
+                            'c-indent-new-comment-line
+                            c-mode-base-map global-map)
+  ;; RMS says don't make these the default.
+;;  (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)
+  (define-key c-mode-base-map "\C-c\C-u"  'c-up-conditional)
+  (substitute-key-definition 'indent-for-tab-command
+                            'c-indent-command
+                            c-mode-base-map global-map)
+  ;; It doesn't suffice to put c-fill-paragraph on
+  ;; fill-paragraph-function due to the way it works.
+  (substitute-key-definition 'fill-paragraph 'c-fill-paragraph
+                            c-mode-base-map global-map)
+  ;; In XEmacs the default fill function is called
+  ;; fill-paragraph-or-region.
+  (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
+                            c-mode-base-map global-map)
+  ;; Caution!  Enter here at your own risk.  We are trying to support
+  ;; several behaviors and it gets disgusting. :-(
+  ;;
+  (if (boundp 'delete-key-deletes-forward)
+      (progn
+       ;; In XEmacs 20 it is possible to sanely define both backward
+       ;; and forward deletion behavior under X separately (TTYs are
+       ;; forever beyond hope, but who cares?  XEmacs 20 does the
+       ;; right thing with these too).
+       (define-key c-mode-base-map [delete]    'c-electric-delete)
+       (define-key c-mode-base-map [backspace] 'c-electric-backspace))
+    ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
+    ;; backwards deletion behavior to DEL, which both Delete and
+    ;; Backspace get translated to.  There's no way to separate this
+    ;; behavior in a clean way, so deal with it!  Besides, it's been
+    ;; this way since the dawn of BOCM.
+    (define-key c-mode-base-map "\177" 'c-electric-backspace))
+  ;; these are new keybindings, with no counterpart to BOCM
+  (define-key c-mode-base-map ","         'c-electric-semi&comma)
+  (define-key c-mode-base-map "*"         'c-electric-star)
+  (define-key c-mode-base-map "/"         'c-electric-slash)
+  (define-key c-mode-base-map "\C-c\C-q"  'c-indent-defun)
+  (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
+  ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
+  (define-key c-mode-base-map "\C-c\C-a"  'c-toggle-auto-state)
+  (define-key c-mode-base-map "\C-c\C-b"  'c-submit-bug-report)
+  (define-key c-mode-base-map "\C-c\C-c"  'comment-region)
+  (define-key c-mode-base-map "\C-c\C-d"  'c-toggle-hungry-state)
+  (define-key c-mode-base-map "\C-c\C-o"  'c-set-offset)
+  (define-key c-mode-base-map "\C-c\C-s"  'c-show-syntactic-information)
+  (define-key c-mode-base-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
+  (define-key c-mode-base-map "\C-c."     'c-set-style)
+  ;; conflicts with OOBR
+  ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
+  )
+
+(defvar c-c-menu nil)
+(defvar c-c++-menu nil)
+(defvar c-objc-menu nil)
+(defvar c-java-menu nil)
+(defvar c-pike-menu nil)
+
+(defun c-mode-menu (modestr)
+  (let ((m
+        '(["Comment Out Region"     comment-region (c-fn-region-is-active-p)]
+          ["Uncomment Region"
+           (comment-region (region-beginning) (region-end) '(4))
+           (c-fn-region-is-active-p)]
+          ["Fill Comment Paragraph" c-fill-paragraph t]
+          "---"
+          ["Indent Expression"      c-indent-exp
+           (memq (char-after) '(?\( ?\[ ?\{))]
+          ["Indent Line or Region"  c-indent-line-or-region t]
+          ["Up Conditional"         c-up-conditional t]
+          ["Backward Conditional"   c-backward-conditional t]
+          ["Forward Conditional"    c-forward-conditional t]
+          ["Backward Statement"     c-beginning-of-statement t]
+          ["Forward Statement"      c-end-of-statement t]
+          "---"
+          ["Macro Expand Region"    c-macro-expand (c-fn-region-is-active-p)]
+          ["Backslashify"           c-backslash-region
+           (c-fn-region-is-active-p)]
+          )))
+    (cons modestr m)))
+
+;; We don't require the outline package, but we configure it a bit anyway.
+(cc-bytecomp-defvar outline-level)
+
+(defun c-common-init ()
+  ;; Common initializations for all modes.
+  ;; these variables should always be buffer local; they do not affect
+  ;; indentation style.
+  (make-local-variable 'require-final-newline)
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (make-local-variable 'indent-line-function)
+  (make-local-variable 'indent-region-function)
+  (make-local-variable 'outline-regexp)
+  (make-local-variable 'outline-level)
+  (make-local-variable 'normal-auto-fill-function)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (make-local-variable 'comment-column)
+  (make-local-variable 'comment-start-skip)
+  (make-local-variable 'comment-multi-line)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-ignore-fill-prefix)
+  (make-local-variable 'adaptive-fill-mode)
+  (make-local-variable 'adaptive-fill-regexp)
+  (make-local-variable 'imenu-generic-expression) ;set in the mode functions
+  ;; X/Emacs 20 only
+  (and (boundp 'comment-line-break-function)
+       (progn
+        (make-local-variable 'comment-line-break-function)
+        (setq comment-line-break-function
+              'c-indent-new-comment-line)))
+  ;; now set their values
+  (setq require-final-newline t
+       parse-sexp-ignore-comments t
+       indent-line-function 'c-indent-line
+       indent-region-function 'c-indent-region
+       outline-regexp "[^#\n\^M]"
+       outline-level 'c-outline-level
+       normal-auto-fill-function 'c-do-auto-fill
+       comment-column 32
+       comment-start-skip "/\\*+ *\\|//+ *"
+       comment-multi-line t)
+  ;; now set the mode style based on c-default-style
+  (let ((style (if (stringp c-default-style)
+                  c-default-style
+                (or (cdr (assq major-mode c-default-style))
+                    (cdr (assq 'other c-default-style))
+                    "gnu"))))
+    ;; Override style variables if `c-old-style-variable-behavior' is
+    ;; set.  Also override if we are using global style variables,
+    ;; have already initialized a style once, and are switching to a
+    ;; different style.  (It's doubtful whether this is desirable, but
+    ;; the whole situation with nonlocal style variables is a bit
+    ;; awkward.  It's at least the most compatible way with the old
+    ;; style init procedure.)
+    (c-set-style style (not (or c-old-style-variable-behavior
+                               (and (not c-style-variables-are-local-p)
+                                    c-indentation-style
+                                    (not (string-equal c-indentation-style
+                                                       style)))))))
+  ;; Fix things up for paragraph recognition and filling inside
+  ;; comments by using c-current-comment-prefix in the relevant
+  ;; places.  We use adaptive filling for this to make it possible to
+  ;; use filladapt or some other fancy package.
+  (setq c-current-comment-prefix
+       (if (listp c-comment-prefix-regexp)
+           (cdr-safe (or (assoc major-mode c-comment-prefix-regexp)
+                         (assoc 'other c-comment-prefix-regexp)))
+         c-comment-prefix-regexp))
+  (let ((comment-line-prefix
+        (concat "[ \t]*\\(" c-current-comment-prefix "\\)[ \t]*")))
+    (setq paragraph-start (concat comment-line-prefix
+                                 c-append-paragraph-start
+                                 "\\|"
+                                 page-delimiter)
+         paragraph-separate (concat comment-line-prefix
+                                    c-append-paragraph-separate
+                                    "\\|"
+                                    page-delimiter)
+         paragraph-ignore-fill-prefix t
+         adaptive-fill-mode t
+         adaptive-fill-regexp
+         (concat comment-line-prefix
+                 (if adaptive-fill-regexp
+                     (concat "\\(" adaptive-fill-regexp "\\)")
+                   "")))
+    (when (boundp 'adaptive-fill-first-line-regexp)
+      ;; XEmacs (20.x) adaptive fill mode doesn't have this.
+      (make-local-variable 'adaptive-fill-first-line-regexp)
+      (setq adaptive-fill-first-line-regexp
+           (concat "\\`" comment-line-prefix
+                   ;; Maybe we should incorporate the old value here,
+                   ;; but then we have to do all sorts of kludges to
+                   ;; deal with the \` and \' it probably contains.
+                   "\\'"))))
+  ;; we have to do something special for c-offsets-alist so that the
+  ;; buffer local value has its own alist structure.
+  (setq c-offsets-alist (copy-alist c-offsets-alist))
+  ;; setup the comment indent variable in a Emacs version portable way
+  ;; ignore any byte compiler warnings you might get here
+  (make-local-variable 'comment-indent-function)
+  (setq comment-indent-function 'c-comment-indent)
+  ;; add menus to menubar
+  (easy-menu-add (c-mode-menu mode-name))
+  ;; put auto-hungry designators onto minor-mode-alist, but only once
+  (or (assq 'c-auto-hungry-string minor-mode-alist)
+      (setq minor-mode-alist
+           (cons '(c-auto-hungry-string c-auto-hungry-string)
+                 minor-mode-alist)))
+  )
+
+(defun c-postprocess-file-styles ()
+  "Function that post processes relevant file local variables.
+Currently, this function simply applies any style and offset settings
+found in the file's Local Variable list.  It first applies any style
+setting found in `c-file-style', then it applies any offset settings
+it finds in `c-file-offsets'.
+
+Note that the style variables are always made local to the buffer."
+  ;; apply file styles and offsets
+  (if (or c-file-style c-file-offsets)
+      (c-make-styles-buffer-local t))
+  (and c-file-style
+       (c-set-style c-file-style))
+  (and c-file-offsets
+       (mapcar
+       (function
+        (lambda (langentry)
+          (let ((langelem (car langentry))
+                (offset (cdr langentry)))
+            (c-set-offset langelem offset)
+            )))
+       c-file-offsets)))
+
+(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
+
+\f
+;; Support for C
+
+(defvar c-mode-abbrev-table nil
+  "Abbreviation table used in c-mode buffers.")
+(define-abbrev-table 'c-mode-abbrev-table
+  '(("else" "else" c-electric-continued-statement 0)
+    ("while" "while" c-electric-continued-statement 0)))
+
+(defvar c-mode-map ()
+  "Keymap used in c-mode buffers.")
+(if c-mode-map
+    nil
+  (setq c-mode-map (c-make-inherited-keymap))
+  ;; add bindings which are only useful for C
+  (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
+  )
+
+(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
+                 (c-mode-menu "C"))
+
 ;;;###autoload
 (defun c-mode ()
   "Major mode for editing K&R and ANSI C code.
@@ -162,11 +442,13 @@ Key bindings:
   (set-syntax-table c-mode-syntax-table)
   (setq major-mode 'c-mode
        mode-name "C"
-       local-abbrev-table c-mode-abbrev-table)
+       local-abbrev-table c-mode-abbrev-table
+       abbrev-mode t)
   (use-local-map c-mode-map)
   (c-common-init)
   (setq comment-start "/* "
        comment-end   " */"
+       c-keywords (c-identifier-re c-C-keywords)
        c-conditional-key c-C-conditional-key
        c-class-key c-C-class-key
        c-baseclass-key nil
@@ -179,6 +461,29 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Support for C++
+
+(defvar c++-mode-abbrev-table nil
+  "Abbreviation table used in c++-mode buffers.")
+(define-abbrev-table 'c++-mode-abbrev-table
+  '(("else" "else" c-electric-continued-statement 0)
+    ("while" "while" c-electric-continued-statement 0)
+    ("catch" "catch" c-electric-continued-statement 0)))
+
+(defvar c++-mode-map ()
+  "Keymap used in c++-mode buffers.")
+(if c++-mode-map
+    nil
+  (setq c++-mode-map (c-make-inherited-keymap))
+  ;; add bindings which are only useful for C++
+  (define-key c++-mode-map "\C-c\C-e" 'c-macro-expand)
+  (define-key c++-mode-map "\C-c:"    'c-scope-operator)
+  (define-key c++-mode-map "<"        'c-electric-lt-gt)
+  (define-key c++-mode-map ">"        'c-electric-lt-gt))
+
+(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
+                 (c-mode-menu "C++"))
+
 ;;;###autoload
 (defun c++-mode ()
   "Major mode for editing C++ code.
@@ -202,11 +507,13 @@ Key bindings:
   (set-syntax-table c++-mode-syntax-table)
   (setq major-mode 'c++-mode
        mode-name "C++"
-       local-abbrev-table c++-mode-abbrev-table)
+       local-abbrev-table c++-mode-abbrev-table
+       abbrev-mode t)
   (use-local-map c++-mode-map)
   (c-common-init)
   (setq comment-start "// "
        comment-end ""
+       c-keywords (c-identifier-re c-C++-keywords)
        c-conditional-key c-C++-conditional-key
        c-comment-start-regexp c-C++-comment-start-regexp
        c-class-key c-C++-class-key
@@ -221,6 +528,25 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Support for Objective-C
+
+(defvar objc-mode-abbrev-table nil
+  "Abbreviation table used in objc-mode buffers.")
+(define-abbrev-table 'objc-mode-abbrev-table
+  '(("else" "else" c-electric-continued-statement 0)
+    ("while" "while" c-electric-continued-statement 0)))
+
+(defvar objc-mode-map ()
+  "Keymap used in objc-mode buffers.")
+(if objc-mode-map
+    nil
+  (setq objc-mode-map (c-make-inherited-keymap))
+  ;; add bindings which are only useful for Objective-C
+  (define-key objc-mode-map "\C-c\C-e" 'c-macro-expand))
+
+(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
+                 (c-mode-menu "ObjC"))
+
 ;;;###autoload
 (defun objc-mode ()
   "Major mode for editing Objective C code.
@@ -244,11 +570,13 @@ Key bindings:
   (set-syntax-table objc-mode-syntax-table)
   (setq major-mode 'objc-mode
        mode-name "ObjC"
-       local-abbrev-table objc-mode-abbrev-table)
+       local-abbrev-table objc-mode-abbrev-table
+       abbrev-mode t)
   (use-local-map objc-mode-map)
   (c-common-init)
   (setq comment-start "// "
        comment-end   ""
+       c-keywords (c-identifier-re c-ObjC-keywords)
        c-conditional-key c-ObjC-conditional-key
        c-comment-start-regexp c-ObjC-comment-start-regexp
        c-class-key c-ObjC-class-key
@@ -262,6 +590,27 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Support for Java
+
+(defvar java-mode-abbrev-table nil
+  "Abbreviation table used in java-mode buffers.")
+(define-abbrev-table 'java-mode-abbrev-table
+  '(("else" "else" c-electric-continued-statement 0)
+    ("while" "while" c-electric-continued-statement 0)
+    ("catch" "catch" c-electric-continued-statement 0)
+    ("finally" "finally" c-electric-continued-statement 0)))
+
+(defvar java-mode-map ()
+  "Keymap used in java-mode buffers.")
+(if java-mode-map
+    nil
+  (setq java-mode-map (c-make-inherited-keymap))
+  ;; add bindings which are only useful for Java
+  )
+
+(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
+                 (c-mode-menu "Java"))
+
 ;;;###autoload
 (defun java-mode ()
   "Major mode for editing Java code.
@@ -288,18 +637,19 @@ Key bindings:
   (setq major-mode 'java-mode
        mode-name "Java"
        local-abbrev-table java-mode-abbrev-table
+       abbrev-mode t
        c-append-paragraph-start c-Java-javadoc-paragraph-start)
   (use-local-map java-mode-map)
   (c-common-init)
   (setq comment-start "// "
        comment-end   ""
+       c-keywords (c-identifier-re c-Java-keywords)
        c-conditional-key c-Java-conditional-key
        c-comment-start-regexp c-Java-comment-start-regexp
        c-class-key c-Java-class-key
        c-method-key nil
        c-baseclass-key nil
        c-recognize-knr-p nil
-       c-access-key c-Java-access-key
        c-inexpr-class-key c-Java-inexpr-class-key
        ;defun-prompt-regexp c-Java-defun-prompt-regexp
        )
@@ -309,6 +659,23 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Support for CORBA's IDL language
+
+(defvar idl-mode-abbrev-table nil
+  "Abbreviation table used in idl-mode buffers.")
+(define-abbrev-table 'idl-mode-abbrev-table ())
+
+(defvar idl-mode-map ()
+  "Keymap used in idl-mode buffers.")
+(if idl-mode-map
+    nil
+  (setq idl-mode-map (c-make-inherited-keymap))
+  ;; add bindings which are only useful for IDL
+  )
+
+(easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands"
+                 (c-mode-menu "IDL"))
+
 ;;;###autoload
 (defun idl-mode ()
   "Major mode for editing CORBA's IDL code.
@@ -337,13 +704,13 @@ Key bindings:
   (c-common-init)
   (setq comment-start "// "
        comment-end ""
+       c-keywords (c-identifier-re c-IDL-keywords)
        c-conditional-key c-IDL-conditional-key
        c-comment-start-regexp c-IDL-comment-start-regexp
        c-class-key c-IDL-class-key
        c-method-key nil
        c-baseclass-key nil
        c-extra-toplevel-key c-IDL-extra-toplevel-key
-       c-access-key c-IDL-access-key
        c-recognize-knr-p nil
        )
   ;;(cc-imenu-init cc-imenu-idl-generic-expression) ;FIXME
@@ -352,6 +719,25 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Support for Pike
+
+(defvar pike-mode-abbrev-table nil
+  "Abbreviation table used in pike-mode buffers.")
+(define-abbrev-table 'pike-mode-abbrev-table
+  '(("else" "else" c-electric-continued-statement 0)
+    ("while" "while" c-electric-continued-statement 0)))
+
+(defvar pike-mode-map ()
+  "Keymap used in pike-mode buffers.")
+(if pike-mode-map
+    nil
+  (setq pike-mode-map (c-make-inherited-keymap))
+  ;; additional bindings
+  (define-key pike-mode-map "\C-c\C-e" 'c-macro-expand))
+
+(easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands"
+                 (c-mode-menu "Pike"))
+
 ;;;###autoload
 (defun pike-mode ()
   "Major mode for editing Pike code.
@@ -375,18 +761,21 @@ Key bindings:
   (set-syntax-table pike-mode-syntax-table)
   (setq major-mode 'pike-mode
        mode-name "Pike"
-       local-abbrev-table pike-mode-abbrev-table)
+       local-abbrev-table pike-mode-abbrev-table
+       abbrev-mode t
+       c-append-paragraph-start c-Pike-pikedoc-paragraph-start
+       c-append-paragraph-separate c-Pike-pikedoc-paragraph-separate)
   (use-local-map pike-mode-map)
   (c-common-init)
   (setq comment-start "// "
        comment-end   ""
+       c-keywords (c-identifier-re c-Pike-keywords)
        c-conditional-key c-Pike-conditional-key
        c-comment-start-regexp c-Pike-comment-start-regexp
        c-class-key c-Pike-class-key
        c-method-key nil
        c-baseclass-key nil
        c-recognize-knr-p nil
-       c-access-key c-Pike-access-key
        c-lambda-key c-Pike-lambda-key
        c-inexpr-block-key c-Pike-inexpr-block-key
        c-inexpr-class-key c-Pike-inexpr-class-key
@@ -398,6 +787,12 @@ Key bindings:
   (c-update-modeline))
 
 \f
+;; Helper for setting up Filladapt mode.  It's not used by CC Mode itself.
+
+(cc-bytecomp-defvar filladapt-token-table)
+(cc-bytecomp-defvar filladapt-token-match-table)
+(cc-bytecomp-defvar filladapt-token-conversion-table)
+
 (defun c-setup-filladapt ()
   "Convenience function to configure Kyle E. Jones' Filladapt mode for
 CC Mode by making sure the proper entries are present on
@@ -415,10 +810,10 @@ CC Mode by making sure the proper entries are present on
     (while (and p (not (eq (car-safe (cdr-safe (car-safe p))) 'c-comment)))
       (setq p (cdr-safe p)))
     (if p
-       (setcar (car p) c-comment-prefix-regexp)
+       (setcar (car p) c-current-comment-prefix)
       (setq filladapt-token-table
            (append (list (car filladapt-token-table)
-                         (list c-comment-prefix-regexp 'c-comment))
+                         (list c-current-comment-prefix 'c-comment))
                    (cdr filladapt-token-table)))))
   (unless (assq 'c-comment filladapt-token-match-table)
     (setq filladapt-token-match-table
@@ -442,16 +837,20 @@ CC Mode by making sure the proper entries are present on
   (message "Using CC Mode version %s" c-version)
   (c-keep-region-active))
 
+(defvar c-prepare-bug-report-hooks nil)
+
+;; Dynamic variables used by reporter.
+(defvar reporter-prompt-for-summary-p)
+(defvar reporter-dont-compact-list)
+
 (defun c-submit-bug-report ()
   "Submit via mail a bug report on CC Mode."
   (interactive)
   (require 'reporter)
-  (require 'cc-vars)
   ;; load in reporter
   (let ((reporter-prompt-for-summary-p t)
        (reporter-dont-compact-list '(c-offsets-alist))
        (style c-indentation-style)
-       (hook c-special-indent-hook)
        (c-features c-emacs-features))
     (and
      (if (y-or-n-p "Do you want to submit a report on CC Mode? ")
@@ -500,12 +899,12 @@ CC Mode by making sure the proper entries are present on
        vars)
       (function
        (lambda ()
+        (run-hooks 'c-prepare-bug-report-hooks)
         (insert
          "Buffer Style: " style "\n\n"
          (format "c-emacs-features: %s\n" c-features)
-         )))
-      nil))))
+         )))))))
 
 \f
-(provide 'cc-mode)
+(cc-provide 'cc-mode)
 ;;; cc-mode.el ends here
index 3ce24cfa3bd790cdab2368f08ca3365fe8f9d341..68591f125c0d2c0a31dc791daa343d3df3dd2fb4 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-styles.el --- support for styles in CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'cc-vars)
+    (require 'cc-bytecomp)))
 
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
 
 \f
 ;; Warning: don't eval-defun this constant or you'll break style inheritance.
@@ -339,61 +339,6 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
   (and set-p (c-set-style style)))
 
 
-\f
-(defun c-evaluate-offset (offset langelem symbol)
-  ;; offset can be a number, a function, a variable, a list, or one of
-  ;; the symbols + or -
-  (cond
-   ((eq offset '+)         (setq offset c-basic-offset))
-   ((eq offset '-)         (setq offset (- c-basic-offset)))
-   ((eq offset '++)        (setq offset (* 2 c-basic-offset)))
-   ((eq offset '--)        (setq offset (* 2 (- c-basic-offset))))
-   ((eq offset '*)         (setq offset (/ c-basic-offset 2)))
-   ((eq offset '/)         (setq offset (/ (- c-basic-offset) 2)))
-   ((functionp offset)     (setq offset (funcall offset langelem)))
-   ((listp offset)
-    (setq offset
-         (let (done)
-           (while (and (not done) offset)
-             (setq done (c-evaluate-offset (car offset) langelem symbol)
-                   offset (cdr offset)))
-           (if (not done)
-               (if c-strict-syntax-p
-                   (error "No offset found for syntactic symbol %s" symbol)
-                 0)
-             done))))
-   ((not (numberp offset)) (setq offset (symbol-value offset)))
-   )
-  offset)
-
-(defun c-get-offset (langelem)
-  ;; Get offset from LANGELEM which is a cons cell of the form:
-  ;; (SYMBOL . RELPOS).  The symbol is matched against
-  ;; c-offsets-alist and the offset found there is either returned,
-  ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
-  ;; the offset is simply returned.
-  (let* ((symbol (car langelem))
-        (relpos (cdr langelem))
-        (match  (assq symbol c-offsets-alist))
-        (offset (cdr-safe match)))
-    (if (not match)
-       (if c-strict-syntax-p
-           (error "No offset found for syntactic symbol %s" symbol)
-         (setq offset 0
-               relpos 0))
-      (setq offset (c-evaluate-offset offset langelem symbol)))
-    (+ (if (and relpos
-               (< relpos (c-point 'bol)))
-          (save-excursion
-            (goto-char relpos)
-            (current-column))
-        0)
-       (or (and (numberp offset) offset)
-          (and (symbolp offset) (symbol-value offset))
-          0))
-    ))
-
-
 \f
 (defvar c-read-offset-history nil)
 
@@ -405,7 +350,7 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
                                                    'c-stylevar-fallback)))))
         (symname (symbol-name langelem))
         (defstr  (format "(default %s): " oldoff))
-        (errmsg  (concat "Offset must be int, func, var, list, "
+        (errmsg  (concat "Offset must be int, func, var, vector, list, "
                          "or [+,-,++,--,*,/] "
                          defstr))
         (prompt (concat symname " offset " defstr))
@@ -425,11 +370,14 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
                         ;; a symbol with a function binding
                         ((fboundp (setq interned (intern input)))
                          interned)
-                        ;; a lambda function
-                        ((c-safe (functionp (setq raw (read input))))
-                         raw)
                         ;; a symbol with variable binding
                         ((boundp interned) interned)
+                        ;; a lambda function or a vector
+                        ((progn
+                           (c-safe (setq raw (read input)))
+                           (or (functionp raw)
+                               (vectorp raw)))
+                         raw)
                         ;; error, but don't signal one, keep trying
                         ;; to read an input value
                         (t (ding)
@@ -466,7 +414,8 @@ and exists only for compatibility reasons."
      (list langelem offset current-prefix-arg)))
   ;; sanity check offset
   (unless (c-valid-offset offset)
-    (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
+    (error (concat "Offset must be int, func, var, vector, list, "
+                  "or in [+,-,++,--,*,/]: %s")
           offset))
   (let ((entry (assq symbol c-offsets-alist)))
     (if entry
@@ -485,7 +434,7 @@ and exists only for compatibility reasons."
   ;; style.  Only do this once!
   (unless (get 'c-initialize-builtin-style 'is-run)
     (put 'c-initialize-builtin-style 'is-run t)
-    (c-initialize-cc-mode)
+    ;;(c-initialize-cc-mode)
     (or (assoc "cc-mode" c-style-alist)
        (assoc "user" c-style-alist)
        (progn
@@ -550,5 +499,5 @@ instead of `make-variable-buffer-local'."
 
 
 \f
-(provide 'cc-styles)
+(cc-provide 'cc-styles)
 ;;; cc-styles.el ends here
index e7f84f491106a5b567c5443f077da1543a03c366..ec4a729b7b3fe6072bf0df9b94f27bdbca39d863 100644 (file)
@@ -1,6 +1,6 @@
 ;;; cc-vars.el --- user customization variables for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
 ;; Authors:    2000- Martin Stjernholm
 ;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
   (let ((load-path
-        (if (and (boundp 'byte-compile-current-file)
-                 (stringp byte-compile-current-file))
-            (cons (file-name-directory byte-compile-current-file)
-                  load-path)
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
-    (load "cc-defs" nil t)))
-(require 'custom)
-
+    (require 'cc-bytecomp)))
+
+(cc-require 'cc-defs)
+
+;; Silence the compiler.
+(cc-bytecomp-defun get-char-table)     ; XEmacs 20+
+(cc-bytecomp-defun char-table-range)   ; Emacs 19+
+(cc-bytecomp-defun char-table-p)       ; Emacs 19+, XEmacs 20+
+
+;; Pull in custom if it exists and is recent enough (the one in Emacs
+;; 19.34 isn't).
+(eval
+ (cc-eval-when-compile
+   (condition-case nil
+       (progn
+        (require 'custom)
+        (or (fboundp 'defcustom) (error ""))
+        (require 'wid-edit)
+        '(progn                        ; Compile in the require's.
+           (require 'custom)
+           (require 'wid-edit)))
+     (error
+      (message "Warning: Compiling without Customize support \
+since a (good enough) custom library wasn't found")
+      (cc-bytecomp-defmacro define-widget (name class doc &rest args))
+      (cc-bytecomp-defmacro defcustom (symbol value doc &rest args)
+       `(defvar ,symbol ,value ,doc))
+      nil))))
 
 \f
 ;;; Helpers
@@ -84,11 +108,8 @@ Useful as last item in a `choice' widget."
 
 (defmacro defcustom-c-stylevar (name val doc &rest args)
   "Defines a style variable."
-  (setq val (if (eq (car-safe val) 'quote)
-               (nth 1 val)
-             (eval val)))
   `(progn
-     (put ',name 'c-stylevar-fallback ',val)
+     (put ',name 'c-stylevar-fallback ,val)
      (defcustom ,name 'set-from-style
        ,(concat doc "
 
@@ -124,6 +145,7 @@ See `c-offsets-alist'."
       (eq offset '*)
       (eq offset '/)
       (integerp offset)
+      (vectorp offset)
       (functionp offset)
       (and (symbolp offset)
           (or (boundp offset)
@@ -195,7 +217,7 @@ should be inserted.  Value must be a function taking no arguments."
   :group 'c)
 
 (defcustom c-syntactic-indentation t
-  "*Whether the identation should be controlled by the syntactic context.
+  "*Whether the indentation should be controlled by the syntactic context.
 
 If t, the indentation functions indents according to the syntactic
 context, using the style settings specified by `c-offsets-alist'.
@@ -240,6 +262,15 @@ comment-only lines."
   :type 'boolean
   :group 'c)
 
+(make-obsolete-variable 'c-comment-continuation-stars
+                       'c-block-comment-prefix)
+
+;; Although c-comment-continuation-stars is obsolete, we look at it in
+;; some places in CC Mode anyway, so make the compiler ignore it
+;; during our compilation.
+(cc-bytecomp-obsolete-var c-comment-continuation-stars)
+(cc-bytecomp-defvar c-comment-continuation-stars)
+
 (defcustom-c-stylevar c-block-comment-prefix
   (if (boundp 'c-comment-continuation-stars)
       c-comment-continuation-stars
@@ -259,25 +290,50 @@ style comments."
   :type 'string
   :group 'c)
 
-(make-obsolete-variable 'c-comment-continuation-stars
-                       'c-block-comment-prefix)
-
-(defcustom-c-stylevar c-comment-prefix-regexp "//+\\|\\**"
+(defcustom-c-stylevar c-comment-prefix-regexp
+  '((pike-mode . "//+!?\\|\\**")
+    (other . "//+\\|\\**"))
   "*Regexp to match the line prefix inside comments.
 This regexp is used to recognize the fill prefix inside comments for
 correct paragraph filling and other things.
 
-It should match the prefix used in both C++ style line comments and C
-style block comments, but it does not need to match a block comment
-starter.  In other words, it should at least match \"//\" for line
-comments and the string in `c-block-comment-prefix', which is
-sometimes inserted by CC Mode inside block comments.  It should not
-match any surrounding whitespace.
+If this variable is a string, it will be used in all CC Mode major
+modes.  It can also be an association list, to associate specific
+regexps to specific major modes.  The symbol for the major mode is
+looked up in the association list, and its value is used as the line
+prefix regexp.  If it's not found, then the symbol `other' is looked
+up and its value is used instead.
+
+The regexp should match the prefix used in both C++ style line
+comments and C style block comments, but it does not need to match a
+block comment starter.  In other words, it should at least match
+\"//\" for line comments and the string in `c-block-comment-prefix',
+which is sometimes inserted by CC Mode inside block comments.  It
+should not match any surrounding whitespace.
 
 Note that CC Mode modifies other variables from this one at mode
-initialization, so you might need to do \\[c-mode] (or whatever mode
+initialization, so you will need to do \\[c-mode] (or whatever mode
 you're currently using) if you change it in a CC Mode buffer."
-  :type 'regexp
+  :type '(radio
+         (regexp :tag "Regexp for all modes")
+         (list
+          :tag "Mode-specific regexps"
+          (set
+           :inline t :format "%v"
+           (cons :format "%v"
+                 (const :format "C     " c-mode) (regexp :format "%v"))
+           (cons :format "%v"
+                 (const :format "C++   " c++-mode) (regexp :format "%v"))
+           (cons :format "%v"
+                 (const :format "ObjC  " objc-mode) (regexp :format "%v"))
+           (cons :format "%v"
+                 (const :format "Java  " java-mode) (regexp :format "%v"))
+           (cons :format "%v"
+                 (const :format "IDL   " idl-mode) (regexp :format "%v"))
+           (cons :format "%v"
+                 (const :format "Pike  " pike-mode) (regexp :format "%v")))
+          (cons :format "    %v"
+                (const :format "Other " other) (regexp :format "%v"))))
   :group 'c)
 
 (defcustom c-ignore-auto-fill '(string cpp code)
@@ -303,47 +359,74 @@ contexts are:
 
 (defcustom-c-stylevar c-cleanup-list '(scope-operator)
   "*List of various C/C++/ObjC constructs to \"clean up\".
-These clean ups only take place when the auto-newline feature is
-turned on, as evidenced by the `/a' or `/ah' appearing next to the
-mode name.  Valid symbols are:
+The following clean ups only take place when the auto-newline feature
+is turned on, as evidenced by the `/a' or `/ah' appearing next to the
+mode name:
 
- brace-else-brace    -- cleans up `} else {' constructs by placing entire
-                        construct on a single line.  This clean up
-                        only takes place when there is nothing but
+ brace-else-brace    -- Clean up \"} else {\" constructs by placing
+                        entire construct on a single line.  This clean
+                        up only takes place when there is nothing but
                         white space between the braces and the `else'.
                         Clean up occurs when the open brace after the
                         `else' is typed.
- brace-elseif-brace  -- similar to brace-else-brace, but cleans up
-                        `} else if (...) {' constructs.  Clean up occurs
-                        after the open parenthesis and the open brace.
- brace-catch-brace   -- similar to brace-elseif-brace, but cleans up
-                        `} catch (...) {' constructs.
- empty-defun-braces  -- cleans up empty defun braces by placing the
+ brace-elseif-brace  -- Similar to brace-else-brace, but clean up
+                        \"} else if (...) {\" constructs.  Clean up
+                        occurs after the open parenthesis and the open
+                        brace.
+ brace-catch-brace   -- Similar to brace-elseif-brace, but clean up
+                        \"} catch (...) {\" constructs.
+ empty-defun-braces  -- Clean up empty defun braces by placing the
                         braces on the same line.  Clean up occurs when
                        the defun closing brace is typed.
- defun-close-semi    -- cleans up the terminating semi-colon on defuns
+ defun-close-semi    -- Clean up the terminating semi-colon on defuns
                        by placing the semi-colon on the same line as
                        the closing brace.  Clean up occurs when the
                        semi-colon is typed.
- list-close-comma    -- cleans up commas following braces in array
+ list-close-comma    -- Clean up commas following braces in array
                         and aggregate initializers.  Clean up occurs
                        when the comma is typed.
- scope-operator      -- cleans up double colons which may designate
+ scope-operator      -- Clean up double colons which may designate
                        a C++ scope operator split across multiple
-                       lines. Note that certain C++ constructs can
+                       lines.  Note that certain C++ constructs can
                        generate ambiguous situations.  This clean up
                        only takes place when there is nothing but
-                       whitespace between colons. Clean up occurs
-                       when the second colon is typed."
+                       whitespace between colons.  Clean up occurs
+                       when the second colon is typed.
+
+The following clean ups always take place when they are on this list,
+regardless of the auto-newline feature, since they typically don't
+involve auto-newline inserted newlines:
+
+ space-before-funcall -- Insert exactly one space before the opening
+                        parenthesis of a function call.  Clean up
+                        occurs when the opening parenthesis is typed.
+ compact-empty-funcall -- Clean up any space before the function call
+                       opening parenthesis if and only if the
+                        argument list is empty.  This is typically
+                        useful together with `space-before-funcall' to
+                        get the style \"foo (bar)\" and \"foo()\".
+                        Clean up occurs when the closing parenthesis
+                        is typed."
   :type '(set
          :extra-offset 8
-         (const :tag "Put `} else {' on one line" brace-else-brace)
-         (const :tag "Put `} else if (...) {' on one line" brace-elseif-brace)
-         (const :tag "Put `} catch (...) {' on one line" brace-catch-brace)
-         (const :tag "Put empty defun braces on one line" empty-defun-braces)
-         (const :tag "Put `};' ending defuns on one line" defun-close-semi)
-         (const :tag "Put `},' in aggregates on one line" list-close-comma)
-         (const :tag "Put C++ style `::' on one line" scope-operator))
+         (const :tag "Put \"} else {\" on one line"
+                brace-else-brace)
+         (const :tag "Put \"} else if (...) {\" on one line"
+                brace-elseif-brace)
+         (const :tag "Put \"} catch (...) {\" on one line"
+                brace-catch-brace)
+         (const :tag "Put empty defun braces on one line"
+                empty-defun-braces)
+         (const :tag "Put \"};\" ending defuns on one line"
+                defun-close-semi)
+         (const :tag "Put \"},\" in aggregates on one line"
+                list-close-comma)
+         (const :tag "Put C++ style \"::\" on one line"
+                scope-operator)
+         (const :tag "Put a space before funcall parens, e.g. \"foo (bar)\""
+                space-before-funcall)
+         (const :tag "Remove space before empty funcalls, e.g. \"foo()\""
+                compact-empty-funcall))
   :group 'c)
 
 (defcustom-c-stylevar c-hanging-braces-alist '((brace-list-open)
@@ -500,7 +583,7 @@ this variable to nil."
   :type 'integer
   :group 'c)
 
-(defcustom c-default-style "gnu"
+(defcustom c-default-style '((java-mode . "java") (other . "gnu"))
   "*Style which gets installed by default when a file is visited.
 
 The value of this variable can be any style defined in
@@ -508,8 +591,7 @@ The value of this variable can be any style defined in
 association list of major mode symbols to style names.
 
 When the value is a string, all CC Mode major modes will install this
-style by default, except `java-mode', which always installs the
-\"java\" style (this is for backwards compatibility).
+style by default.
 
 When the value is an alist, the major mode symbol is looked up in it
 and the associated style is installed.  If the major mode is not
@@ -519,22 +601,24 @@ the alist, then \"gnu\" style is used.
 
 The default style gets installed before your mode hooks run, so you
 can always override the use of `c-default-style' by making calls to
-`c-set-style' in the appropriate mode hook.
-
-Tip: If you use different styles in different languages, you probably
-want to set `c-style-variables-are-local-p'."
+`c-set-style' in the appropriate mode hook."
   :type '(radio
-         (string :tag "Style in all modes (except Java)")
-         (repeat :tag "Mode-specific styles"
-                 :value ((other . "gnu"))
-                 (cons :format "%v"
-                       (choice :tag "Mode"
-                               (const c-mode) (const c++-mode)
-                               (const objc-mode) (const java-mode)
-                               (const idl-mode) (const pike-mode)
-                               (const other))
-                       (string :tag "Style")
-                       )))
+         (string :tag "Style in all modes")
+         (set :tag "Mode-specific styles"
+           (cons :format "%v"
+                 (const :format "C     " c-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "C++   " c++-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "ObjC  " objc-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "Java  " java-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "IDL   " idl-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "Pike  " pike-mode) (string :format "%v"))
+           (cons :format "%v"
+                 (const :format "Other " other) (string :format "%v"))))
   :group 'c)
 
 (put 'c-offsets-alist 'c-stylevar-fallback
@@ -660,13 +744,13 @@ want to set `c-style-variables-are-local-p'."
        (inclass               . +)
        ;; Relpos: At the class open brace if it's at boi, otherwise
        ;; boi at the class decl start.
-       (cpp-macro             . -1000)
+       (cpp-macro             . [0])
        ;; Relpos: None.
        (cpp-macro-cont        . c-lineup-dont-change)
        ;; Relpos: At the macro start (always at boi).
        (friend                . 0)
        ;; Relpos: None.
-       (objc-method-intro     . -1000)
+       (objc-method-intro     . [0])
        ;; Relpos: Boi.
        (objc-method-args-cont . c-lineup-ObjC-method-args)
        ;; Relpos: At the method start (always at boi).
@@ -722,23 +806,33 @@ The sum of this calculation for each element in the syntactic list is
 the absolute offset for line being indented.
 
 If the syntactic element does not match any in the `c-offsets-alist',
-an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
-element is ignored.
-
-Actually, OFFSET can be an integer, a function, a variable, or one of
-the following symbols: `+', `-', `++', `--', `*', or `/'.  These
-latter designate positive or negative multiples of `c-basic-offset',
-respectively: 1, -1, 2, -2, 0.5, and -0.5.  If OFFSET is a function,
-it is called with a single argument containing the cons of the
-syntactic element symbol and the relative indent point.  The function
-should return an integer offset or nil if it can't decide.
-
-OFFSET can also be a list, in which case it is recursively evaluated
-using the semantics described above.  The first element of the list to 
-return a non-nil value succeeds.  If none of the elements returns a
-non-nil value, then what happends depends on the value of
-`c-strict-syntax-p'.  When `c-strict-syntax-p' is nil, then an offset
-of zero is used, otherwise an error is generated.
+the element is ignored.
+
+If OFFSET is nil, the syntactic element is ignored in the offset
+calculation.
+
+If OFFSET is an integer, it's added to the relative indent.
+
+If OFFSET is one of the symbols `+', `-', `++', `--', `*', or `/', a
+positive or negative multiple of `c-basic-offset' is added; 1, -1, 2,
+-2, 0.5, and -0.5, respectively.
+
+If OFFSET is a vector, it's first element, which must be an integer,
+is used as an absolute indentation column.  This overrides all
+relative offsets.  If there are several syntactic elements which
+evaluates to absolute indentation columns, the first one takes
+precedence.  You can see in which order CC Mode combines the syntactic
+elements in a certain context by using \\[c-show-syntactic-information] on the line.
+
+If OFFSET is a function, it's called with a single argument
+containing the cons of the syntactic element symbol and the relative
+indent point.  The return value from the function is then
+reinterpreted as an OFFSET value.
+
+If OFFSET is a list, it's recursively evaluated using the semantics
+described above.  The first element of the list to return a non-nil
+value succeeds.  If none of the elements returns a non-nil value, the
+syntactic element is ignored.
 
 `c-offsets-alist' is a style variable.  This means that the offsets on
 this variable are normally taken from the style system in CC Mode
@@ -962,11 +1056,18 @@ as designated in the variable `c-file-style'.")
 (make-variable-buffer-local 'c-file-offsets)
 
 (defvar c-syntactic-context nil
-  "Variable containing syntactic analysis list during indentation.")
+  "Variable containing syntactic analysis list during indentation.
+This is always bound dynamically.  It should never be set statically
+(e.g. with `setq').")
 
 (defvar c-indentation-style nil
-  "Name of the currently installed style.")
+  "Name of the currently installed style.
+Don't change this directly; call `c-set-style' instead.")
 
+(defvar c-current-comment-prefix nil
+  "The current comment prefix regexp.
+Set from `c-comment-prefix-regexp' at mode initialization.")
+(make-variable-buffer-local 'c-current-comment-prefix)
 
 \f
 ;; Figure out what features this Emacs has
@@ -1011,7 +1112,6 @@ supported list, along with the values for this variable:
 Infodock (based on XEmacs) has an additional symbol on this list:
 `infodock'.")
 
-
 \f
-(provide 'cc-vars)
+(cc-provide 'cc-vars)
 ;;; cc-vars.el ends here