]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-engine.el
(gud-stop-subjob): Using jdb, suspend threads
[gnu-emacs] / lisp / progmodes / cc-engine.el
index 717016af7eae97d09d3e5ed60a66caefde64c5c8..817b161ff878b8a29db9d445680b4eb65e965c32 100644 (file)
@@ -1,7 +1,7 @@
 ;;; cc-engine.el --- core syntax guessing engine for CC mode
 
 ;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
 ;;   Free Software Foundation, Inc.
 
 ;; Authors:    2001- Alan Mackenzie
 
 ;; 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 2, 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
@@ -27,9 +27,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:
 
@@ -81,8 +79,9 @@
 ;; assume that these text properties are used as described here.
 ;;
 ;; 'syntax-table
-;;   Used to modify the syntax of some characters.  Currently used to
-;;   mark the "<" and ">" of angle bracket parens with paren syntax.
+;;   Used to modify the syntax of some characters.  It is used to
+;;   mark the "<" and ">" of angle bracket parens with paren syntax, and
+;;   to "hide" obtrusive characters in preprocessor lines.
 ;;
 ;;   This property is used on single characters and is therefore
 ;;   always treated as front and rear nonsticky (or start and end open
@@ -604,7 +603,7 @@ comment at the start of cc-engine.el for more info."
   ;;         (e.g. if).
   ;;
   ;;
-  ;; The following diagram briefly outlines the PDA.  
+  ;; The following diagram briefly outlines the PDA.
   ;;
   ;; Common state:
   ;;   "else": Push state, goto state `else'.
@@ -1079,7 +1078,7 @@ single `?' is found, then `c-maybe-labelp' is cleared.
 
 For AWK, a statement which is terminated by an EOL (not a \; or a }) is
 regarded as having a \"virtual semicolon\" immediately after the last token on
