Spelling fixes.
[bpt/emacs.git] / lisp / progmodes / cc-mode.el
index ed76915..a6bf241 100644 (file)
@@ -1,8 +1,6 @@
 ;;; cc-mode.el --- major mode for editing C and similar languages
 
-;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2011  Free Software Foundation, Inc.
 
 ;; Authors:    2003- Alan Mackenzie
 ;;             1998- Martin Stjernholm
@@ -12,7 +10,7 @@
 ;;             1985 Richard M. Stallman
 ;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    a long, long, time ago. adapted from the original c-mode.el
-;; Keywords:   c languages oop
+;; Keywords:   c languages
 
 ;; This file is part of GNU Emacs.
 
 (cc-require 'cc-cmds)
 (cc-require 'cc-align)
 (cc-require 'cc-menus)
+(cc-require 'cc-guess)
 
 ;; Silence the compiler.
 (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
 (cc-bytecomp-defun set-keymap-parents) ; XEmacs
 (cc-bytecomp-defun run-mode-hooks)     ; Emacs 21.1
-(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1.
 
 ;; We set these variables during mode init, yet we don't require
 ;; font-lock.
 ;   '
 (require 'cc-fonts) ;)
 
-;; cc-langs isn't loaded when we're byte compiled, so add autoload
-;; directives for the interface functions.
-(autoload 'c-make-init-lang-vars-fun "cc-langs")
-(autoload 'c-init-language-vars "cc-langs" nil nil 'macro)
-
 \f
 ;; Other modes and packages which depend on CC Mode should do the
 ;; following to make sure everything is loaded and available for their
@@ -488,15 +481,10 @@ that requires a literal mode spec at compile time."
 
   ;; these variables should always be buffer local; they do not affect
   ;; indentation style.
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (make-local-variable 'indent-line-function)
-  (make-local-variable 'indent-region-function)
-  (make-local-variable 'normal-auto-fill-function)
   (make-local-variable 'comment-start)
   (make-local-variable 'comment-end)
   (make-local-variable 'comment-start-skip)
-  (make-local-variable 'comment-multi-line)
-  (make-local-variable 'comment-line-break-function)
+  
   (make-local-variable 'paragraph-start)
   (make-local-variable 'paragraph-separate)
   (make-local-variable 'paragraph-ignore-fill-prefix)
@@ -504,25 +492,25 @@ that requires a literal mode spec at compile time."
   (make-local-variable 'adaptive-fill-regexp)
 
   ;; now set their values
-  (setq parse-sexp-ignore-comments t
-       indent-line-function 'c-indent-line
-       indent-region-function 'c-indent-region
-       normal-auto-fill-function 'c-do-auto-fill
-       comment-multi-line t
-       comment-line-break-function 'c-indent-new-comment-line)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'indent-line-function) 'c-indent-line)
+  (set (make-local-variable 'indent-region-function) 'c-indent-region)
+  (set (make-local-variable 'normal-auto-fill-function) 'c-do-auto-fill)
+  (set (make-local-variable 'comment-multi-line) t)
+  (set (make-local-variable 'comment-line-break-function)
+       'c-indent-new-comment-line)
 
   ;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a
   ;; direct call to `fill-paragraph' behaves better.  This still
   ;; doesn't work with filladapt but it's better than nothing.
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'c-fill-paragraph)
+  (set (make-local-variable 'fill-paragraph-function) 'c-fill-paragraph)
 
   ;; Initialise the cache of brace pairs, and opening braces/brackets/parens.
   (c-state-cache-init)
 
   (when (or c-recognize-<>-arglists
            (c-major-mode-is 'awk-mode)
-           (c-major-mode-is '(c-mode c++-mode objc-mode)))
+           (c-major-mode-is '(java-mode c-mode c++-mode objc-mode)))
     ;; We'll use the syntax-table text property to change the syntax
     ;; of some chars for this language, so do the necessary setup for
     ;; that.
@@ -533,22 +521,19 @@ that requires a literal mode spec at compile time."
 
     ;; Emacs.
     (when (boundp 'parse-sexp-lookup-properties)
-      (make-local-variable 'parse-sexp-lookup-properties)
-      (setq parse-sexp-lookup-properties t))
+      (set (make-local-variable 'parse-sexp-lookup-properties) t))
 
     ;; Same as above for XEmacs.
     (when (boundp 'lookup-syntax-properties)
-      (make-local-variable 'lookup-syntax-properties)
-      (setq lookup-syntax-properties t)))
+      (set (make-local-variable 'lookup-syntax-properties) t)))
 
   ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
   ;; property on each character.
   (when (boundp 'text-property-default-nonsticky)
-    (make-local-variable 'text-property-default-nonsticky)
     (mapc (lambda (tprop)
            (unless (assq tprop text-property-default-nonsticky)
-             (setq text-property-default-nonsticky
-                   (cons `(,tprop . t) text-property-default-nonsticky))))
+             (set (make-local-variable 'text-property-default-nonsticky)
+                   (cons `(,tprop . t) text-property-default-nonsticky))))
          '(syntax-table category c-type)))
 
   ;; In Emacs 21 and later it's possible to turn off the ad-hoc
@@ -564,11 +549,7 @@ that requires a literal mode spec at compile time."
   (c-clear-found-types)
 
   ;; now set the mode style based on default-style
-  (let ((style (if (stringp default-style)
-                  default-style
-                (or (cdr (assq mode default-style))
-                    (cdr (assq 'other default-style))
-                    "gnu"))))
+  (let ((style (cc-choose-style-for-mode mode default-style)))
     ;; 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
@@ -588,8 +569,7 @@ that requires a literal mode spec at compile time."
   (setq c-offsets-alist (copy-alist c-offsets-alist))
 
   ;; setup the comment indent variable in a Emacs version portable way
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'c-comment-indent)
+  (set (make-local-variable 'comment-indent-function) 'c-comment-indent)
 
 ;;   ;; Put submode indicators onto minor-mode-alist, but only once.
 ;;   (or (assq 'c-submode-indicators minor-mode-alist)
@@ -600,9 +580,10 @@ that requires a literal mode spec at compile time."
 
   ;; Install the functions that ensure that various internal caches
   ;; don't become invalid due to buffer changes.
-  (make-local-hook 'before-change-functions)
+  (when (featurep 'xemacs)
+    (make-local-hook 'before-change-functions)
+    (make-local-hook 'after-change-functions))
   (add-hook 'before-change-functions 'c-before-change nil t)
-  (make-local-hook 'after-change-functions)
   (add-hook 'after-change-functions 'c-after-change nil t)
   (set (make-local-variable 'font-lock-extend-after-change-region-function)
        'c-extend-after-change-region)) ; Currently (2009-05) used by all
@@ -616,6 +597,15 @@ that requires a literal mode spec at compile time."
     (font-lock-mode 0)
     (font-lock-mode 1)))
 
+;; Buffer local variables defining the region to be fontified by a font lock
+;; after-change function.  They are set in c-after-change to
+;; after-change-function's BEG and END, and may be modified by a
+;; `c-before-font-lock-function'.
+(defvar c-new-BEG 0)
+(make-variable-buffer-local 'c-new-BEG)
+(defvar c-new-END 0)
+(make-variable-buffer-local 'c-new-END)
+
 (defun c-common-init (&optional mode)
   "Common initialization for all CC Mode modes.
 In addition to the work done by `c-basic-common-init' and
@@ -651,17 +641,26 @@ compatible with old code; callers should always specify it."
          (funcall c-before-font-lock-function (point-min) (point-max)
                   (- (point-max) (point-min))))))
 
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (setq outline-regexp "[^#\n\^M]"
-       outline-level 'c-outline-level)
+  (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
+  (set (make-local-variable 'outline-level) 'c-outline-level)
 
   (let ((rfn (assq mode c-require-final-newline)))
     (when rfn
-      (make-local-variable 'require-final-newline)
       (and (cdr rfn)
-          (setq require-final-newline mode-require-final-newline)))))
-
+          (set (make-local-variable 'require-final-newline)
+                mode-require-final-newline)))))
+
+(defun c-count-cfss (lv-alist)
+  ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
+  ;; elements with the key `c-file-style' there are in it.
+  (let ((elt-ptr lv-alist) elt (cownt 0))
+    (while elt-ptr
+      (setq elt (car elt-ptr)
+           elt-ptr (cdr elt-ptr))
+      (when (eq (car elt) 'c-file-style)
+       (setq cownt (1+ cownt))))
+    cownt))
+                                                         
 (defun c-before-hack-hook ()
   "Set the CC Mode style and \"offsets\" when in the buffer's local variables.
 They are set only when, respectively, the pseudo variables
@@ -678,7 +677,16 @@ This function is called from the hook `before-hack-local-variables-hook'."
              (delq mode-cons file-local-variables-alist)))
       (when stile
        (or (stringp stile) (error "c-file-style is not a string"))
-       (c-set-style stile))
+       (if (boundp 'dir-local-variables-alist)
+           ;; Determine whether `c-file-style' was set in the file's local
+           ;; variables or in a .dir-locals.el (a directory setting).
+           (let ((cfs-in-file-and-dir-count
+                  (c-count-cfss file-local-variables-alist))
+                 (cfs-in-dir-count (c-count-cfss dir-local-variables-alist)))
+             (c-set-style stile
+                          (and (= cfs-in-file-and-dir-count cfs-in-dir-count)
+                               'keep-defaults)))
+         (c-set-style stile)))
       (when offsets
        (mapc
         (lambda (langentry)
@@ -792,15 +800,6 @@ Note that the style variables are always made local to the buffer."
 \f
 ;;; Change hooks, linking with Font Lock.
 
-;; Buffer local variables defining the region to be fontified by a font lock
-;; after-change function.  They are set in c-after-change to
-;; after-change-function's BEG and END, and may be modified by a
-;; `c-before-font-lock-function'.
-(defvar c-new-BEG 0)
-(make-variable-buffer-local 'c-new-BEG)
-(defvar c-new-END 0)
-(make-variable-buffer-local 'c-new-END)
-
 ;; Buffer local variables recording Beginning/End-of-Macro position before a
 ;; change, when a macro straddles, respectively, the BEG or END (or both) of
 ;; the change region.  Otherwise these have the values BEG/END.
@@ -1010,10 +1009,6 @@ Note that the style variables are always made local to the buffer."
                            (buffer-substring-no-properties type-pos term-pos)
                            (buffer-substring-no-properties beg end)))))))
 
-       ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
-       ;; larger than (beg end).
-       (setq c-new-BEG beg
-             c-new-END end)
        (if c-get-state-before-change-functions
            (mapc (lambda (fn)
                    (funcall fn beg end))
@@ -1067,6 +1062,10 @@ Note that the style variables are always made local to the buffer."
        (when c-recognize-<>-arglists
          (c-after-change-check-<>-operators beg end))
 
+       ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
+       ;; larger than (beg end).
+       (setq c-new-BEG beg
+             c-new-END end)
        (if c-before-font-lock-function
            (save-excursion
              (funcall c-before-font-lock-function beg end old-len)))))))
@@ -1081,8 +1080,7 @@ Note that the style variables are always made local to the buffer."
 This does not load the font-lock package.  Use after
 `c-basic-common-init' and after cc-fonts has been loaded."
 
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults
+  (set (make-local-variable 'font-lock-defaults)
        `(,(if (c-major-mode-is 'awk-mode)
               ;; awk-mode currently has only one font lock level.
               'awk-font-lock-keywords
@@ -1094,8 +1092,8 @@ This does not load the font-lock package.  Use after
          c-beginning-of-syntax
          (font-lock-mark-block-function
           . c-mark-function)))
-
-  (make-local-hook 'font-lock-mode-hook)
+  (if (featurep 'xemacs)
+      (make-local-hook 'font-lock-mode-hook))
   (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
 
 (defun c-extend-after-change-region (beg end old-len)
@@ -1169,7 +1167,7 @@ This does not load the font-lock package.  Use after
 
 
 ;;;###autoload
-(defun c-mode ()
+(define-derived-mode c-mode prog-mode "C"
   "Major mode for editing K&R and ANSI C code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from a
 c-mode buffer.  This automatically sets up a mail buffer with version
@@ -1183,16 +1181,13 @@ initialization, then `c-mode-hook'.
 
 Key bindings:
 \\{c-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table c-mode-syntax-table)
-  (setq major-mode 'c-mode
-       mode-name "C"
-       local-abbrev-table c-mode-abbrev-table
+  (setq local-abbrev-table c-mode-abbrev-table
        abbrev-mode t)
   (use-local-map c-mode-map)
   (c-init-language-vars-for 'c-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c-mode)
   (easy-menu-add c-c-menu)
   (cc-imenu-init cc-imenu-c-generic-expression)
@@ -1231,7 +1226,7 @@ Key bindings:
                  (cons "C++" (c-lang-const c-mode-menu c++)))
 
 ;;;###autoload
-(defun c++-mode ()
+(define-derived-mode c++-mode prog-mode "C++"
   "Major mode for editing C++ code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from a
 c++-mode buffer.  This automatically sets up a mail buffer with
@@ -1246,16 +1241,13 @@ initialization, then `c++-mode-hook'.
 
 Key bindings:
 \\{c++-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table c++-mode-syntax-table)
-  (setq major-mode 'c++-mode
-       mode-name "C++"
-       local-abbrev-table c++-mode-abbrev-table
+  (setq local-abbrev-table c++-mode-abbrev-table
        abbrev-mode t)
   (use-local-map c++-mode-map)
   (c-init-language-vars-for 'c++-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c++-mode)
   (easy-menu-add c-c++-menu)
   (cc-imenu-init cc-imenu-c++-generic-expression)
@@ -1292,7 +1284,7 @@ Key bindings:
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.m\\'" . objc-mode))
 
 ;;;###autoload
-(defun objc-mode ()
+(define-derived-mode objc-mode prog-mode "ObjC"
   "Major mode for editing Objective C code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from an
 objc-mode buffer.  This automatically sets up a mail buffer with
@@ -1307,16 +1299,13 @@ initialization, then `objc-mode-hook'.
 
 Key bindings:
 \\{objc-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table objc-mode-syntax-table)
-  (setq major-mode 'objc-mode
-       mode-name "ObjC"
-       local-abbrev-table objc-mode-abbrev-table
+  (setq local-abbrev-table objc-mode-abbrev-table
        abbrev-mode t)
   (use-local-map objc-mode-map)
   (c-init-language-vars-for 'objc-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'objc-mode)
   (easy-menu-add c-objc-menu)
   (cc-imenu-init nil 'cc-imenu-objc-function)
@@ -1362,7 +1351,7 @@ Key bindings:
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.java\\'" . java-mode))
 
 ;;;###autoload
-(defun java-mode ()
+(define-derived-mode java-mode prog-mode "Java"
   "Major mode for editing Java code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from a
 java-mode buffer.  This automatically sets up a mail buffer with
@@ -1377,13 +1366,9 @@ initialization, then `java-mode-hook'.
 
 Key bindings:
 \\{java-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table java-mode-syntax-table)
-  (setq major-mode 'java-mode
-       mode-name "Java"
-       local-abbrev-table java-mode-abbrev-table
+  (setq local-abbrev-table java-mode-abbrev-table
        abbrev-mode t)
   (use-local-map java-mode-map)
   (c-init-language-vars-for 'java-mode)
@@ -1421,7 +1406,7 @@ Key bindings:
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.idl\\'" . idl-mode))
 
 ;;;###autoload
-(defun idl-mode ()
+(define-derived-mode idl-mode prog-mode "IDL"
   "Major mode for editing CORBA's IDL, PSDL and CIDL code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from an
 idl-mode buffer.  This automatically sets up a mail buffer with
@@ -1436,13 +1421,9 @@ initialization, then `idl-mode-hook'.
 
 Key bindings:
 \\{idl-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table idl-mode-syntax-table)
-  (setq major-mode 'idl-mode
-       mode-name "IDL"
-       local-abbrev-table idl-mode-abbrev-table)
+  (setq local-abbrev-table idl-mode-abbrev-table)
   (use-local-map idl-mode-map)
   (c-init-language-vars-for 'idl-mode)
   (c-common-init 'idl-mode)
@@ -1482,7 +1463,7 @@ Key bindings:
 ;;;###autoload (add-to-list 'interpreter-mode-alist '("pike" . pike-mode))
 
 ;;;###autoload
-(defun pike-mode ()
+(define-derived-mode pike-mode prog-mode "Pike"
   "Major mode for editing Pike code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from a
 pike-mode buffer.  This automatically sets up a mail buffer with
@@ -1497,13 +1478,9 @@ initialization, then `pike-mode-hook'.
 
 Key bindings:
 \\{pike-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table pike-mode-syntax-table)
-  (setq major-mode 'pike-mode
-       mode-name "Pike"
-       local-abbrev-table pike-mode-abbrev-table
+  (setq local-abbrev-table pike-mode-abbrev-table
        abbrev-mode t)
   (use-local-map pike-mode-map)
   (c-init-language-vars-for 'pike-mode)
@@ -1556,7 +1533,8 @@ Key bindings:
 (defvar awk-mode-syntax-table)
 (declare-function c-awk-unstick-NL-prop "cc-awk" ())
 
-(defun awk-mode ()
+;;;###autoload
+(define-derived-mode awk-mode prog-mode "AWK"
   "Major mode for editing AWK code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from an
 awk-mode buffer.  This automatically sets up a mail buffer with version
@@ -1570,14 +1548,14 @@ initialization, then `awk-mode-hook'.
 
 Key bindings:
 \\{awk-mode-map}"
-  (interactive)
+  ;; We need the next line to stop the macro defining
+  ;; `awk-mode-syntax-table'.  This would mask the real table which is
+  ;; declared in cc-awk.el and hasn't yet been loaded.
+  :syntax-table nil
   (require 'cc-awk)                    ; Added 2003/6/10.
-  (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table awk-mode-syntax-table)
-  (setq major-mode 'awk-mode
-       mode-name "AWK"
-       local-abbrev-table awk-mode-abbrev-table
+  (setq local-abbrev-table awk-mode-abbrev-table
        abbrev-mode t)
   (use-local-map awk-mode-map)
   (c-init-language-vars-for 'awk-mode)
@@ -1661,7 +1639,7 @@ Key bindings:
                     adaptive-fill-regexp)
                   nil)))
        (mapc (lambda (var) (unless (boundp var)
-                             (setq vars (delq var vars))))
+                         (setq vars (delq var vars))))
              '(signal-error-on-buffer-boundary
                filladapt-mode
                defun-prompt-regexp
@@ -1678,5 +1656,4 @@ Key bindings:
 \f
 (cc-provide 'cc-mode)
 
-;; arch-tag: 7825e5c4-fd09-439f-a04d-4c13208ba3d7
 ;;; cc-mode.el ends here