Merge from emacs-23
[bpt/emacs.git] / lisp / progmodes / cc-defs.el
index dcdcdae..f0d9bee 100644 (file)
@@ -1,18 +1,19 @@
 ;;; cc-defs.el --- compile time definitions for CC Mode
 
 ;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 ;;   Free Software Foundation, Inc.
 
 ;; Authors:    2003- Alan Mackenzie
 ;;             1998- Martin Stjernholm
 ;;             1992-1999 Barry A. Warsaw
-;;             1987 Dave Detlefs and Stewart Clamen
+;;             1987 Dave Detlefs
+;;             1987 Stewart Clamen
 ;;             1985 Richard M. Stallman
 ;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    22-Apr-1997 (split from cc-mode.el)
-;; Version:    See cc-mode.el
-;; Keywords:   c languages oop
+;; Keywords:   c languages
+;; Package:    cc-mode
 
 ;; This file is part of GNU Emacs.
 
@@ -94,7 +95,7 @@
 \f
 ;;; Variables also used at compile time.
 
-(defconst c-version "5.31.5"
+(defconst c-version "5.31.8"
   "CC Mode version number.")
 
 (defconst c-version-sym (intern c-version))
@@ -406,7 +407,7 @@ properties to be changed, even in a read-only buffer.
 
 This macro should be placed around all calculations which set
 \"insignificant\" text properties in a buffer, even when the buffer is
-known to be writeable.  That way, these text properties remain set
+known to be writable.  That way, these text properties remain set
 even if the user undoes the command which set them.
 
 This macro should ALWAYS be placed around \"temporary\" internal buffer
@@ -932,7 +933,9 @@ MODE is either a mode symbol or a list of mode symbols."
                (or (memq property prop)
                    (put-text-property pos (1+ pos)
                                       'rear-nonsticky
-                                      (cons property prop))))))))))
+                                      (cons property prop)))))))
+         ;; This won't be used for anything.
+         (t 'ignore))))
 (cc-bytecomp-defun c-put-char-property-fun) ; Make it known below.
 
 (defmacro c-put-char-property (pos property value)
@@ -1007,7 +1010,7 @@ MODE is either a mode symbol or a list of mode symbols."
         `(c-clear-char-property-fun ,pos ',property))))
 
 (defmacro c-clear-char-properties (from to property)
-  ;; Remove all the occurences of the given property in the given
+  ;; Remove all the occurrences of the given property in the given
   ;; region that has been put with `c-put-char-property'.  PROPERTY is
   ;; assumed to be constant.
   ;;
@@ -1026,13 +1029,51 @@ MODE is either a mode symbol or a list of mode symbols."
     ;; Emacs.
     `(remove-text-properties ,from ,to '(,property nil))))
 
+(defmacro c-search-forward-char-property (property value &optional limit)
+  "Search forward for a text-property PROPERTY having value VALUE.
+LIMIT bounds the search.  The comparison is done with `equal'.
+
+Leave point just after the character, and set the match data on
+this character, and return point.  If VALUE isn't found, Return
+nil; point is then left undefined."
+  `(let ((place (point)))
+     (while
+        (and
+         (< place ,(or limit '(point-max)))
+         (not (equal (get-text-property place ,property) ,value)))
+       (setq place (next-single-property-change
+                   place ,property nil ,(or limit '(point-max)))))
+     (when (< place ,(or limit '(point-max)))
+       (goto-char place)
+       (search-forward-regexp ".")     ; to set the match-data.
+       (point))))
+
+(defmacro c-search-backward-char-property (property value &optional limit)
+  "Search backward for a text-property PROPERTY having value VALUE.
+LIMIT bounds the search.  The comparison is done with `equal'.
+
+Leave point just before the character, set the match data on this
+character, and return point.  If VALUE isn't found, Return nil;
+point is then left undefined."
+  `(let ((place (point)))
+     (while
+        (and
+         (> place ,(or limit '(point-min)))
+         (not (equal (get-text-property (1- place) ,property) ,value)))
+       (setq place (previous-single-property-change
+                   place ,property nil ,(or limit '(point-min)))))
+     (when (> place ,(or limit '(point-max)))
+       (goto-char place)
+       (search-backward-regexp ".")    ; to set the match-data.
+       (point))))
+
 (defun c-clear-char-property-with-value-function (from to property value)
   "Remove all text-properties PROPERTY from the region (FROM, TO)
 which have the value VALUE, as tested by `equal'.  These
 properties are assumed to be over individual characters, having
 been put there by c-put-char-property.  POINT remains unchanged."
   (let ((place from) end-place)
-    (while                       ; loop round occurrances of (PROPERTY VALUE)
+    (while                       ; loop round occurrences of (PROPERTY VALUE)
        (progn
          (while           ; loop round changes in PROPERTY till we find VALUE
              (and
@@ -1041,7 +1082,7 @@ been put there by c-put-char-property.  POINT remains unchanged."
            (setq place (next-single-property-change place property nil to)))
          (< place to))
       (setq end-place (next-single-property-change place property nil to))
-      (put-text-property place end-place property nil)
+      (remove-text-properties place end-place (cons property nil))
       ;; Do we have to do anything with stickiness here?
       (setq place end-place))))
 
@@ -1142,23 +1183,117 @@ been put there by c-put-char-property.  POINT remains unchanged."
        (goto-char (point-max)))))
 
 (defconst c-<-as-paren-syntax '(4 . ?>))
+(put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
 
 (defsubst c-mark-<-as-paren (pos)
-  ;; Mark the "<" character at POS as an sexp list opener using the
-  ;; syntax-table property.
+  ;; Mark the "<" character at POS as a template opener using the
+  ;; `syntax-table' property via the `category' property.
   ;;
-  ;; This function does a hidden buffer change.
-  (c-put-char-property pos 'syntax-table c-<-as-paren-syntax))
+  ;; This function does a hidden buffer change.  Note that we use
+  ;; indirection through the `category' text property.  This allows us to
+  ;; toggle the property in all template brackets simultaneously and
+  ;; cheaply.  We use this, for instance, in `c-parse-state'.
+  (c-put-char-property pos 'category 'c-<-as-paren-syntax))
 
 (defconst c->-as-paren-syntax '(5 . ?<))
+(put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax)
 
 (defsubst c-mark->-as-paren (pos)
   ;; Mark the ">" character at POS as an sexp list closer using the
   ;; syntax-table property.
   ;;
-  ;; This function does a hidden buffer change.
-  (c-put-char-property pos 'syntax-table c->-as-paren-syntax))
-
+  ;; This function does a hidden buffer change.  Note that we use
+  ;; indirection through the `category' text property.  This allows us to
+  ;; toggle the property in all template brackets simultaneously and
+  ;; cheaply.  We use this, for instance, in `c-parse-state'.
+  (c-put-char-property pos 'category 'c->-as-paren-syntax))
+
+(defsubst c-unmark-<->-as-paren (pos)
+  ;; Unmark the "<" or "<" character at POS as an sexp list opener using
+  ;; the syntax-table property indirectly through the `category' text
+  ;; property.
+  ;;
+  ;; This function does a hidden buffer change.  Note that we use
+  ;; indirection through the `category' text property.  This allows us to
+  ;; toggle the property in all template brackets simultaneously and
+  ;; cheaply.  We use this, for instance, in `c-parse-state'.
+  (c-clear-char-property pos 'category))
+
+(defsubst c-suppress-<->-as-parens ()
+  ;; Suppress the syntactic effect of all marked < and > as parens.  Note
+  ;; that this effect is NOT buffer local.  You should probably not use
+  ;; this directly, but only through the macro
+  ;; `c-with-<->-as-parens-suppressed'
+  (put 'c-<-as-paren-syntax 'syntax-table nil)
+  (put 'c->-as-paren-syntax 'syntax-table nil))
+
+(defsubst c-restore-<->-as-parens ()
+  ;; Restore the syntactic effect of all marked <s and >s as parens.  This
+  ;; has no effect on unmarked <s and >s
+  (put 'c-<-as-paren-syntax 'syntax-table c-<-as-paren-syntax)
+  (put 'c->-as-paren-syntax 'syntax-table c->-as-paren-syntax))
+
+(defmacro c-with-<->-as-parens-suppressed (&rest forms)
+  ;; Like progn, except that the paren property is suppressed on all
+  ;; template brackets whilst they are running.  This macro does a hidden
+  ;; buffer change.
+  `(unwind-protect
+       (progn
+        (c-suppress-<->-as-parens)
+        ,@forms)
+     (c-restore-<->-as-parens)))
+
+;;;;;;;;;;;;;;;
+
+(defconst c-cpp-delimiter '(14)) ; generic comment syntax
+;; This is the value of the `category' text property placed on every #
+;; which introduces a CPP construct and every EOL (or EOB, or character
+;; preceding //, etc.) which terminates it.  We can instantly "comment
+;; out" all CPP constructs by giving `c-cpp-delimiter' a syntax-table
+;; propery '(14) (generic comment delimiter).
+(defmacro c-set-cpp-delimiters (beg end)
+  ;; This macro does a hidden buffer change.
+  `(progn
+     (c-put-char-property ,beg 'category 'c-cpp-delimiter)
+     (if (< ,end (point-max))
+        (c-put-char-property ,end 'category 'c-cpp-delimiter))))
+(defmacro c-clear-cpp-delimiters (beg end)
+  ;; This macro does a hidden buffer change.
+  `(progn
+     (c-clear-char-property ,beg 'category)
+     (if (< ,end (point-max))
+        (c-clear-char-property ,end 'category))))
+
+(defsubst c-comment-out-cpps ()
+  ;; Render all preprocessor constructs syntactically commented out.
+  (put 'c-cpp-delimiter 'syntax-table c-cpp-delimiter))
+(defsubst c-uncomment-out-cpps ()
+  ;; Restore the syntactic visibility of preprocessor constructs.
+  (put 'c-cpp-delimiter 'syntax-table nil))
+
+(defmacro c-with-cpps-commented-out (&rest forms)
+  ;; Execute FORMS... whilst the syntactic effect of all characters in
+  ;; all CPP regions is suppressed.  In particular, this is to suppress
+  ;; the syntactic significance of parens/braces/brackets to functions
+  ;; such as `scan-lists' and `parse-partial-sexp'.
+  `(unwind-protect
+       (c-save-buffer-state ()
+          (c-comment-out-cpps)
+          ,@forms)
+     (c-save-buffer-state ()
+       (c-uncomment-out-cpps))))
+
+(defmacro c-with-all-but-one-cpps-commented-out (beg end &rest forms)
+  ;; Execute FORMS... whilst the syntactic effect of all characters in
+  ;; every CPP region APART FROM THE ONE BETWEEN BEG and END is
+  ;; suppressed.
+  `(unwind-protect
+       (c-save-buffer-state ()
+        (c-clear-cpp-delimiters ,beg ,end)
+        ,`(c-with-cpps-commented-out ,@forms))
+     (c-save-buffer-state ()
+       (c-set-cpp-delimiters ,beg ,end))))
+\f
 (defsubst c-intersect-lists (list alist)
   ;; return the element of ALIST that matches the first element found
   ;; in LIST.  Uses assq.
@@ -1440,12 +1575,33 @@ non-nil, a caret is prepended to invert the set."
                         '1-bit)
                       list)))
 
+    ;; Check whether beginning/end-of-defun call
+    ;; beginning/end-of-defun-function nicely, passing through the
+    ;; argument and respecting the return code.
+    (let* (mark-ring
+          (bod-param 'foo) (eod-param 'foo)
+          (beginning-of-defun-function
+           (lambda (&optional arg)
+             (or (eq bod-param 'foo) (setq bod-param 'bar))
+             (and (eq bod-param 'foo)
+                  (setq bod-param arg)
+                  (eq arg 3))))
+          (end-of-defun-function
+           (lambda (&optional arg)
+             (and (eq eod-param 'foo)
+                  (setq eod-param arg)
+                  (eq arg 3)))))
+      (if (save-excursion (and (beginning-of-defun 3) (eq bod-param 3)
+                              (not (beginning-of-defun))
+                              (end-of-defun 3) (eq eod-param 3)
+                              (not (end-of-defun))))
+         (setq list (cons 'argumentative-bod-function list))))
+
     (let ((buf (generate-new-buffer " test"))
          parse-sexp-lookup-properties
          parse-sexp-ignore-comments
          lookup-syntax-properties)
-      (save-excursion
-       (set-buffer buf)
+      (with-current-buffer buf
        (set-syntax-table (make-syntax-table))
 
        ;; For some reason we have to set some of these after the
@@ -1539,6 +1695,9 @@ might be present:
 
 '8-bit              8 bit syntax entry flags (XEmacs style).
 '1-bit              1 bit syntax entry flags (Emacs style).
+'argumentative-bod-function         beginning-of-defun passes ARG through
+                    to a non-null beginning-of-defun-function.  It is assumed
+                   the end-of-defun does the same thing.
 'syntax-properties  It works to override the syntax for specific characters
                    in the buffer with the 'syntax-table property.  It's
                    always set - CC Mode no longer works in emacsen without
@@ -1672,6 +1831,9 @@ itself is evaluated."
   ;; `cl-macroexpand-all' inside `c-lang-defconst'.
   (eval form))
 
+;; Only used at compile time - suppress "might not be defined at runtime".
+(declare-function cl-macroexpand-all "cl-extra" (form &optional env))
+
 (defmacro c-lang-defconst (name &rest args)
   "Set the language specific values of the language constant NAME.
 The second argument can optionally be a docstring.  The rest of the