-the line.  If this virtual semicolon is _at_ from, the function recognises it.
+the line.  If this virtual semicolon is _at_ from, the function recognizes it.
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
@@ -1916,7 +1915,7 @@ comment at the start of cc-engine.el for more info."
 (defun c-partial-ws-p (beg end)
   ;; Is the region (beg end) WS, and is there WS (or BOB/EOB) next to the
   ;; region?  This is a "heuristic" function.  .....
-  ;; 
+  ;;
   ;; The motivation for the second bit is to check whether removing this
   ;; region would coalesce two symbols.
   ;;
@@ -3291,7 +3290,7 @@ comment at the start of cc-engine.el for more info."
 ;; The workaround for this is for the AWK Mode initialisation to switch the
 ;; defalias for c-in-literal to c-slow-in-literal.  This will slow down other
 ;; cc-modes in Xemacs whenever an awk-buffer has been initialised.
-;; 
+;;
 ;; (Alan Mackenzie, 2003/4/30).
 
 (defun c-fast-in-literal (&optional lim detect-cpp)
@@ -3406,7 +3405,7 @@ comment at the start of cc-engine.el for more info."
        (if (and (consp range) (progn
                                 (goto-char (car range))
                                 (looking-at c-line-comment-starter)))
-           (let ((col (current-column)) 
+           (let ((col (current-column))
                  (beg (point))
                  (bopl (c-point 'bopl))
                  (end (cdr range)))
@@ -4035,6 +4034,9 @@ comment at the start of cc-engine.el for more info."
              c-found-types)
     (sort type-list 'string-lessp)))
 
+;; Shut up the byte compiler.
+(defvar c-maybe-stale-found-type)
+
 (defun c-trim-found-types (beg end old-len)
   ;; An after change function which, in conjunction with the info in
   ;; c-maybe-stale-found-type (set in c-before-change), removes a type
@@ -4042,7 +4044,7 @@ comment at the start of cc-engine.el for more info."
   ;; example, this happens to "foo" when "foo \n bar();" becomes
   ;; "foo(); \n bar();".  Such stale types, if not removed, foul up
   ;; the fontification.
-  ;; 
+  ;;
   ;; Have we, perhaps, added non-ws characters to the front/back of a found
   ;; type?
   (when (> end beg)
@@ -4061,13 +4063,12 @@ comment at the start of cc-engine.el for more info."
                        (c-beginning-of-current-token)))
            (c-unfind-type (buffer-substring-no-properties
                            (point) beg))))))
-           
+
   (if c-maybe-stale-found-type ; e.g. (c-decl-id-start "foo" 97 107 " (* ooka) " "o")
       (cond
        ;; Changing the amount of (already existing) whitespace - don't do anything.
        ((and (c-partial-ws-p beg end)
             (or (= beg end)            ; removal of WS
-                ; (string-match "\\s *\\'" (nth 5 c-maybe-stale-found-type))
                 (string-match "^[ \t\n\r\f\v]*$" (nth 5 c-maybe-stale-found-type)))))
 
        ;; The syntactic relationship which defined a "found type" has been
@@ -5092,7 +5093,8 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;;   The point is left at the first token after the first complete
   ;;   declarator, if there is one.  The return value is a cons where
-  ;;   the car is the position of the first token in the declarator.
+  ;;   the car is the position of the first token in the declarator.  (See
+  ;;   below for the cdr.)
   ;;   Some examples:
   ;;
   ;;    void foo (int a, char *b) stuff ...
@@ -5116,9 +5118,9 @@ comment at the start of cc-engine.el for more info."
   ;;     Foo::Foo (int b) : Base (b) {}
   ;; car ^                ^ point
   ;;
-  ;;   The cdr of the return value is non-nil iff a
-  ;;   `c-typedef-decl-kwds' specifier is found in the declaration,
-  ;;   i.e. the declared identifier(s) are types.
+  ;;   The cdr of the return value is non-nil iff a `c-typedef-decl-kwds'
+  ;;   specifier (e.g. class, struct, enum, typedef) is found in the
+  ;;   declaration, i.e. the declared identifier(s) are types.
   ;;
   ;; If a cast is parsed:
   ;;
@@ -5133,7 +5135,7 @@ comment at the start of cc-engine.el for more info."
   ;; the first token in (the visible part of) the buffer.
   ;;
   ;; CONTEXT is a symbol that describes the context at the point:
-  ;; 'decl     In a comma-separatded declaration context (typically
+  ;; 'decl     In a comma-separated declaration context (typically
   ;;           inside a function declaration arglist).
   ;; '<>       In an angle bracket arglist.
   ;; 'arglist  Some other type of arglist.
@@ -5891,7 +5893,7 @@ comment at the start of cc-engine.el for more info."
   ;;   "private:"/"protected:"/"public:"/"more:" looking like "public slots:".
   ;;   Returns the symbol `qt-2kwds-colon'.
   ;; (v) QT's construct "signals:".  Returns the symbol `qt-1kwd-colon'.
-  ;; (v) One of the keywords matched by `c-opt-extra-label-key' (without any
+  ;; (vi) One of the keywords matched by `c-opt-extra-label-key' (without any
   ;;   colon).  Currently (2006-03), this applies only to Objective C's
   ;;   keywords "@private", "@protected", and "@public".  Returns t.
   ;;
@@ -5927,7 +5929,7 @@ comment at the start of cc-engine.el for more info."
        macro-start                     ; if we're in one.
        label-type)
     (cond
-     ;; "case" or "default" (Doesn't apply to AWK). 
+     ;; "case" or "default" (Doesn't apply to AWK).
      ((looking-at c-label-kwds-regexp)
       (let ((kwd-end (match-end 1)))
        ;; Record only the keyword itself for fontification, since in
@@ -6046,7 +6048,7 @@ comment at the start of cc-engine.el for more info."
                         (c-forward-label nil pte start))))))))))
 
           ;; Point is still at the beginning of the possible label construct.
