]> code.delx.au - gnu-emacs/commitdiff
Installed version 5.26
authorGerd Moellmann <gerd@gnu.org>
Sun, 12 Dec 1999 18:24:19 +0000 (18:24 +0000)
committerGerd Moellmann <gerd@gnu.org>
Sun, 12 Dec 1999 18:24:19 +0000 (18:24 +0000)
lisp/progmodes/cc-align.el
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 c051172ce9661f7564dace5fc4fd40fe5d0e08c8..9244d6e471498c031d31ebbc9192778e1e871bb6 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-align.el --- custom indentation functions for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
-  (require 'cc-defs)
-  (require 'cc-vars)
-  (require 'cc-engine)
-  (require 'cc-langs))
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-engine)
 
 \f
 ;; Standard indentation line-ups
+
 (defun c-lineup-arglist (langelem)
-  ;; lineup the current arglist line with the arglist appearing just
-  ;; after the containing paren which starts the arglist.
+  "Line up the current argument line under the first argument.
+
+Works with: arglist-cont-nonempty."
   (save-excursion
     (let* ((containing-sexp
            (save-excursion
@@ -65,7 +71,7 @@
                 (- (current-column) langelem-col))
        (goto-char containing-sexp)
        (or (eolp)
-           (not (memq (char-after) '(?{ ?\( )))
+           (not (memq (char-after) '(?{ ?\( ?\[)))
            (let ((eol (c-point 'eol))
                  (here (progn
                          (forward-char 1)
        ))))
 
 (defun c-lineup-arglist-intro-after-paren (langelem)
-  ;; lineup an arglist-intro line to just after the open paren
+  "Line up a line just after the open paren of the surrounding paren or
+brace block.
+
+Works with: defun-block-intro, brace-list-intro,
+statement-block-intro, statement-case-intro, arglist-intro."
   (save-excursion
     (let ((langelem-col (c-langelem-col langelem t))
          (ce-curcol (save-excursion
       (- ce-curcol langelem-col -1))))
 
 (defun c-lineup-arglist-close-under-paren (langelem)
-  ;; lineup an arglist-close line under the corresponding open paren
+  "Line up a closing paren line under the corresponding open paren.
+
+Works with: defun-close, class-close, inline-close, block-close,
+brace-list-close, arglist-close, extern-lang-close, namespace-close
+\(for most of these, a zero offset will normally produce the same
+result, though)."
   (save-excursion
     (let ((langelem-col (c-langelem-col langelem t))
          (ce-curcol (save-excursion
       (- ce-curcol langelem-col))))
 
 (defun c-lineup-close-paren (langelem)
-  ;; Indents the closing paren under its corresponding open paren if
-  ;; the open paren is followed by code.  If the open paren ends its
-  ;; line, no indentation is added.  E.g:
-  ;;
-  ;; main (int,                main (
-  ;;       char **               int, char **
-  ;;      )            <->     )              <- c-lineup-close-paren
-  ;;
-  ;; Works with any type of paren.
+  "Line up the closing paren under its corresponding open paren if the
+open paren is followed by code.  If the open paren ends its line, no
+indentation is added.  E.g:
+
+main (int,              main (
+      char **               int, char **
+     )           <->    )                 <- c-lineup-close-paren
+
+Works with: defun-close, class-close, inline-close, block-close,
+brace-list-close, arglist-close, extern-lang-close, namespace-close."
   (save-excursion
     (condition-case nil
        (let (opencol spec)
          (if (eolp)
              0
            (- opencol (c-langelem-col langelem t))))
-      (error 0))))
+      (error nil))))
 
 (defun c-lineup-streamop (langelem)
-  ;; lineup stream operators
+  "Line up C++ stream operators under each other.
+
+Works with: stream-op."
   (save-excursion
     (let ((langelem-col (c-langelem-col langelem)))
       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
       (- (current-column) langelem-col))))
 
 (defun c-lineup-multi-inher (langelem)
-  ;; line up multiple inheritance lines
+  "Line up the classes in C++ multiple inheritance clauses under each other.
+
+Works with: inher-cont."
   (save-excursion
     (let ((eol (c-point 'eol))
          (here (point))
       )))
 
 (defun c-lineup-java-inher (langelem)
-  ;; line up Java implements and extends continuations
+  "Line up Java implements and extends declarations.
+If class names follows on the same line as the implements/extends
+keyword, they are lined up under each other.  Otherwise, they are
+indented by adding `c-basic-offset' to the column of the keyword.
+E.g:
+
+class Foo             class Foo
+    extends               extends Cyphr,
+        Bar    <->                Bar     <- c-lineup-java-inher
+    <--> c-basic-offset
+
+Works with: inher-cont."
   (save-excursion
     (let ((langelem-col (c-langelem-col langelem)))
       (forward-word 1)
       (if (looking-at "[ \t]*$")
-         langelem-col
+         c-basic-offset
        (c-forward-syntactic-ws)
        (- (current-column) langelem-col)))))
 
 (defun c-lineup-java-throws (langelem)
-  ;; lineup func-decl-cont's in Java which are continuations of throws
-  ;; declarations.  If `throws' starts the previous line, line up to
-  ;; just after that keyword.  If not, lineup under the previous line.
+  "Line up Java throws declarations.
+If exception names follows on the same line as the throws keyword,
+they are lined up under each other.  Otherwise, they are indented by
+adding `c-basic-offset' to the column of the throws keyword.  The
+throws keyword itself is also indented by `c-basic-offset' from the
+function declaration start if it doesn't hang.  E.g:
+
+int foo()           int foo() throws Cyphr,
+    throws     <->                   Bar,    <- c-lineup-java-throws
+        Bar    <->                   Vlod    <- c-lineup-java-throws
+<--><--> c-basic-offset
+
+Works with: func-decl-cont."
   (save-excursion
-    (let ((iopl (c-point 'iopl))
-         (langelem-col (c-langelem-col langelem t))
-         (extra 0))
-      (back-to-indentation)
-      (cond
-       ((looking-at "throws[ \t\n]")
-       (goto-char (cdr langelem))
-       (setq extra c-basic-offset))
-       ((and (goto-char iopl)
-            (looking-at "throws[ \t\n]"))
-       (forward-word 1)
-       (skip-chars-forward " \t")
-       (if (eolp)
-           (progn
-             (back-to-indentation)
-             (setq extra c-basic-offset))))
-       (t (goto-char iopl)))
-      (+ (- (current-column) langelem-col) extra))))
+    (let* ((lim (1- (c-point 'bol)))
+          (throws (catch 'done
+                    (goto-char (cdr langelem))
+                    (while (zerop (c-forward-token-1 1 t lim))
+                      (if (looking-at "throws\\>[^_]")
+                          (throw 'done t))))))
+      (if throws
+         (if (zerop (c-forward-token-1 1 nil (c-point 'eol)))
+             (- (current-column) (c-langelem-col langelem))
+           (back-to-indentation)
+           (+ (- (current-column) (c-langelem-col langelem))
+              c-basic-offset))
+       c-basic-offset))))
 
 (defun c-indent-one-line-block (langelem)
-  ;; Adds c-basic-offset to the indentation if the line is a one line
-  ;; block, otherwise 0.  E.g:
-  ;;
-  ;; if (n)                     if (n)
-  ;;   {m+=n; n=0;}     <->     {            <- c-indent-one-line-block
-  ;;                              m+=n; n=0;
-  ;;                            }
+  "Indent a one line block `c-basic-offset' extra.
+E.g:
+
+if (n > 0)                 if (n > 0)
+    {m+=n; n=0;}    <->    {               <- c-indent-one-line-block
+<--> 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.
+
+Work with: Almost all syntactic symbols, but most useful on *-open."
   (save-excursion
-    (let ((eol (progn (end-of-line) (point))))
-      (beginning-of-line)
-      (skip-chars-forward " \t")
-      (if (and (eq (following-char) ?{)
+    (let ((eol (c-point 'eol)))
+      (back-to-indentation)
+      (if (and (eq (char-syntax (char-after)) ?\()
               (c-safe (progn (c-forward-sexp) t))
-              (<= (point) eol)
-              (eq (preceding-char) ?}))
+              (<= (point) eol))
          c-basic-offset
-       0))))
+       nil))))
 
-(defun c-lineup-C-comments (langelem)
-  ;; line up C block comment continuation lines
+(defun c-indent-multi-line-block (langelem)
+  "Indent a multi line block `c-basic-offset' extra.
+E.g:
+
+int *foo[] = {           int *foo[] = {
+    NULL,                    NULL,
+    {17},         <->            {       <- c-indent-multi-line-block
+                                 17
+                                 }
+                             <--> 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.
+
+Work with: Almost all syntactic symbols, but most useful on *-open."
   (save-excursion
-    (let ((here (point))
-         (stars (progn (back-to-indentation)
-                       (skip-chars-forward "*")))
-         (langelem-col (c-langelem-col langelem)))
+    (let ((eol (c-point 'eol)))
       (back-to-indentation)
-      (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
-         (progn
-           (if (not (looking-at "[*]+"))
+      (if (and (eq (char-syntax (char-after)) ?\()
+              (or (not (c-safe (progn (c-forward-sexp) t)))
+                  (> (point) eol)))
+         c-basic-offset
+       nil))))
+
+(defun c-lineup-C-comments (langelem)
+  "Line up C block comment continuation lines.
+Various heuristics are used to handle most of the common comment
+styles.  Some examples:
+
+/*          /**         /*         /* text      /*          /**
+ * text      * text       text        text      ** text      ** text
+ */          */         */         */           */           */
+
+/*********************************************************************
+ * text
+ ********************************************************************/
+
+/*********************************************************************
+    Free form text comments:
+ In comments with a long delimiter line at the start, the indentation
+ is kept unchanged for lines that start with an empty comment line
+ prefix.  The delimiter line is whatever matches the
+ `comment-start-skip' regexp.
+*********************************************************************/
+
+The variable `c-comment-prefix-regexp' is used to recognize the
+comment line prefix, e.g. the `*' that usually starts every line
+inside a comment.
+
+Works with: The `c' syntactic symbol."
+  (save-excursion
+    (let* ((here (point))
+          (prefixlen (progn (back-to-indentation)
+                            (if (looking-at c-comment-prefix-regexp)
+                                (- (match-end 0) (point))
+                              0)))
+          (starterlen (save-excursion
+                        (goto-char (cdr langelem))
+                        (looking-at comment-start-skip)
+                        (- (save-excursion
+                             (goto-char (match-end 0))
+                             (skip-chars-backward " \t")
+                             (point))
+                           (or (match-end 1) (point))
+                           1)))        ; Don't count the first '/'.
+          (langelem-col (save-excursion (c-langelem-col langelem))))
+      (if (and (> starterlen 10) (zerop prefixlen))
+         ;; The comment has a long starter and the line doesn't have
+         ;; a nonempty comment prefix.  Treat it as free form text
+         ;; and don't change the indentation.
+         (- (current-column) langelem-col)
+       (forward-line -1)
+       (back-to-indentation)
+       (if (>= (cdr langelem) (point))
+           ;; On the second line in the comment.
+           (if (zerop prefixlen)
+               ;; No nonempty comment prefix. Align after comment
+               ;; starter.
                (progn
-                 ;; we now have to figure out where this comment begins.
-                 (goto-char here)
-                 (back-to-indentation)
-                 (if (looking-at "[*]+/")
-                     (progn (goto-char (match-end 0))
-                            (forward-comment -1))
+                 (goto-char (match-end 0))
+                 (if (looking-at "\\([ \t]+\\).+$")
+                     ;; Align with the text that hangs after the
+                     ;; comment starter.
+                     (goto-char (match-end 1)))
+                 (- (current-column) langelem-col))
+             ;; How long is the comment starter?  if greater than the
+             ;; length of the comment prefix, align left.  if less
+             ;; than or equal, align right.  this should also pick up
+             ;; Javadoc style comments.
+             (if (> starterlen prefixlen)
+                 (progn
                    (goto-char (cdr langelem))
-                   (back-to-indentation))))
-           (- (current-column) langelem-col))
-       (if (zerop stars)
-           (progn
-             (skip-chars-forward " \t")
-             (- (current-column) langelem-col))
-         ;; how many stars on comment opening line?  if greater than
-         ;; on current line, align left.  if less than or equal,
-         ;; align right.  this should also pick up Javadoc style
-         ;; comments.
-         (if (> (length (match-string 1)) stars)
-             (progn
-               (back-to-indentation)
-               (- (current-column) -1 langelem-col))
-           (- (current-column) stars langelem-col))
-         )))))
+                   (- (current-column) -1 langelem-col))
+               (goto-char (match-end 0))
+               (skip-chars-backward " \t")
+               (- (current-column) prefixlen langelem-col)))
+         ;; Not on the second line in the comment.  If the previous
+         ;; 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))
+                   (eq (match-beginning 0) (match-end 0)))
+           (goto-char here)
+           (back-to-indentation)
+           (if (looking-at (concat "\\(" c-comment-prefix-regexp "\\)\\*/"))
+               (goto-char (cdr langelem))
+             (while (and (zerop (forward-line -1))
+                         (looking-at "^[ \t]*$")))
+             (back-to-indentation)
+             (if (< (point) (cdr langelem))
+                 ;; Align with the comment starter rather than
+                 ;; with the code before it.
+                 (goto-char (cdr langelem)))))
+         (- (current-column) langelem-col))))))
 
 (defun c-lineup-comment (langelem)
-  ;; support old behavior for comment indentation. we look at
-  ;; c-comment-only-line-offset to decide how to indent comment
-  ;; only-lines
+  "Line up a comment start according to `c-comment-only-line-offset'.
+If the comment is lined up with a comment starter on the previous
+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)))
+    (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag))
+         (col (current-column)))
       (cond
-       ;; CASE 1: preserve comment-column
        (recurse-prevention-flag 0)
-       ((= (current-column) comment-column)
+       ;; CASE 1: preserve aligned comments
+       ((save-excursion
+         (and (c-forward-comment -1)
+              (= col (current-column))))
        ;; we have to subtract out all other indentation
-       (- comment-column (apply '+ (mapcar 'c-get-offset
-                                           c-syntactic-context))))
+       (- col (apply '+ (mapcar 'c-get-offset
+                                c-syntactic-context))))
        ;; indent as specified by c-comment-only-line-offset
        ((not (bolp))
        (or (car-safe c-comment-only-line-offset)
        ))))
 
 (defun c-lineup-runin-statements (langelem)
-  ;; line up statements in coding standards which place the first
-  ;; statement on the same line as the block opening brace.
+  "Line up statements when the first statement is on the same line as
+the block opening brace.  E.g:
+
+int main()
+{ puts (\"Hello world!\");
+  return 0;                 <- c-lineup-runin-statements
+}
+
+If there is no statement after the opening brace to align with, nil is
+returned.  This makes the function usable in list expressions.
+
+Works with: The `statement' syntactic symbol."
   (if (eq (char-after (cdr langelem)) ?{)
       (save-excursion
        (let ((langelem-col (c-langelem-col langelem)))
          (forward-char 1)
          (skip-chars-forward " \t")
-         (- (current-column) langelem-col)))
-    0))
+         (unless (eolp)
+           (- (current-column) langelem-col))))))
 
 (defun c-lineup-math (langelem)
-  ;; line up math statement-cont after the equals
+  "Line up the current line after the equal sign on the first line in
+the statement.  If there isn't any, indent with `c-basic-offset'.  If
+the current line contains an equal sign too, try to align it with the
+first one.
+
+Works with: statement-cont."
   (save-excursion
     (let ((equalp (save-excursion
                    (goto-char (c-point 'boi))
        (- (current-column) equalp langelem-col))
       )))
 
+(defun c-lineup-template-args (langelem)
+  "Line up template argument lines under the first argument.
+To allow this function to be used in a list expression, nil is
+returned if there's no template argument on the first line.
+
+Works with: template-args-cont."
+  (save-excursion
+    (c-with-syntax-table c++-template-syntax-table
+      (beginning-of-line)
+      (backward-up-list 1)
+      (if (and (eq (char-after) ?<)
+              (zerop (c-forward-token-1 1 nil (c-point 'eol))))
+         (- (current-column) (c-langelem-col langelem))))))
+
 (defun c-lineup-ObjC-method-call (langelem)
-  ;; Line up methods args as elisp-mode does with function args: go to
-  ;; the position right after the message receiver, and if you are at
-  ;; (eolp) indent the current line by a constant offset from the
-  ;; opening bracket; otherwise we are looking at the first character
-  ;; of the first method call argument, so lineup the current line
-  ;; with it.
+  "Line up selector args as elisp-mode does with function args:
+Go to the position right after the message receiver, and if you are at
+the end of the line, indent the current line c-basic-offset columns
+from the opening bracket; otherwise you are looking at the first
+character of the first method call argument, so lineup the current
+line with it.
+
+Works with: objc-method-call-cont."
   (save-excursion
     (let* ((extra (save-excursion
                    (back-to-indentation)
       (- target-col open-bracket-col extra))))
 
 (defun c-lineup-ObjC-method-args (langelem)
-  ;; Line up the colons that separate args. This is done trying to
-  ;; align colons vertically.
+  "Line up the colons that separate args.
+The colon on the current line is aligned with the one on the first
+line.
+
+Works with: objc-method-args-cont."
   (save-excursion
     (let* ((here (c-point 'boi))
           (curcol (progn (goto-char here) (current-column)))
          c-basic-offset)))))
 
 (defun c-lineup-ObjC-method-args-2 (langelem)
-  ;; Line up the colons that separate args. This is done trying to
-  ;; align the colon on the current line with the previous one.
+  "Line up the colons that separate args.
+The colon on the current line is aligned with the one on the previous
+line.
+
+Works with: objc-method-args-cont."
   (save-excursion
     (let* ((here (c-point 'boi))
           (curcol (progn (goto-char here) (current-column)))
          c-basic-offset)))))
 
 (defun c-lineup-inexpr-block (langelem)
-  ;; This function lines up the block for the various constructs that
-  ;; uses a block inside an expression.  For constructs matching
-  ;; c-lambda-key and c-inexpr-block-key, indentation to the column of
-  ;; the beginning of the match is added.  For standalone statement
-  ;; blocks, indentation to the column of the opening brace is added.
+  "Line up the block for constructs that use a block inside an expression,
+e.g. anonymous classes in Java and lambda functions in Pike.  The body
+is aligned with the start of the header, e.g. with the \"new\" or
+\"lambda\" keyword.  Returns nil if the block isn't part of such a
+construct.
+
+Works with: inlambda, inexpr-statement, inexpr-class."
   (save-excursion
     (back-to-indentation)
     (let ((res (or (c-looking-at-inexpr-block)
                   (if (c-safe (backward-up-list 1)
                               (eq (char-after) ?{))
                       (c-looking-at-inexpr-block)))))
-      (if (not res)
-         0
+      (when res
        (goto-char (cdr res))
        (- (current-column)
           (progn
             (back-to-indentation)
             (current-column)))))))
 
-(defun c-lineup-dont-change (langelem)
-  ;; Do not change the indentation of the current line
+(defun c-lineup-whitesmith-in-block (langelem)
+  "Line up lines inside a block in whitesmith style.
+It's done in a way that works both when the opening brace hangs and
+when it doesn't.  E.g:
+
+something
+    {                something {
+    foo;     <->         foo;     <- c-lineup-whitesmith-in-block
+    }                    }
+                     <--> c-basic-offset
+
+In the first case the indentation is kept unchanged, in the
+second `c-basic-offset' is added.
+
+Works with: defun-close, defun-block-intro, block-close,
+brace-list-close, brace-list-intro, statement-block-intro, inclass,
+inextern-lang, innamespace."
   (save-excursion
+    (goto-char (cdr langelem))
     (back-to-indentation)
-    (current-column)))
+    (if (eq (char-syntax (char-after)) ?\()
+       0
+      c-basic-offset)))
+
+(defun c-lineup-dont-change (langelem)
+  "Do not change the indentation of the current line.
 
+Works with: Any syntactic symbol."
+  (save-excursion
+    (back-to-indentation)
+    (- (current-column) (c-langelem-col langelem))))
 
 \f
 (defun c-snug-do-while (syntax pos)
@@ -450,6 +638,7 @@ indentation amount."
 
 \f
 ;; Useful for c-hanging-semi&comma-criteria
+
 (defun c-semi&comma-inside-parenlist ()
   "Controls newline insertion after semicolons in parenthesis lists.
 If a comma was inserted, no determination is made.  If a semicolon was
index 9877832804a2c29c3ec200a0011698064834f4ca..05d2599d957a6c1eefcd050ae289d1c6ae376af2 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-cmds.el --- user level commands for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Softare Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-
-\f
 (eval-when-compile
-  (require 'cc-defs))
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-engine)
 
+\f
 (defun c-calculate-state (arg prevstate)
   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
   ;; arg is nil or zero, toggle the state. If arg is negative, turn
@@ -331,7 +337,7 @@ This function does various newline cleanups based on the value of
        ;; Do all appropriate clean ups
        (let ((here (point))
              (pos (- (point-max) (point)))
-             mbeg mend)
+             mbeg mend tmp)
          ;; clean up empty defun braces
          (if (and c-auto-newline
                   (memq 'empty-defun-braces c-cleanup-list)
@@ -345,19 +351,36 @@ This function does various newline cleanups based on the value of
                   ;; make sure matching open brace isn't in a comment
                   (not (c-in-literal)))
              (delete-region (point) (1- here)))
-         ;; clean up brace-else-brace
-         (if (and c-auto-newline
-                  (memq 'brace-else-brace c-cleanup-list)
-                  (eq last-command-char ?\{)
+         ;; clean up brace-else-brace and brace-elseif-brace
+         (when (and c-auto-newline
+                    (eq last-command-char ?\{)
+                    (not (c-in-literal)))
+           (cond
+            ((and (memq 'brace-else-brace c-cleanup-list)
                   (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
                   (progn
                     (setq mbeg (match-beginning 0)
                           mend (match-end 0))
-                    (= mend here))
-                  (not (c-in-literal)))
-             (progn
-               (delete-region mbeg mend)
-               (insert "} else {")))
+                    (eq (match-end 0) here)))
+             (delete-region mbeg mend)
+             (insert "} else {"))
+            ((and (memq 'brace-elseif-brace c-cleanup-list)
+                  (progn
+                    (goto-char (1- here))
+                    (setq mend (point))
+                    (skip-chars-backward " \t\n")
+                    (setq mbeg (point))
+                    (eq (char-before) ?\)))
+                  (= (c-backward-token-1 1 t) 0)
+                  (eq (char-after) ?\()
+                  (progn
+                    (setq tmp (point))
+                    (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*"
+                                        nil t))
+                  (eq (match-end 0) tmp))
+             (delete-region mbeg mend)
+             (goto-char mbeg)
+             (insert " "))))
          (goto-char (- (point-max) pos))
          )
        ;; does a newline go after the brace?
@@ -598,8 +621,8 @@ or \"/ah\" string on the mode line, 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 colon, or
-the colon is inserted inside a literal."
+are non-whitespace characters present on the line after the
+parenthesis, or the parenthesis is inserted inside a literal."
   (interactive "*P")
   (let (;; shut this up
        (c-echo-syntactic-information-p nil))
@@ -647,7 +670,8 @@ the colon is inserted inside a literal."
                  (insert "} catch (")))
            (goto-char (- (point-max) pos))
            ))
-       (funcall old-blink-paren)))))
+       (if old-blink-paren
+           (funcall old-blink-paren))))))
 
 
 \f
@@ -692,6 +716,7 @@ Unlike the built-in `beginning-of-defun' this tries to be smarter
 about finding the char with open-parenthesis syntax that starts the
 defun."
   (interactive "p")
+  (unless arg (setq arg 1))
   (if (< arg 0)
       (c-end-of-defun (- arg))
     (while (> arg 0)
@@ -706,13 +731,16 @@ defun."
        (cond
         (bod (goto-char bod))
         (prevbod (goto-char prevbod))
-        (t (goto-char (c-point 'bod)))))
-      (setq arg (1- arg))))
-  (c-keep-region-active))
+        (t (goto-char (point-min))
+           (setq arg 0)))
+       (setq arg (1- arg))))
+    (c-keep-region-active)
+    (= arg 0)))
 
 (defun c-end-of-defun (&optional arg)
   "Move forward to next end of defun.  With argument, do it that many times.
 Negative argument -N means move back to Nth preceding end of defun.
+Returns t unless search stops due to beginning or end of buffer.
 
 An end of a defun occurs right after the close-parenthesis that matches
 the open-parenthesis that starts a defun; see `beginning-of-defun'."
@@ -722,16 +750,25 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
   (if (< arg 0)
       (c-beginning-of-defun (- arg))
     (while (> arg 0)
-      ;; skip down into the next defun-block
-      (while (and (c-safe (down-list 1) t)
-                 (not (eq (char-before) ?{)))
-       (forward-char -1)
-       (c-forward-sexp))
-      (c-beginning-of-defun 1)
-      (c-forward-sexp 1)
-      (setq arg (1- arg)))
-    (forward-line 1))
-  (c-keep-region-active))
+      (let ((pos (point))
+           eol)
+       (while (and (c-safe (down-list 1) t)
+                   (not (eq (char-before) ?{)))
+         ;; skip down into the next defun-block
+         (forward-char -1)
+         (c-forward-sexp))
+       (c-beginning-of-defun 1)
+       (setq eol (c-point 'eol))
+       (c-forward-sexp)
+       (if (< eol (point))
+           ;; Don't move to next line for one line defuns.
+           (forward-line 1))
+       (when (<= (point) pos)
+         (goto-char (point-max))
+         (setq arg 0))
+       (setq arg (1- arg))))
+    (c-keep-region-active)
+    (= arg 0)))
 
 \f
 (defun c-beginning-of-statement (&optional count lim sentence-flag)
@@ -759,18 +796,12 @@ comment."
          (save-excursion
            ;; Find the comment next to point if we're not in one.
            (if (> count 0)
-               ;; Finding a comment backwards is a bit cumbersome
-               ;; because `forward-comment' regards every newline as
-               ;; a comment when searching backwards (Emacs 19.34).
-               (while (and (progn (skip-chars-backward " \t")
-                                  (setq range (point))
-                                  (setq range (if (forward-comment -1)
-                                                  (cons (point) range)
-                                                nil)))
-                           (= (char-after) ?\n)))
+               (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 (forward-comment 1)
+             (setq range (if (c-forward-comment 1)
                              (cons range (point))
                            nil)))
            (setq range (c-collect-line-comments range))))
@@ -780,23 +811,72 @@ comment."
       (if range
          (if (and sentence-flag
                   (/= (char-syntax (char-after (car range))) ?\"))
-             (progn
+             (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
                (save-restriction
-                 (narrow-to-region (save-excursion
-                                     (goto-char (car range))
-                                     (looking-at comment-start-skip)
-                                     (goto-char (match-end 0))
-                                     (point))
-                                   (save-excursion
-                                     (goto-char (cdr range))
-                                     (if (save-excursion
-                                           (goto-char (car range))
-                                           (looking-at "/\\*"))
-                                         (backward-char 2))
-                                     (skip-chars-backward " \t\n")
-                                     (point)))
-                 (c-safe (forward-sentence (if (> count 0) -1 1))))
+                 (narrow-to-region 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)
+                          (save-excursion
+                            (beginning-of-line)
+                            (looking-at (concat "[ \t]*\\("
+                                                c-comment-prefix-regexp
+                                                "\\)[ \t]*")))
+                          (>= (point) (match-beginning 0))
+                          (/= (match-beginning 1) (match-end 1))
+                          (or (< (point) (match-end 0))
+                              (and
+                               (= (point) (match-end 0))
+                               ;; The comment prefix may contain
+                               ;; characters that is regarded as end
+                               ;; of sentence.
+                               (or (eolp)
+                                   (and
+                                    (save-excursion
+                                      (forward-paragraph -1)
+                                      (< (point) (match-beginning 0)))
+                                    (save-excursion
+                                      (beginning-of-line)
+                                      (or (not (re-search-backward
+                                                sentence-end
+                                                (c-point 'bopl)
+                                                t))
+                                          (< (match-end 0)
+                                             (c-point 'eol)))))))))
+                     (setq count (+ count (if (< count 0) -1 1)))
+                   (if (< count 0)
+                       (progn
+                         ;; In block comments, if there's only
+                         ;; horizontal ws between the text and the
+                         ;; 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))
+                           (widen)
+                           (skip-chars-backward " \t")
+                           (when (or (eq (point) end) (bolp))
+                             (goto-char (cdr range)))))
+                     (when (and (eq (point) beg) (looking-at "[ \t]*$"))
+                       ;; Stop before instead of after the comment
+                       ;; starter if nothing follows it.
+                       (widen)
+                       (goto-char (car range))))))
                ;; See if we should escape the literal.
                (if (> count 0)
                    (if (< (point) here)
@@ -810,89 +890,143 @@ comment."
            (goto-char (if (> count 0) (car range) (cdr range)))
            (setq range nil))
        ;; Below we do approximately the same as
-       ;; c-beginning-of-statement-1 and c-end-of-statement-1 and
+       ;; c-beginning-of-statement-1 and c-end-of-statement-1, and
        ;; perhaps they should be changed, but that'd likely break a
        ;; lot in cc-engine.
        (goto-char here)
        (if (> count 0)
-           (if (condition-case nil
-                   ;; Stop before `{' and after `;', `{', `}' and
-                   ;; `};' when not followed by `}' or `)', but on
-                   ;; the other side of the syntactic ws.  Also stop
-                   ;; before `}', but only to catch comments.  Move
-                   ;; by sexps and move into parens.
-                   (catch 'done
-                     (let (last)
-                       (while t
-                         (setq last (point))
-                         (if (and (looking-at "[{}]")
-                                  (/= here last))
-                             (throw 'done (= (char-after) ?{)))
-                         (c-backward-syntactic-ws)
-                         (cond ((bobp) ; Must handle bob specially.
-                                (if (= here last)
-                                    (if (= last (point-min))
-                                        (throw 'done t)
-                                      (goto-char last)
-                                      (throw 'done nil))
-                                  (goto-char last)
-                                  (throw 'done t)))
-                               ((progn (backward-char)
-                                       (looking-at "[;{}]"))
-                                (if (or (= here last)
-                                        (memq (char-after last) '(?\) ?})))
-                                    (if (and (= (char-before) ?})
-                                             (= (char-after) ?\;))
-                                        (backward-char))
-                                  (goto-char last)
-                                  (throw 'done t)))
-                               ((= (char-syntax (char-after)) ?\")
-                                (forward-char)
-                                (c-backward-sexp))
-                               ))))
-                 (error
-                  (goto-char (point-min))
-                  t))
-               (setq count (1- count)))
-         (if (condition-case nil
-                 ;; Stop before `{' and `}', but on the other side of
-                 ;; the syntactic ws, and after `;', `}' and `};'.
-                 ;; Only stop before `{' if at top level or inside
-                 ;; braces, though.  Also stop after `{', but only to
-                 ;; catch comments.  Move by sexps and move into
-                 ;; parens.
+           (condition-case nil
+               ;; 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
+               ;; on a line.
+               (let ((comment-pos (not sentence-flag))
+                     (large-enough (- (point-max)))
+                     last last-below-line)
                  (catch 'done
-                   (let (last)
-                     (while t
-                       (setq last (point))
-                       (c-forward-syntactic-ws)
-                       (cond ((= (char-after) ?{)
+                   (while t
+                     (setq last (point))
+                     (when (and (looking-at "{\\|^#") (/= here last))
+                       (unless (and c-special-brace-lists
+                                    (eq (char-after) ?{)
+                                    (c-looking-at-special-brace-list))
+                         (if (and (eq (char-after) ?#)
+                                  (numberp last-below-line)
+                                  (not (eq last-below-line here)))
+                             (goto-char last-below-line))
+                         (throw 'done t)))
+                     (if comment-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)))
+                         (c-forward-comment large-enough)))
+                     (unless last-below-line
+                       (if (save-excursion
+                             (re-search-forward "\\(^\\|[^\\]\\)$" last t))
+                           (setq last-below-line last)))
+                     (cond ((bobp)     ; Must handle bob specially.
+                            (if (= here last)
+                                (throw 'done t)
+                              (goto-char last)
+                              (throw 'done t)))
+                           ((progn (backward-char)
+                                   (looking-at "[;{}]"))
+                            (if (and c-special-brace-lists
+                                     (eq (char-after) ?{)
+                                     (c-looking-at-special-brace-list))
+                                (skip-syntax-backward "w_") ; Speedup only.
                               (if (or (= here last)
-                                      (save-excursion
-                                        (and (c-safe (progn (up-list -1) t))
-                                             (/= (char-after) ?{))))
-                                  (progn (forward-char)
-                                         (throw 'done nil))
+                                      (memq (char-after last) '(?\) ?})))
+                                  (if (and (eq (char-before) ?})
+                                           (eq (char-after) ?\;))
+                                      (backward-char))
                                 (goto-char last)
-                                (throw 'done t)))
-                             ((and (= (char-after) ?})
-                                   (/= here last))
-                              (goto-char last)
-                              (throw 'done t))
-                             ((looking-at ";\\|};?")
-                              (goto-char (match-end 0))
-                              (throw 'done t))
-                             ((= (char-syntax (char-after)) ?\")
-                              (c-forward-sexp))
-                             (t
-                              (forward-char))
-                             ))))
-               (error
-                (goto-char (point-max))
-                t))
-             (setq count (1+ count)))))
+                                (throw 'done t))))
+                           ((= (char-syntax (char-after)) ?\")
+                            (forward-char)
+                            (c-backward-sexp))
+                           (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)
+                   (setq count (1- count))))
+             (error
+              (goto-char (point-min))
+              (setq count 0)))
+         (condition-case nil
+             ;; Stop before `{', `}', and `#' when it's first 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))
+                   (large-enough (point-max))
+                   last)
+               (catch 'done
+                 (while t
+                   (setq last (point))
+                   (if comment-pos
+                       (c-forward-comment large-enough)
+                     (if (progn
+                           (skip-chars-forward " \t\n\r\f")
+                           ;; Record position of first comment.
+                           (setq comment-pos (point))
+                           (c-forward-comment 1))
+                         (c-forward-comment large-enough)
+                       (setq comment-pos nil)))
+                   (cond ((and (eq (char-after) ?{)
+                               (not (and c-special-brace-lists
+                                         (c-looking-at-special-brace-list)))
+                               (/= here last)
+                               (save-excursion
+                                 (or (not (c-safe (up-list -1) t))
+                                     (= (char-after) ?{))))
+                          (goto-char last)
+                          (throw 'done t))
+                         ((and c-special-brace-lists
+                               (eq (char-after) ?})
+                               (save-excursion
+                                 (and (c-safe (up-list -1) t)
+                                      (c-looking-at-special-brace-list))))
+                          (forward-char 1)
+                          (skip-syntax-forward "w_")) ; Speedup only.
+                         ((and (eq (char-after) ?})
+                               (/= here last))
+                          (goto-char last)
+                          (throw 'done t))
+                         ((looking-at "^#")
+                          (if (= here last)
+                              (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)
+                                  (goto-char (point-max)))
+                            (goto-char last))
+                          (throw 'done t))
+                         ((looking-at ";\\|};?")
+                          (goto-char (match-end 0))
+                          (throw 'done t))
+                         ((= (char-syntax (char-after)) ?\")
+                          (c-forward-sexp))
+                         (t
+                          (forward-char 1)
+                          (skip-syntax-forward "w_")) ; Speedup only.
+                         )))
+               (if (and (numberp comment-pos)
+                        (> (point) comment-pos))
+                   ;; We jumped over a comment that should be investigated.
+                   (goto-char comment-pos)
+                 (setq count (1+ count))))
+           (error
+            (goto-char (point-max))
+            (setq count 0)))
+         ))
       ;; If we haven't moved we're near a buffer limit.
-      (when (= (point) here)
+      (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
@@ -987,8 +1121,10 @@ comment."
                     (cons c-comment-only-line-offset
                           c-comment-only-line-offset))))
              (apply '+ (mapcar 'c-get-offset syntax)))))
-        ;; CASE 4: use comment-column if previous line is a
-        ;; comment-only line indented to the left of comment-column
+        ;; 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
+        ;; character in any case.
         ((save-excursion
            (beginning-of-line)
            (and (not (bobp))
@@ -996,11 +1132,12 @@ comment."
            (skip-chars-forward " \t")
            (prog1
                (looking-at c-comment-start-regexp)
-             (setq placeholder (point))))
-         (goto-char placeholder)
-         (if (< (current-column) comment-column)
-             comment-column
-           (current-column)))
+             (setq placeholder (current-column))))
+         (goto-char opoint)
+         (skip-chars-backward " \t")
+         (max (if (bolp) 0 (1+ (current-column)))
+              placeholder
+              comment-column))
         ;; CASE 5: If comment-column is 0, and nothing but space
         ;; before the comment, align it at 0 rather than 1.
         ((progn
@@ -1015,93 +1152,89 @@ comment."
         )))))
 
 \f
-;; for proposed new variable comment-line-break-function
-(defun c-comment-line-break-function (&optional soft)
-  ;; we currently don't do anything with soft line breaks
-  (let ((literal (c-in-literal))
-       at-comment-col)
-    (cond
-     ((eq literal 'string)
-      (insert ?\n))
-     ((or (not c-comment-continuation-stars)
-         (not literal))
-      (indent-new-comment-line soft))
-     (t (let ((here (point))
-             (leader c-comment-continuation-stars))
-         (back-to-indentation)
-         ;; comment could be hanging
-         (if (not (c-in-literal))
-             (progn
-               (forward-line 1)
-               (forward-comment -1)
-               (setq at-comment-col (= (current-column) comment-column))))
-         ;; are we looking at a block or lines style comment?
-         (if (and (looking-at (concat "\\(" c-comment-start-regexp
-                                      "\\)[ \t]+"))
-                  (string-equal (match-string 1) "//"))
-             ;; line style
-             (setq leader (match-string 0)))
-         (goto-char here)
-         (delete-region (progn (skip-chars-backward " \t") (point))
-                        (progn (skip-chars-forward " \t") (point)))
-         (newline)
-         ;; to avoid having an anchored comment that c-indent-line will
-         ;; trip up on
-         (insert " " leader)
-         (if at-comment-col
-             (indent-for-comment))
-         (c-indent-line))))))
-
-;; advice for indent-new-comment-line for older Emacsen
-(or (boundp 'comment-line-break-function)
-    (defadvice indent-new-comment-line (around c-line-break-advice
-                                              activate preactivate)
-      "Calls c-comment-line-break-function if in a comment in CC Mode."
-      (if (or (not c-buffer-is-cc-mode)
-             (not (c-in-literal))
-             (not c-comment-continuation-stars))
-         ad-do-it
-       (c-comment-line-break-function (ad-get-arg 0)))))
-
 ;; used by outline-minor-mode
 (defun c-outline-level ()
-  ;; This so that `current-column' DTRT in otherwise-hidden text.
-  (let (buffer-invisibility-spec)
-    (save-excursion
-      (skip-chars-forward "\t ")
-      (current-column))))
+  (save-excursion
+    (skip-chars-forward "\t ")
+    (current-column)))
 
 \f
 (defun c-up-conditional (count)
   "Move back to the containing preprocessor conditional, leaving mark behind.
 A prefix argument acts as a repeat count.  With a negative argument,
 move forward to the end of the containing preprocessor conditional.
-When going backwards, `#elif' is treated like `#else' followed by
-`#if'.  When going forwards, `#elif' is ignored."
+
+`#elif' is treated like `#else' followed by `#if', so the function
+stops at them when going backward, but not when going forward."
+  (interactive "p")
+  (c-forward-conditional (- count) -1)
+  (c-keep-region-active))
+  
+(defun c-up-conditional-with-else (count)
+  "Move back to the containing preprocessor conditional, including `#else'.
+Just like `c-up-conditional', except it also stops at `#else'
+directives."
+  (interactive "p")
+  (c-forward-conditional (- count) -1 t)
+  (c-keep-region-active))
+
+(defun c-down-conditional (count)
+  "Move forward into the next preprocessor conditional, leaving mark behind.
+A prefix argument acts as a repeat count.  With a negative argument,
+move backward into the previous preprocessor conditional.
+
+`#elif' is treated like `#else' followed by `#if', so the function
+stops at them when going forward, but not when going backward."
   (interactive "p")
-  (c-forward-conditional (- count) t)
+  (c-forward-conditional count 1)
   (c-keep-region-active))
 
-(defun c-backward-conditional (count &optional up-flag)
+(defun c-down-conditional-with-else (count)
+  "Move forward into the next preprocessor conditional, including `#else'.
+Just like `c-down-conditional', except it also stops at `#else'
+directives."
+  (interactive "p")
+  (c-forward-conditional count 1 t)
+  (c-keep-region-active))
+
+(defun c-backward-conditional (count &optional target-depth with-else)
   "Move back across a preprocessor conditional, leaving mark behind.
 A prefix argument acts as a repeat count.  With a negative argument,
 move forward across a preprocessor conditional."
   (interactive "p")
-  (c-forward-conditional (- count) up-flag)
+  (c-forward-conditional (- count) target-depth with-else)
   (c-keep-region-active))
 
-(defun c-forward-conditional (count &optional up-flag)
+(defun c-forward-conditional (count &optional target-depth with-else)
   "Move forward across a preprocessor conditional, leaving mark behind.
 A prefix argument acts as a repeat count.  With a negative argument,
-move backward across a preprocessor conditional."
+move backward across a preprocessor conditional.
+
+`#elif' is treated like `#else' followed by `#if', except that the
+nesting level isn't changed when tracking subconditionals.
+
+The optional argument TARGET-DEPTH specifies the wanted nesting depth
+after each scan.  I.e. if TARGET-DEPTH is -1, the function will move
+out of the enclosing conditional.  A non-integer non-nil TARGET-DEPTH
+counts as -1.
+
+If the optional argument WITH-ELSE is non-nil, `#else' directives are
+treated as conditional clause limits.  Normally they are ignored."
   (interactive "p")
   (let* ((forward (> count 0))
         (increment (if forward -1 1))
         (search-function (if forward 're-search-forward 're-search-backward))
         (new))
+    (unless (integerp target-depth)
+      (setq target-depth (if target-depth -1 0)))
     (save-excursion
       (while (/= count 0)
-       (let ((depth (if up-flag 0 -1)) found)
+       (let ((depth 0)
+             ;; subdepth is the depth in "uninteresting" subtrees,
+             ;; i.e. those that takes us farther from the target
+             ;; depth instead of closer.
+             (subdepth 0)
+             found)
          (save-excursion
            ;; Find the "next" significant line in the proper direction.
            (while (and (not found)
@@ -1112,36 +1245,50 @@ move backward across a preprocessor conditional."
                        ;; precedes it.  This is faster on account of
                        ;; the fastmap feature of the regexp matcher.
                        (funcall search-function
-                                "#[ \t]*\\(if\\|elif\\|endif\\)"
+                                "#[ \t]*\\(if\\|elif\\|endif\\|else\\)"
                                 nil t))
              (beginning-of-line)
              ;; Now verify it is really a preproc line.
-             (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
-                 (let ((prev depth))
-                   ;; Update depth according to what we found.
-                   (beginning-of-line)
-                   (cond ((looking-at "[ \t]*#[ \t]*endif")
-                          (setq depth (+ depth increment)))
-                         ((looking-at "[ \t]*#[ \t]*elif")
-                          (if (and forward (= depth 0))
-                              (setq found (point))))
-                         (t (setq depth (- depth increment))))
-                   ;; If we are trying to move across, and we find an
-                   ;; end before we find a beginning, get an error.
-                   (if (and (< prev 0) (< depth prev))
-                       (error (if forward
-                                  "No following conditional at this level"
-                                "No previous conditional at this level")))
+             (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\|else\\)")
+                 (let (dchange (directive (match-string 1)))
+                   (cond ((string= directive "if")
+                          (setq dchange (- increment)))
+                         ((string= directive "endif")
+                          (setq dchange increment))
+                         ((= subdepth 0)
+                          ;; When we're not in an "uninteresting"
+                          ;; subtree, we might want to act on "elif"
+                          ;; and "else" too.
+                          (if (cond (with-else
+                                     ;; Always move toward the target depth.
+                                     (setq dchange
+                                           (if (> target-depth 0) 1 -1)))
+                                    ((string= directive "elif")
+                                     (setq dchange (- increment))))
+                              ;; Ignore the change if it'd take us
+                              ;; into an "uninteresting" subtree.
+                              (if (eq (> dchange 0) (<= target-depth 0))
+                                  (setq dchange nil)))))
+                   (when dchange
+                     (when (or (/= subdepth 0)
+                               (eq (> dchange 0) (<= target-depth 0)))
+                       (setq subdepth (+ subdepth dchange)))
+                     (setq depth (+ depth dchange))
+                     ;; If we are trying to move across, and we find an
+                     ;; end before we find a beginning, get an error.
+                     (if (and (< depth target-depth) (< dchange 0))
+                         (error (if forward
+                                    "No following conditional at this level"
+                                  "No previous conditional at this level"))))
                    ;; When searching forward, start from next line so
                    ;; that we don't find the same line again.
                    (if forward (forward-line 1))
-                   ;; If this line exits a level of conditional, exit
-                   ;; inner loop.
-                   (if (< depth 0)
+                   ;; We found something if we've arrived at the
+                   ;; target depth.
+                   (if (and dchange (= depth target-depth))
                        (setq found (point))))
                ;; else
-               (if forward (forward-line 1))
-               )))
+               (if forward (forward-line 1)))))
          (or found
              (error "No containing preprocessor conditional"))
          (goto-char (setq new found)))
@@ -1217,8 +1364,9 @@ of the expression is preserved.
   "Indent each line in balanced expression following point.
 Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
   (interactive "*P")
-  (let ((here (point))
+  (let ((here (point-marker))
        end progress-p)
+    (set-marker-insertion-type here t)
     (unwind-protect
        (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
              (start (progn
@@ -1259,7 +1407,8 @@ Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
           (set-marker end nil))
       (and progress-p
           (c-progress-fini 'c-indent-exp))
-      (goto-char here))))
+      (goto-char here)
+      (set-marker here nil))))
 
 (defun c-indent-defun ()
   "Re-indents the current top-level function def, struct or class declaration."
@@ -1342,13 +1491,16 @@ Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
                          (setq sexpbeg (point))))
                    (if (and sexpbeg (< sexpbeg fence))
                        (setq sexpbeg fence)))
-                 ;; check to see if the next line starts a
-                 ;; comment-only line
-                 (save-excursion
-                   (forward-line 1)
-                   (skip-chars-forward " \t")
-                   (if (looking-at c-comment-start-regexp)
-                       (setq sexpbeg (c-point 'bol))))
+                 ;; 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
@@ -1560,12 +1712,288 @@ command to conveniently insert and align the necessary backslashes."
            (delete-region (1+ (point))
                           (progn (skip-chars-backward " \t") (point)))))))
 
+
 \f
+;;; Line breaking and paragraph filling.
+
+;; 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
+;; possible to make them work correctly wrt the comment and string
+;; separators, one-line paragraphs etc.  Unfortunately, when it comes
+;; to it, there's quite a lot of special cases to handle which makes
+;; the code anything but simple.  The intention is that it will work
+;; with any well-written text filling package that preserves a fill
+;; prefix.
+;;
+;; We temporarily mask comment starters and enders as necessary for
+;; the filling code to do its job on a seemingly normal text block.
+;; We do _not_ mask the fill prefix, so it's up to the filling code to
+;; preserve it correctly (especially important when filling C++ style
+;; line comments).  By default, we set up and use adaptive-fill-mode,
+;; which is standard in all supported Emacs flavors.
+
+(defun c-guess-fill-prefix (lit-limits lit-type)
+  ;; Determine the appropriate comment fill prefix for a block or line
+  ;; comment.  Return a cons of the prefix string and the column where
+  ;; it ends.  If fill-prefix is set, it'll override.  Note that this
+  ;; function also uses the value of point in some heuristics.
+  (let* ((here (point))
+        (prefix-regexp (concat "[ \t]*\\("
+                               c-comment-prefix-regexp
+                               "\\)[ \t]*"))
+        (comment-start-regexp (if (eq lit-type 'c++)
+                                  prefix-regexp
+                                comment-start-skip))
+        prefix-line comment-prefix res)
+    (cond
+     (fill-prefix
+      (setq res (cons fill-prefix
+                     ;; Ugly way of getting the column after the fill
+                     ;; prefix; it'd be nice with a current-column
+                     ;; that works on strings..
+                     (let ((buffer-modified (buffer-modified-p))
+                           (buffer-undo-list t)
+                           (start (point)))
+                       (unwind-protect
+                           (progn
+                             (insert ?\n fill-prefix)
+                             (current-column))
+                         (delete-region start (point))
+                         (set-buffer-modified-p buffer-modified))))))
+     ((eq lit-type 'c++)
+      (save-excursion
+       ;; Set fallback for comment-prefix if none is found.
+       (setq comment-prefix "// ")
+       (beginning-of-line)
+       (if (> (point) (car lit-limits))
+           ;; The current line is not the comment starter, so the
+           ;; comment has more than one line, and it can therefore be
+           ;; used to find the comment fill prefix.
+           (setq prefix-line (point))
+         (goto-char (car lit-limits))
+         (if (and (= (forward-line 1) 0)
+                  (< (point) (cdr lit-limits)))
+             ;; The line after the comment starter is inside the
+             ;; comment, so we can use it.
+             (setq prefix-line (point))
+           ;; The comment is only one line.  Take the comment prefix
+           ;; from it and keep the indentation.
+           (goto-char (car lit-limits))
+           (if (looking-at prefix-regexp)
+               (goto-char (match-end 0))
+             (forward-char 2)
+             (skip-chars-forward " \t"))
+           (setq res
+                 (if (eq (c-point 'boi) (car lit-limits))
+                     ;; There is only whitespace before the comment
+                     ;; starter; take the prefix straight from this
+                     ;; line.
+                     (cons (buffer-substring-no-properties
+                            (c-point 'bol) (point))
+                           (current-column))
+                   ;; There is code before the comment starter, so we
+                   ;; have to temporarily insert and indent a new
+                   ;; line to get the right space/tab mix in the
+                   ;; indentation.
+                   (let ((buffer-modified (buffer-modified-p))
+                         (buffer-undo-list t)
+                         (prefix-len (- (point) (car lit-limits)))
+                         tmp)
+                     (unwind-protect
+                         (progn
+                           (goto-char (car lit-limits))
+                           (indent-to (prog1 (current-column)
+                                        (insert ?\n)))
+                           (setq tmp (point))
+                           (forward-char prefix-len)
+                           (cons (buffer-substring-no-properties
+                                  (c-point 'bol) (point))
+                                 (current-column)))
+                       (delete-region (car lit-limits) tmp)
+                       (set-buffer-modified-p buffer-modified))))
+                 )))))
+     (t
+      (save-excursion
+       (beginning-of-line)
+       (if (and (> (point) (car lit-limits))
+                (not (and (looking-at "[ \t]*\\*/")
+                          (eq (cdr lit-limits) (match-end 0)))))
+           ;; The current line is not the comment starter and
+           ;; contains more than just the ender, so it's good enough
+           ;; to be used for the comment fill prefix.
+           (setq prefix-line (point))
+         (goto-char (car lit-limits))
+         (if (or (/= (forward-line 1) 0)
+                 (>= (point) (cdr lit-limits))
+                 (and (looking-at "[ \t]*\\*/")
+                      (eq (cdr lit-limits) (match-end 0)))
+                 (and (looking-at prefix-regexp)
+                      (<= (1- (cdr lit-limits)) (match-end 0)))
+                 (and (< here (point))
+                      (or (not (match-beginning 0))
+                          (looking-at "[ \t]*$"))))
+             ;; 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
+             ;; 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
+             ;; information about a suitable comment prefix, so we
+             ;; resort to c-block-comment-prefix.
+             (setq comment-prefix (or c-block-comment-prefix "")
+                   res (let ((buffer-modified (buffer-modified-p))
+                             (buffer-undo-list t)
+                             tmp-pre tmp-post)
+                         ;; The comment doesn't give any information
+                         ;; about the indentation column.  We'll have to
+                         ;; temporarily insert a new comment line and
+                         ;; indent it to find the correct column.
+                         (unwind-protect
+                             (progn
+                               (goto-char (car lit-limits))
+                               (if (looking-at comment-start-regexp)
+                                   (goto-char (match-end 0))
+                                 (forward-char 2)
+                                 (skip-chars-forward " \t"))
+                               (when (eq (char-syntax (char-before)) ?\ )
+                                 ;; If there's ws on the current
+                                 ;; line, we'll use it instead of
+                                 ;; what's ending comment-prefix.
+                                 (setq comment-prefix
+                                       (concat (substring comment-prefix
+                                                          0 (string-match
+                                                             "\\s *\\'"
+                                                             comment-prefix))
+                                               (buffer-substring-no-properties
+                                                (save-excursion
+                                                  (skip-chars-backward " \t")
+                                                  (point))
+                                                (point)))))
+                               (setq tmp-pre (point-marker))
+                               ;; We insert an extra non-whitespace
+                               ;; character before the line break and
+                               ;; after comment-prefix in case it's
+                               ;; "" or ends with whitespace.
+                               (insert "x\n" comment-prefix ?x)
+                               (setq tmp-post (point-marker))
+                               (c-indent-line)
+                               (goto-char (1- tmp-post))
+                               (cons (buffer-substring-no-properties
+                                        (c-point 'bol) (point))
+                                     (current-column)))
+                           (when tmp-post
+                             (delete-region tmp-pre tmp-post)
+                             (set-marker tmp-pre nil)
+                             (set-marker tmp-post nil))
+                           (set-buffer-modified-p buffer-modified))))
+           ;; Otherwise the line after the comment starter is good
+           ;; enough to find the prefix in.
+           (setq prefix-line (point)))))))
+    (or res
+       (save-excursion
+         ;; prefix-line is the bol of a line on which we should try
+         ;; to find the prefix.
+         (let* (fb-string fb-endpos    ; Contains any fallback prefix found.
+                (test-line
+                 (lambda ()
+                   (when (and (looking-at prefix-regexp)
+                              (< (match-end 0) (1- (cdr lit-limits))))
+                     (unless fb-string
+                       (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
+                 ;; 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)))
+                   ;; 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))
+                 (goto-char prefix-line)
+                 (while (and (zerop (forward-line 1))
+                             (< (point) (cdr lit-limits)))
+                   (funcall test-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
+                 ;; 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)
+                        ;; There are ws after the prefix, so let's use it.
+                        (cons fb-string
+                              (progn (goto-char fb-endpos) (current-column))))
+                       ((progn
+                          ;; Check if there's any whitespace padding
+                          ;; on the comment start line that we can
+                          ;; use after the prefix.
+                          (goto-char (car lit-limits))
+                          (if (looking-at comment-start-regexp)
+                              (goto-char (match-end 0))
+                            (forward-char 2)
+                            (skip-chars-forward " \t"))
+                          (eq (char-syntax (char-before)) ?\ ))
+                        (setq fb-string (buffer-substring-no-properties
+                                         (save-excursion
+                                           (skip-chars-backward " \t")
+                                           (point))
+                                         (point)))
+                        (goto-char fb-endpos)
+                        (skip-chars-backward " \t")
+                        (let ((buffer-modified (buffer-modified-p))
+                              (buffer-undo-list t)
+                              (tmp (point)))
+                          ;; Got to mess in the buffer once again to
+                          ;; ensure the column gets correct.  :P
+                          (unwind-protect
+                              (progn
+                                (insert fb-string)
+                                (cons (buffer-substring-no-properties
+                                       (c-point 'bol)
+                                       (point))
+                                      (current-column)))
+                            (delete-region tmp (point)))))
+                       (t
+                        ;; Last resort: Just add a single space after
+                        ;; the prefix.
+                        (cons (concat fb-string " ")
+                              (progn (goto-char fb-endpos)
+                                     (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.
+                   (cons (concat (buffer-substring-no-properties
+                                  prefix-line (c-point 'boi))
+                                 comment-prefix)
+                         (progn (back-to-indentation)
+                                (+ (current-column) (length comment-prefix))))
+                 ;; Assume we are dealing with a "free text" block
+                 ;; comment where the lines doesn't have any comment
+                 ;; prefix at all and we should just fill it as
+                 ;; normal text.
+                 '("" . 0)))))))
+    ))
+
 (defun c-fill-paragraph (&optional arg)
   "Like \\[fill-paragraph] but handles C and C++ style comments.
-If any of the current line is a comment or within a comment,
-fill the comment or the paragraph of it that point is in,
-preserving the comment indentation or line-starting decorations.
+If any of the current line is a comment or within a comment, fill the
+comment or the paragraph of it that point is in, preserving the
+comment indentation or line-starting decorations (see the
+`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
+details).
 
 If point is inside multiline string literal, fill it.  This currently
 does not respect escaped newlines, except for the special case when it
@@ -1580,274 +2008,376 @@ If point is in any other situation, i.e. in normal code, do nothing.
 
 Optional prefix ARG means justify paragraph as well."
   (interactive "*P")
-  (let* ((point-save (point-marker))
-        limits
-        comment-start-place
-        (first-line
-         ;; Check for obvious entry to comment.
-         (save-excursion
-           (beginning-of-line)
-           (skip-chars-forward " \t")
-           (and (looking-at comment-start-skip)
-                (setq comment-start-place (point)))))
-        (re1 "\\|\\([ \t]*/\\*[ \t]*\\|[ \t]*\\*/[ \t]*\\|[ \t/*]*\\)"))
-    (if (save-excursion
-         (beginning-of-line)
-         (looking-at ".*//"))
-       (let ((fill-prefix fill-prefix)
-              ;; Lines containing just a comment start or just an end
-              ;; should not be filled into paragraphs they are next
-              ;; to.
-             (paragraph-start (concat paragraph-start re1 "$"))
-             (paragraph-separate (concat paragraph-separate re1 "$")))
-         (save-excursion
-           (beginning-of-line)
-           ;; Move up to first line of this comment.
-           (while (and (not (bobp))
-                       (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
-             (forward-line -1))
-           (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
-               (forward-line 1))
-           ;; Find the comment start in this line.
-           (re-search-forward "[ \t]*//[ \t]*")
-           ;; Set the fill-prefix to be what all lines except the first
-           ;; should start with.  But do not alter a user set fill-prefix.
-           (if (null fill-prefix)
-               (setq fill-prefix (buffer-substring (match-beginning 0)
-                                                   (match-end 0))))
-           (save-restriction
-             ;; Narrow down to just the lines of this comment.
-             (narrow-to-region (c-point 'bol)
-                               (save-excursion
-                                 (forward-line 1)
-                                 (while
-                                     (looking-at (regexp-quote fill-prefix))
-                                   (forward-line 1))
-                                 (point)))
-             (or (c-safe
-                  ;; fill-paragraph sometimes fails to detect when we
-                  ;; are between paragraphs.
-                  (beginning-of-line)
-                  (search-forward fill-prefix (c-point 'eol))
-                  (looking-at paragraph-separate))
-                 ;; Avoids recursion
-                 (let (fill-paragraph-function)
-                   (fill-paragraph arg))))))
-      ;; else C style comments
-      (if (or first-line
-             ;; t if we enter a comment between start of function and
-             ;; this line.
+  (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
+       ;; 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)
+    ;; 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-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)
+      (setq beg (point)))
+    (when (and (>= (point) beg) (<= (point) end))
+      (unwind-protect
+         (progn
+           (cond
+            ((eq lit-type 'c++)        ; Line comment.
              (save-excursion
-               (setq limits (c-literal-limits))
-               (and (consp limits)
-                    (save-excursion
-                      (goto-char (car limits))
-                      (looking-at c-comment-start-regexp))))
-             ;; t if this line contains a comment starter.
-             (setq first-line
-                   (save-excursion
-                     (beginning-of-line)
-                     (prog1
-                         (re-search-forward comment-start-skip
-                                            (save-excursion (end-of-line)
-                                                            (point))
-                                            t)
-                       (setq comment-start-place (point)))))
-             ;; t if we're in the whitespace after a comment ender
-             ;; which ends its line.
-             (and (not limits)
-                  (when (and (looking-at "[ \t]*$")
-                             (save-excursion
-                               (beginning-of-line)
-                               (looking-at ".*\\*/[ \t]*$")))
-                    (save-excursion
-                      (forward-comment -1)
-                      (setq comment-start-place (point)))
-                    t)))
-         ;; Inside a comment: fill one comment paragraph.
-         (let ((fill-prefix
-                (or
-                 ;; Keep user set fill prefix if any.
-                 fill-prefix
-                 ;; The prefix for each line of this paragraph
-                 ;; is the appropriate part of the start of this line,
-                 ;; up to the column at which text should be indented.
-                 (save-excursion
-                   (beginning-of-line)
-                   (if (looking-at ".*/\\*.*\\*/")
-                       (progn (re-search-forward comment-start-skip)
-                              (make-string (current-column) ?\ ))
-                     (if first-line
-                         (forward-line 1)
-                       (if (and (looking-at "[ \t]*\\*/")
-                                (not (save-excursion
-                                       (forward-line -1)
-                                       (looking-at ".*/\\*"))))
-                           (forward-line -1)))
-
-                     (let ((line-width (progn (end-of-line)
-                                              (current-column))))
-                       (beginning-of-line)
-                       (prog1
-                           (buffer-substring
-                            (point)
-
-                            ;; How shall we decide where the end of the
-                            ;; fill-prefix is?
-                            (progn
-                              (skip-chars-forward " \t*" (c-point 'eol))
-                              ;; kludge alert, watch out for */, in
-                              ;; which case fill-prefix should *not*
-                              ;; be "*"!
-                              (if (and (eq (char-after) ?/)
-                                       (eq (char-before) ?*))
-                                  (forward-char -1))
-                              (point)))
-
-                         ;; If the comment is only one line followed
-                         ;; by a blank line, calling move-to-column
-                         ;; above may have added some spaces and tabs
-                         ;; to the end of the line; the fill-paragraph
-                         ;; function will then delete it and the
-                         ;; newline following it, so we'll lose a
-                         ;; blank line when we shouldn't.  So delete
-                         ;; anything move-to-column added to the end
-                         ;; of the line.  We record the line width
-                         ;; instead of the position of the old line
-                         ;; end because move-to-column might break a
-                         ;; tab into spaces, and the new characters
-                         ;; introduced there shouldn't be deleted.
-
-                         ;; If you can see a better way to do this,
-                         ;; please make the change.  This seems very
-                         ;; messy to me.
-                         (delete-region (progn (move-to-column line-width)
-                                               (point))
-                                        (progn (end-of-line) (point)))))))))
-
-               ;; Lines containing just a comment start or just an end
-               ;; should not be filled into paragraphs they are next
-               ;; to.
-               (paragraph-start (if (c-major-mode-is 'java-mode)
-                                    (concat paragraph-start
-                                            re1 "\\("
-                                            c-Java-javadoc-paragraph-start
-                                            "\\|$\\)")
-                                  (concat paragraph-start re1 "$")))
-               (paragraph-separate (concat paragraph-separate re1 "$"))
-               (chars-to-delete 0)
-               )
-           (save-restriction
-             ;; Don't fill the comment together with the code
-             ;; following it.  So temporarily exclude everything
-             ;; before the comment start, and everything after the
-             ;; line where the comment ends.  If comment-start-place
-             ;; is non-nil, the comment starter is there.  Otherwise,
-             ;; point is inside the comment.
-             (narrow-to-region (save-excursion
-                                 (if comment-start-place
-                                     (goto-char comment-start-place)
-                                   (search-backward "/*"))
-                                 (if (and (not c-hanging-comment-starter-p)
-                                          (looking-at
-                                           (concat c-comment-start-regexp
-                                                   "[ \t]*$")))
-                                     (forward-line 1))
-                                 ;; Protect text before the comment
-                                 ;; start by excluding it.  Add
-                                 ;; spaces to bring back proper
-                                 ;; indentation of that point.
-                                 (let ((column (current-column)))
-                                   (prog1 (point)
-                                     (setq chars-to-delete column)
-                                     (insert-char ?\  column))))
-                               (save-excursion
-                                 (if comment-start-place
-                                     (goto-char (+ comment-start-place 2)))
-                                 (search-forward "*/" nil 'move)
-                                 (if (and (not c-hanging-comment-ender-p)
-                                          (save-excursion
-                                            (beginning-of-line)
-                                            (looking-at "[ \t]*\\*/")))
-                                     (beginning-of-line)
-                                   (forward-line 1))
-                                 (point)))
-             (or (c-safe
-                  ;; fill-paragraph sometimes fails to detect when we
-                  ;; are between paragraphs.
-                  (beginning-of-line)
-                  (search-forward fill-prefix (c-point 'eol))
-                  (looking-at paragraph-separate))
-                 ;; Avoids recursion
-                 (let (fill-paragraph-function)
-                   (fill-paragraph arg)))
+               ;; 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
-               ;; Delete the chars we inserted to avoid clobbering
-               ;; the stuff before the comment start.
-               (goto-char (point-min))
-               (if (> chars-to-delete 0)
-                   (delete-region (point) (+ (point) chars-to-delete)))
-               ;; Find the comment ender (should be on last line of
-               ;; buffer, given the narrowing) and don't leave it on
-               ;; its own line, unless that's the style that's desired.
-               (goto-char (point-max))
-               (forward-line -1)
-               (search-forward "*/" nil 'move)
-               (beginning-of-line)
-               (if (and c-hanging-comment-ender-p
-                        (looking-at "[ \t]*\\*/"))
-                   ;(delete-indentation)))))
-                   (let ((fill-column (+ fill-column 9999)))
+               (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))))
+                     (goto-char (cdr lit-limits))
+                     (setq tmp-post (point-marker))
+                     (insert ?\n)
+                     (set-marker end (point))
                      (forward-line -1)
-                     (fill-region-as-paragraph (point) (point-max))
-                     ;; If fill-prefix ended with a `*', it may be
-                     ;; taken away from the comment ender.  We got to
-                     ;; check this and put it back if that is the
-                     ;; case.
-                     (goto-char (- (point-max) 2))
-                     (if (not (= (char-before) ?*))
-                         (insert ?*))
-                     )))))
-       ;; Else maybe a string.  Fill it if it's a multiline string.
-       ;; FIXME: This currently doesn't handle escaped newlines.
-       ;; Doing that correctly is a bit tricky.
-       (if (and limits
-                (eq (char-syntax (char-after (car limits))) ?\")
-                (save-excursion
-                  (goto-char (car limits))
-                  (end-of-line)
-                  (< (point) (cdr limits))))
-           (let (fill-paragraph-function)
-             (save-restriction
-               (narrow-to-region (save-excursion
-                                   (goto-char (1+ (car limits)))
-                                   (if (looking-at "\\\\$")
-                                       ;; Some DWIM: Leave the start
-                                       ;; line if it's nothing but an
-                                       ;; escaped newline.
-                                       (1+ (match-end 0))
-                                     (point)))
-                                 (save-excursion
-                                   (goto-char (1- (cdr limits)))
-                                   ;; Inserting a newline and
-                                   ;; removing it again after
-                                   ;; fill-paragraph makes it more
-                                   ;; predictable.
-                                   (insert ?\n)
-                                   (point)))
-               ;; Do not compensate for the narrowed column.  This
-               ;; way the literal will always be filled at the same
-               ;; column internally.
-               (fill-paragraph arg)
-               (goto-char (1- (point-max)))
-               (delete-char 1)))
-         )))
-    (goto-char (marker-position point-save))
-    (set-marker point-save 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.
-    t))
+                     (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.
+                         nil
+                       (goto-char ender-start))
+                     (skip-chars-backward " \t\r\n")
+                     (when (/= (point) ender-start)
+                       (insert ?x)     ; Insert first to keep marks right.
+                       (delete-region (point) (1+ ender-start))
+                       (setq hang-ender-stuck t)))))
+               (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'.
+             (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 -1)
+             (insert ?\ )
+             (delete-char 1))
+           (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.
+  t)
+
+(defun c-do-auto-fill ()
+  ;; Do automatic filling if not inside a context where it should be
+  ;; ignored.
+  (let ((c-auto-fill-prefix
+        ;; The decision whether the line should be broken is actually
+        ;; done in c-indent-new-comment-line, which do-auto-fill
+        ;; calls to break lines.  We just set this special variable
+        ;; so that we'll know when we're called from there.  It's
+        ;; also used to detect whether fill-prefix is user set or
+        ;; generated automatically by do-auto-fill.
+        fill-prefix))
+    (do-auto-fill)))
+
+(defun c-indent-new-comment-line (&optional soft)
+  "Break line at point and indent, continuing comment if within one.
+If inside a comment and `comment-multi-line' is non-nil, the
+indentation and line prefix are preserved (see the
+`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
+details).  If inside a comment and `comment-multi-line' is nil, a new
+comment of the same type is started on the next line and indented as
+appropriate for comments.
+
+If a fill prefix is specified, it overrides all the above."
+  (interactive)
+  (let ((fill-prefix fill-prefix)
+       (do-line-break
+        (lambda ()
+          (delete-region (progn (skip-chars-backward " \t") (point))
+                         (progn (skip-chars-forward " \t") (point)))
+          (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)
+      ;; Called from do-auto-fill.
+      (unless c-lit-limits
+       (setq c-lit-limits (c-literal-limits nil nil t)))
+      (unless c-lit-type
+       (setq c-lit-type (c-literal-type c-lit-limits)))
+      (if (memq (cond ((eq c-lit-type 'pound)
+                      ;; Come to think about it, "pound" is a bit
+                      ;; of a misnomer, so call it "cpp" instead
+                      ;; in user interaction.
+                      'cpp)
+                     ((null c-lit-type) 'code)
+                     (t c-lit-type))
+               c-ignore-auto-fill)
+         (setq fill-prefix t)          ; Used as flag in the cond.
+       (if (null c-auto-fill-prefix)
+           (setq fill-prefix nil))))
+    (cond ((eq fill-prefix t)
+          ;; A call from do-auto-fill which should be ignored.
+          )
+         (fill-prefix
+          ;; A fill-prefix overrides anything.
+          (funcall do-line-break)
+          (insert-and-inherit fill-prefix))
+         ((progn
+            (unless c-lit-limits
+              (setq c-lit-limits (c-literal-limits nil nil t)))
+            (unless c-lit-type
+              (setq c-lit-type (c-literal-type c-lit-limits)))
+            (memq c-lit-type '(c c++)))
+          (if comment-multi-line
+              ;; Inside a comment that should be continued.
+              (let ((fill (c-guess-fill-prefix
+                           (setq c-lit-limits
+                                 (c-collect-line-comments c-lit-limits))
+                           c-lit-type))
+                    (pos (point)))
+                (if (save-excursion
+                      (back-to-indentation)
+                      (> (point) (car c-lit-limits))
+                      (looking-at c-comment-prefix-regexp))
+                    (progn
+                      ;; Skip forward past the fill prefix in case
+                      ;; we're standing in it.
+                      (while (and (< (current-column) (cdr fill))
+                                  (not (eolp)))
+                        (forward-char 1))
+                      (if (> (point) (if (and (eq c-lit-type 'c)
+                                              (save-excursion
+                                                (forward-char -2)
+                                                (looking-at "\\*/")))
+                                         (- (cdr c-lit-limits) 2)
+                                       (cdr c-lit-limits)))
+                          (progn
+                            ;; The skip takes us out of the comment;
+                            ;; insert the fill prefix at bol instead
+                            ;; and keep the position.
+                            (setq pos (copy-marker pos t))
+                            (beginning-of-line)
+                            (insert-and-inherit (car fill))
+                            (if soft (insert-and-inherit ?\n) (newline 1))
+                            (goto-char pos)
+                            (set-marker pos nil))
+                        (funcall do-line-break)
+                        (insert-and-inherit (car fill))))
+                  (funcall do-line-break)
+                  (insert-and-inherit (car fill))))
+            ;; Inside a comment that should be broken.
+            (let ((comment-start comment-start)
+                  (comment-end comment-end)
+                  col)
+              (if (eq c-lit-type 'c)
+                  (unless (string-match "[ \t]*/\\*" comment-start)
+                    (setq comment-start "/* " comment-end " */"))
+                (unless (string-match "[ \t]*//" comment-start)
+                  (setq comment-start "// " comment-end "")))
+              (setq col (save-excursion
+                          (back-to-indentation)
+                          (current-column)))
+              (funcall do-line-break)
+              (when (and comment-end (not (equal comment-end "")))
+                (forward-char -1)
+                (insert-and-inherit comment-end)
+                (forward-char 1))
+              ;; c-comment-indent may look at the current
+              ;; indentation, so let's start out with the same
+              ;; indentation as the previous one.
+              (indent-to col)
+              (insert-and-inherit comment-start)
+              (indent-for-comment))))
+         (t
+          ;; Somewhere else in the code.
+          (let ((col (save-excursion
+                       (while (progn (back-to-indentation)
+                                     (and (looking-at "^\\s *$")
+                                          (= (forward-line -1) 0))))
+                       (current-column))))
+            (funcall do-line-break)
+            (indent-to col))))))
+
+(defalias 'c-comment-line-break-function 'c-indent-new-comment-line)
+(make-obsolete 'c-comment-line-break-function 'c-indent-new-comment-line)
+
+;; advice for indent-new-comment-line for older Emacsen
+(unless (boundp 'comment-line-break-function)
+  (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)
+           (not c-buffer-is-cc-mode))
+       ad-do-it
+      (let (c-inside-line-break-advice)
+       (c-indent-new-comment-line (ad-get-arg 0))))))
+
+(defun c-context-line-break ()
+  "Do a line break suitable to the context.
+
+When point is outside a comment, insert a newline and indent according
+to the syntactic context.
+
+When point is inside a comment, continue it with the appropriate
+comment prefix (see the `c-comment-prefix-regexp' and
+`c-block-comment-prefix' variables for details).  The end of a
+C++-style line comment doesn't count as inside the comment, though."
+  (interactive "*")
+  (let* ((c-lit-limits (c-literal-limits nil nil t))
+        (c-lit-type (c-literal-type c-lit-limits)))
+    (if (or (eq c-lit-type 'c)
+           (and (eq c-lit-type 'c++)
+                (< (point)
+                   (1- (cdr (setq c-lit-limits
+                                  (c-collect-line-comments c-lit-limits)))))))
+       (let ((comment-multi-line t)
+             (fill-prefix nil))
+         (c-indent-new-comment-line))
+      (delete-region (point) (progn (skip-chars-backward " \t") (point)))
+      (newline)
+      ;; c-indent-line may look at the current indentation, so let's
+      ;; start out with the same indentation as the previous line.
+      (let ((col (save-excursion
+                  (forward-line -1)
+                  (while (progn (back-to-indentation)
+                                (and (looking-at "^\\s *$")
+                                     (= (forward-line -1) 0))))
+                  (current-column))))
+       (indent-to col))
+      (c-indent-line))))
 
 \f
 (provide 'cc-cmds)
index d7556a6084e57caf63e2eca573c907a9fdd2e26e..93b4e5bc5afd2ca0bab1fee09bae3ca6589eea71 100644 (file)
@@ -1,9 +1,9 @@
 ;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
 ;; Author:     1994-1997 Barry A. Warsaw
-;; Maintainer: bug-cc-mode@gnu.org
+;; Maintainer: Unmaintained
 ;; Created:    August 1994, split from cc-mode.el
 ;; Version:    See cc-mode.el
 ;; Keywords:   c languages oop
 ;;; Code:
 
 (eval-when-compile
-  (require 'cc-defs)
-  (require 'cc-styles)
-  (require 'cc-engine))
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-styles)
+(require 'cc-engine)
 
 \f
 ;; In case c-mode.el isn't loaded
index 2ae6c7bdcf0161bc2bd8b47641a3622201442d95..e9b1a30d32e5d26147a95e46814fe4b5b73cd29a 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-defs.el --- compile time definitions for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-\f
 ;; Get all the necessary compile time definitions.
 (require 'custom)
-(require 'cc-menus)
 (require 'derived)                     ;only necessary in Emacs 20
 
 ;; cc-mode-19.el contains compatibility macros that should be compiled
@@ -48,7 +46,7 @@
     (require 'cc-mode-19))
 
 \f
-(defsubst c-point (position)
+(defmacro c-point (position)
   ;; Returns the value of point at certain commonly referenced POSITIONs.
   ;; POSITION can be one of the following symbols:
   ;; 
   ;; bopl -- beginning of previous line
   ;; 
   ;; This function does not modify point or mark.
-  (let ((here (point)))
-    (cond
-     ((eq position 'bol)  (beginning-of-line))
-     ((eq position 'eol)  (end-of-line))
-     ((eq position 'boi)  (back-to-indentation))
-     ((eq position 'bonl) (forward-line 1))
-     ((eq position 'bopl) (forward-line -1))
-     ((eq position 'iopl)
-      (forward-line -1)
-      (back-to-indentation))
-     ((eq position 'ionl)
-      (forward-line 1)
-      (back-to-indentation))
-     ((eq position 'eod)  (c-end-of-defun))
-     ((eq position 'bod)
-      (if (and (fboundp 'buffer-syntactic-context-depth)
-              c-enable-xemacs-performance-kludge-p)
-         ;; XEmacs only.  This can improve the performance of
-         ;; c-parse-state to between 3 and 60 times faster when
-         ;; braces are hung.  It can also degrade performance by
-         ;; about as much when braces are not hung.
-         (let (pos)
-           (while (not pos)
-             (save-restriction
-               (widen)
-               (setq pos (scan-lists (point) -1
-                                     (buffer-syntactic-context-depth)
-                                     nil t)))
-             (cond
-              ((bobp) (setq pos (point-min)))
-              ((not pos)
-               (let ((distance (skip-chars-backward "^{")))
-                 ;; unbalanced parenthesis, while illegal C code,
-                 ;; shouldn't cause an infloop!  See unbal.c
-                 (when (zerop distance)
-                   ;; Punt!
-                   (beginning-of-defun)
-                   (setq pos (point)))))
-              ((= pos 0))
-              ((not (eq (char-after pos) ?{))
-               (goto-char pos)
-               (setq pos nil))
-              ))
-           (goto-char pos))
-       ;; Emacs, which doesn't have buffer-syntactic-context-depth
-       ;;
-       ;; NOTE: This should be the only explicit use of
-       ;; beginning-of-defun in CC Mode.  Eventually something better
-       ;; than b-o-d will be available and this should be the only
-       ;; place the code needs to change.  Everything else should use
-       ;; (goto-char (c-point 'bod))
-       (beginning-of-defun)
-       ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at
-       ;; the open brace.
-       (and defun-prompt-regexp
-            (looking-at defun-prompt-regexp)
-            (goto-char (match-end 0)))
-       ))
-     (t (error "unknown buffer position requested: %s" position))
-     )
-    (prog1
-       (point)
-      (goto-char here))))
+  `(save-excursion
+     ,(if (and (eq (car-safe position) 'quote)
+              (symbolp (eval position)))
+         (let ((position (eval position)))
+           (cond
+            ((eq position 'bol)  `(beginning-of-line))
+            ((eq position 'eol)  `(end-of-line))
+            ((eq position 'boi)  `(back-to-indentation))
+            ((eq position 'bonl) `(forward-line 1))
+            ((eq position 'bopl) `(forward-line -1))
+            ((eq position 'bod)  `(c-beginning-of-defun-1))
+            ((eq position 'eod)  `(c-end-of-defun-1))
+            ((eq position 'iopl) `(progn
+                                    (forward-line -1)
+                                    (back-to-indentation)))
+            ((eq position 'ionl) `(progn
+                                    (forward-line 1)
+                                    (back-to-indentation)))
+            (t (error "unknown buffer position requested: %s" position))))
+       ;;(message "c-point long expansion")
+       `(let ((position ,position))
+          (cond
+           ((eq position 'bol)  (beginning-of-line))
+           ((eq position 'eol)  (end-of-line))
+           ((eq position 'boi)  (back-to-indentation))
+           ((eq position 'bonl) (forward-line 1))
+           ((eq position 'bopl) (forward-line -1))
+           ((eq position 'bod)  (c-beginning-of-defun-1))
+           ((eq position 'eod)  (c-end-of-defun-1))
+           ((eq position 'iopl) (progn
+                                  (forward-line -1)
+                                  (back-to-indentation)))
+           ((eq position 'ionl) (progn
+                                  (forward-line 1)
+                                  (back-to-indentation)))
+           (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))))
+  `(condition-case nil
+       (progn ,@body)
+     (error nil)))
+
+(defsubst c-beginning-of-defun-1 ()
+  ;; Wrapper around beginning-of-defun.
+  ;;
+  ;; NOTE: This function should contain the only explicit use of
+  ;; beginning-of-defun in CC Mode.  Eventually something better than
+  ;; b-o-d will be available and this should be the only place the
+  ;; code needs to change.  Everything else should use
+  ;; (c-beginning-of-defun-1)
+  (if (and (fboundp 'buffer-syntactic-context-depth)
+          c-enable-xemacs-performance-kludge-p)
+      ;; XEmacs only.  This can improve the performance of
+      ;; c-parse-state to between 3 and 60 times faster when
+      ;; braces are hung.  It can also degrade performance by
+      ;; about as much when braces are not hung.
+      (let (pos)
+       (while (not pos)
+         (save-restriction
+           (widen)
+           (setq pos (scan-lists (point) -1
+                                 (buffer-syntactic-context-depth)
+                                 nil t)))
+         (cond
+          ((bobp) (setq pos (point-min)))
+          ((not pos)
+           (let ((distance (skip-chars-backward "^{")))
+             ;; unbalanced parenthesis, while illegal C code,
+             ;; shouldn't cause an infloop!  See unbal.c
+             (when (zerop distance)
+               ;; Punt!
+               (beginning-of-defun)
+               (setq pos (point)))))
+          ((= pos 0))
+          ((not (eq (char-after pos) ?{))
+           (goto-char pos)
+           (setq pos nil))
+          ))
+       (goto-char pos))
+    ;; Emacs, which doesn't have buffer-syntactic-context-depth
+    (beginning-of-defun))
+  ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at the
+  ;; open brace.
+  (and defun-prompt-regexp
+       (looking-at defun-prompt-regexp)
+       (goto-char (match-end 0))))
+
+(defsubst c-end-of-defun-1 ()
+  ;; Replacement for end-of-defun that use c-beginning-of-defun-1.
+  (while (and (c-safe (down-list 1) t)
+             (not (eq (char-before) ?{)))
+    ;; skip down into the next defun-block
+    (forward-char -1)
+    (c-forward-sexp))
+  (c-beginning-of-defun-1)
+  (c-forward-sexp))
 
 (defmacro c-forward-sexp (&optional arg)
   ;; like forward-sexp except
   (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. ;)
+  (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).
+         (if (and (eolp) (nth 7 (parse-partial-sexp here (point))))
+             (condition-case nil (forward-char 1)))
+         t)
+      ;; When we got newline terminated comments,
+      ;; forward-comment in all supported emacsen so far will
+      ;; stop at eol of each line not ending with a comment when
+      ;; moving backwards.  The following corrects for it when
+      ;; count is -1.  The other common case, when count is
+      ;; large and negative, works regardless.  It's too much
+      ;; work to correct for the rest of the cases.
+      (skip-chars-backward " \t\n\r\f")
+      (if (bobp)
+         ;; Some emacsen return t when moving backwards at bob.
+         nil
+       (re-search-forward "[\n\r]" here 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))))
+  `(setq syntax (cons (cons ,symbol ,relpos) syntax)))
 
-(defsubst c-auto-newline ()
+(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))))))
+
+(defmacro c-auto-newline ()
   ;; if auto-newline feature is turned on, insert a newline character
   ;; and return t, otherwise return nil.
-  (and c-auto-newline
-       (not (c-in-literal))
-       (not (newline))))
+  `(and c-auto-newline
+       (not (c-in-literal))
+       (not (newline))))
 
 (defsubst c-intersect-lists (list alist)
   ;; return the element of ALIST that matches the first element found
          (goto-char here))
       )))
 
-(defsubst c-update-modeline ()
+(defmacro c-update-modeline ()
   ;; set the c-auto-hungry-string for the correct designation on the modeline
-  (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))
+  `(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.
   (cond
    ;; XEmacs
    ((and (fboundp 'region-active-p)
+        (boundp 'zmacs-regions)
         zmacs-regions)
     (region-active-p))
    ;; Emacs
 (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-defs.el ends here
index fccb032e62cdb203132fbad2e640137d6ae61977..08ed5eb26644f0a0a5ecde48fcb868c4fa60b04c 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-engine.el --- core syntax guessing engine for CC mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-\f
 (eval-when-compile
-  (require 'cc-defs))
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-langs)
 
+\f
 ;; 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
           ;; CASE 2: some other kind of literal?
           ((c-in-literal lim))
           ;; CASE 3: are we looking at a conditional keyword?
-          ((or (looking-at c-conditional-key)
+          ((or (and c-conditional-key (looking-at c-conditional-key))
                (and (eq (char-after) ?\()
                     (save-excursion
                       (c-forward-sexp 1)
                                          (<= lim (point))
                                          (not (c-in-literal lim))
                                          (not (eq (char-before) ?_))
+                                         c-conditional-key
                                          (looking-at c-conditional-key)
                                          ))))
                       ;; did we find a conditional?
                (setq substmt-p nil))
            (setq last-begin (point)
                  donep substmt-p))
-          ;; CASE 4: are we looking at a label?
-          ((looking-at c-label-key))
+          ;; CASE 4: are we looking at a label?  (But we handle
+          ;; switch labels later.)
+          ((and (looking-at c-label-key)
+                (not (looking-at "default\\>"))))
           ;; CASE 5: is this the first time we're checking?
           (firstp (setq firstp nil
                         substmt-p (not (c-crosses-statement-barrier-p
                     ;; `case' or `default' is first thing on line
                     (let ((here (point)))
                       (beginning-of-line)
-                      (c-forward-syntactic-ws)
+                      (c-forward-syntactic-ws here)
                       (if (looking-at c-switch-label-key)
                           t
                         (goto-char here)
     ;; 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 ()
         (hugenum (point-max)))
     (while (/= here (point))
       (setq here (point))
-      (forward-comment hugenum)
+      (c-forward-comment hugenum)
       ;; skip preprocessor directives
       (when (and (eq (char-after) ?#)
                 (= (c-point 'boi) (point)))
       )
     (if lim (goto-char (min (point) lim)))))
 
-(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 (eq (char-after) ?#)
-       t
-      (goto-char here)
-      nil)))
-
 (defun c-backward-syntactic-ws (&optional lim)
   ;; Backward skip over syntactic whitespace for Emacs 19.
   (let* ((here (point-min))
         (hugenum (- (point-max))))
     (while (/= here (point))
       (setq here (point))
-      (forward-comment hugenum)
+      (c-forward-comment hugenum)
       (c-beginning-of-macro))
     (if lim (goto-char (max (point) lim)))))
 
 (if (fboundp 'buffer-syntactic-context)
     (defalias 'c-in-literal 'c-fast-in-literal))
 
-(defun c-literal-limits (&optional lim near)
+(defun c-literal-limits (&optional lim near not-in-delimiter)
   ;; Returns a cons of the beginning and end positions of the comment
   ;; or string surrounding point (including both delimiters), or nil
   ;; if point isn't in one.  If LIM is non-nil, it's used as the
   ;; "safe" position to start parsing from.  If NEAR is non-nil, then
   ;; the limits of any literal next to point is returned.  "Next to"
   ;; means there's only [ \t] between point and the literal.  The
-  ;; search for such a literal is done first in forward direction.
-  ;;
-  ;; This is the Emacs 19 version.
+  ;; search for such a literal is done first in forward direction.  If
+  ;; NOT-IN-DELIMITER is non-nil, the case when point is inside a
+  ;; starting delimiter won't be recognized.  This only has effect for
+  ;; comments, which have starting delimiters with more than one
+  ;; character.
   (save-excursion
     (let* ((pos (point))
           (lim (or lim (c-point 'bod)))
                            lim (point) nil nil state)
                     lim (point)))
             (backward-char 2)
-            (cons (point) (progn (forward-comment 1) (point))))
+            (cons (point) (progn (c-forward-comment 1) (point))))
            ((nth 4 state)
             ;; Block comment.  Search backward for the comment starter.
             (while (nth 4 state)
               (search-backward "/*")   ; Should never fail.
               (setq state (parse-partial-sexp lim (point))))
-            (cons (point) (progn (forward-comment 1) (point))))
-           ((c-safe (nth 4 (parse-partial-sexp ; Can't use prev state due
-                            lim (1+ (point))))) ; to bug in Emacs 19.34.
+            (cons (point) (progn (c-forward-comment 1) (point))))
+           ((and (not not-in-delimiter)
+                 (not (nth 5 state))
+                 (eq (char-before) ?/)
+                 (looking-at "[/*]"))
             ;; We're standing in a comment starter.
-            (backward-char 2)
-            (cons (point) (progn (forward-comment 1) (point))))
+            (backward-char 1)
+            (cons (point) (progn (c-forward-comment 1) (point))))
            (near
             (goto-char pos)
             ;; Search forward for a literal.
               (cons (point) (or (c-safe (c-forward-sexp 1) (point))
                                 (point-max))))
              ((looking-at "/[/*]")     ; Line or block comment.
-              (cons (point) (progn (forward-comment 1) (point))))
+              (cons (point) (progn (c-forward-comment 1) (point))))
              (t
               ;; Search backward.
               (skip-chars-backward " \t")
                   ;; comments, they will always be covered by the
                   ;; normal case above.
                   (goto-char end)
-                  (forward-comment -1)
+                  (c-forward-comment -1)
                   ;; If LIM is bogus, beg will be bogus.
                   (setq beg (point))))
                 (if beg (cons beg end))))))
            ))))
 
-(defun c-literal-limits-fast (&optional lim)
+(defun c-literal-limits-fast (&optional lim near not-in-delimiter)
   ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
-  ;; returns the pos of the comment start.  FIXME: Add NEAR.
+  ;; returns the pos of the comment start.
   (save-excursion
-    (let ((state (parse-partial-sexp lim (point))))
+    (let* ((pos (point))
+          (lim (or lim (c-point 'bod)))
+          (state (parse-partial-sexp lim (point))))
       (cond ((nth 3 state)             ; String.
             (goto-char (nth 8 state))
             (cons (point) (or (c-safe (c-forward-sexp 1) (point))
                               (point-max))))
            ((nth 4 state)              ; Comment.
             (goto-char (nth 8 state))
-            (cons (point) (progn (forward-comment 1) (point))))
-           ((c-safe
-             (nth 4 (parse-partial-sexp ; Works?
-                     (point) (1+ (point)) nil nil state)))
-            ;; We're in a comment starter.
-            (backward-char 2)
-            (cons (point) (progn (forward-comment 1) (point))))
+            (cons (point) (progn (c-forward-comment 1) (point))))
+           ((and (not not-in-delimiter)
+                 (not (nth 5 state))
+                 (eq (char-before) ?/)
+                 (looking-at "[/*]"))
+            ;; We're standing in a comment starter.
+            (backward-char 1)
+            (cons (point) (progn (c-forward-comment 1) (point))))
+           (near
+            (goto-char pos)
+            ;; Search forward for a literal.
+            (skip-chars-forward " \t")
+            (cond
+             ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
+              (cons (point) (or (c-safe (c-forward-sexp 1) (point))
+                                (point-max))))
+             ((looking-at "/[/*]")     ; Line or block comment.
+              (cons (point) (progn (c-forward-comment 1) (point))))
+             (t
+              ;; Search backward.
+              (skip-chars-backward " \t")
+              (let ((end (point)) beg)
+                (cond
+                 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String.
+                  (setq beg (c-safe (c-backward-sexp 1) (point))))
+                 ((and (c-safe (forward-char -2) t)
+                       (looking-at "*/"))
+                  ;; Block comment.  Due to the nature of line
+                  ;; comments, they will always be covered by the
+                  ;; normal case above.
+                  (goto-char end)
+                  (c-forward-comment -1)
+                  ;; If LIM is bogus, beg will be bogus.
+                  (setq beg (point))))
+                (if beg (cons beg end))))))
            ))))
 
+(if (c-safe (> (length (save-excursion (parse-partial-sexp 1 1))) 8))
+    (defalias 'c-literal-limits 'c-literal-limits-fast))
+
 (defun c-collect-line-comments (range)
   ;; If the argument is a cons of two buffer positions (such as
   ;; returned by c-literal-limits), and that range contains a C++
            (let ((col (current-column))
                  (beg (point))
                  (end (cdr range)))
-             (while (and (not (bobp))
-                         (forward-comment -1)
+             (while (and (c-forward-comment -1)
                          (looking-at "//")
                          (= col (current-column)))
                (setq beg (point)))
              (goto-char end)
-             (while (progn
-                      (skip-chars-forward " \t")
-                      (and (looking-at "//")
-                           (= col (current-column))))
-               (forward-comment 1)
-               (setq end (point)))
+             (while (and (progn (skip-chars-forward " \t")
+                                (looking-at "//"))
+                         (= col (current-column))
+                         (prog1 (zerop (forward-line 1))
+                           (setq end (point)))))
              (cons beg end))
          range)
       (error range))))
   ;; It's much faster than using c-in-literal and is intended to be
   ;; used when you need both the type of a literal and its limits.
   (if (consp range)
-    (save-excursion
-      (goto-char (car range))
-      (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
-           ((looking-at "//") 'c++)
-           (t 'c)))                    ; Assuming the range is valid.
+      (save-excursion
+       (goto-char (car range))
+       (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
+             ((looking-at "//") 'c++)
+             (t 'c)))                  ; Assuming the range is valid.
     range))
 
 
@@ -1230,28 +1260,32 @@ brace."
   ;; backward search.
   (save-excursion
     (or lim (setq lim (point-min)))
-    (if (and (eq (char-after) ?{)
-            (progn (c-backward-syntactic-ws) (> (point) lim))
-            (eq (char-before) ?\()
-            (not (and c-special-brace-lists
-                      (c-looking-at-special-brace-list))))
-       (cons 'inexpr-statement (point))
-      (let (res)
-       (while (and (not res)
-                   (= (c-backward-token-1 1 t lim) 0)
-                   (>= (point) lim)
-                   (looking-at "(\\|\\w\\|\\s_\\|\\."))
-         (setq res
-               (cond ((and c-inexpr-class-key
-                           (looking-at c-inexpr-class-key))
-                      (cons 'inexpr-class (point)))
-                     ((and c-inexpr-block-key
-                           (looking-at c-inexpr-block-key))
-                      (cons 'inexpr-statement (point)))
-                     ((and c-lambda-key
-                           (looking-at c-lambda-key))
-                      (cons 'inlambda (point))))))
-       res))))
+    (let ((block-follows (eq (char-after) ?{)))
+      ;; Look at the character after point only as a last resort when
+      ;; we can't disambiguate.
+      (if (and block-follows
+              (progn (c-backward-syntactic-ws) (> (point) lim))
+              (eq (char-before) ?\()
+              (not (and c-special-brace-lists
+                        (c-looking-at-special-brace-list))))
+         (cons 'inexpr-statement (point))
+       (let (res)
+         (while (and (not res)
+                     (= (c-backward-token-1 1 t lim) 0)
+                     (>= (point) lim)
+                     (looking-at "(\\|\\w\\|\\s_\\|\\."))
+           (setq res
+                 (cond ((and block-follows
+                             c-inexpr-class-key
+                             (looking-at c-inexpr-class-key))
+                        (cons 'inexpr-class (point)))
+                       ((and c-inexpr-block-key
+                             (looking-at c-inexpr-block-key))
+                        (cons 'inexpr-statement (point)))
+                       ((and c-lambda-key
+                             (looking-at c-lambda-key))
+                        (cons 'inlambda (point))))))
+         res)))))
 
 (defun c-looking-at-inexpr-block-backward (&optional lim)
   ;; Returns non-nil if we're looking at the end of an in-expression
@@ -1323,19 +1357,6 @@ brace."
     ;; return the class vector
     inclass-p))
 
-(defsubst 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)
-    (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)))))
-
 \f
 ;; This function implements the main decision tree for determining the
 ;; syntactic analysis of the current line of code.  Yes, it's huge and
@@ -1425,10 +1446,7 @@ brace."
          (c-add-syntax 'string (c-point 'bopl)))
         ;; CASE 2: in a C or C++ style comment.
         ((memq literal '(c c++))
-         ;; we need to catch multi-paragraph C comments
-         (while (and (zerop (forward-line -1))
-                     (looking-at "^[ \t]*$")))
-         (c-add-syntax literal (c-point 'boi)))
+         (c-add-syntax literal (car (c-literal-limits lim))))
         ;; CASE 3: in a cpp preprocessor macro
         ((eq literal 'pound)
          (let ((boi (c-point 'boi))
@@ -1638,9 +1656,16 @@ brace."
              ;; don't add inclass symbol since relative point already
              ;; contains any class offset
              )))
-          ;; CASE 5D: this could be a top-level compound statement or a
-          ;; member init list continuation
-          ((eq char-before-ip ?,)
+          ;; CASE 5D: this could be a top-level compound statement, a
+          ;; member init list continuation, or a template argument
+          ;; list continuation.
+          ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+                                    c++-template-syntax-table
+                                  (syntax-table))
+             (save-excursion
+               (while (and (= (c-backward-token-1 1 t lim) 0)
+                           (not (looking-at "[;{<,]"))))
+               (eq (char-after) ?,)))
            (goto-char indent-point)
            (c-backward-syntactic-ws lim)
            (while (and (< lim (point))
@@ -1659,7 +1684,6 @@ brace."
             ;; for bogus matches on access specifiers inside classes.
             ((and (save-excursion
                     ;; There might be member inits on the first line too.
-                    (end-of-line)
                     (while (and (> (point) lim)
                                 (eq (char-before) ?,)
                                 (= (c-backward-token-1 2 t lim) 0)
@@ -1667,15 +1691,16 @@ brace."
                                 (= (c-backward-token-1 1 t lim) 0))
                       (c-backward-syntactic-ws lim))
                     (setq placeholder (point))
-                    (c-backward-syntactic-ws lim)
-                    (eq (char-before) ?:))
+                    (c-backward-token-1 1 t lim)
+                    (and (eq (char-after) ?:)
+                         (not (eq (char-before) ?:))))
                   (save-excursion
                     (goto-char placeholder)
                     (back-to-indentation)
                     (and
-                     c-access-key
-                     (not (looking-at c-access-key))
-                     (not (looking-at c-class-key)))
+                     (if c-access-key (not (looking-at c-access-key)) t)
+                     (not (looking-at c-class-key))
+                     (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
                     ))
              (goto-char placeholder)
              (c-forward-syntactic-ws)
@@ -1708,7 +1733,7 @@ brace."
              ;; we can probably indent it just like an arglist-cont
              (goto-char placeholder)
              (c-beginning-of-statement-1 lim)
-             (c-add-syntax 'template-args-cont (point)))
+             (c-add-syntax 'template-args-cont (c-point 'boi)))
             ;; CASE 5D.5: perhaps a top-level statement-cont
             (t
              (c-beginning-of-statement-1 lim)
@@ -1821,7 +1846,13 @@ brace."
                   (beginning-of-line)
                   (looking-at c-method-key)))
            (c-add-syntax 'objc-method-args-cont (point)))
-          ;; CASE 5K: we are at a topmost continuation line
+          ;; CASE 5K: we are at the first argument of a template
+          ;; arglist that begins on the previous line.
+          ((eq (char-before) ?<)
+           (c-beginning-of-statement-1 lim)
+           (c-forward-syntactic-ws)
+           (c-add-syntax 'template-args-cont (c-point 'boi)))
+          ;; CASE 5L: we are at a topmost continuation line
           (t
            (c-beginning-of-statement-1 lim)
            (c-forward-syntactic-ws)
@@ -1839,12 +1870,9 @@ brace."
            ;; It's a Pike lambda.  Check whether we are between the
            ;; lambda keyword and the argument list or at the defun
            ;; opener.
-           (setq tmpsymbol
-                 (if (save-excursion
-                       (and (c-safe (c-forward-sexp -1) t)
-                            (looking-at c-lambda-key)))
-                     'lambda-intro-cont
-                   'inline-open)))
+           (setq tmpsymbol (if (eq char-after-ip ?{)
+                               'inline-open
+                             'lambda-intro-cont)))
          (goto-char (cdr placeholder))
          (c-add-syntax tmpsymbol (c-point 'boi))
          (c-add-syntax (car placeholder)))
@@ -1859,7 +1887,10 @@ brace."
          (c-backward-syntactic-ws containing-sexp)
          (cond
           ;; CASE 7A: we are looking at the arglist closing paren
-          ((and (not (eq char-before-ip ?,))
+          ((and (or (c-major-mode-is 'pike-mode)
+                    ;; Don't check this in Pike since it allows a
+                    ;; comma after the last arg.
+                    (not (eq char-before-ip ?,)))
                 (memq char-after-ip '(?\) ?\])))
            (goto-char containing-sexp)
            (c-add-syntax 'arglist-close (c-point 'boi)))
@@ -1961,10 +1992,13 @@ brace."
           ((and (consp special-brace-list)
                 (eq char-after-ip (car (cdr special-brace-list))))
            (goto-char (car (car special-brace-list)))
-           (c-beginning-of-statement-1 lim)
-           (c-forward-token-1 0)
-           (if (looking-at "typedef\\>") (c-forward-token-1 1))
-           (c-add-syntax 'brace-list-open (c-point 'boi)))
+           (skip-chars-backward " \t")
+           (if (bolp)
+               (setq syntax (c-guess-basic-syntax))
+             (c-beginning-of-statement-1 lim)
+             (c-forward-token-1 0)
+             (if (looking-at "typedef\\>") (c-forward-token-1 1))
+             (c-add-syntax 'brace-list-open (c-point 'boi))))
           ;; CASE 9B: brace-list-close brace
           ((if (consp special-brace-list)
                ;; Check special brace list closer.
@@ -2034,7 +2068,7 @@ brace."
          (let ((after-cond-placeholder
                 (save-excursion
                   (goto-char placeholder)
-                  (if (looking-at c-conditional-key)
+                  (if (and c-conditional-key (looking-at c-conditional-key))
                       (progn
                         (c-safe (c-skip-conditional))
                         (c-forward-syntactic-ws)
@@ -2078,7 +2112,14 @@ brace."
                                  (= (c-backward-token-1 1 t) 0)
                                  (/= (char-after) ?=)))
                      (eq (char-after) ?=)))
-               (c-add-syntax 'brace-list-open placeholder))
+               ;; The most semantically accurate symbol here is
+               ;; brace-list-open, but we report it simply as a
+               ;; statement-cont.  The reason is that one normally
+               ;; adjusts brace-list-open for brace lists as
+               ;; top-level constructs, and brace lists inside
+               ;; statements is a completely different context.
+               (goto-char placeholder)
+               (c-add-syntax 'statement-cont (c-point 'boi)))
               ;; CASE 10B.3: catch-all for unknown construct.
               (t
                ;; Can and should I add an extensibility hook here?
@@ -2131,7 +2172,8 @@ brace."
                   (setq placeholder (point))
                   (looking-at "do\\b[^_]"))
                 ))
-         (c-add-syntax 'do-while-closure placeholder))
+         (goto-char placeholder)
+         (c-add-syntax 'do-while-closure (c-point 'boi)))
         ;; CASE 13: A catch or finally clause?  This case is simpler
         ;; than if-else and do-while, because a block is required
         ;; after every try, catch and finally.
@@ -2405,6 +2447,17 @@ With universal argument, inserts the analysis as a comment on that line."
       ))
   (c-keep-region-active))
 
+(defun c-syntactic-information-on-region (from to)
+  "Inserts a comment with the syntactic analysis on every line in the region."
+  (interactive "*r")
+  (save-excursion
+    (save-restriction
+      (narrow-to-region from to)
+      (goto-char (point-min))
+      (while (not (eobp))
+       (c-show-syntactic-information '(0))
+       (forward-line)))))
+
 \f
 (provide 'cc-engine)
 ;;; cc-engine.el ends here
index 912e36446bb703ea1cb30fa8d06680727f7c2167..255ce7420e248ea4315e2a0be841ec77deb15d18 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-langs.el --- specific language support for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; 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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-styles)
+
+;; 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)
 
 \f
-(eval-when-compile
-  (require 'cc-defs))
+(defvar c-buffer-is-cc-mode nil
+  "Non-nil for all buffers with a `major-mode' derived from CC Mode.
+Otherwise, this variable is nil. I.e. this variable is non-nil for
+`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode',
+`pike-mode', and any other non-CC Mode mode that calls
+`c-initialize-cc-mode' (e.g. `awk-mode').")
+(make-variable-buffer-local 'c-buffer-is-cc-mode)
+(put 'c-buffer-is-cc-mode 'permanent-local t)
 
+\f
 ;; Regular expressions and other values which must be parameterized on
 ;; a per-language basis.
 
@@ -56,7 +83,7 @@
 ;; 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 "\\(class\\|struct\\|union\\|interface\\)")
+(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\\)")
 (defvar c-extra-toplevel-key c-C-extra-toplevel-key)
 (make-variable-buffer-local 'c-extra-toplevel-key)
 
+;; Keywords that can introduce bitfields in the languages that supports that.
+(defconst c-C-bitfield-key "\\(char\\|int\\|long\\|signed\\|unsigned\\)")
+
+(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-ObjC-access-key (concat "@" c-protection-key))
 (defconst c-Java-access-key nil)
 (defconst c-Pike-access-key nil)
 ;; keywords introducing conditional blocks
 (defconst c-C-conditional-key nil)
 (defconst c-C++-conditional-key nil)
+(defconst c-IDL-conditional-key nil)
+(defconst c-ObjC-conditional-key nil)
 (defconst c-Java-conditional-key nil)
 (defconst c-Pike-conditional-key nil)
 
       (back    "\\)\\b[^_]"))
   (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.
+       c-ObjC-conditional-key c-C-conditional-key
        c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)
        c-Pike-conditional-key (concat front all-kws "\\|foreach" back)))
 
 \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)
+(defconst c-IDL-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-ObjC-comment-start-regexp c-C++-comment-start-regexp)
+(defconst c-Pike-comment-start-regexp c-C++-comment-start-regexp)
 ;; We need to match all 3 Java style comments
 ;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
 (defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)")
 
 ;; Regexp describing Javadoc markup that always starts paragraphs.
 (defconst c-Java-javadoc-paragraph-start
-  "@\\(author\\|exception\\|param\\|return\\|see\\|version\\)")
+  "@\\(author\\|exception\\|param\\|return\\|see\\|throws\\|version\\)")
 
 ;; Regexp that starts lambda constructs.
 (defvar c-lambda-key nil)
   ;; Common initializations for all modes.
   ;; these variables should always be buffer local; they do not affect
   ;; indentation style.
-  (make-local-variable 'paragraph-start)
-  (make-local-variable 'paragraph-separate)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
   (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 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (make-local-variable 'adaptive-fill-regexp)
+  (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)
-       (make-local-variable 'comment-line-break-function))
-  ;; Emacs 19.30 and beyond only, AFAIK
-  (if (boundp 'fill-paragraph-function)
-      (progn
-       (make-local-variable 'fill-paragraph-function)
-       (setq fill-paragraph-function 'c-fill-paragraph)))
+       (progn
+        (make-local-variable 'comment-line-break-function)
+        (setq comment-line-break-function
+              'c-indent-new-comment-line)))
   ;; now set their values
-  (setq paragraph-start (concat page-delimiter "\\|$")
-       paragraph-separate paragraph-start
-       paragraph-ignore-fill-prefix t
-       require-final-newline t
+  (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 nil
-       comment-line-break-function 'c-comment-line-break-function
-       adaptive-fill-regexp nil
-       adaptive-fill-mode nil)
+       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 "$\\|"
+                                 page-delimiter)
+         paragraph-separate paragraph-start
+         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))
       (setq minor-mode-alist
            (cons '(c-auto-hungry-string c-auto-hungry-string)
                  minor-mode-alist)))
-  ;; now set the mode style based on c-default-style
-  (c-set-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")))
   )
 
 
@@ -386,31 +459,49 @@ Note that the style variables are always made local to the buffer."
   ;; 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)
-  (define-key c-mode-base-map "\ea"       'c-beginning-of-statement)
-  (define-key c-mode-base-map "\ee"       'c-end-of-statement)
+  (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)
-  (define-key c-mode-base-map "\t"        'c-indent-command)
+  (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. :-(
   ;;
-  ;; 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.
-  (if (not (boundp 'delete-key-deletes-forward))
-      (define-key c-mode-base-map "\177" 'c-electric-backspace)
-    ;; However, XEmacs 20 actually achieved enlightenment.  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))
+  (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)
@@ -430,10 +521,6 @@ Note that the style variables are always made local to the buffer."
   ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
   )
 
-;; menu support for both XEmacs and Emacs.  If you don't have easymenu
-;; with your version of Emacs, you are incompatible!
-(require 'easymenu)
-
 (defvar c-c-menu nil)
 (defvar c-c++-menu nil)
 (defvar c-objc-menu nil)
@@ -524,6 +611,17 @@ Note that the style variables are always made local to the buffer."
   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
   )
 
+(defvar c++-template-syntax-table nil
+  "A variant of `c++-mode-syntax-table' that defines `<' and `>' as
+parenthesis characters.  Used temporarily when template argument lists
+are parsed.")
+(if c++-template-syntax-table
+    ()
+  (setq c++-template-syntax-table
+       (copy-syntax-table c++-mode-syntax-table))
+  (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++"))
 
index 83dd49f21c3182660078f0728629c97e3021f6fa..8eb10050d015687359ca9bea11eec89710739abb 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-menus.el --- imenu support for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-;; Pull in Imenu when compiling, if it exists
 (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+
+;; Dummy definitions to shut up the compiler in case imenu doesn't exist.
+(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.
+(eval-and-compile
   (condition-case nil
       (require 'imenu)
     (error nil)))
@@ -52,14 +67,12 @@ For example:
 A sample value might look like: `\\(_P\\|_PROTO\\)'.")
 
 (defvar cc-imenu-c++-generic-expression
-  (` 
-   (
+  `(
     ;; Try to match ::operator definitions first. Otherwise `X::operator new ()'
     ;; will be incorrectly recognised as function `new ()' because the regexps
     ;; work by backtracking from the end of the definition.
     (nil
-     (, 
-      (concat
+     ,(concat
        "^\\<.*"
        "[^a-zA-Z0-9_:<>~]"                    ; match any non-identifier char
                                               ; (note: this can be `\n')
@@ -77,37 +90,35 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
                                               ; the parentheses surrounding
                                               ; the parameters.  e.g.:
                                               ; `int foo(int a=bar()) {...}'
-       )) 1)
+       ) 1)
     ;; Special case to match a line like `main() {}'
     ;; e.g. no return type, not even on the previous line.
     (nil
-     (, 
-      (concat
+     ,(concat
        "^"
        "\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)"     ; match function name
        "[ \t]*("                             ; see above, BUT
        "[ \t]*\\([^ \t(*][^)]*\\)?)"          ; the arg list must not start
        "[ \t]*[^ \t;(]"                       ; with an asterisk or parentheses
-       )) 1)
+       ) 1)
     ;; General function name regexp
     (nil
-     (, 
-      (concat
-       "^\\<.*"                               ; line MUST start with word char
+     ,(concat
+       "^\\<"                                 ; line MUST start with word char
+       "[^()]*"                               ; no parentheses before
        "[^a-zA-Z0-9_:<>~]"                    ; match any non-identifier char
        "\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)"     ; match function name
        "[ \t]*("                             ; see above, BUT
        "[ \t]*\\([^ \t(*][^)]*\\)?)"          ; the arg list must not start
        "[ \t]*[^ \t;(]"                       ; with an asterisk or parentheses
-       )) 1)
+       ) 1)
     ;; Special case for definitions using phony prototype macros like:
     ;; `int main _PROTO( (int argc,char *argv[]) )'.
     ;; This case is only included if cc-imenu-c-prototype-macro-regexp is set.
     ;; Only supported in c-code, so no `:<>~' chars in function name!
-    (,@ (if cc-imenu-c-prototype-macro-regexp
-            (` ((nil
-                 (,
-                  (concat
+    ,@(if cc-imenu-c-prototype-macro-regexp
+            `((nil
+                 ,(concat
                    "^\\<.*"                   ; line MUST start with word char
                    "[^a-zA-Z0-9_]"            ; match any non-identifier char
                    "\\([a-zA-Z_][a-zA-Z0-9_]*\\)"       ; match function name
@@ -115,10 +126,10 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
                    cc-imenu-c-prototype-macro-regexp
                    "[ \t]*("                  ; ws followed by first paren.
                    "[ \t]*([^)]*)[ \t]*)[ \t]*[^ \t;]" ; see above
-                   )) 1)))))
+                   ) 1)))
     ;; Class definitions
     ("Class" 
-     (, (concat 
+     ,(concat
          "^"                                  ; beginning of line is required
          "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>'
          "class[ \t]+"
@@ -126,8 +137,8 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
          "[a-zA-Z0-9_]+"                      ; class name
          "\\(<[^>]+>\\)?"                     ; possibly explicitely specialized
          "\\)"
-         "[ \t]*[:{]"
-         )) 2)))
+         "[ \t\n]*[:{]"
+         ) 2))
   "Imenu generic expression for C++ mode.  See `imenu-generic-expression'.")
  
 (defvar cc-imenu-c-generic-expression
@@ -135,22 +146,20 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
   "Imenu generic expression for C mode.  See `imenu-generic-expression'.")
 
 (defvar cc-imenu-java-generic-expression
-  (`
-   ((nil
-     (,
-      (concat
+  `((nil
+     ,(concat
        "^\\([ \t]\\)*"
-       "\\([A-Za-z0-9_-]+[ \t]+\\)?"         ; type specs; there can be
-        "\\([A-Za-z0-9_-]+[ \t]+\\)?"        ; more than 3 tokens, right?
-       "\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
+       "\\([.A-Za-z0-9_-]+[ \t]+\\)?"        ; type specs; there can be
+       "\\([.A-Za-z0-9_-]+[ \t]+\\)?"        ; more than 3 tokens, right?
+       "\\([.A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
        "\\([ \t]\\)"
        "\\([A-Za-z0-9_-]+\\)"                ; the string we want to get
        "\\([ \t]*\\)+("
-       "[][a-zA-Z,_1-9\n \t]*"   ; arguments
+       "[][a-zA-Z,_1-9\n \t]*"               ; arguments
        ")[ \t]*"
 ;       "[^;(]"
        "[,a-zA-Z_1-9\n \t]*{"               
-       )) 6)))
+       ) 6))
   "Imenu generic expression for Java mode.  See `imenu-generic-expression'.")
 
 ;;                        *Warning for cc-mode developers* 
@@ -398,6 +407,10 @@ Example:
 ;  ())
 ; FIXME: Please contribute one!
 
+(defun cc-imenu-init (mode-generic-expression)
+  (setq imenu-generic-expression mode-generic-expression
+       imenu-case-fold-search nil))
+
 \f
 (provide 'cc-menus)
 ;;; cc-menus.el ends here
index 06e7a18b0d52ea158733cf908ec1d737f3e730f4..83c8c566104d756d7455228a1b3d9b481854a0f1 100644 (file)
@@ -1,8 +1,8 @@
 ;;; 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 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
@@ -10,7 +10,7 @@
 ;; Created:    a long, long, time ago. adapted from the original c-mode.el
 ;; Keywords:   c languages oop
 
-(defconst c-version "5.25"
+(defconst c-version "5.26e"
   "CC Mode version number.")
 
 ;; NOTE: Read the commentary below for the right way to submit bug reports!
 
 ;;; Code:
 
-\f
-(defvar c-buffer-is-cc-mode nil
-  "Non-nil for all buffers with a `major-mode' derived from CC Mode.
-Otherwise, this variable is nil. I.e. this variable is non-nil for
-`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode',
-`pike-mode', and any other non-CC Mode mode that calls
-`c-initialize-cc-mode' (e.g. `awk-mode').")
-(make-variable-buffer-local 'c-buffer-is-cc-mode)
-(put 'c-buffer-is-cc-mode 'permanent-local t)
-
-(eval-and-compile
-  (require 'cc-defs))
+(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)
+          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-engine)
+(require 'cc-styles)
 (require 'cc-langs)
+(require 'cc-engine)
 (require 'cc-align)
-(require 'cc-styles)
 (require 'cc-cmds)
 
-
 \f
 ;; Other modes and packages which depend on CC Mode should do the
 ;; following to make sure everything is loaded and available for their
@@ -120,15 +127,17 @@ Otherwise, this variable is nil. I.e. this variable is non-nil for
   (let ((initprop 'cc-mode-is-initialized)
        c-initialization-ok)
     (unless (get 'c-initialize-cc-mode initprop)
-      (put 'c-initialize-cc-mode initprop t)
-      (c-initialize-builtin-style)
       (unwind-protect
          (progn
+           (put 'c-initialize-cc-mode initprop t)
+           (c-initialize-builtin-style)
            (run-hooks 'c-initialization-hook)
+           ;; Fix obsolete variables.
+           (if (boundp 'c-comment-continuation-stars)
+               (setq c-block-comment-prefix c-comment-continuation-stars))
            (setq c-initialization-ok t))
        ;; Will try initialization hooks again if they failed.
-       (unless c-initialization-ok
-         (put 'c-initialize-cc-mode initprop nil))))
+       (put 'c-initialize-cc-mode initprop c-initialization-ok)))
     ))
 
 \f
@@ -162,10 +171,10 @@ Key bindings:
        c-conditional-key c-C-conditional-key
        c-class-key c-C-class-key
        c-baseclass-key nil
-       c-comment-start-regexp c-C++-comment-start-regexp
-       imenu-generic-expression cc-imenu-c-generic-expression
-       imenu-case-fold-search nil
+       c-comment-start-regexp c-C-comment-start-regexp
+       c-bitfield-key c-C-bitfield-key
        )
+  (cc-imenu-init cc-imenu-c-generic-expression)
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'c-mode-hook)
   (c-update-modeline))
@@ -205,9 +214,9 @@ Key bindings:
        c-extra-toplevel-key c-C++-extra-toplevel-key
        c-access-key c-C++-access-key
        c-recognize-knr-p nil
-       imenu-generic-expression cc-imenu-c++-generic-expression
-       imenu-case-fold-search nil
+       c-bitfield-key c-C-bitfield-key
        )
+  (cc-imenu-init cc-imenu-c++-generic-expression)
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'c++-mode-hook)
   (c-update-modeline))
@@ -241,15 +250,14 @@ Key bindings:
   (c-common-init)
   (setq comment-start "// "
        comment-end   ""
-       c-conditional-key c-C-conditional-key
-       c-comment-start-regexp c-C++-comment-start-regexp
+       c-conditional-key c-ObjC-conditional-key
+       c-comment-start-regexp c-ObjC-comment-start-regexp
        c-class-key c-ObjC-class-key
        c-baseclass-key nil
        c-access-key c-ObjC-access-key
        c-method-key c-ObjC-method-key
-       imenu-create-index-function 'cc-imenu-objc-function
-       imenu-case-fold-search nil
        )
+  (cc-imenu-init cc-imenu-objc-generic-expression)
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'objc-mode-hook)
   (c-update-modeline))
@@ -285,6 +293,10 @@ Key bindings:
   (c-common-init)
   (setq comment-start "// "
        comment-end   ""
+       paragraph-start (concat paragraph-start
+                               "\\("
+                               c-Java-javadoc-paragraph-start
+                               "\\|$\\)")
        c-conditional-key c-Java-conditional-key
        c-comment-start-regexp c-Java-comment-start-regexp
        c-class-key c-Java-class-key
@@ -294,9 +306,8 @@ Key bindings:
        c-access-key c-Java-access-key
        c-inexpr-class-key c-Java-inexpr-class-key
        ;defun-prompt-regexp c-Java-defun-prompt-regexp
-       imenu-generic-expression cc-imenu-java-generic-expression
-       imenu-case-fold-search nil
        )
+  (cc-imenu-init cc-imenu-java-generic-expression)
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'java-mode-hook)
   (c-update-modeline))
@@ -330,15 +341,16 @@ Key bindings:
   (c-common-init)
   (setq comment-start "// "
        comment-end ""
-       c-conditional-key c-C++-conditional-key
-       c-comment-start-regexp c-C++-comment-start-regexp
+       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-C++-access-key
+       c-access-key c-IDL-access-key
        c-recognize-knr-p nil
-;;     imenu-generic-expression cc-imenu-c++-generic-expression
-;;     imenu-case-fold-search nil
        )
+  ;;(cc-imenu-init cc-imenu-idl-generic-expression) ;FIXME
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'idl-mode-hook)
   (c-update-modeline))
@@ -373,6 +385,7 @@ Key bindings:
   (setq comment-start "// "
        comment-end   ""
        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
@@ -381,13 +394,44 @@ Key bindings:
        c-lambda-key c-Pike-lambda-key
        c-inexpr-block-key c-Pike-inexpr-block-key
        c-special-brace-lists c-Pike-special-brace-lists
-       ;imenu-generic-expression cc-imenu-java-generic-expression ;FIXME
-       ;imenu-case-fold-search nil ;FIXME
        )
+  ;;(cc-imenu-init cc-imenu-pike-generic-expression) ;FIXME
   (run-hooks 'c-mode-common-hook)
   (run-hooks 'pike-mode-hook)
   (c-update-modeline))
 
+\f
+(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
+`filladapt-token-table', `filladapt-token-match-table', and
+`filladapt-token-conversion-table'.  This is intended to be used on
+`c-mode-common-hook' or similar."
+  ;; This function is intended to be used explicitly by the end user
+  ;; only.
+  ;;
+  ;; The default configuration already handles C++ comments, but we
+  ;; need to add handling of C block comments.  A new filladapt token
+  ;; `c-comment' is added for that.
+  (let (p)
+    (setq p filladapt-token-table)
+    (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)
+      (setq filladapt-token-table
+           (append (list (car filladapt-token-table)
+                         (list c-comment-prefix-regexp 'c-comment))
+                   (cdr filladapt-token-table)))))
+  (unless (assq 'c-comment filladapt-token-match-table)
+    (setq filladapt-token-match-table
+         (append '((c-comment c-comment))
+                 filladapt-token-match-table)))
+  (unless (assq 'c-comment filladapt-token-conversion-table)
+    (setq filladapt-token-conversion-table
+         (append '((c-comment . exact))
+                 filladapt-token-conversion-table))))
+
 \f
 ;; bug reporting
 
@@ -423,36 +467,40 @@ Key bindings:
                    ((eq major-mode 'c-mode)    "C")
                    ((eq major-mode 'objc-mode) "ObjC")
                    ((eq major-mode 'java-mode) "Java")
+                   ((eq major-mode 'idl-mode)  "IDL")
                    ((eq major-mode 'pike-mode) "Pike")
                    )
              ")")
-      (let ((vars (list
+      (let ((vars (append
                   ;; report only the vars that affect indentation
-                  'c-basic-offset
-                  'c-offsets-alist
-                  'c-cleanup-list
-                  'c-comment-only-line-offset
-                  'c-backslash-column
-                  'c-delete-function
-                  'c-electric-pound-behavior
-                  'c-hanging-braces-alist
-                  'c-hanging-colons-alist
-                  'c-hanging-comment-starter-p
-                  'c-hanging-comment-ender-p
-                  'c-indent-comments-syntactically-p
-                  'c-tab-always-indent
-                  'c-comment-continuation-stars
-                  'c-label-minimum-indentation
-                  'defun-prompt-regexp
-                  'tab-width
-                  'comment-column
-                  ;; A brain-damaged XEmacs only variable that, if
-                  ;; set to nil can cause all kinds of chaos.
-                  'signal-error-on-buffer-boundary
-                  )))
-       (if (not (boundp 'defun-prompt-regexp))
-           (delq 'defun-prompt-regexp vars)
-         vars))
+                  c-style-variables
+                  '(c-delete-function
+                    c-electric-pound-behavior
+                    c-indent-comments-syntactically-p
+                    c-tab-always-indent
+                    defun-prompt-regexp
+                    tab-width
+                    comment-column
+                    parse-sexp-ignore-comments
+                    ;; A brain-damaged XEmacs only variable that, if
+                    ;; set to nil can cause all kinds of chaos.
+                    signal-error-on-buffer-boundary
+                    ;; Variables that affect line breaking and comments.
+                    auto-fill-mode
+                    filladapt-mode
+                    comment-multi-line
+                    comment-start-skip
+                    fill-prefix
+                    paragraph-start
+                    adaptive-fill-mode
+                    adaptive-fill-regexp)
+                  nil)))
+       (delq 'c-special-indent-hook vars)
+       (unless (boundp 'defun-prompt-regexp)
+         (delq 'defun-prompt-regexp vars))
+       (unless (boundp 'filladapt-mode)
+         (delq 'filladapt-mode vars))
+       vars)
       (function
        (lambda ()
         (insert
index f394a9b3fdc48ed643ddf744999d380d9be7a35d..7cfb1d1e99f6734a869dcf2a2a95d46638a08db8 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-styles.el --- support for styles in CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-
-;; explicit compile-time dependencies
 (eval-when-compile
-  (require 'cc-defs))
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
+(require 'cc-vars)
+
 
 \f
 ;; Warning: don't eval-defun this constant or you'll break style inheritance.
@@ -50,8 +56,7 @@
                         (inline-open . 0)
                         ))
      (c-special-indent-hook . c-gnu-impose-minimum)
-     (c-comment-continuation-stars . "")
-     (c-hanging-comment-ender-p . t)
+     (c-block-comment-prefix . "")
      )
     ("k&r"
      (c-basic-offset . 5)
@@ -71,6 +76,8 @@
                         (substatement-open . 0)
                         (label . 0)
                         (statement-cont . +)
+                        (inline-open . 0)
+                        (inexpr-class . 0)
                         ))
      )
     ("stroustrup"
     ("whitesmith"
      (c-basic-offset . 4)
      (c-comment-only-line-offset . 0)
-     (c-offsets-alist . ((statement-block-intro . +)
-                        (knr-argdecl-intro . +)
-                        (substatement-open . 0)
+     (c-offsets-alist . ((knr-argdecl-intro . +)
                         (label . 0)
                         (statement-cont . +)
+                        (substatement-open . +)
+                        (block-open . +)
+                        (statement-block-intro . c-lineup-whitesmith-in-block)
+                        (block-close . c-lineup-whitesmith-in-block)
+                        (inline-open . +)
+                        (defun-open . +)
+                        (defun-block-intro . c-lineup-whitesmith-in-block)
+                        (defun-close . c-lineup-whitesmith-in-block)
+                        (brace-list-open . +)
+                        (brace-list-intro . c-lineup-whitesmith-in-block)
+                        (brace-entry-open . c-indent-multi-line-block)
+                        (brace-list-close . c-lineup-whitesmith-in-block)
+                        (class-open . +)
+                        (inclass . c-lineup-whitesmith-in-block)
+                        (class-close . +)
+                        (inexpr-class . 0)
+                        (extern-lang-open . +)
+                        (inextern-lang . c-lineup-whitesmith-in-block)
+                        (extern-lang-close . +)
+                        (namespace-open . +)
+                        (innamespace . c-lineup-whitesmith-in-block)
+                        (namespace-close . +)
                         ))
-
      )
     ("ellemtel"
      (c-basic-offset . 3)
      )
     ("python"
      (indent-tabs-mode . t)
-     (fill-column      . 72)
+     (fill-column      . 78)
      (c-basic-offset   . 8)
      (c-offsets-alist  . ((substatement-open . 0)
                          (inextern-lang . 0)
                                (substatement-open after)
                                (block-close . c-snug-do-while)
                                ))
-     (c-comment-continuation-stars . "")
-     (c-hanging-comment-ender-p . nil)
-     (fill-column . 78)
+     (c-block-comment-prefix . "")
      )
     ("java"
      (c-basic-offset . 4)
      (c-comment-only-line-offset . (0 . 0))
      ;; the following preserves Javadoc starter lines
-     (c-hanging-comment-starter-p . nil)
      (c-offsets-alist . ((inline-open . 0)
                         (topmost-intro-cont    . +)
                         (statement-block-intro . +)
                         (knr-argdecl-intro     . 5)
                         (substatement-open     . +)
-                        (label                 . 0)
+                        (label                 . +)
                         (statement-case-open   . +)
                         (statement-cont        . +)
                         (arglist-intro  . c-lineup-arglist-intro-after-paren)
                         (inher-cont     . c-lineup-java-inher)
                         (func-decl-cont . c-lineup-java-throws)
                         ))
-
      )
     )
   "Styles of indentation.
@@ -175,7 +197,7 @@ for that variable when using the selected style.
 
 Optional BASE-STYLE if present, is a string and must follow
 STYLE-STRING.  BASE-STYLE names a style that this style inherits from.
-By default, all styles inherit from the \"cc-mode\" style, which is
+By default, all styles inherit from the \"user\" style, which is
 computed at run time.  Style loops generate errors.
 
 Two variables are treated specially.  When VARIABLE is
@@ -197,9 +219,10 @@ to add new styles or modify existing styles (it is not a good idea to
 modify existing styles -- you should create a new style that inherits
 the existing style.")
 
+
 \f
 ;; Functions that manipulate styles
-(defun c-set-style-1 (conscell)
+(defun c-set-style-1 (conscell dont-override)
   ;; Set the style for one variable
   (let ((attr (car conscell))
        (val  (cdr conscell)))
@@ -211,50 +234,68 @@ the existing style.")
        (lambda (langentry)
          (let ((langelem (car langentry))
                (offset (cdr langentry)))
-           (c-set-offset langelem offset)
+           (unless (and dont-override
+                        (assq langelem c-offsets-alist))
+             (c-set-offset langelem offset))
            )))
-       val))
+       (if dont-override (reverse val) val)))
      ;; second special variable
      ((eq attr 'c-special-indent-hook)
-      (if (listp val)
-         (while val
-           (add-hook 'c-special-indent-hook (car val))
-           (setq val (cdr val)))
-       (add-hook 'c-special-indent-hook val)))
+      (let ((add-func (if dont-override
+                         (lambda (func)
+                           (unless (memq func c-special-indent-hook)
+                             (add-hook 'c-special-indent-hook func t)))
+                       (lambda (func)
+                         (add-hook 'c-special-indent-hook func)))))
+       (if (listp val)
+           (mapcar add-func (if dont-override (reverse val) val))
+         (funcall add-func val))))
      ;; all other variables
-     (t (set attr val)))
+     (t (if (or (not dont-override)
+               (not (memq attr c-style-variables))
+               (eq (symbol-value attr) 'set-from-style))
+           (set attr val))))
     ))
 
-(defun c-set-style-2 (style basestyles)
-  ;; Recursively set the base style.  If no base style is given, the
-  ;; default base style is "user" (a.k.a. "cc-mode") and the recursion
-  ;; stops.  Be sure to detect loops.
+(defun c-get-style-variables (style basestyles)
+  ;; Return all variables in a style by resolving inheritances.
   (let ((vars (cdr (or (assoc (downcase style) c-style-alist)
                       (assoc (upcase style) c-style-alist)
                       (assoc style c-style-alist)
                       (error "Undefined style: %s" style)))))
-    (if (not (string-equal style "user"))
-       (let ((base (if (stringp (car vars))
-                       (prog1
-                           (downcase (car vars))
-                         (setq vars (cdr vars)))
-                     "user")))
-         (if (memq base basestyles)
-             (error "Style loop detected: %s in %s" base basestyles))
-         (c-set-style-2 base (cons base basestyles))))
-    (mapcar 'c-set-style-1 vars)))
-    
+    (if (string-equal style "user")
+       (copy-alist vars)
+      (let ((base (if (stringp (car vars))
+                     (prog1
+                         (downcase (car vars))
+                       (setq vars (cdr vars)))
+                   "user")))
+       (if (memq base basestyles)
+           (error "Style loop detected: %s in %s" base basestyles))
+       (nconc (c-get-style-variables base (cons base basestyles))
+              (copy-alist vars))))))
+
 (defvar c-set-style-history nil)
 
 ;;;###autoload
-(defun c-set-style (stylename)
+(defun c-set-style (stylename &optional dont-override)
   "Set CC Mode variables to use one of several different indentation styles.
 STYLENAME is a string representing the desired style from the list of
 styles described in the variable `c-style-alist'.  See that variable
 for details of setting up styles.
 
 The variable `c-indentation-style' always contains the buffer's current
-style name."
+style name.
+
+If the optional argument DONT-OVERRIDE is non-nil, no style variables
+that already have values will be overridden.  I.e. in the case of
+`c-offsets-alist', syntactic symbols will only be added, and in the
+case of all other style variables, only those set to `set-from-style'
+will be reassigned.
+
+Obviously, specifying DONT-OVERRIDE is useful mainly when the initial
+style is chosen for a CC Mode buffer by a major mode.  Since this is
+done internally by CC Mode, there's hardly ever a reason to use it."
   (interactive (list (let ((completion-ignore-case t)
                           (prompt (format "Which %s indentation style? "
                                           mode-name)))
@@ -262,7 +303,12 @@ style name."
                                        (cons c-indentation-style 0)
                                        'c-set-style-history))))
   (c-initialize-builtin-style)
-  (c-set-style-2 stylename nil)
+  (let ((vars (c-get-style-variables stylename nil)))
+    (mapcar (lambda (elem)
+             (c-set-style-1 elem dont-override))
+           ;; Need to go through the variables backwards when we
+           ;; don't override.
+           (if dont-override (nreverse vars) vars)))
   (setq c-indentation-style stylename)
   (c-keep-region-active))
 
@@ -292,195 +338,6 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
 
 
 \f
-(defconst c-offsets-alist
-  '((string                . c-lineup-dont-change)
-    (c                     . c-lineup-C-comments)
-    (defun-open            . 0)
-    (defun-close           . 0)
-    (defun-block-intro     . +)
-    (class-open            . 0)
-    (class-close           . 0)
-    (inline-open           . +)
-    (inline-close          . 0)
-    (func-decl-cont        . +)
-    (knr-argdecl-intro     . +)
-    (knr-argdecl           . 0)
-    (topmost-intro         . 0)
-    (topmost-intro-cont    . 0)
-    (member-init-intro     . +)
-    (member-init-cont      . 0)
-    (inher-intro           . +)
-    (inher-cont            . c-lineup-multi-inher)
-    (block-open            . 0)
-    (block-close           . 0)
-    (brace-list-open       . 0)
-    (brace-list-close      . 0)
-    (brace-list-intro      . +)
-    (brace-list-entry      . 0)
-    (brace-entry-open      . 0)
-    (statement             . 0)
-    ;; some people might prefer
-    ;;(statement             . c-lineup-runin-statements)
-    (statement-cont        . +)
-    ;; some people might prefer
-    ;;(statement-cont        . c-lineup-math)
-    (statement-block-intro . +)
-    (statement-case-intro  . +)
-    (statement-case-open   . 0)
-    (substatement          . +)
-    (substatement-open     . +)
-    (case-label            . 0)
-    (access-label          . -)
-    (label                 . 2)
-    (do-while-closure      . 0)
-    (else-clause           . 0)
-    (catch-clause          . 0)
-    (comment-intro         . c-lineup-comment)
-    (arglist-intro         . +)
-    (arglist-cont          . 0)
-    (arglist-cont-nonempty . c-lineup-arglist)
-    (arglist-close         . +)
-    (stream-op             . c-lineup-streamop)
-    (inclass               . +)
-    (cpp-macro             . -1000)
-    (cpp-macro-cont        . c-lineup-dont-change)
-    (friend                . 0)
-    (objc-method-intro     . -1000)
-    (objc-method-args-cont . c-lineup-ObjC-method-args)
-    (objc-method-call-cont . c-lineup-ObjC-method-call)
-    (extern-lang-open      . 0)
-    (extern-lang-close     . 0)
-    (inextern-lang         . +)
-    (namespace-open        . 0)
-    (namespace-close       . 0)
-    (innamespace           . +)
-    (template-args-cont    . +)
-    (inlambda              . c-lineup-inexpr-block)
-    (lambda-intro-cont     . +)
-    (inexpr-statement      . 0)
-    (inexpr-class          . +)
-    )
-  "Association list of syntactic element symbols and indentation offsets.
-As described below, each cons cell in this list has the form:
-
-    (SYNTACTIC-SYMBOL . OFFSET)
-
-When a line is indented, CC Mode first determines the syntactic
-context of the line by generating a list of symbols called syntactic
-elements.  This list can contain more than one syntactic element and
-the global variable `c-syntactic-context' contains the context list
-for the line being indented.  Each element in this list is actually a
-cons cell of the syntactic symbol and a buffer position.  This buffer
-position is called the relative indent point for the line.  Some
-syntactic symbols may not have a relative indent point associated with
-them.
-
-After the syntactic context list for a line is generated, CC Mode
-calculates the absolute indentation for the line by looking at each
-syntactic element in the list.  First, it compares the syntactic
-element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it
-finds a match, it adds the OFFSET to the column of the relative indent
-point.  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.
-
-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.
-
-Here is the current list of valid syntactic element symbols:
-
- string                 -- inside multi-line string
- c                      -- inside a multi-line C style block comment
- defun-open             -- brace that opens a function definition
- defun-close            -- brace that closes a function definition
- defun-block-intro      -- the first line in a top-level defun
- class-open             -- brace that opens a class definition
- class-close            -- brace that closes a class definition
- inline-open            -- brace that opens an in-class inline method
- inline-close           -- brace that closes an in-class inline method
- func-decl-cont         -- the region between a function definition's
-                           argument list and the function opening brace
-                           (excluding K&R argument declarations). In C, you
-                           cannot put anything but whitespace and comments
-                           between them; in C++ and Java, throws declarations
-                           and other things can appear in this context.
- knr-argdecl-intro      -- first line of a K&R C argument declaration
- knr-argdecl            -- subsequent lines in a K&R C argument declaration
- topmost-intro          -- the first line in a topmost construct definition
- topmost-intro-cont     -- topmost definition continuation lines
- member-init-intro      -- first line in a member initialization list
- member-init-cont       -- subsequent member initialization list lines
- inher-intro            -- first line of a multiple inheritance list
- inher-cont             -- subsequent multiple inheritance lines
- block-open             -- statement block open brace
- block-close            -- statement block close brace
- brace-list-open        -- open brace of an enum or static array list
- brace-list-close       -- close brace of an enum or static array list
- brace-list-intro       -- first line in an enum or static array list
- brace-list-entry       -- subsequent lines in an enum or static array list
- brace-entry-open       -- subsequent lines in an enum or static array
-                           list that start with an open brace.
- statement              -- a C (or like) statement
- statement-cont         -- a continuation of a C (or like) statement
- statement-block-intro  -- the first line in a new statement block
- statement-case-intro   -- the first line in a case \"block\"
- statement-case-open    -- the first line in a case block starting with brace
- substatement           -- the first line after an if/while/for/do/else
- substatement-open      -- the brace that opens a substatement block
- case-label             -- a `case' or `default' label
- access-label           -- C++ private/protected/public access label
- label                  -- any ordinary label
- do-while-closure       -- the `while' that ends a do/while construct
- else-clause            -- the `else' of an if/else construct
- catch-clause           -- the `catch' or `finally' of a try/catch construct
- comment-intro          -- a line containing only a comment introduction
- arglist-intro          -- the first line in an argument list
- arglist-cont           -- subsequent argument list lines when no
-                           arguments follow on the same line as the
-                           arglist opening paren
- arglist-cont-nonempty  -- subsequent argument list lines when at
-                           least one argument follows on the same
-                           line as the arglist opening paren
- arglist-close          -- the solo close paren of an argument list
- stream-op              -- lines continuing a stream operator construct
- inclass                -- the construct is nested inside a class definition
- cpp-macro              -- the start of a C preprocessor macro definition
- cpp-macro-cont         -- the second and subsequent lines in a
-                           multi-line C preprocessor macro definition
- friend                 -- a C++ friend declaration
- objc-method-intro      -- the first line of an Objective-C method definition
- objc-method-args-cont  -- lines continuing an Objective-C method definition
- objc-method-call-cont  -- lines continuing an Objective-C method call
- extern-lang-open       -- brace that opens an external language block
- extern-lang-close      -- brace that closes an external language block
- inextern-lang          -- analogous to `inclass' syntactic symbol,
-                           but used inside, e.g. extern \"C\" constructs
- namespace-open         -- brace that opens a C++ namespace block
- namespace-close        -- brace that closes a C++ namespace block
- innamespace            -- analogous to `inextern-lang' syntactic
-                           symbol, but used inside C++ namespace constructs
- template-args-cont     -- C++ template argument list continuations
- inlambda               -- in the header or body of a lambda function
- lambda-intro-cont      -- continuation of the header of a lambda function
- inexpr-statement       -- the statement is inside an expression
- inexpr-class           -- the class is inside an expression
-")
-
 (defun c-evaluate-offset (offset langelem symbol)
   ;; offset can be a number, a function, a variable, a list, or one of
   ;; the symbols + or -
@@ -529,16 +386,21 @@ Here is the current list of valid syntactic element symbols:
             (goto-char relpos)
             (current-column))
         0)
-       (c-evaluate-offset offset langelem symbol))
+       (or (and (numberp offset) offset)
+          (and (symbolp offset) (symbol-value offset))
+          0))
     ))
 
+
 \f
 (defvar c-read-offset-history nil)
 
 (defun c-read-offset (langelem)
   ;; read new offset value for LANGELEM from minibuffer. return a
   ;; legal value only
-  (let* ((oldoff  (cdr-safe (assq langelem c-offsets-alist)))
+  (let* ((oldoff  (cdr-safe (or (assq langelem c-offsets-alist)
+                               (assq langelem (get 'c-offsets-alist
+                                                   'c-stylevar-fallback)))))
         (symname (symbol-name langelem))
         (defstr  (format "(default %s): " oldoff))
         (errmsg  (concat "Offset must be int, func, var, list, "
@@ -574,11 +436,11 @@ Here is the current list of valid syntactic element symbols:
     offset))
 
 ;;;###autoload
-(defun c-set-offset (symbol offset &optional add-p)
+(defun c-set-offset (symbol offset &optional ignored)
   "Change the value of a syntactic element symbol in `c-offsets-alist'.
 SYMBOL is the syntactic element symbol to change and OFFSET is the new
-offset for that syntactic element.  Optional ADD says to add SYMBOL to
-`c-offsets-alist' if it doesn't already appear there."
+offset for that syntactic element.  The optional argument is not used
+and exists only for compatibility reasons."
   (interactive
    (let* ((langelem
           (intern (completing-read
@@ -588,7 +450,7 @@ offset for that syntactic element.  Optional ADD says to add SYMBOL to
                    (mapcar
                     #'(lambda (langelem)
                         (cons (format "%s" (car langelem)) nil))
-                    c-offsets-alist)
+                    (get 'c-offsets-alist 'c-stylevar-fallback))
                    nil (not current-prefix-arg)
                    ;; initial contents tries to be the last element
                    ;; on the syntactic analysis list for the current
@@ -601,33 +463,19 @@ offset for that syntactic element.  Optional ADD says to add SYMBOL to
          (offset (c-read-offset langelem)))
      (list langelem offset current-prefix-arg)))
   ;; sanity check offset
-  (or (eq offset '+)
-      (eq offset '-)
-      (eq offset '++)
-      (eq offset '--)
-      (eq offset '*)
-      (eq offset '/)
-      (integerp offset)
-      (functionp offset)
-      (listp offset)
-      (boundp offset)
-      (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
-            offset))
+  (unless (c-valid-offset offset)
+    (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
+          offset))
   (let ((entry (assq symbol c-offsets-alist)))
     (if entry
        (setcdr entry offset)
-      (if add-p
+      (if (assq symbol (get 'c-offsets-alist 'c-stylevar-fallback))
          (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
-       (error "%s is not a valid syntactic symbol." symbol))))
+       (error "%s is not a valid syntactic symbol" symbol))))
   (c-keep-region-active))
 
-\f
-(defun c-copy-tree (tree)
-  (if (consp tree)
-      (cons (c-copy-tree (car tree))
-            (c-copy-tree (cdr tree)))
-    tree))
 
+\f
 (defun c-initialize-builtin-style ()
   ;; Dynamically append the default value of most variables. This is
   ;; crucial because future c-set-style calls will always reset the
@@ -639,39 +487,42 @@ offset for that syntactic element.  Optional ADD says to add SYMBOL to
     (or (assoc "cc-mode" c-style-alist)
        (assoc "user" c-style-alist)
        (progn
-         (c-add-style "user"
-                      (mapcar
-                       (function
-                        (lambda (var)
-                          (let ((val (symbol-value var)))
-                            (cons var (c-copy-tree val)))))
-                       '(c-backslash-column
-                         c-basic-offset
-                         c-cleanup-list
-                         c-comment-only-line-offset
-                         c-electric-pound-behavior
-                         c-hanging-braces-alist
-                         c-hanging-colons-alist
-                         c-hanging-comment-starter-p
-                         c-hanging-comment-ender-p
-                         c-offsets-alist
-                         )))
-         (c-add-style "cc-mode" '("user"))
-         ))
+         (c-add-style
+          "user"
+          (mapcar
+           (lambda (var)
+             (let ((val (symbol-value var)))
+               (cons var
+                     (cond ((eq var 'c-offsets-alist)
+                            (mapcar
+                             (lambda (langentry)
+                               (setq langentry (or (assq (car langentry) val)
+                                                   langentry))
+                               (cons (car langentry)
+                                     (cdr langentry)))
+                             (get var 'c-stylevar-fallback)))
+                           ((eq var 'c-special-indent-hook)
+                            val)
+                           (t
+                            (if (eq val 'set-from-style)
+                                (get var 'c-stylevar-fallback)
+                              val))))))
+           c-style-variables))
+         (c-add-style "cc-mode" '("user"))))
     (if c-style-variables-are-local-p
        (c-make-styles-buffer-local))))
 
-
 (defun c-make-styles-buffer-local (&optional this-buf-only-p)
   "Make all CC Mode style variables buffer local.
-If you edit primarily one style of C (or C++, Objective-C, Java) code,
-you probably want style variables to be global.  This is the default.
+If you edit primarily one style of C (or C++, Objective-C, Java, etc)
+code, you probably want style variables to be global.  This is the
+default.
 
-If you edit many different styles of C (or C++, Objective-C, Java) at
-the same time, you probably want the CC Mode style variables to be
-buffer local.  If you do, then you will need to set any CC Mode style
-variables in a hook function (e.g. off of c-mode-common-hook), instead
-of at the top level of your ~/.emacs file.
+If you edit many different styles of C (or C++, Objective-C, Java,
+etc) at the same time, you probably want the CC Mode style variables
+to be buffer local.  If you do, it's advicable to set any CC Mode
+style variables in a hook function (e.g. off of `c-mode-common-hook'),
+instead of at the top level of your ~/.emacs file.
 
 This function makes all the CC Mode style variables buffer local.
 Call it after CC Mode is loaded into your Emacs environment.
@@ -685,24 +536,14 @@ instead of `make-variable-buffer-local'."
   (let ((func (if this-buf-only-p
                  'make-local-variable
                'make-variable-buffer-local))
-       (varsyms '(c-offsets-alist
-                  c-basic-offset
-                  c-file-style
-                  c-file-offsets
-                  c-comment-only-line-offset
-                  c-cleanup-list
-                  c-hanging-braces-alist
-                  c-hanging-colons-alist
-                  c-hanging-comment-starter-p
-                  c-hanging-comment-ender-p
-                  c-backslash-column
-                  c-label-minimum-indentation
-                  c-indentation-style)))
+       (varsyms (cons 'c-indentation-style (copy-alist c-style-variables))))
+    (delq 'c-special-indent-hook varsyms)
     (mapcar func varsyms)
     ;; Hooks must be handled specially
     (if this-buf-only-p
        (make-local-hook 'c-special-indent-hook)
-      (make-variable-buffer-local 'c-special-indent-hook))
+      (make-variable-buffer-local 'c-special-indent-hook)
+      (setq c-style-variables-are-local-p t))
     ))
 
 
index fd05cbdda10ee33785242108f87b9cd76f4125e2..25608653c9eb8c6793039f63a6fb7cf7f6025b56 100644 (file)
@@ -1,8 +1,8 @@
 ;;; cc-vars.el --- user customization variables for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
 
-;; Authors:    1998 Barry A. Warsaw and Martin Stjernholm
+;; Authors:    1998-1999 Barry A. Warsaw and Martin Stjernholm
 ;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Boston, MA 02111-1307, USA.
 
 (eval-when-compile
-  (require 'cc-defs))
-
+  (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)
+          load-path)))
+    (load "cc-defs" nil t)))
 (require 'custom)
 
+
+\f
+;;; Helpers
+
+;; This widget will show up in newer versions of the Custom library
+(or (get 'other 'widget-type)
+    (define-widget 'other 'sexp
+      "Matches everything, but doesn't let the user edit the value.
+Useful as last item in a `choice' widget."
+      :tag "Other"
+      :format "%t%n"
+      :value 'other))
+
+(define-widget 'c-const-symbol 'item
+  "An uneditable lisp symbol."
+  :value nil
+  :tag "Symbol"
+  :format "%t: %v\n%d"
+  :match (lambda (widget value) (symbolp value))
+  :value-to-internal
+  (lambda (widget value)
+    (let ((s (if (symbolp value)
+                (symbol-name value)
+              value))
+         (l (widget-get widget :size)))
+      (if l
+         (setq s (concat s (make-string (- l (length s)) ?\ ))))
+      s))
+  :value-to-external
+  (lambda (widget value)
+    (if (stringp value)
+       (intern (progn
+                 (string-match "\\`[^ ]*" value)
+                 (match-string 0 value)))
+      value)))
+
+(defvar c-style-variables
+  '(c-basic-offset c-comment-only-line-offset c-block-comment-prefix
+    c-comment-prefix-regexp c-cleanup-list c-hanging-braces-alist
+    c-hanging-colons-alist c-hanging-semi&comma-criteria c-backslash-column
+    c-special-indent-hook c-label-minimum-indentation c-offsets-alist)
+  "List of the style variables.")
+
+(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)
+     (defcustom ,name 'set-from-style
+       ,(concat doc "
+
+This is a style variable.  Apart from the valid values described
+above, it can be set to the symbol `set-from-style'.  In that case, it
+takes its value from the style system (see `c-default-style' and
+`c-styles-alist') when a CC Mode buffer is initialized.  Otherwise,
+the value set here overrides the style system (there is a variable
+`c-old-style-variable-behavior' that changes this, though).")
+       ,@(plist-put
+         args ':type
+         `'(radio
+            (const :tag "Use style settings"
+                   set-from-style)
+            ,(let ((type (eval (plist-get args ':type))))
+               (unless (consp type)
+                 (setq type (list type)))
+               (unless (c-safe (plist-get (cdr type) ':value))
+                 (setcdr type (append `(:value ,val)
+                                      (cdr type))))
+               (unless (c-safe (plist-get (cdr type) ':tag))
+                 (setcdr type (append '(:tag "Override style settings")
+                                      (cdr type))))
+               type))))))
+
+(defun c-valid-offset (offset)
+  "Return non-nil iff OFFSET is a valid offset for a syntactic symbol.
+See `c-offsets-alist'."
+  (or (eq offset '+)
+      (eq offset '-)
+      (eq offset '++)
+      (eq offset '--)
+      (eq offset '*)
+      (eq offset '/)
+      (integerp offset)
+      (functionp offset)
+      (and (symbolp offset)
+          (or (boundp offset)
+              (fboundp offset)))
+      (progn
+       (while (and (consp offset)
+                   (c-valid-offset (car offset)))
+         (setq offset (cdr offset)))
+       (null offset))))
+
+
 \f
+;;; User variables
+
 (defcustom c-strict-syntax-p nil
   "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
 If the syntactic symbol for a particular line does not match a symbol
 in the offsets alist, or if no non-nil offset value can be determined
 for a symbol, an error is generated, otherwise no error is reported
-and the syntactic symbol is ignored."
+and the syntactic symbol is ignored.
+
+This variable is considered obsolete; it doesn't work well with lineup
+functions that return nil to support the feature of using lists on
+syntactic symbols in `c-offsets-alist'.  Please keep it set to nil."
   :type 'boolean
   :group 'c)
 
@@ -48,20 +155,11 @@ and the syntactic symbol is ignored."
   :type 'boolean
   :group 'c)
 
-(defcustom c-basic-offset 4
+(defcustom-c-stylevar c-basic-offset 4
   "*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
   :type 'integer
   :group 'c)
 
-;; This widget will show up in newer versions of the Custom library
-(or (get 'other 'widget-type)
-    (define-widget 'other 'sexp
-      "Matches everything, but doesn't let the user edit the value.
-Useful as last item in a `choice' widget."
-      :tag "Other"
-      :format "%t%n"
-      :value 'other))
-
 (defcustom c-tab-always-indent t
   "*Controls the operation of the TAB key.
 If t, hitting TAB always just indents the current line.  If nil,
@@ -72,7 +170,7 @@ literals -- defined as comments and strings -- and inside preprocessor
 directives, but the line is always reindented.
 
 Note: The value of `indent-tabs-mode' will determine whether a real
-tab character will be inserted, or the equivalent number of space.
+tab character will be inserted, or the equivalent number of spaces.
 When inserting a tab, actually the function stored in the variable
 `c-insert-tab-function' is called.
 
@@ -93,7 +191,7 @@ should be inserted.  Value must be a function taking no arguments."
   :type 'function
   :group 'c)
 
-(defcustom c-comment-only-line-offset 0
+(defcustom-c-stylevar c-comment-only-line-offset 0
   "*Extra offset for line which contains only the start of a comment.
 Can contain an integer or a cons cell of the form:
 
@@ -102,8 +200,12 @@ Can contain an integer or a cons cell of the form:
 Where NON-ANCHORED-OFFSET is the amount of offset given to
 non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
 the amount of offset to give column-zero anchored comment-only lines.
-Just an integer as value is equivalent to (<val> . -1000)."
-  :type '(choice (integer :tag "Non-anchored offset")
+Just an integer as value is equivalent to (<val> . -1000).
+
+Note that this variable only has effect when the `c-lineup-comment'
+lineup function is used on the `comment-intro' syntactic symbol (the
+default)."
+  :type '(choice (integer :tag "Non-anchored offset" 0)
                 (cons :tag "Non-anchored & anchored offset"
                       :value (0 . 0)
                       :extra-offset 8
@@ -112,25 +214,77 @@ Just an integer as value is equivalent to (<val> . -1000)."
   :group 'c)
 
 (defcustom c-indent-comments-syntactically-p nil
-  "*Specifies how comment-only lines should be indented.
+  "*Specifies how \\[indent-for-comment] should handle comment-only lines.
 When this variable is non-nil, comment-only lines are indented
-according to syntactic analysis via `c-offsets-alist', even when
-\\[indent-for-comment] is used."
+according to syntactic analysis via `c-offsets-alist'.  Otherwise, the
+comment is indented as if it was preceded by code.  Note that this
+variable does not affect how the normal line indentation treats
+comment-only lines."
   :type 'boolean
   :group 'c)
 
-(defcustom c-comment-continuation-stars "* "
-  "*Specifies the leader of continued block comments.
+(defcustom-c-stylevar c-block-comment-prefix
+  (if (boundp 'c-comment-continuation-stars)
+      c-comment-continuation-stars
+    "* ")
+  "*Specifies the line prefix of continued C-style block comments.
 You should set this variable to the literal string that gets inserted
 at the front of continued block style comment lines.  This should
-either be the empty string, or some number of stars followed by a
-single space.  Note that for line style comments, this variable is not
-used."
-  :type '(choice (const :tag "Use old semantics" nil)
-                string)
+either be the empty string, or some characters without preceding
+spaces.  To adjust the alignment under the comment starter, put an
+appropriate value on the `c' syntactic symbol (see the
+`c-offsets-alist' variable).
+
+It's only used when a one-line block comment is broken into two or
+more lines for the first time; otherwise the appropriate prefix is
+adapted from the comment.  This variable is not used for C++ line
+style comments."
+  :type 'string
+  :group 'c)
+
+(make-obsolete-variable 'c-comment-continuation-stars
+                       'c-block-comment-prefix)
+
+(defcustom-c-stylevar c-comment-prefix-regexp "//+\\|\\**"
+  "*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.
+
+Note that CC Mode modifies other variables from this one at mode
+initialization, so you might need to do \\[c-mode] (or whatever mode
+you're currently using) if you change it in a CC Mode buffer."
+  :type 'regexp
   :group 'c)
 
-(defcustom c-cleanup-list '(scope-operator)
+(defcustom c-ignore-auto-fill '(string cpp code)
+  "*List of contexts in which automatic filling never occurs.
+If Auto Fill mode is active, it will be temporarily disabled if point
+is in any context on this list.  It's e.g. useful to enable Auto Fill
+in comments only, but not in strings or normal code.  The valid
+contexts are:
+
+ string  -- inside a string or character literal
+ c       -- inside a C style block comment
+ c++     -- inside a C++ style line comment
+ cpp     -- inside a preprocessor directive
+ code    -- anywhere else, i.e. in normal code"
+  :type '(set
+         :extra-offset 8
+         (const :tag "String literals" string)
+         (const :tag "C style block comments" c)
+         (const :tag "C++ style line comments" c++)
+         (const :tag "Preprocessor directives" cpp)
+         (const :tag "Normal code" code))
+  :group 'c)
+
+(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
@@ -140,12 +294,11 @@ mode name.  Valid symbols are:
                         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
+                        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
-                        both after the open parenthesis and after the
-                        open brace.
+                        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
@@ -171,21 +324,22 @@ mode name.  Valid symbols are:
          (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))
   :group 'c)
 
-(defcustom c-hanging-braces-alist '((brace-list-open)
-                                   (brace-entry-open)
-                                   (substatement-open after)
-                                   (block-close . c-snug-do-while)
-                                   (extern-lang-open after)
-                                   (inexpr-class-open after)
-                                   (inexpr-class-close before)
-                                   )
-  "*Controls the insertion of newlines before and after braces.
-This variable contains an association list with elements of the
-following form: (SYNTACTIC-SYMBOL . ACTION).
+(defcustom-c-stylevar c-hanging-braces-alist '((brace-list-open)
+                                              (brace-entry-open)
+                                              (substatement-open after)
+                                              (block-close . c-snug-do-while)
+                                              (extern-lang-open after)
+                                              (inexpr-class-open after)
+                                              (inexpr-class-close before))
+  "*Controls the insertion of newlines before and after braces
+when the auto-newline feature is active.  This variable contains an
+association list with elements of the following form:
+\(SYNTACTIC-SYMBOL . ACTION).
 
 When a brace (either opening or closing) is inserted, the syntactic
 context it defines is looked up in this list, and if found, the
@@ -197,12 +351,12 @@ SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
 class-close, inline-open, inline-close, block-open, block-close,
 substatement-open, statement-case-open, extern-lang-open,
 extern-lang-close, brace-list-open, brace-list-close,
-brace-list-intro, brace-entry-open, inexpr-class-open, or
-inexpr-class-close.  See `c-offsets-alist' for details, except for
-inexpr-class-open and inexpr-class-close, which doesn't have any
-corresponding symbols there.  Those two symbols are used for the
-opening and closing braces, respectively, of anonymous inner classes
-in Java.
+brace-list-intro, brace-entry-open, namespace-open, namespace-close,
+inexpr-class-open, or inexpr-class-close.  See `c-offsets-alist' for
+details, except for inexpr-class-open and inexpr-class-close, which
+doesn't have any corresponding symbols there.  Those two symbols are
+used for the opening and closing braces, respectively, of anonymous
+inner classes in Java.
 
 ACTION can be either a function symbol or a list containing any
 combination of the symbols `before' or `after'.  If the list is empty,
@@ -214,28 +368,35 @@ at which the brace was inserted.  The function must return a list as
 described in the preceding paragraph.  Note that during the call to
 the function, the variable `c-syntactic-context' is set to the entire
 syntactic context for the brace line."
-  :type '(repeat
-         (cons :format "%v"
-               (choice :tag "Syntax"
-                       (const defun-open) (const defun-close)
-                       (const class-open) (const class-close)
-                       (const inline-open) (const inline-close)
-                       (const block-open) (const block-close)
-                       (const substatement-open) (const statement-case-open)
-                       (const extern-lang-open) (const extern-lang-close)
-                       (const brace-list-open) (const brace-list-close)
-                       (const brace-list-intro) (const brace-entry-open)
-                       (const inexpr-class-open) (const inexpr-class-close))
-               (choice :tag "Action"
-                       (set :format "Insert a newline %v"
-                            :extra-offset 38
-                            (const :tag "before brace" before)
-                            (const :tag "after brace" after))
-                       (function :format "Run function %v" :value c-)
-                       )))
-  :group 'c)
-
-(defcustom c-hanging-colons-alist nil
+  :type
+  `(set ,@(mapcar
+          (lambda (elt)
+            `(cons :format "%v"
+                   (c-const-symbol :format "%v: "
+                                   :size 20
+                                   :value ,elt)
+                   (choice :format "%[Choice%] %v"
+                    :value (before after)
+                           (set :menu-tag "Before/after"
+                                :format "Newline %v brace\n"
+                                (const :format "%v, " before)
+                                (const :format "%v" after))
+                           (function :menu-tag "Function"
+                                     :format "Run function: %v"
+                                     :value c-))))
+          '(defun-open defun-close
+             class-open class-close
+             inline-open inline-close
+             block-open block-close
+             substatement-open statement-case-open
+             extern-lang-open extern-lang-close
+             brace-list-open brace-list-close
+             brace-list-intro brace-entry-open
+             namespace-open namespace-close
+             inexpr-class-open inexpr-class-close)))
+    :group 'c)
+
+(defcustom-c-stylevar c-hanging-colons-alist nil
   "*Controls the insertion of newlines before and after certain colons.
 This variable contains an association list with elements of the
 following form: (SYNTACTIC-SYMBOL . ACTION).
@@ -246,18 +407,21 @@ member-init-intro, or inher-intro.
 See the variable `c-hanging-braces-alist' for the semantics of this
 variable.  Note however that making ACTION a function symbol is
 currently not supported for this variable."
-  :type '(repeat
-         (cons :format "%v"
-               (choice :tag "Syntax"
-                       (const case-label) (const label) (const access-label)
-                       (const member-init-intro) (const inher-intro))
-               (set :tag "Action"
-                    :format "%t: %v"
-                    :extra-offset 8
-                    (const before) (const after))))
+  :type
+  `(set ,@(mapcar
+          (lambda (elt)
+            `(cons :format "%v"
+                   (c-const-symbol :format "%v: "
+                                   :size 20
+                                   :value ,elt)
+                   (set :format "Newline %v brace\n"
+                        (const :format "%v, " before)
+                        (const :format "%v" after))))
+          '(case-label label access-label member-init-intro inher-intro)))
   :group 'c)
 
-(defcustom c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
+(defcustom-c-stylevar c-hanging-semi&comma-criteria
+  '(c-semi&comma-inside-parenlist)
   "*List of functions that decide whether to insert a newline or not.
 The functions in this list are called, in order, whenever the
 auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
@@ -274,24 +438,7 @@ then no newline is inserted."
   :type '(repeat function)
   :group 'c)
 
-(defcustom c-hanging-comment-ender-p t
-  "*Controls what \\[fill-paragraph] does to C block comment enders.
-When set to nil, C block comment enders are left on their own line.
-When set to t, block comment enders will be placed at the end of the
-previous line (i.e. they `hang' on that line)."
-  :type 'boolean
-  :group 'c)
-
-(defcustom c-hanging-comment-starter-p t
-  "*Controls what \\[fill-paragraph] does to C block comment starters.
-When set to nil, C block comment starters are left on their own line.
-When set to t, text that follows a block comment starter will be
-placed on the same line as the block comment starter (i.e. the text
-`hangs' on that line)."
-  :type 'boolean
-  :group 'c)
-
-(defcustom c-backslash-column 48
+(defcustom-c-stylevar c-backslash-column 48
   "*Column to insert backslashes when macroizing a region."
   :type 'integer
   :group 'c)
@@ -318,7 +465,7 @@ Only currently supported behavior is `alignleft'."
   :type '(set :extra-offset 8 (const alignleft))
   :group 'c)
 
-(defcustom c-label-minimum-indentation 1
+(defcustom-c-stylevar c-label-minimum-indentation 1
   "*Minimum indentation for lines inside of top-level constructs.
 This variable typically only affects code using the `gnu' style, which
 mandates a minimum of one space in front of every line inside
@@ -347,32 +494,336 @@ 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).
 
-When the value is an alist, the named style is installed.  If the
-major mode is not listed in the alist, then the symbol `other' is
-looked up in the alist, and if found, the associated style is used.
-If `other' is not found in the alist, then \"gnu\" style is used.
-
-Note that if you set any CC Mode variables in the top-level of your
-.emacs file (i.e. *not* in a hook), these get incorporated into the
-`user' style, so you would need to add:
-
-  (setq c-default-style '((other . \"user\")))
-
-to see your customizations.  This is also true if you use the Custom
-interface -- be sure to set the default style to `user'.
-
-Finally, 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."
-  :type '(choice string
-                (repeat :tag "" :menu-tag "Major mode list"
-                 (cons :tag ""
-                  (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")
-                  )))
+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
+listed in the alist, then the symbol `other' is looked up in it, and
+if found, the style in that entry is used.  If `other' is not found in
+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'."
+  :type '(radio
+         (string :tag "Style in all modes (except Java)")
+         (repeat :tag "Mode-specific styles"
+                 :value ((other . "user"))
+                 (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")
+                       )))
+  :group 'c)
+
+(put 'c-offsets-alist 'c-stylevar-fallback
+     '((string                . c-lineup-dont-change)
+       ;; Relpos: Beg of previous line.
+       (c                     . c-lineup-C-comments)
+       ;; Relpos: Beg of the comment.
+       (defun-open            . 0)
+       ;; Relpos: Boi at the func decl start when inside classes, bol
+       ;; at the func decl start when at top level.
+       (defun-close           . 0)
+       ;; Relpos: Boi at the func decl start.
+       (defun-block-intro     . +)
+       ;; Relpos: Boi at the block open.
+       (class-open            . 0)
+       ;; Relpos: Boi at the class decl start.
+       (class-close           . 0)
+       ;; Relpos: Boi at the class decl start.
+       (inline-open           . +)
+       ;; Relpos: None for functions (inclass got the relpos then),
+       ;; boi at the lambda start for lambdas.
+       (inline-close          . 0)
+       ;; Relpos: For functions: Boi at the func decl start.  For
+       ;; lambdas: At the block open if it's at boi, at the boi of the
+       ;; lambda start otherwise.
+       (func-decl-cont        . +)
+       ;; Relpos: Boi at the func decl start.
+       (knr-argdecl-intro     . +)
+       ;; Relpos: Boi at the current line.
+       (knr-argdecl           . 0)
+       ;; Relpos: Boi at the argdecl intro line.
+       (topmost-intro         . 0)
+       ;; Relpos: Bol at the last line of previous construct.
+       (topmost-intro-cont    . 0)
+       ;; Relpos: Boi at the topmost intro line.
+       (member-init-intro     . +)
+       ;; Relpos: Boi at the func decl arglist open.
+       (member-init-cont      . 0)
+       ;; Relpos: Beg of the first member init.
+       (inher-intro           . +)
+       ;; Relpos: Java: Boi at the class decl start.  Otherwise: Boi
+       ;; of current line (a bug?), unless it begins with an inher
+       ;; start colon, in which case boi of previous line is used.
+       (inher-cont            . c-lineup-multi-inher)
+       ;; Relpos: Java: At the implements/extends keyword start.
+       ;; Otherwise: At the inher start colon, or boi at the class
+       ;; decl start if the first inherit clause hangs and it's not a
+       ;; func-local inherit clause (when does that occur?).
+       (block-open            . 0)
+       ;; Relpos: Inexpr statement: Boi at the the preceding
+       ;; paren.  Otherwise: None.
+       (block-close           . 0)
+       ;; Relpos: At the open brace if it's at boi.  Otherwise boi at
+       ;; the start of the statement the open brace hangs on, or boi
+       ;; at the preceding paren for inexpr statements.
+       (brace-list-open       . 0)
+       ;; Relpos: Boi at the brace list decl start, but a starting
+       ;; "typedef" token is ignored.
+       (brace-list-close      . 0)
+       ;; Relpos: Boi at the brace list open.
+       (brace-list-intro      . +)
+       ;; Relpos: Boi at the brace list open.
+       (brace-list-entry      . 0)
+       ;; Relpos: At the first non-ws char after the open paren if the
+       ;; first token is on the same line, otherwise boi at that
+       ;; token.
+       (brace-entry-open      . 0)
+       ;; Relpos: Same as brace-list-entry.
+       (statement             . 0)
+       ;; Relpos: After a ';' in the condition clause of a for
+       ;; statement: At the first token after the starting paren.
+       ;; Otherwise: Boi at the start of the closest non-hanging
+       ;; previous statement, but after any switch label.
+       (statement-cont        . +)
+       ;; Relpos: After the first token in the condition clause of a
+       ;; for statement: At the first token after the starting paren.
+       ;; On the first line in a continued expression that starts with
+       ;; a stream op and there's no stream op on the previous line:
+       ;; Boi of previous line.  Otherwise: Boi at the beginning of
+       ;; the statement, but after any type of label.
+       (statement-block-intro . +)
+       ;; Relpos: At the block start if it's at boi, otherwise boi at
+       ;; the start of the statement the open brace hangs on, or boi
+       ;; at the preceding paren for inexpr statements.
+       (statement-case-intro  . +)
+       ;; Relpos: At the label keyword (always at boi).
+       (statement-case-open   . 0)
+       ;; Relpos: At the label keyword (always at boi).
+       (substatement          . +)
+       ;; Relpos: Boi at the containing statement or else clause.
+       (substatement-open     . +)
+       ;; Relpos: Boi at the containing statement or else clause.
+       (case-label            . 0)
+       ;; Relpos: At the switch block start if it's at boi, otherwise
+       ;; boi at the start of the switch condition clause.
+       (access-label          . -)
+       ;; Relpos: Eol (a bug?).
+       (label                 . 2)
+       ;; Relpos: At the start of the containing block if it's at boi,
+       ;; otherwise boi at the start of the sexp before the block.
+       (do-while-closure      . 0)
+       ;; Relpos: Boi at the corresponding while keyword.
+       (else-clause           . 0)
+       ;; Relpos: Boi at the corresponding if keyword.
+       (catch-clause          . 0)
+       ;; Relpos: Boi at the previous try or catch keyword in the try
+       ;; statement.
+       (comment-intro         . c-lineup-comment)
+       ;; Relpos: None.
+       (arglist-intro         . +)
+       ;; Relpos: Boi at the open paren.
+       (arglist-cont          . 0)
+       ;; Relpos: At the first token after the open paren.
+       (arglist-cont-nonempty . c-lineup-arglist)
+       ;; Relpos: Boi at the open paren.
+       (arglist-close         . +)
+       ;; Relpos: Boi at the open paren.
+       (stream-op             . c-lineup-streamop)
+       ;; Relpos: Boi at the first stream op in the statement.
+       (inclass               . +)
+       ;; Relpos: At the class open brace if it's at boi, otherwise
+       ;; boi at the class decl start.
+       (cpp-macro             . -1000)
+       ;; Relpos: Boi.
+       (cpp-macro-cont        . c-lineup-dont-change)
+       ;; Relpos: At the macro start (always at boi).
+       (friend                . 0)
+       ;; Relpos: None.
+       (objc-method-intro     . -1000)
+       ;; Relpos: Boi.
+       (objc-method-args-cont . c-lineup-ObjC-method-args)
+       ;; Relpos: At the method start (always at boi).
+       (objc-method-call-cont . c-lineup-ObjC-method-call)
+       ;; Relpos: At the open bracket.
+       (extern-lang-open      . 0)
+       ;; Relpos: Boi at the extern keyword.
+       (extern-lang-close     . 0)
+       ;; Relpos: Boi at the corresponding extern keyword.
+       (inextern-lang         . +)
+       ;; Relpos: At the extern block open brace if it's at boi,
+       ;; otherwise boi at the extern keyword.
+       (namespace-open        . 0)
+       ;; Relpos: Boi at the namespace keyword.
+       (namespace-close       . 0)
+       ;; Relpos: Boi at the corresponding namespace keyword.
+       (innamespace           . +)
+       ;; Relpos: At the namespace block open brace if it's at boi,
+       ;; otherwise boi at the namespace keyword.
+       (template-args-cont    . (c-lineup-template-args +))
+       ;; Relpos: Boi at the decl start.
+       (inlambda              . c-lineup-inexpr-block)
+       ;; Relpos: None.
+       (lambda-intro-cont     . +)
+       ;; Relpos: Boi at the lambda start.
+       (inexpr-statement      . 0)
+       ;; Relpos: None.
+       (inexpr-class          . +)
+       ;; Relpos: None.
+       ))
+(defcustom c-offsets-alist nil
+  "Association list of syntactic element symbols and indentation offsets.
+As described below, each cons cell in this list has the form:
+
+    (SYNTACTIC-SYMBOL . OFFSET)
+
+When a line is indented, CC Mode first determines the syntactic
+context of it by generating a list of symbols called syntactic
+elements.  This list can contain more than one syntactic element and
+the global variable `c-syntactic-context' contains the context list
+for the line being indented.  Each element in this list is actually a
+cons cell of the syntactic symbol and a buffer position.  This buffer
+position is called the relative indent point for the line.  Some
+syntactic symbols may not have a relative indent point associated with
+them.
+
+After the syntactic context list for a line is generated, CC Mode
+calculates the absolute indentation for the line by looking at each
+syntactic element in the list.  It compares the syntactic element
+against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it finds a
+match, it adds the OFFSET to the column of the relative indent point.
+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.
+
+`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
+\(see `c-default-style' and `c-styles-alist').  However, any offsets
+put explicitly on this list will override the style system when a CC
+Mode buffer is initialized \(there is a variable
+`c-old-style-variable-behavior' that changes this, though).
+
+Here is the current list of valid syntactic element symbols:
+
+ string                 -- Inside multi-line string.
+ c                      -- Inside a multi-line C style block comment.
+ defun-open             -- Brace that opens a function definition.
+ defun-close            -- Brace that closes a function definition.
+ defun-block-intro      -- The first line in a top-level defun.
+ class-open             -- Brace that opens a class definition.
+ class-close            -- Brace that closes a class definition.
+ inline-open            -- Brace that opens an in-class inline method.
+ inline-close           -- Brace that closes an in-class inline method.
+ func-decl-cont         -- The region between a function definition's
+                           argument list and the function opening brace
+                           (excluding K&R argument declarations).  In C, you
+                           cannot put anything but whitespace and comments
+                           between them; in C++ and Java, throws declarations
+                           and other things can appear in this context.
+ knr-argdecl-intro      -- First line of a K&R C argument declaration.
+ knr-argdecl            -- Subsequent lines in a K&R C argument declaration.
+ topmost-intro          -- The first line in a topmost construct definition.
+ topmost-intro-cont     -- Topmost definition continuation lines.
+ member-init-intro      -- First line in a member initialization list.
+ member-init-cont       -- Subsequent member initialization list lines.
+ inher-intro            -- First line of a multiple inheritance list.
+ inher-cont             -- Subsequent multiple inheritance lines.
+ block-open             -- Statement block open brace.
+ block-close            -- Statement block close brace.
+ brace-list-open        -- Open brace of an enum or static array list.
+ brace-list-close       -- Close brace of an enum or static array list.
+ brace-list-intro       -- First line in an enum or static array list.
+ brace-list-entry       -- Subsequent lines in an enum or static array list.
+ brace-entry-open       -- Subsequent lines in an enum or static array
+                           list that start with an open brace.
+ statement              -- A C (or like) statement.
+ statement-cont         -- A continuation of a C (or like) statement.
+ statement-block-intro  -- The first line in a new statement block.
+ statement-case-intro   -- The first line in a case \"block\".
+ statement-case-open    -- The first line in a case block starting with brace.
+ substatement           -- The first line after an if/while/for/do/else.
+ substatement-open      -- The brace that opens a substatement block.
+ case-label             -- A `case' or `default' label.
+ access-label           -- C++ private/protected/public access label.
+ label                  -- Any ordinary label.
+ do-while-closure       -- The `while' that ends a do/while construct.
+ else-clause            -- The `else' of an if/else construct.
+ catch-clause           -- The `catch' or `finally' of a try/catch construct.
+ comment-intro          -- A line containing only a comment introduction.
+ arglist-intro          -- The first line in an argument list.
+ arglist-cont           -- Subsequent argument list lines when no
+                           arguments follow on the same line as the
+                           arglist opening paren.
+ arglist-cont-nonempty  -- Subsequent argument list lines when at
+                           least one argument follows on the same
+                           line as the arglist opening paren.
+ arglist-close          -- The solo close paren of an argument list.
+ stream-op              -- Lines continuing a stream operator construct.
+ inclass                -- The construct is nested inside a class definition.
+                           Used together with e.g. `topmost-intro'.
+ cpp-macro              -- The start of a C preprocessor macro definition.
+ cpp-macro-cont         -- Subsequent lines in a multi-line C preprocessor
+                           macro definition.
+ friend                 -- A C++ friend declaration.
+ objc-method-intro      -- The first line of an Objective-C method definition.
+ objc-method-args-cont  -- Lines continuing an Objective-C method definition.
+ objc-method-call-cont  -- Lines continuing an Objective-C method call.
+ extern-lang-open       -- Brace that opens an external language block.
+ extern-lang-close      -- Brace that closes an external language block.
+ inextern-lang          -- Analogous to the `inclass' syntactic symbol,
+                           but used inside extern constructs.
+ namespace-open         -- Brace that opens a C++ namespace block.
+ namespace-close        -- Brace that closes a C++ namespace block.
+ innamespace            -- Analogous to the `inextern-lang' syntactic
+                           symbol, but used inside C++ namespace constructs.
+ template-args-cont     -- C++ template argument list continuations.
+ inlambda               -- In the header or body of a lambda function.
+ lambda-intro-cont      -- Continuation of the header of a lambda function.
+ inexpr-statement       -- The statement is inside an expression.
+ inexpr-class           -- The class is inside an expression.  Used e.g. for
+                           Java anonymous classes."
+  :type
+  `(set :format "%{%t%}:
+ Override style setting
+ |  Syntax                     Offset
+%v"
+       ,@(mapcar
+          (lambda (elt)
+            `(cons :format "%v"
+                   :value ,elt
+                   (c-const-symbol :format "%v: "
+                                   :size 25)
+                   (sexp :format "%v"
+                         :validate
+                         (lambda (widget)
+                           (unless (c-valid-offset (widget-value widget))
+                             (widget-put widget :error "Invalid offset")
+                             widget)))))
+          (get 'c-offsets-alist 'c-stylevar-fallback)))
   :group 'c)
 
 (defcustom c-style-variables-are-local-p nil
@@ -385,14 +836,13 @@ localized, they cannot be made global again.
 The list of variables to buffer localize are:
     c-offsets-alist
     c-basic-offset
-    c-file-style
-    c-file-offsets
     c-comment-only-line-offset
+    c-block-comment-prefix
+    c-comment-prefix-regexp
     c-cleanup-list
     c-hanging-braces-alist
     c-hanging-colons-alist
-    c-hanging-comment-starter-p
-    c-hanging-comment-ender-p
+    c-hanging-semi&comma-criteria
     c-backslash-column
     c-label-minimum-indentation
     c-special-indent-hook
@@ -402,7 +852,7 @@ The list of variables to buffer localize are:
 
 (defcustom c-mode-hook nil
   "*Hook called by `c-mode'."
-  :type '(hook :format "%{C Mode Hook%}:\n%v")
+  :type 'hook
   :group 'c)
 
 (defcustom c++-mode-hook nil
@@ -425,6 +875,11 @@ The list of variables to buffer localize are:
   :type 'hook
   :group 'c)
 
+(defcustom pike-mode-hook nil
+  "*Hook called by `pike-mode'."
+  :type 'hook
+  :group 'c)
+
 (defcustom c-mode-common-hook nil
   "*Hook called by all CC Mode modes for common initializations."
   :type '(hook :format "%{CC Mode Common Hook%}:\n%v")
@@ -446,6 +901,23 @@ styles that conform to the Emacs recommendation of putting these
 braces in column zero, this can degrade performance about as much.
 This variable only has effect in XEmacs.")
 
+(defcustom c-old-style-variable-behavior nil
+  "*Enables the old style variable behavior when non-nil.
+
+Normally the values of the style variables will override the style
+settings specified by the variables `c-default-style' and
+`c-styles-alist'.  However, in CC Mode 5.25 and earlier, it was the
+other way around, meaning that changes made to the style variables
+from e.g. Customize would not take effect unless special precautions
+were taken.  That was confusing, especially for novice users.
+
+It's believed that despite this change, the new behavior will still
+produce the same results for most old CC Mode configurations, since
+all style variables are per default set in a special non-override
+state.  Set this variable only if your configuration has stopped
+working due to this change.")
+
+
 \f
 ;; Non-customizable variables, still part of the interface to CC Mode
 (defvar c-file-style nil
@@ -456,6 +928,7 @@ will set the style of the file to this value automatically.
 
 Note that file style settings are applied before file offset settings
 as designated in the variable `c-file-offsets'.")
+(make-variable-buffer-local 'c-file-style)
 
 (defvar c-file-offsets nil
   "Variable interface for setting offsets via File Local Variables.
@@ -466,12 +939,13 @@ automatically.
 
 Note that file offset settings are applied after file style settings
 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.")
 
-(defvar c-indentation-style c-default-style
-  "Name of style installed in the current buffer.")
+(defvar c-indentation-style nil
+  "Name of the currently installed style.")
 
 
 \f
@@ -511,9 +985,8 @@ There are many flavors of Emacs out there, each with different
 features supporting those needed by CC Mode.  Here's the current
 supported list, along with the values for this variable:
 
- XEmacs 19:                  (8-bit)
- XEmacs 20:                  (8-bit)
- Emacs 19:                   (1-bit)
+ XEmacs 19, 20, 21:          (8-bit)
+ Emacs 19, 20:               (1-bit)
 
 Infodock (based on XEmacs) has an additional symbol on this list:
 `infodock'.")