]> code.delx.au - gnu-emacs/commitdiff
Amend a cache so that typing into C++ raw strings has no undue delay.
authorAlan Mackenzie <acm@muc.de>
Mon, 27 Jun 2016 11:34:02 +0000 (11:34 +0000)
committerAlan Mackenzie <acm@muc.de>
Mon, 27 Jun 2016 11:34:02 +0000 (11:34 +0000)
Also amend the code so that low-level searches to the end of literals are done
only when these positions get used.

* lisp/progmodes/cc-engine.el (c-crosses-statement-barrier-p): Use the new
c-literal-start instead of c-literal-limit.
(c-state-semi-nonlit-pos-cache): Change the structure of this cache, such that
it stores details of the literal at a point, rather than merely points outside
of literals.
(c-state-semi-pp-to-literal, c-state-full-pp-to-literal)
(c-cache-to-parse-ps-state, c-parse-ps-state-to-cache, c-ps-state-cache-pos)
(c-parse-ps-state-below, c-literal-start): New functions.
(c-state-semi-safe-place): Removed.
(c-in-literal): Use c-state-semi-pp-to-literal, so as not to scan to its end.
(c-literal-limits, c-determine-limit-get-base): consequential amendments.
(c-find-decl-spots, c-before-change-check-<>-operators, c-raw-string-pos)
(c-guess-basic-syntax (CASE 2)): Avoid needless scans to end of literals.

* lisp/progmodes/cc-fonts.el (c-font-lock-doc-comments): Avoid needless scans
to end of literals.

* lisp/progmodes/cc-mode.el (c-fl-decl-start): Avoid needless scans to end of
literals.

* lisp/progmodes/cc-cmds.el (c-beginning-of-defun, c-end-of-defun)
(c-defun-name, c-declaration-limits): Avoid needless scans to end of literals.

lisp/progmodes/cc-cmds.el
lisp/progmodes/cc-engine.el
lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-mode.el

index 59f2729c43d4ca51183563ecb2bb98779897d89d..f0ad2942457623612071749b30732033596c0857 100644 (file)
@@ -1610,8 +1610,8 @@ defun."
 
       ;; Move back out of any macro/comment/string we happen to be in.
       (c-beginning-of-macro)
-      (setq pos (c-literal-limits))
-      (if pos (goto-char (car pos)))
+      (setq pos (c-literal-start))
+      (if pos (goto-char pos))
 
       (setq where (c-where-wrt-brace-construct))
 
@@ -1734,8 +1734,8 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
 
       ;; Move back out of any macro/comment/string we happen to be in.
       (c-beginning-of-macro)
-      (setq pos (c-literal-limits))
-      (if pos (goto-char (car pos)))
+      (setq pos (c-literal-start))
+      (if pos (goto-char pos))
 
       (setq where (c-where-wrt-brace-construct))
 