-          ;; 
+          ;;
           ;; Check that the next nonsymbol token is ":", or that we're in one
           ;; of QT's "slots" declarations.  Allow '(' for the sake of macro
           ;; arguments.  FIXME: Should build this regexp from the language
@@ -6072,7 +6074,7 @@ comment at the start of cc-engine.el for more info."
                     (and (c-major-mode-is 'c++-mode)
                          (string-match
                           "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>"
-                          (buffer-substring start (point)))))  
+                          (buffer-substring start (point)))))
               (c-forward-syntactic-ws limit)
               (cond
                ((looking-at ":\\([^:]\\|\\'\\)") ; A single colon.
@@ -6117,8 +6119,7 @@ comment at the start of cc-engine.el for more info."
                                     (match-end 0)))))
 
          (c-put-c-type-property (1- (point-max)) 'c-decl-end)
-         (goto-char (point-max))
-         )))
+         (goto-char (point-max)))))
 
      (t
       ;; Not a label.
@@ -6333,7 +6334,8 @@ comment at the start of cc-engine.el for more info."
       ;; the searchable range.
       (let* ((macro-start (c-query-macro-start))
             (lim (max (or lim (point-min)) (or macro-start (point-min))))
-            before-lparen after-rparen)
+            before-lparen after-rparen
+            (pp-count-out 20)) ; Max number of paren/brace constructs before we give up
        (narrow-to-region lim (c-point 'eol))
 
        ;; Search backwards for the defun's argument list.  We give up if we
@@ -6355,7 +6357,8 @@ comment at the start of cc-engine.el for more info."
        ;; {
 
        (catch 'knr
-         (while t ; go round one paren/bracket construct each time round.
+         (while (> pp-count-out 0) ; go back one paren/bracket pair each time.
+           (setq pp-count-out (1- pp-count-out))
            (c-syntactic-skip-backward "^)]}")
            (cond ((eq (char-before) ?\))
                   (setq after-rparen (point)))
@@ -7197,6 +7200,23 @@ comment at the start of cc-engine.el for more info."
 ;; auto newline analysis.
 (defvar c-auto-newline-analysis nil)
 
+(defun c-brace-anchor-point (bracepos)
+  ;; BRACEPOS is the position of a brace in a construct like "namespace
+  ;; Bar {".  Return the anchor point in this construct; this is the
+  ;; earliest symbol on the brace's line which isn't earlier than
+  ;; "namespace".
+  ;;
+  ;; Currently (2007-08-17), "like namespace" means "matches
+  ;; c-other-block-decl-kwds".  It doesn't work with "class" or "struct"
+  ;; or anything like that.
+  (save-excursion
+    (let ((boi (c-point 'boi bracepos)))
+      (goto-char bracepos)
+      (while (and (> (point) boi)
+                 (not (looking-at c-other-decl-block-key)))
+       (c-backward-token-2))
+      (if (> (point) boi) (point) boi))))
+
 (defsubst c-add-syntax (symbol &rest args)
   ;; A simple function to prepend a new syntax element to
   ;; `c-syntactic-context'.  Using `setq' on it is unsafe since it
@@ -7220,7 +7240,7 @@ comment at the start of cc-engine.el for more info."
   ;; needed with further syntax elements of the types `substatement',
   ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro', and
   ;; `defun-block-intro'.
-  ;; 
+  ;;
   ;; Do the generic processing to anchor the given syntax symbol on
   ;; the preceding statement: Skip over any labels and containing
   ;; statements on the same line, and then search backward until we
@@ -7229,8 +7249,12 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;; Point is assumed to be at the prospective anchor point for the
   ;; given SYNTAX-SYMBOL.  More syntax entries are added if we need to
-  ;; skip past open parens and containing statements.  All the added
-  ;; syntax elements will get the same anchor point.
+  ;; skip past open parens and containing statements.  Most of the added
+  ;; syntax elements will get the same anchor point - the exception is
+  ;; for an anchor in a construct like "namespace"[*] - this is as early
+  ;; as possible in the construct but on the same line as the {.
+  ;;
+  ;; [*] i.e. with a keyword matching c-other-block-decl-kwds.
   ;;
   ;; SYNTAX-EXTRA-ARGS are a list of the extra arguments for the
   ;; syntax symbol.  They are appended after the anchor point.
@@ -7255,7 +7279,11 @@ comment at the start of cc-engine.el for more info."
          ;; now at the start.
          on-label)
 
-      (apply 'c-add-syntax syntax-symbol nil syntax-extra-args)
+      ;; Use point as the anchor point for "namespace", "extern", etc.
+      (apply 'c-add-syntax syntax-symbol
+            (if (rassq syntax-symbol c-other-decl-block-key-in-symbols-alist)
+                (point) nil)
+            syntax-extra-args)
 
       ;; Loop while we have to back out of containing blocks.
       (while
@@ -7375,22 +7403,31 @@ comment at the start of cc-engine.el for more info."
                (setq step-type 'same
                      on-label nil))
 
+           ;; Stepped out of a brace block.
            (setq step-type (c-beginning-of-statement-1 containing-sexp)
                  on-label (eq step-type 'label))
 
            (if (and (eq step-type 'same)
                     (/= paren-pos (point)))
-               (save-excursion
-                 (goto-char paren-pos)
-                 (let ((inexpr (c-looking-at-inexpr-block
-                                (c-safe-position containing-sexp
-                                                 paren-state)
-                                containing-sexp)))
-                   (if (and inexpr
-                            (not (eq (car inexpr) 'inlambda)))
-                       (c-add-syntax 'statement-block-intro nil)
-                     (c-add-syntax 'defun-block-intro nil))))
-             (c-add-syntax 'statement-block-intro nil)))
+               (let (inexpr)
+                 (cond
+                  ((save-excursion
+                     (goto-char paren-pos)
+                     (setq inexpr (c-looking-at-inexpr-block
+                                   (c-safe-position containing-sexp paren-state)
+                                   containing-sexp)))
+                   (c-add-syntax (if (eq (car inexpr) 'inlambda)
+                                     'defun-block-intro
+                                   'statement-block-intro)
+                                 nil))
+                  ((looking-at c-other-decl-block-key)
+                   (c-add-syntax
+                    (cdr (assoc (match-string 1)
+                                c-other-decl-block-key-in-symbols-alist))
+                    (max (c-point 'boi paren-pos) (point))))
+                  (t (c-add-syntax 'defun-block-intro nil))))
+
+                (c-add-syntax 'statement-block-intro nil)))
 
          (if (= paren-pos boi)
              ;; Always done if the open brace was at boi.  The
@@ -7402,10 +7439,13 @@ comment at the start of cc-engine.el for more info."
 
       ;; Fill in the current point as the anchor for all the symbols
       ;; added above.
-      (let ((p c-syntactic-context))
+      (let ((p c-syntactic-context) q)
        (while (not (eq p syntax-last))
-         (if (cdr (car p))
-             (setcar (cdr (car p)) (point)))
+         (setq q (cdr (car p))) ; e.g. (nil 28) [from (arglist-cont-nonempty nil 28)]
+         (while q
+           (unless (car q)
+             (setcar q (point)))
+           (setq q (cdr q)))
          (setq p (cdr p))))
       )))
 
@@ -7994,12 +8034,15 @@ comment at the start of cc-engine.el for more info."
 
             ;; CASE 5A.5: ordinary defun open
             (t
-             (goto-char placeholder)
-             (if (or containing-decl-open macro-start)
-                 (c-add-syntax 'defun-open (c-point 'boi))
-               ;; Bogus to use bol here, but it's the legacy.
-               (c-add-syntax 'defun-open (c-point 'bol)))
-             )))
+             (save-excursion
+               (c-beginning-of-decl-1 lim)
+               (while (looking-at c-specifier-key)
+                 (goto-char (match-end 1))
+                 (c-forward-syntactic-ws indent-point))
+               (c-add-syntax 'defun-open (c-point 'boi))
+               ;; Bogus to use bol here, but it's the legacy.  (Resolved,
+               ;; 2007-11-09)
+               ))))
 
           ;; CASE 5B: After a function header but before the body (or
           ;; the ending semicolon if there's no body).
@@ -8209,24 +8252,27 @@ comment at the start of cc-engine.el for more info."
              (c-add-syntax 'inher-cont (c-point 'boi)))
 
             ;; CASE 5D.5: Continuation of the "expression part" of a
-            ;; top level construct.
+            ;; top level construct.  Or, perhaps, an unrecognised construct.
             (t
-             (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
+             (while (and (setq placeholder (point))
+                         (eq (car (c-beginning-of-decl-1 containing-sexp))
                              'same)
                          (save-excursion
                            (c-backward-syntactic-ws)
-                           (eq (char-before) ?}))))
+                           (eq (char-before) ?}))
+                         (< (point) placeholder)))
              (c-add-stmt-syntax
-              (if (eq char-before-ip ?,)
+              (cond
+               ((eq (point) placeholder) 'statement) ; unrecognised construct
                   ;; A preceding comma at the top level means that a
                   ;; new variable declaration starts here.  Use
                   ;; topmost-intro-cont for it, for consistency with
                   ;; the first variable declaration.  C.f. case 5N.
-                  'topmost-intro-cont
-                'statement-cont)
+               ((eq char-before-ip ?,) 'topmost-intro-cont)
+               (t 'statement-cont))
               nil nil containing-sexp paren-state))
             ))
-          
+
           ;; CASE 5F: Close of a non-class declaration level block.
           ((and (eq char-after-ip ?})
                 (c-keyword-member containing-decl-kwd
@@ -8258,6 +8304,7 @@ comment at the start of cc-engine.el for more info."
 
           ;; CASE 5H: we could be looking at subsequent knr-argdecls
           ((and c-recognize-knr-p
+                (not containing-sexp)  ; can't be knr inside braces.
                 (not (eq char-before-ip ?}))
                 (save-excursion
                   (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
@@ -8360,9 +8407,7 @@ comment at the start of cc-engine.el for more info."
                (if (c-keyword-member containing-decl-kwd
                                      'c-other-block-decl-kwds)
                    (progn
-                     (goto-char containing-decl-open)
-                     (unless (= (point) (c-point 'boi))
-                       (goto-char containing-decl-start))
+                     (goto-char (c-brace-anchor-point containing-decl-open))
                      (c-add-stmt-syntax
                       (if (string-equal (symbol-name containing-decl-kwd)
                                         "extern")
@@ -9173,5 +9218,5 @@ Cannot combine absolute offsets %S and %S in `add' method"
 \f
 (cc-provide 'cc-engine)
 
-;;; arch-tag: 149add18-4673-4da5-ac47-6805e4eae089
+;; arch-tag: 149add18-4673-4da5-ac47-6805e4eae089
 ;;; cc-engine.el ends here