changeset 26817:03befb219d03

Installed version 5.26
author Gerd Moellmann <gerd@gnu.org>
date Sun, 12 Dec 1999 18:24:19 +0000
parents e719053e967a
children 1004bdd01f7b
files 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
diffstat 10 files changed, 2781 insertions(+), 1429 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/progmodes/cc-align.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-align.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -29,16 +29,22 @@
 ;; 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)
 
 
 ;; 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)
@@ -78,7 +84,11 @@
 	))))
 
 (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
@@ -89,7 +99,12 @@
       (- 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
@@ -99,15 +114,16 @@
       (- 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)
@@ -124,10 +140,12 @@
 	  (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)
@@ -135,7 +153,9 @@
       (- (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))
@@ -149,110 +169,215 @@
       )))
 
 (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-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 ((eol (c-point 'eol)))
+      (back-to-indentation)
+      (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
+  "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))
-	  (stars (progn (back-to-indentation)
-			(skip-chars-forward "*")))
-	  (langelem-col (c-langelem-col langelem)))
-      (back-to-indentation)
-      (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
-	  (progn
-	    (if (not (looking-at "[*]+"))
+    (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)
@@ -264,18 +389,33 @@
        ))))
 
 (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))
@@ -307,13 +447,29 @@
 	(- (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)
@@ -336,8 +492,11 @@
       (- 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)))
@@ -357,8 +516,11 @@
 	  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)))
@@ -377,31 +539,57 @@
 	  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-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)
+    (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
+  "Do not change the indentation of the current line.
+
+Works with: Any syntactic symbol."
   (save-excursion
     (back-to-indentation)
-    (current-column)))
-
+    (- (current-column) (c-langelem-col langelem))))
 
 
 (defun c-snug-do-while (syntax pos)
@@ -450,6 +638,7 @@
 
 
 ;; 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
--- a/lisp/progmodes/cc-cmds.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-cmds.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,11 +28,17 @@
 ;; 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-engine)
 
 
-(eval-when-compile
-  (require 'cc-defs))
-
 (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 @@
 	;; 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 @@
 		   ;; 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 @@
 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 @@
 		  (insert "} catch (")))
 	    (goto-char (- (point-max) pos))
 	    ))
-	(funcall old-blink-paren)))))
+	(if old-blink-paren
+	    (funcall old-blink-paren))))))
 
 
 
@@ -692,6 +716,7 @@
 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 @@
 	(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 @@
   (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)))
 
 
 (defun c-beginning-of-statement (&optional count lim sentence-flag)
@@ -759,18 +796,12 @@
 	  (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 @@
       (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 @@
 	    (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) ?{)
-			       (if (or (= here last)
-				       (save-excursion
-					 (and (c-safe (progn (up-list -1) t))
-					      (/= (char-after) ?{))))
-				   (progn (forward-char)
-					  (throw 'done nil))
-				 (goto-char last)
-				 (throw 'done t)))
-			      ((and (= (char-after) ?})
-				    (/= here last))
+		    (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))
-			      ((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)))
+			    ((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)
+				       (memq (char-after last) '(?\) ?})))
+				   (if (and (eq (char-before) ?})
+					    (eq (char-after) ?\;))
+				       (backward-char))
+				 (goto-char last)
+				 (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 @@
 		     (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 @@
 	    (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 @@
 	 )))))
 
 
-;; 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)))
 
 
 (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) t)
+  (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-backward-conditional (count &optional up-flag)
+(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 1)
+  (c-keep-region-active))
+
+(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 @@
 			;; 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 @@
   "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 @@
 	   (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 @@
 			  (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 @@
  	    (delete-region (1+ (point))
  			   (progn (skip-chars-backward " \t") (point)))))))
 
+
 
+;;; 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 @@
 
 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
+		;; 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
-		(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)))
+		(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)
+		      (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)
 
-			  ;; 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.
+(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)))
 
-			  ;; 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)))))))))
+(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.
 
-		;; 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)))
-	      (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)))
-		      (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 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))))
 
 
 (provide 'cc-cmds)
--- a/lisp/progmodes/cc-compat.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-compat.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -40,9 +40,15 @@
 ;;; 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)
 
 
 ;; In case c-mode.el isn't loaded
