]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-engine.el
* lisp/emacs-lisp/nadvice.el (advice--member-p): Return the advice if found.
[gnu-emacs] / lisp / progmodes / cc-engine.el
index f23dfff9c2d8c5476ee736729a329ac025f4e49d..6a23da1f2cd34223d98dba91140d82b89e0755d4 100644 (file)
@@ -1,4 +1,4 @@
-;;; cc-engine.el --- core syntax guessing engine for CC mode
+;;; cc-engine.el --- core syntax guessing engine for CC mode -*- coding: utf-8 -*-
 
 ;; Copyright (C) 1985, 1987, 1992-2013 Free Software Foundation, Inc.
 
@@ -2180,32 +2180,45 @@ comment at the start of cc-engine.el for more info."
 ;; reduced by buffer changes, and increased by invocations of
 ;; `c-state-literal-at'.  FIXME!!!
 
-(defsubst c-state-pp-to-literal (from to)
+(defsubst c-state-pp-to-literal (from to &optional not-in-delimiter)
   ;; Do a parse-partial-sexp from FROM to TO, returning either
   ;;     (STATE TYPE (BEG . END))     if TO is in a literal; or
   ;;     (STATE)                      otherwise,
   ;; where STATE is the parsing state at TO, TYPE is the type of the literal
   ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal.
   ;;
+  ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
+  ;; comment opener, this is recognized as being in a comment literal.
+  ;;
   ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote),
   ;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of
   ;; STATE are valid.
   (save-excursion
     (let ((s (parse-partial-sexp from to))
-         ty)
-      (when (or (nth 3 s) (nth 4 s))   ; in a string or comment
+         ty co-st)
+      (cond
+       ((or (nth 3 s) (nth 4 s))       ; in a string or comment
        (setq ty (cond
                  ((nth 3 s) 'string)
-                 ((eq (nth 7 s) t) 'c++)
+                 ((nth 7 s) 'c++)
                  (t 'c)))
        (parse-partial-sexp (point) (point-max)
-                           nil                  ; TARGETDEPTH
-                           nil                  ; STOPBEFORE
-                           s                    ; OLDSTATE
-                           'syntax-table))      ; stop at end of literal
-      (if ty
-         `(,s ,ty (,(nth 8 s) . ,(point)))
-       `(,s)))))
+                           nil            ; TARGETDEPTH
+                           nil            ; STOPBEFORE
+                           s              ; OLDSTATE
+                           'syntax-table) ; stop at end of literal
+       `(,s ,ty (,(nth 8 s) . ,(point))))
+
+       ((and (not not-in-delimiter)    ; inside a comment starter
+            (not (bobp))
+            (progn (backward-char)
+                   (looking-at c-comment-start-regexp)))
+       (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
+             co-st (point))
+       (forward-comment 1)
+       `(,s ,ty (,co-st . ,(point))))
+
+       (t `(,s))))))
 
 (defun c-state-safe-place (here)
   ;; Return a buffer position before HERE which is "safe", i.e. outside any
@@ -2280,25 +2293,25 @@ comment at the start of cc-engine.el for more info."
        (while (and c (> (car c) c-state-semi-nonlit-pos-cache-limit))
          (setq c (cdr c)))
        (setq c-state-semi-nonlit-pos-cache c)
-       
+
        (while (and c (> (car c) here))
          (setq high-pos (car c))
          (setq c (cdr c)))
        (setq pos (or (car c) (point-min)))
-       
+
        (unless high-pos
          (while
              ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
              (and
               (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here)
-              
+
               ;; Test for being in a literal.  If so, go to after it.
               (progn
                 (setq lit (car (cddr (c-state-pp-to-literal pos npos))))
                 (or (null lit)
                     (prog1 (<= (cdr lit) here)
                       (setq npos (cdr lit))))))
-              
+
            (setq pos npos)
            (setq c-state-semi-nonlit-pos-cache
                  (cons pos c-state-semi-nonlit-pos-cache))))
@@ -2606,11 +2619,11 @@ comment at the start of cc-engine.el for more info."
   ;; OLD:   {                       (.)    {...........}
   ;;                                       ^             ^
   ;;                                     FROM          HERE
-  ;;                                     
+  ;;
   ;; NEW:   {             {....}    (.)    {.........
   ;;                         ^           ^           ^
   ;;                LOWER BRACE PAIR   HERE   or   HERE
-  ;;                                       
+  ;;
   ;; This routine should be fast.  Since it can get called a LOT, we maintain
   ;; `c-state-brace-pair-desert', a small cache of "failures", such that we
   ;; reduce the time wasted in repeated fruitless searches in brace deserts.
@@ -2907,7 +2920,7 @@ comment at the start of cc-engine.el for more info."
                    start-point))
        (goto-char pos)
        (while (and c-state-cache
-                   (or (numberp (car c-state-cache)) ; Have we a { at all? 
+                   (or (numberp (car c-state-cache)) ; Have we a { at all?
                        (cdr c-state-cache))
                    (< (point) here))
          (cond
@@ -3143,10 +3156,13 @@ comment at the start of cc-engine.el for more info."
   ;; This function is called from c-after-change.
 
   ;; The caches of non-literals:
-  (if (< here c-state-nonlit-pos-cache-limit)
-      (setq c-state-nonlit-pos-cache-limit here))
-  (if (< here c-state-semi-nonlit-pos-cache-limit)
-      (setq c-state-semi-nonlit-pos-cache-limit here))
+  ;; Note that we use "<=" for the possibility of the second char of a two-char
+  ;; comment opener being typed; this would invalidate any cache position at
+  ;; HERE.
+  (if (<= here c-state-nonlit-pos-cache-limit)
+      (setq c-state-nonlit-pos-cache-limit (1- here)))
+  (if (<= here c-state-semi-nonlit-pos-cache-limit)
+      (setq c-state-semi-nonlit-pos-cache-limit (1- here)))
 
   ;; `c-state-cache':
   ;; Case 1: if `here' is in a literal containing point-min, everything
@@ -4444,19 +4460,12 @@ comment at the start of cc-engine.el for more info."
           (lim (or lim (c-state-semi-safe-place pos)))
           (pp-to-lit (save-restriction
                        (widen)
-                       (c-state-pp-to-literal lim pos)))
+                       (c-state-pp-to-literal lim pos not-in-delimiter)))
           (state (car pp-to-lit))
           (lit-limits (car (cddr pp-to-lit))))
 
       (cond
        (lit-limits)
-       ((and (not not-in-delimiter)
-            (not (elt state 5))
-            (eq (char-before) ?/)
-            (looking-at "[/*]")) ; FIXME!!! use c-line/block-comment-starter.  2008-09-28.
-       ;; We're standing in a comment starter.
-       (backward-char 1)
-       (cons (point) (progn (c-forward-single-comment) (point))))
 
        (near
        (goto-char pos)
@@ -4610,7 +4619,7 @@ comment at the start of cc-engine.el for more info."
                     s                  ; state
                     'syntax-table)))   ; stop-comment
        (setq pos (point)))
-    
+
       ;; Now try and find enough non-literal characters recorded on the stack.
       ;; Go back one recorded literal each time round this loop.
       (while (and (< count how-far-back)
@@ -6466,6 +6475,52 @@ comment at the start of cc-engine.el for more info."
           (c-go-list-forward)
          t)))
 
+(defun c-back-over-member-initializers ()
+  ;; Test whether we are in a C++ member initializer list, and if so, go back
+  ;; to the introducing ":", returning the position of the opening paren of
+  ;; the function's arglist.  Otherwise return nil, leaving point unchanged.
+  (let ((here (point))
+       (paren-state (c-parse-state))
+       res)
+
+    (setq res
+         (catch 'done
+           (if (not (c-at-toplevel-p))
+               (progn
+                 (while (not (c-at-toplevel-p))
+                   (goto-char (c-pull-open-brace paren-state)))
+                 (c-backward-syntactic-ws)
+                 (when (not (c-simple-skip-symbol-backward))
+                   (throw 'done nil))
+                 (c-backward-syntactic-ws))
+             (c-backward-syntactic-ws)
+             (when (memq (char-before) '(?\) ?}))
+               (when (not (c-go-list-backward))
+                 (throw 'done nil))
+               (c-backward-syntactic-ws))
+             (when (c-simple-skip-symbol-backward)
+               (c-backward-syntactic-ws)))
+
+           (while (eq (char-before) ?,)
+             (backward-char)
+             (c-backward-syntactic-ws)
+
+             (when (not (memq (char-before) '(?\) ?})))
+               (throw 'done nil))
+             (when (not (c-go-list-backward))
+               (throw 'done nil))
+             (c-backward-syntactic-ws)
+             (when (not (c-simple-skip-symbol-backward))
+               (throw 'done nil))
+             (c-backward-syntactic-ws))
+
+           (and
+            (eq (char-before) ?:)
+            (c-just-after-func-arglist-p))))
+
+    (or res (goto-char here))
+    res))
+
 \f
 ;; Handling of large scale constructs like statements and declarations.
 
@@ -8516,8 +8571,8 @@ comment at the start of cc-engine.el for more info."
    ))
 
 (defun c-looking-at-special-brace-list (&optional lim)
-  ;; If we're looking at the start of a pike-style list, ie `({ })',
-  ;; `([ ])', `(< >)' etc, a cons of a cons of its starting and ending
+  ;; If we're looking at the start of a pike-style list, i.e., `({ })',
+  ;; `([ ])', `(< >)', etc., a cons of a cons of its starting and ending
   ;; positions and its entry in c-special-brace-lists is returned, nil
   ;; otherwise.  The ending position is nil if the list is still open.
   ;; LIM is the limit for forward search.  The point may either be at
@@ -8762,7 +8817,7 @@ comment at the start of cc-engine.el for more info."
        (c-simple-skip-symbol-backward)
        (looking-at c-macro-with-semi-re)
        (goto-char pos)
-       (not (c-in-literal))))))                ; The most expensive check last. 
+       (not (c-in-literal))))))                ; The most expensive check last.
 
 (defun c-macro-vsemi-status-unknown-p () t) ; See cc-defs.el.
 