@@ -1793,8 +1793,8 @@ with a brace block."
       (save-excursion
        ;; Move back out of any macro/comment/string we happen to be in.
        (c-beginning-of-macro)
-       (setq pos (c-literal-limits))
-       (if pos (goto-char (car pos)))
+       (setq pos (c-literal-start))
+       (if pos (goto-char pos))
 
        (setq where (c-where-wrt-brace-construct))
 
@@ -1880,103 +1880,103 @@ with a brace block."
        (or (save-restriction
              (c-narrow-to-most-enclosing-decl-block nil)
 
-    ;; Note: Some code duplication in `c-beginning-of-defun' and
-    ;; `c-end-of-defun'.
-    (catch 'exit
-      (let ((start (point))
-           (paren-state (c-parse-state))
-           lim pos end-pos)
-       (unless (c-safe
-                 (goto-char (c-least-enclosing-brace paren-state))
+             ;; Note: Some code duplication in `c-beginning-of-defun' and
+             ;; `c-end-of-defun'.
+             (catch 'exit
+               (let ((start (point))
+                     (paren-state (c-parse-state))
+                     lim pos end-pos)
+                 (unless (c-safe
+                           (goto-char (c-least-enclosing-brace paren-state))
                            ;; If we moved to the outermost enclosing paren
                            ;; then we can use c-safe-position to set the
                            ;; limit. Can't do that otherwise since the
                            ;; earlier paren pair on paren-state might very
                            ;; well be part of the declaration we should go
                            ;; to.
-                 (setq lim (c-safe-position (point) paren-state))
-                 t)
-         ;; At top level.  Make sure we aren't inside a literal.
-         (setq pos (c-literal-limits
-                    (c-safe-position (point) paren-state)))
-         (if pos (goto-char (car pos))))
-
-       (when (c-beginning-of-macro)
-         (throw 'exit
-                (cons (point)
-                      (save-excursion
-                        (c-end-of-macro)
-                        (forward-line 1)
-                        (point)))))
+                           (setq lim (c-safe-position (point) paren-state))
+                           t)
+                   ;; At top level.  Make sure we aren't inside a literal.
+                   (setq pos (c-literal-start
+                              (c-safe-position (point) paren-state)))
+                   (if pos (goto-char pos)))
+
+                 (when (c-beginning-of-macro)
+                   (throw 'exit
+                          (cons (point)
+                                (save-excursion
+                                  (c-end-of-macro)
+                                  (forward-line 1)
+                                  (point)))))
 
-       (setq pos (point))
-       (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
-                 (= pos (point)))
-         ;; We moved back over the previous defun.  Skip to the next
-         ;; one.  Not using c-forward-syntactic-ws here since we
-         ;; should not skip a macro.  We can also be directly after
-         ;; the block in a `c-opt-block-decls-with-vars-key'
-         ;; declaration, but then we won't move significantly far
-         ;; here.
-         (goto-char pos)
-         (c-forward-comments)
-
-         (when (and near (c-beginning-of-macro))
-           (throw 'exit
-                  (cons (point)
-                        (save-excursion
-                          (c-end-of-macro)
-                          (forward-line 1)
-                          (point))))))
-
-       (if (eobp) (throw 'exit nil))
-
-       ;; Check if `c-beginning-of-decl-1' put us after the block in a
-       ;; declaration that doesn't end there.  We're searching back and
-       ;; forth over the block here, which can be expensive.
-       (setq pos (point))
-       (if (and c-opt-block-decls-with-vars-key
-                (progn
-                  (c-backward-syntactic-ws)
-                  (eq (char-before) ?}))
-                (eq (car (c-beginning-of-decl-1))
-                    'previous)
-                (save-excursion
-                  (c-end-of-decl-1)
-                  (and (> (point) pos)
-                       (setq end-pos (point)))))
-           nil
-         (goto-char pos))
-
-       (if (and (not near) (> (point) start))
-           nil
-
-         ;; Try to be line oriented; position the limits at the
-         ;; closest preceding boi, and after the next newline, that
-         ;; isn't inside a comment, but if we hit a neighboring
-         ;; declaration then we instead use the exact declaration
-         ;; limit in that direction.
-         (cons (progn
                  (setq pos (point))
-                 (while (and (/= (point) (c-point 'boi))
-                             (c-backward-single-comment)))
-                 (if (/= (point) (c-point 'boi))
-                     pos
-                   (point)))
-               (progn
-                 (if end-pos
-                     (goto-char end-pos)
-                   (c-end-of-decl-1))
+                 (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
+                           (= pos (point)))
+                   ;; We moved back over the previous defun.  Skip to the next
+                   ;; one.  Not using c-forward-syntactic-ws here since we
+                   ;; should not skip a macro.  We can also be directly after
+                   ;; the block in a `c-opt-block-decls-with-vars-key'
+                   ;; declaration, but then we won't move significantly far
+                   ;; here.
+                   (goto-char pos)
+                   (c-forward-comments)
+
+                   (when (and near (c-beginning-of-macro))
+                     (throw 'exit
+                            (cons (point)
+                                  (save-excursion
+                                    (c-end-of-macro)
+                                    (forward-line 1)
+                                    (point))))))
+
+                 (if (eobp) (throw 'exit nil))
+
+                 ;; Check if `c-beginning-of-decl-1' put us after the block in a
+                 ;; declaration that doesn't end there.  We're searching back and
+                 ;; forth over the block here, which can be expensive.
                  (setq pos (point))
-                 (while (and (not (bolp))
-                             (not (looking-at "\\s *$"))
-                             (c-forward-single-comment)))
-                 (cond ((bolp)
-                        (point))
-                       ((looking-at "\\s *$")
-                        (forward-line 1)
-                        (point))
-                       (t
+                 (if (and c-opt-block-decls-with-vars-key
+                          (progn
+                            (c-backward-syntactic-ws)
+                            (eq (char-before) ?}))
+                          (eq (car (c-beginning-of-decl-1))
+                              'previous)
+                          (save-excursion
+                            (c-end-of-decl-1)
+                            (and (> (point) pos)
+                                 (setq end-pos (point)))))
+                     nil
+                   (goto-char pos))
+
+                 (if (and (not near) (> (point) start))
+                     nil
+
+                   ;; Try to be line oriented; position the limits at the
+                   ;; closest preceding boi, and after the next newline, that
+                   ;; isn't inside a comment, but if we hit a neighboring
+                   ;; declaration then we instead use the exact declaration
+                   ;; limit in that direction.
+                   (cons (progn
+                           (setq pos (point))
+                           (while (and (/= (point) (c-point 'boi))
+                                       (c-backward-single-comment)))
+                           (if (/= (point) (c-point 'boi))
+                               pos
+                             (point)))
+                         (progn
+                           (if end-pos
+                               (goto-char end-pos)
+                             (c-end-of-decl-1))
+                           (setq pos (point))
+                           (while (and (not (bolp))
+                                       (not (looking-at "\\s *$"))
+                                       (c-forward-single-comment)))
+                           (cond ((bolp)
+                                  (point))
+                                 ((looking-at "\\s *$")
+                                  (forward-line 1)
+                                  (point))
+                                 (t
                                   pos))))))))
            (and (not near)
                 (goto-char (point-min))
index 17415a259b6d3248a148b2b09b956f95479b4cb6..4bc4056081b0cc60fff271a4146df33eee095edf 100644 (file)
@@ -1300,7 +1300,7 @@ comment at the start of cc-engine.el for more info."
            c-stmt-delim-chars))
         (non-skip-list
          (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
-        lit-range vsemi-pos)
+        lit-range lit-start vsemi-pos)
     (save-restriction
       (widen)
       (save-excursion
@@ -1315,8 +1315,8 @@ comment at the start of cc-engine.el for more info."
             ((and (bolp)
                   (save-excursion
                     (progn
-                      (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment?
-                          (goto-char (car lit-range)))
+                      (if (setq lit-start (c-literal-start from)) ; Have we landed in a string/comment?
+                          (goto-char lit-start))
                       (c-backward-syntactic-ws) ; ? put a limit here, maybe?
                       (setq vsemi-pos (point))
                       (c-at-vsemi-p))))
@@ -2279,15 +2279,110 @@ comment at the start of cc-engine.el for more info."
 
 (defvar c-state-semi-nonlit-pos-cache nil)
 (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache)
-;; A list of buffer positions which are known not to be in a literal.  This is
-;; ordered with higher positions at the front of the list.  Only those which
-;; are less than `c-state-semi-nonlit-pos-cache-limit' are valid.
+;; A list of elements which are either buffer positions (when such positions
+;; are not in literals) or lists of the form (POS TYPE START), where POS is
+;; a buffer position inside a literal, TYPE is the type of the literal
+;; ('string, 'c, or 'c++) and START is the start of the literal.
 
 (defvar c-state-semi-nonlit-pos-cache-limit 1)
 (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache-limit)
-;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'.  This is
-;; reduced by buffer changes, and increased by invocations of
-;; `c-state-literal-at'.  FIXME!!!
+;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'.  This
+;; is reduced by buffer changes, and increased by invocations of
+;; `c-parse-ps-state-below'.
+
+(defun c-state-semi-pp-to-literal (here &optional not-in-delimiter)
+  ;; Do a parse-partial-sexp from a position in the buffer before HERE which
+  ;; isn't in a literal, and return information about HERE, either:
+  ;; (STATE TYPE BEG)          if HERE is in a literal; or
+  ;; (STATE)                   otherwise,
+  ;; where STATE is the parsing state at HERE, TYPE is the type of the literal
+  ;; enclosing HERE, (one of 'string, 'c, 'c++) and BEG is the starting
+  ;; position of that literal (including the delimiter).
+  ;;
+  ;; 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 10 (in
+  ;; newer Emacsen only, the syntax of a position after a potential first char
+  ;; of a two char construct) of STATE are valid.
+  (save-excursion
+    (save-match-data
+      (let* ((base-and-state (c-parse-ps-state-below here))
+            (base (car base-and-state))
+            (s (cdr base-and-state))
+            (s (parse-partial-sexp base here nil nil s))
+            ty)
+       (cond
+        ((or (nth 3 s) (nth 4 s))      ; in a string or comment
+         (setq ty (cond
+                   ((nth 3 s) 'string)
+                   ((nth 7 s) 'c++)
+                   (t 'c)))
+         (list s ty (nth 8 s)))
+        
+        ((and (not not-in-delimiter)   ; inside a comment starter
+              (not (bobp))
+              (progn (backward-char)
+                     (and (not (and (memq 'category-properties c-emacs-features)
+                                    (looking-at "\\s!")))
+                          (looking-at c-comment-start-regexp))))
+         (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++))
+         (list s ty (point)))
+        
+        (t (list s)))))))
+
+(defun c-state-full-pp-to-literal (here &optional not-in-delimiter)
+  ;; This function will supersede c-state-pp-to-literal.
+  ;; 
+  ;; Do a parse-partial-sexp from a position in the buffer before HERE which
+  ;; isn't in a literal, and return information about HERE, either:
+  ;; (STATE TYPE (BEG . END))   if HERE is in a literal; or
+  ;; (STATE)                    otherwise,
+  ;; where STATE is the parsing state at HERE, TYPE is the type of the literal
+  ;; enclosing HERE, (one of 'string, 'c, 'c++) and (BEG . END) is the
+  ;; boundaries of that literal (including the delimiters).
+  ;;
+  ;; 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 10 (in
+  ;; newer Emacsen only, the syntax of a position after a potential first char
+  ;; of a two char construct) of STATE are valid.
+  (save-excursion
+    (save-match-data
+      (let* ((base-and-state (c-parse-ps-state-below here))
+            (base (car base-and-state))
+            (s (cdr base-and-state))
+            (s (parse-partial-sexp base here nil nil s))
+            ty start)
+       (cond
+        ((or (nth 3 s) (nth 4 s))      ; in a string or comment
+         (setq ty (cond
+                   ((nth 3 s) 'string)
+                   ((nth 7 s) 'c++)
+                   (t 'c)))
+         (setq start (nth 8 s))
+         (parse-partial-sexp here (point-max)
+                             nil                             ; TARGETDEPTH
+                             nil                             ; STOPBEFORE
+                             s                               ; OLDSTATE
+                             'syntax-table) ; stop at end of literal
+         (list s ty (cons start (point))))
+
+        ((and (not not-in-delimiter)   ; inside a comment starter
+              (not (bobp))
+              (progn (backward-char)
+                     (and (not (and (memq 'category-properties c-emacs-features)
+                                    (looking-at "\\s!")))
+                          (looking-at c-comment-start-regexp))))
+         (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
+               start (point))
+         (forward-comment 1)
+         (list s ty (cons start (point))))
+
+        (t (list s)))))))
 
 (defsubst c-state-pp-to-literal (from to &optional not-in-delimiter)
   ;; Do a parse-partial-sexp from FROM to TO, returning either
@@ -2332,6 +2427,103 @@ comment at the start of cc-engine.el for more info."
 
         (t `(,s)))))))
 
+(defun c-cache-to-parse-ps-state (elt)
+  ;; Create a list suitable to use as the old-state parameter to
+  ;; `parse-partial-sexp', out of ELT.  ELT is either just a number, a buffer
+  ;; position, or it is a list (POS TYPE STARTING-POS).  Here POS is the
+  ;; buffer position the other elements are pertinent for, TYPE is either 'c
+  ;; or 'c++ (for a comment) or a character (for a string delimiter) or t
+  ;; (meaning a string fence opened the string), STARTING-POS is the starting
+  ;; position of the comment or string.
+  (if (consp elt)
+      (let ((depth 0) (containing nil) (last nil)
+           in-string in-comment (after-quote nil)
+           (min-depth 0) com-style com-str-start (intermediate nil)
+           (between-syntax nil)
+           (type (cadr elt)))
+       (setq com-str-start (car (cddr elt)))
+       (cond
+        ((or (numberp type) (eq type t)) ; A string
+         (setq in-string type))
+        ((memq type '(c c++))          ; A comment
+         (setq in-comment t
+               com-style (if (eq type 'c++) 1 nil)))
+        (t (c-benign-error "Invalid type %s in c-cache-to-parse-ps-state"
+                           elt)))
+       (list depth containing last
+             in-string in-comment after-quote
+             min-depth com-style com-str-start
+             intermediate nil))
+    (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil))))
+
+(defun c-parse-ps-state-to-cache (state)
+  ;; Convert STATE, a `parse-partial-sexp' state valid at POINT, to an element
+  ;; for the `c-state-semi-nonlit-pos-cache' cache.  This is either POINT
+  ;; (when point is not in a literal) or a list (POINT TYPE STARTING-POS),
+  ;; where TYPE is the type of the literal, either 'string, 'c, or 'c++, and
+  ;; STARTING-POS is the starting position of the comment or string.
+  (cond
+   ((nth 3 state)                      ; A string
+    (list (point) (nth 3 state) (nth 8 state)))
+   ((nth 4 state)                      ; A comment
+    (list (point)
+         (if (eq (nth 7 state) 1) 'c++ 'c)
+         (nth 8 state)))
+   (t                                  ; Neither string nor comment.
+    (point))))
+
+(defsubst c-ps-state-cache-pos (elt)
+  ;; Get the buffer position from ELT, an element from the cache
+  ;; `c-state-semi-nonlit-pos-cache'.
+  (if (atom elt)
+      elt
+    (car elt)))
+
+(defun c-parse-ps-state-below (here)
+  ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where
+  ;; CACHE-POS is a position not very far before HERE for which the
+  ;; parse-partial-sexp STATE is valid.  Note that the only valid elements of
+  ;; STATE are those concerning comments and strings; STATE is the state of a
+  ;; null `parse-partial-sexp' scan when CACHE-POS is not in a comment or
+  ;; string.
+  (save-restriction
+    (widen)
+    (save-excursion
+      (let ((c c-state-semi-nonlit-pos-cache)
+           elt state pos npos high-elt)
+       ;; Trim the cache to take account of buffer changes.
+       (while (and c (> (c-ps-state-cache-pos (c-ps-state-cache-pos (car c)))
+                        c-state-semi-nonlit-pos-cache-limit))
+         (setq c (cdr c)))
+       (setq c-state-semi-nonlit-pos-cache c)
+
+       (while (and c (> (c-ps-state-cache-pos (car c)) here))
+         (setq high-elt (car c))
+         (setq c (cdr c)))
+       (setq pos (or (and c (c-ps-state-cache-pos (car c)))
+                     (point-min)))
+
+       (if high-elt
+           (setq state (c-cache-to-parse-ps-state (car c)))
+         (setq elt (if c (car c) (point-min)))
+         (setq state
+               (if c
+                   (c-cache-to-parse-ps-state (car c))
+                 (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil))))
+         (while
+             ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
+             (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here)
+           (setq state (parse-partial-sexp pos npos nil nil state))
+           (setq elt (c-parse-ps-state-to-cache state))
+           (setq c-state-semi-nonlit-pos-cache
+                 (cons elt c-state-semi-nonlit-pos-cache))
+           (setq pos npos)))
+
+       (if (> pos c-state-semi-nonlit-pos-cache-limit)
+           (setq c-state-semi-nonlit-pos-cache-limit pos))
+
+       (cons pos state)))))
+
 (defun c-state-safe-place (here)
   ;; Return a buffer position before HERE which is "safe", i.e. outside any
   ;; string, comment, or macro.
@@ -2397,45 +2589,6 @@ comment at the start of cc-engine.el for more info."
            (setq c-state-nonlit-pos-cache-limit pos))
        pos))))
 
-(defun c-state-semi-safe-place (here)
-  ;; Return a buffer position before HERE which is "safe", i.e. outside any
-  ;; string or comment.  It may be in a macro.
-  (save-restriction
-    (widen)
-    (save-excursion
-      (let ((c c-state-semi-nonlit-pos-cache)
-           pos npos high-pos lit macro-beg macro-end)
-       ;; Trim the cache to take account of buffer changes.
-       (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))))
-
-       (if (> pos c-state-semi-nonlit-pos-cache-limit)
-           (setq c-state-semi-nonlit-pos-cache-limit pos))
-       pos))))
-
 (defun c-state-literal-at (here)
   ;; If position HERE is inside a literal, return (START . END), the
   ;; boundaries of the literal (which may be outside the accessible bit of the
@@ -4633,8 +4786,7 @@ Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
   (save-restriction
     (widen)
-    (let* ((safe-place (c-state-semi-safe-place (point)))
-          (lit (c-state-pp-to-literal safe-place (point))))
+    (let ((lit (c-state-semi-pp-to-literal (point))))
       (or (cadr lit)
          (and detect-cpp
               (save-excursion (c-beginning-of-macro))
@@ -4656,14 +4808,19 @@ Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
 
   (save-excursion
-    (let* ((pos (point))
-          (lim (or lim (c-state-semi-safe-place pos)))
-          (pp-to-lit (save-restriction
-                       (widen)
-                       (c-state-pp-to-literal lim pos not-in-delimiter)))
-          (state (car pp-to-lit))
-          (lit-limits (car (cddr pp-to-lit))))
-
+    (let*
+       ((pos (point))
+        (lit-limits
+         (if lim
+             (let ((s (parse-partial-sexp lim (point))))
+               (when (or (nth 3 s) (nth 4 s))
+                 (cons (nth 8 s)
+                       (progn (parse-partial-sexp (point) (point-max)
+                                                  nil 'syntax-table
+                                                  s)
+                              (point)))))
+           (let ((pp-to-lit (c-state-full-pp-to-literal pos not-in-delimiter)))
+             (car (cddr pp-to-lit))))))
       (cond
        (lit-limits)
 
@@ -4702,6 +4859,16 @@ comment at the start of cc-engine.el for more info."
            (if beg (cons beg end))))))
        ))))
 
+(defun c-literal-start (&optional safe-pos)
+  "Return the start of the string or comment surrounding point, or nil if
+point isn't in one.  SAFE-POS, if non-nil, is a position before point which is
+a known \"safe position\", i.e. outside of any string or comment."
+  (if safe-pos
+      (let ((s (parse-partial-sexp safe-pos (point))))
+       (and (or (nth 3 s) (nth 4 s))
+            (nth 8 s)))
+    (car (cddr (c-state-semi-pp-to-literal (point))))))
+
 ;; In case external callers use this; it did have a docstring.
 (defalias 'c-literal-limits-fast 'c-literal-limits)
 
@@ -4766,13 +4933,10 @@ comment at the start of cc-engine.el for more info."
 
 (defsubst c-determine-limit-get-base (start try-size)
   ;; Get a "safe place" approximately TRY-SIZE characters before START.
-  ;; This doesn't preserve point.
+  ;; This defsubst doesn't preserve point.
   (let* ((pos (max (- start try-size) (point-min)))
-        (base (c-state-semi-safe-place pos))
-        (s (parse-partial-sexp base pos)))
-    (if (or (nth 4 s) (nth 3 s))       ; comment or string
-       (nth 8 s)
-      (point))))
+        (s (c-state-semi-pp-to-literal pos)))
+    (or (car (cddr s)) pos)))
 
 (defun c-determine-limit (how-far-back &optional start try-size)
   ;; Return a buffer position HOW-FAR-BACK non-literal characters from START
@@ -5152,8 +5316,9 @@ comment at the start of cc-engine.el for more info."
           ;; arrived at something that looks like a start or else
           ;; resort to `c-literal-limits'.
           (unless (looking-at c-literal-start-regexp)
-            (let ((range (c-literal-limits)))
-              (if range (goto-char (car range)))))
+            (let ((lit-start (c-literal-start)))
+              (if lit-start (goto-char lit-start)))
+            )
 
           (setq start-in-literal (point))) ; end of `and' arm.
 
@@ -5690,12 +5855,12 @@ comment at the start of cc-engine.el for more info."
   ;; 2010-01-29.
   (save-excursion
     (c-save-buffer-state
-       ((beg-lit-limits (progn (goto-char beg) (c-literal-limits)))
+       ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
         (end-lit-limits (progn (goto-char end) (c-literal-limits)))
         new-beg new-end beg-limit end-limit)
       ;; Locate the earliest < after the barrier before the changed region,
       ;; which isn't already marked as a paren.
-      (goto-char  (if beg-lit-limits (car beg-lit-limits) beg))
+      (goto-char (or beg-lit-start beg))
       (setq beg-limit (c-determine-limit 512))
 
       ;; Remove the syntax-table/category properties from each pertinent <...>
@@ -5854,9 +6019,8 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;; Note: this routine is dependant upon the correct syntax-table text
   ;; properties being set.
-  (let* ((safe (c-state-semi-safe-place (point)))
-        (state (c-state-pp-to-literal safe (point)))
-        open-quote-pos open-paren-pos close-paren-pos close-quote-pos id)
+  (let ((state (c-state-semi-pp-to-literal (point)))
+       open-quote-pos open-paren-pos close-paren-pos close-quote-pos id)
     (save-excursion
       (when
          (and
@@ -5865,7 +6029,7 @@ comment at the start of cc-engine.el for more info."
             (or (eq (char-after) ?\")
                 (search-backward "\"" (max (- (point) 17) (point-min)) t)))
            ((and (eq (cadr state) 'string)
-                 (goto-char (car (nth 2 state)))
+                 (goto-char (nth 2 state))
                  (or (eq (char-after) ?\")
                      (search-backward "\"" (max (- (point) 17) (point-min)) t))
                  (not (bobp)))))
@@ -10551,8 +10715,8 @@ comment at the start of cc-engine.el for more info."
             ;; versions, which results in that we get nil from
             ;; `c-literal-limits' even when `c-in-literal' claims
             ;; we're inside a comment.
-            (setq placeholder (c-literal-limits lim)))
-       (c-add-syntax literal (car placeholder)))
+            (setq placeholder (c-literal-start lim)))
+       (c-add-syntax literal placeholder))
 
        ;; CASE 3: in a cpp preprocessor macro continuation.
        ((and (save-excursion
index 3a8c9ec0ec42c4d56d65c784ab462ae64aaf0ca6..52f0b0d86968b752a0c06c8da6ba21bbd8de0899 100644 (file)
@@ -2480,10 +2480,10 @@ need for `pike-font-lock-extra-types'.")
            'font-lock-comment-face)
        ;; Handle the case when the fontified region starts inside a
        ;; comment.
-       (let ((range (c-literal-limits)))
+       (let ((start (c-literal-start)))
          (setq region-beg (point))
-         (when range
-           (goto-char (car range)))
+         (when start
+           (goto-char start))
          (when (looking-at prefix)
            (setq comment-beg (point)))))
 
index 80ac08fb9e01687519a5b7373959195b6dc9c590..5ad7a010641ce7f82f850b6ece67ab36369d4971 100644 (file)
@@ -1299,12 +1299,12 @@ Note that the style variables are always made local to the buffer."
   ;; This function is called indirectly from font locking stuff - either from
   ;; c-after-change (to prepare for after-change font-locking) or from font
   ;; lock context (etc.) fontification.
-  (let ((lit-limits (c-literal-limits))
+  (let ((lit-start (c-literal-start))
        (new-pos pos)
        bod-lim bo-decl)
     (goto-char (c-point 'bol new-pos))
-    (when lit-limits                   ; Comment or string.
-      (goto-char (car lit-limits)))
+    (when lit-start                    ; Comment or string.
+      (goto-char lit-start))
     (setq bod-lim (c-determine-limit 500))
 
     (while