--- a/lisp/progmodes/cc-defs.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-defs.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,10 +28,8 @@
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-
 ;; 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))
 
 
-(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:
   ;; 
@@ -63,76 +61,105 @@
   ;; 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)))
 
 
 (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
@@ -152,17 +179,78 @@
   (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
@@ -188,13 +276,14 @@
 	  (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.
@@ -209,6 +298,7 @@
   (cond
    ;; XEmacs
    ((and (fboundp 'region-active-p)
+	 (boundp 'zmacs-regions)
 	 zmacs-regions)
     (region-active-p))
    ;; Emacs
@@ -219,6 +309,17 @@
 (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)
+
 
 (provide 'cc-defs)
 ;;; cc-defs.el ends here
--- a/lisp/progmodes/cc-engine.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-engine.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,10 +28,17 @@
 ;; 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-langs)
+
 
-(eval-when-compile
-  (require 'cc-defs))
-
 ;; 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
@@ -98,7 +105,7 @@
 	   ;; 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)
@@ -112,6 +119,7 @@
 					  (<= lim (point))
 					  (not (c-in-literal lim))
 					  (not (eq (char-before) ?_))
+					  c-conditional-key
 					  (looking-at c-conditional-key)
 					  ))))
 		       ;; did we find a conditional?
@@ -144,8 +152,10 @@
 		(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
@@ -170,7 +180,7 @@
 		     ;; `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)
@@ -187,7 +197,7 @@
     ;; 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 ()
@@ -254,7 +264,7 @@
 	 (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)))
@@ -264,28 +274,13 @@
       )
     (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)))))
 
@@ -428,16 +423,18 @@
 (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)))
@@ -460,18 +457,20 @@
 			    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.
@@ -481,7 +480,7 @@
 	       (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")
@@ -495,32 +494,65 @@
 		   ;; 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++
@@ -536,18 +568,16 @@
 	    (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))))
@@ -558,11 +588,11 @@
   ;; 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 @@
   ;; 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 @@
     ;; 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)))))
-
 
 ;; 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 @@
 	  (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 @@
 	      ;; 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 @@
 	     ;; 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 @@
 				 (= (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 @@
 	      ;; 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 @@
 		   (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 @@
 	    ;; 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 @@
 	  (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 @@
 	   ((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 @@
 	  (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 @@
 				  (= (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 @@
 		   (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 @@
       ))
   (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)))))
+
 
 (provide 'cc-engine)
 ;;; cc-engine.el ends here
--- a/lisp/progmodes/cc-langs.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-langs.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,11 +28,38 @@
 ;; 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)
 
 
-(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)
 
+
 ;; 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\\)")
@@ -86,11 +113,18 @@
 (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)
+
 
 ;; 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)
@@ -99,6 +133,8 @@
 ;; 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)
 
@@ -109,6 +145,8 @@
       (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)))
 
@@ -132,6 +170,10 @@
 
 ;; 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 "/\\(/\\|[*][*]?\\)")
@@ -173,7 +215,7 @@
 
 ;; 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)
@@ -225,47 +267,86 @@
   ;; 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 '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 'adaptive-fill-mode)
   (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))
@@ -280,14 +361,6 @@
       (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 @@
   ;; 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 @@
   ;;(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 @@
   ;;(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++"))
 
--- a/lisp/progmodes/cc-menus.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-menus.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,8 +28,23 @@
 ;; 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 @@
 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 @@
                                               ; 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 @@
                    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-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 @@
   "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 @@
 ;  ())
 ; FIXME: Please contribute one!
 
+(defun cc-imenu-init (mode-generic-expression)
+  (setq imenu-generic-expression mode-generic-expression
+	imenu-case-fold-search nil))
+
 
 (provide 'cc-menus)
 ;;; cc-menus.el ends here
--- a/lisp/progmodes/cc-mode.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-mode.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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!
@@ -85,27 +85,34 @@
 
 ;;; Code:
 
-
-(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-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)))
 
-(eval-and-compile
-  (require 'cc-defs))
+(require 'cc-defs) ; Not meaningless; this passes on require's from cc-defs.
 (require 'cc-menus)
 (require 'cc-vars)
+(require 'cc-styles)
+(require 'cc-langs)
 (require 'cc-engine)
-(require 'cc-langs)
 (require 'cc-align)
-(require 'cc-styles)
 (require 'cc-cmds)
 
-
 
 ;; 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 @@
   (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)))
     ))
 
 
@@ -162,10 +171,10 @@
 	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 @@
 	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 @@
   (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 @@
   (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 @@
  	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 @@
   (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 @@
   (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,14 +394,45 @@
 	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))
 
 
+(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))))
+
+
 ;; bug reporting
 
 (defconst c-mode-help-address
@@ -423,36 +467,40 @@
 		    ((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
--- a/lisp/progmodes/cc-styles.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-styles.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -28,10 +28,16 @@
 ;; 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-vars)
 
-;; explicit compile-time dependencies
-(eval-when-compile
-  (require 'cc-defs))
 
 
 ;; 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"
@@ -85,13 +92,32 @@
     ("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)
@@ -124,7 +150,7 @@
      )
     ("python"
      (indent-tabs-mode . t)
-     (fill-column      . 72)
+     (fill-column      . 78)
      (c-basic-offset   . 8)
      (c-offsets-alist  . ((substatement-open . 0)
 			  (inextern-lang . 0)
@@ -138,21 +164,18 @@
 				(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)
@@ -161,7 +184,6 @@
 			 (inher-cont     . c-lineup-java-inher)
 			 (func-decl-cont . c-lineup-java-throws)
 			 ))
-
      )
     )
   "Styles of indentation.
@@ -175,7 +197,7 @@
 
 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 @@
 modify existing styles -- you should create a new style that inherits
 the existing style.")
 
+
 
 ;; 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 @@
 	(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 @@
 					(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 @@
 
 
 
-(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 @@
 	     (goto-char relpos)
 	     (current-column))
 	 0)
-       (c-evaluate-offset offset langelem symbol))
+       (or (and (numberp offset) offset)
+	   (and (symbolp offset) (symbol-value offset))
+	   0))
     ))
 
+
 
 (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 @@
     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 @@
 		    (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 (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))
 
+
 
-(defun c-copy-tree (tree)
-  (if (consp tree)
-      (cons (c-copy-tree (car tree))
-            (c-copy-tree (cdr tree)))
-    tree))
-
 (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 @@
     (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 @@
   (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))
     ))
 
 
--- a/lisp/progmodes/cc-vars.el	Sun Dec 12 16:13:50 1999 +0000
+++ b/lisp/progmodes/cc-vars.el	Sun Dec 12 18:24:19 1999 +0000
@@ -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
@@ -29,29 +29,18 @@
 ;; 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)
 
-(require 'custom)
 
 
-(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."
-  :type 'boolean
-  :group 'c)
-
-(defcustom c-echo-syntactic-information-p nil
-  "*If non-nil, syntactic info is echoed when the line is indented."
-  :type 'boolean
-  :group 'c)
-
-(defcustom c-basic-offset 4
-  "*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
-  :type 'integer
-  :group 'c)
+;;; Helpers
 
 ;; This widget will show up in newer versions of the Custom library
 (or (get 'other 'widget-type)
@@ -62,6 +51,115 @@
       :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))))
+
+
+
+;;; 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.
+
+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)
+
+(defcustom c-echo-syntactic-information-p nil
+  "*If non-nil, syntactic info is echoed when the line is indented."
+  :type 'boolean
+  :group 'c)
+
+(defcustom-c-stylevar c-basic-offset 4
+  "*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
+  :type 'integer
+  :group 'c)
+
 (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 @@
 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 @@
   :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 @@
 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 @@
   :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)
 
-(defcustom c-cleanup-list '(scope-operator)
+(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-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 @@
                         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 @@
 	  (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 @@
 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 @@
 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)
+  :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-hanging-colons-alist nil
+(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 @@
 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 @@
   :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 @@
   :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 @@
 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.
+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.
 
-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\")))
+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)
 
-to see your customizations.  This is also true if you use the Custom
-interface -- be sure to set the default style to `user'.
+(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:
 
-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")
-		   )))
+    (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 @@
 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 @@
 
 (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 @@
   :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 @@
 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.")
+
+
 
 ;; Non-customizable variables, still part of the interface to CC Mode
 (defvar c-file-style nil
@@ -456,6 +928,7 @@
 
 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 @@
 
 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.")
 
 
 
@@ -511,9 +985,8 @@
 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'.")