@@ -9668,18 +9723,13 @@ comment at the start of cc-engine.el for more info."
              ;; 2007-11-09)
              ))))
 
-        ;; CASE 5B: After a function header but before the body (or
-        ;; the ending semicolon if there's no body).
+        ;; CASE 5R: Member init list.  (Used to be part of CASE  5B.1)
+        ;; Note there is no limit on the backward search here, since member
+        ;; init lists can, in practice, be very large.
         ((save-excursion
-           (when (setq placeholder (c-just-after-func-arglist-p
-                                    (max lim (c-determine-limit 500))))
+           (when (setq placeholder (c-back-over-member-initializers))
              (setq tmp-pos (point))))
-         (cond
-
-          ;; CASE 5B.1: Member init list.
-          ((eq (char-after tmp-pos) ?:)
-           (if (or (>= tmp-pos indent-point)
-                   (= (c-point 'bosws) (1+ tmp-pos)))
+         (if (= (c-point 'bosws) (1+ tmp-pos))
                (progn
                  ;; There is no preceding member init clause.
                  ;; Indent relative to the beginning of indentation
@@ -9692,6 +9742,23 @@ comment at the start of cc-engine.el for more info."
              (c-forward-syntactic-ws)
              (c-add-syntax 'member-init-cont (point))))
 
+        ;; CASE 5B: After a function header but before the body (or
+        ;; the ending semicolon if there's no body).
+        ((save-excursion
+           (when (setq placeholder (c-just-after-func-arglist-p
+                                    (max lim (c-determine-limit 500))))
+             (setq tmp-pos (point))))
+         (cond
+
+          ;; CASE 5B.1: Member init list.
+          ((eq (char-after tmp-pos) ?:)
+           ;; There is no preceding member init clause.
+           ;; Indent relative to the beginning of indentation
+           ;; for the topmost-intro line that contains the
+           ;; prototype's open paren.
+           (goto-char placeholder)
+           (c-add-syntax 'member-init-intro (c-point 'boi)))
+
           ;; CASE 5B.2: K&R arg decl intro
           ((and c-recognize-knr-p
                 (c-in-knr-argdecl lim))
@@ -9799,6 +9866,18 @@ comment at the start of cc-engine.el for more info."
            ;; contains any class offset
            )))
 
+        ;; CASE 5P: AWK pattern or function or continuation
+        ;; thereof.
+        ((c-major-mode-is 'awk-mode)
+         (setq placeholder (point))
+         (c-add-stmt-syntax
+          (if (and (eq (c-beginning-of-statement-1) 'same)
+                   (/= (point) placeholder))
+              'topmost-intro-cont
+            'topmost-intro)
+          nil nil
+          containing-sexp paren-state))
+
         ;; CASE 5D: this could be a top-level initialization, a
         ;; member init list continuation, or a template argument
         ;; list continuation.
@@ -9958,18 +10037,6 @@ comment at the start of cc-engine.el for more info."
              (goto-char (point-min)))
          (c-add-syntax 'objc-method-intro (c-point 'boi)))
 
-        ;; CASE 5P: AWK pattern or function or continuation
-        ;; thereof.
-        ((c-major-mode-is 'awk-mode)
-         (setq placeholder (point))
-         (c-add-stmt-syntax
-          (if (and (eq (c-beginning-of-statement-1) 'same)
-                   (/= (point) placeholder))
-              'topmost-intro-cont
-            'topmost-intro)
-          nil nil
-          containing-sexp paren-state))
-
         ;; CASE 5N: At a variable declaration that follows a class
         ;; definition or some other block declaration that doesn't
         ;; end at the closing '}'.  C.f. case 5D.5.