]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-mode.el
(c-forward-label): Fix for QT macros.
[gnu-emacs] / lisp / progmodes / cc-mode.el
index db71bf334088eca1766b206413d451d7b54023d1..044d8542bfe70e87fa6ddb61c92ab283eb16f355 100644 (file)
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,9 +26,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with this program; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
+;; For Emacs < 22.2.
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
 (eval-when-compile
   (let ((load-path
         (if (and (boundp 'byte-compile-dest-file)
@@ -190,7 +192,8 @@ control).  See \"cc-mode.el\" for more info."
            (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-block-comment-prefix
+                     (symbol-value 'c-comment-continuation-stars)))
            (add-hook 'change-major-mode-hook 'c-leave-cc-mode-mode)
            (setq c-initialization-ok t))
        ;; Will try initialization hooks again if they failed.
@@ -211,12 +214,12 @@ control).  See \"cc-mode.el\" for more info."
     ;; function is called from top-level forms that are evaluated
     ;; while cc-bytecomp is active when one does M-x eval-buffer.
     (cond
-     ;; XEmacs
-     ((cc-bytecomp-fboundp 'set-keymap-parents)
-      (set-keymap-parents map c-mode-base-map))
      ;; Emacs
      ((cc-bytecomp-fboundp 'set-keymap-parent)
       (set-keymap-parent map c-mode-base-map))
+     ;; XEmacs
+     ((cc-bytecomp-fboundp 'set-keymap-parents)
+      (set-keymap-parents map c-mode-base-map))
      ;; incompatible
      (t (error "CC Mode is incompatible with this version of Emacs")))
     map))
@@ -269,7 +272,9 @@ control).  See \"cc-mode.el\" for more info."
                             'c-indent-new-comment-line
                             c-mode-base-map global-map)
   (substitute-key-definition 'indent-for-tab-command
-                            'c-indent-command
+                            ;; XXX Is this the right thing to do
+                            ;; here?
+                            'c-indent-line-or-region
                             c-mode-base-map global-map)
   (when (fboundp 'comment-indent-new-line)
     ;; indent-new-comment-line has changed name to
@@ -280,8 +285,9 @@ control).  See \"cc-mode.el\" for more info."
 
   ;; RMS says don't make these the default.
   ;; (April 2006): RMS has now approved these commands as defaults.
-  (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)
+  (unless (memq 'argumentative-bod-function c-emacs-features)
+    (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)
@@ -597,7 +603,9 @@ that requires a literal mode spec at compile time."
   (make-local-hook 'before-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))
+  (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 (2008-04), only used by AWK.
 
 (defun c-setup-doc-comment-style ()
   "Initialize the variables that depend on the value of `c-doc-comment-style'."
@@ -649,6 +657,26 @@ compatible with old code; callers should always specify it."
       (and (cdr rfn)
           (setq require-final-newline mode-require-final-newline)))))
 
+(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
+`c-file-style' and `c-file-offsets' are present in the list.
+
+This function is called from the hook `before-hack-local-variables-hook'."
+  (when c-buffer-is-cc-mode
+    (let ((stile (cdr (assq 'c-file-style file-local-variables-alist)))
+         (offsets (cdr (assq 'c-file-offsets file-local-variables-alist))))
+      (when stile
+       (or (stringp stile) (error "c-file-style is not a string"))
+       (c-set-style stile))
+      (when offsets
+       (mapc
+        (lambda (langentry)
+          (let ((langelem (car langentry))
+                (offset (cdr langentry)))
+            (c-set-offset langelem offset)))
+        offsets)))))
+
 (defun c-remove-any-local-eval-or-mode-variables ()
   ;; If the buffer specifies `mode' or `eval' in its File Local Variable list
   ;; or on the first line, remove all occurrences.  See
@@ -708,10 +736,13 @@ Note that the style variables are always made local to the buffer."
   (when c-buffer-is-cc-mode
     (if (or c-file-style c-file-offsets)
        (c-make-styles-buffer-local t))
-    (and c-file-style
-        (c-set-style c-file-style))
+    (when c-file-style
+      (or (stringp c-file-style)
+         (error "c-file-style is not a string"))
+      (c-set-style c-file-style))
+
     (and c-file-offsets
-        (mapcar
+        (mapc
          (lambda (langentry)
            (let ((langelem (car langentry))
                  (offset (cdr langentry)))
@@ -737,7 +768,9 @@ Note that the style variables are always made local to the buffer."
            (hack-local-variables))
          nil))))
 
-(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
+(if (boundp 'before-hack-local-variables-hook)
+    (add-hook 'before-hack-local-variables-hook 'c-before-hack-hook)
+  (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
 
 (defmacro c-run-mode-hooks (&rest hooks)
   ;; Emacs 21.1 has introduced a system with delayed mode hooks that
@@ -787,28 +820,30 @@ Note that the style variables are always made local to the buffer."
   (setq c-old-EOM (point)))
 
 (defun c-neutralize-CPP-line (beg end)
-  ;; BEG and END bound a preprocessor line.  Put a "punctuation" syntax-table
-  ;; property on syntactically obtrusive characters, ones which would interact
-  ;; syntactically with stuff outside the CPP line.
+  ;; BEG and END bound a region, typically a preprocessor line.  Put a
+  ;; "punctuation" syntax-table property on syntactically obtrusive
+  ;; characters, ones which would interact syntactically with stuff outside
+  ;; this region.
   ;;
   ;; These are unmatched string delimiters, or unmatched
   ;; parens/brackets/braces.  An unclosed comment is regarded as valid, NOT
   ;; obtrusive.
-  (let (s)
-    (while
-       (progn
-         (setq s (parse-partial-sexp beg end -1))
-         (cond
-          ((< (nth 0 s) 0)             ; found an unmated ),},]
-           (c-put-char-property (1- (point)) 'syntax-table '(1))
-           t)
-          ((nth 3 s)                   ; In a string
-           (c-put-char-property (nth 8 s) 'syntax-table '(1))
-           t)
-          ((> (nth 0 s) 0)             ; In a (,{,[
-           (c-put-char-property (nth 1 s) 'syntax-table '(1))
-           t)
-          (t nil))))))
+  (save-excursion
+    (let (s)
+      (while
+         (progn
+           (setq s (parse-partial-sexp beg end -1))
+           (cond
+            ((< (nth 0 s) 0)           ; found an unmated ),},]
+             (c-put-char-property (1- (point)) 'syntax-table '(1))
+             t)
+            ((nth 3 s)                 ; In a string
+             (c-put-char-property (nth 8 s) 'syntax-table '(1))
+             t)
+            ((> (nth 0 s) 0)           ; In a (,{,[
+             (c-put-char-property (nth 1 s) 'syntax-table '(1))
+             t)
+            (t nil)))))))
 
 (defun c-neutralize-syntax-in-CPP (begg endd old-len)
   ;; "Neutralize" every preprocessor line wholly or partially in the changed
@@ -828,28 +863,43 @@ Note that the style variables are always made local to the buffer."
   ;;
   ;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
   ;;
-  ;; This function might do invisible changes.
-  (c-save-buffer-state (limits mbeg beg end)
-    ;; First calculate the region, possibly to be extended.
-    (setq beg (min begg c-old-BOM))
+  ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
+  ;; 
+  ;; This function might make hidden buffer changes.
+  (c-save-buffer-state (limits mbeg+1 beg end)
+    ;; First determine the region, (beg end), which may need "neutralizing".
+    ;; This may not start inside a string, comment, or macro.
+    (goto-char c-old-BOM)        ; already set to old start of macro or begg.
+    (setq beg
+         (if (setq limits (c-literal-limits))
+             (cdr limits)          ; go forward out of any string or comment.
+           (point)))
+
     (goto-char endd)
-    (when (c-beginning-of-macro)
-      (c-end-of-macro))
+    (if (setq limits (c-literal-limits))
+       (goto-char (car limits)))  ; go backward out of any string or comment.
+    (if (c-beginning-of-macro)
+       (c-end-of-macro))
     (setq end (max (+ (- c-old-EOM old-len) (- endd begg))
                   (point)))
+
     ;; Clear all old punctuation properties
     (c-clear-char-property-with-value beg end 'syntax-table '(1))
 
     (goto-char beg)
-    ;; If we're inside a string/comment, go to its end.
-    (if (setq limits (c-literal-limits))
-       (goto-char (cdr limits)))
-
-    (while (search-forward-regexp c-anchored-cpp-prefix end t)
-      (when (c-beginning-of-macro)    ; Guard against being in a string/comment.
-       (setq mbeg (point))
-       (c-end-of-macro)          ; Do we need to go forward 1 char here?  No!
-       (c-neutralize-CPP-line mbeg (point)))))) ; We might still be in a comment - this is OK.
+    (let ((pps-position beg)  pps-state)
+      (while (and (< (point) end)
+                 (search-forward-regexp c-anchored-cpp-prefix end t))
+       ;; If we've found a "#" inside a string/comment, ignore it.
+       (setq pps-state
+             (parse-partial-sexp pps-position (point) nil nil pps-state)
+             pps-position (point))
+       (unless (or (nth 3 pps-state)   ; in a string?
+                   (nth 4 pps-state))  ; in a comment?
+         (setq mbeg+1 (point))
+         (c-end-of-macro)        ; Do we need to go forward 1 char here?  No!
+         (c-neutralize-CPP-line mbeg+1 (point))
+         (setq pps-position (point))))))) ; no need to update pps-state.
 
 (defun c-before-change (beg end)
   ;; Function to be put on `before-change-function'.  Primarily, this calls
@@ -1004,19 +1054,17 @@ This does not load the font-lock package.  Use after
   (make-local-hook 'font-lock-mode-hook)
   (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
 
-(defmacro c-advise-fl-for-region (function)
-  `(defadvice ,function (before get-awk-region activate)
-;; When font-locking an AWK Mode buffer, make sure that any string/regexp is
-;; completely font-locked.
-  (when (eq major-mode 'awk-mode)
-    (save-excursion
-      (ad-set-arg 1 c-new-END)   ; end
-      (ad-set-arg 0 c-new-BEG)))))     ; beg
-
-(c-advise-fl-for-region font-lock-after-change-function)
-(c-advise-fl-for-region jit-lock-after-change)
-(c-advise-fl-for-region lazy-lock-defer-rest-after-change)
-(c-advise-fl-for-region lazy-lock-defer-line-after-change)
+(defun c-extend-after-change-region (beg end old-len)
+  "Extend the region to be fontified, if necessary."
+  ;; Note: the parameters are ignored here.  This somewhat indirect
+  ;; implementation exists because it is minimally different from the
+  ;; stand-alone CC Mode which, lacking
+  ;; font-lock-extend-after-change-region-function, is forced to use advice
+  ;; instead.
+  ;;
+  ;; Of the seven CC Mode languages, currently (2008-04) only AWK Mode makes
+  ;; non-null use of this function.
+  (cons c-new-BEG c-new-END))
 
 \f
 ;; Support for C
@@ -1070,6 +1118,11 @@ This does not load the font-lock package.  Use after
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.y\\(acc\\)?\\'" . c-mode))
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.lex\\'" . c-mode))
 
+;; Preprocessed files generated by C and C++ compilers.
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.i\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.ii\\'" . c++-mode))
+
+
 ;;;###autoload
 (defun c-mode ()
   "Major mode for editing K&R and ANSI C code.
@@ -1454,6 +1507,10 @@ Key bindings:
 (easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands"
                  (cons "AWK" (c-lang-const c-mode-menu awk)))
 
+;; (require 'cc-awk) brings these in.
+(defvar awk-mode-syntax-table)
+(declare-function c-awk-unstick-NL-prop "cc-awk" ())
+
 (defun awk-mode ()
   "Major mode for editing AWK code.
 To submit a problem report, enter `\\[c-submit-bug-report]' from an
@@ -1558,15 +1615,15 @@ Key bindings:
                     adaptive-fill-mode
                     adaptive-fill-regexp)
                   nil)))
-       (mapcar (lambda (var) (unless (boundp var)
-                               (setq vars (delq var vars))))
-               '(signal-error-on-buffer-boundary
-                 filladapt-mode
-                 defun-prompt-regexp
-                 font-lock-mode
-                 font-lock-maximum-decoration
-                 parse-sexp-lookup-properties
-                 lookup-syntax-properties))
+       (mapc (lambda (var) (unless (boundp var)
+                             (setq vars (delq var vars))))
+             '(signal-error-on-buffer-boundary
+               filladapt-mode
+               defun-prompt-regexp
+               font-lock-mode
+               font-lock-maximum-decoration
+               parse-sexp-lookup-properties
+               lookup-syntax-properties))
        vars)
       (lambda ()
        (run-hooks 'c-prepare-bug-report-hooks)
@@ -1576,5 +1633,5 @@ Key bindings:
 \f
 (cc-provide 'cc-mode)
 
-;;; arch-tag: 7825e5c4-fd09-439f-a04d-4c13208ba3d7
+;; arch-tag: 7825e5c4-fd09-439f-a04d-4c13208ba3d7
 ;;; cc-mode.el ends here