1 new commit in cc-mode:
https://bitbucket.org/xemacs/cc-mode/commits/598139a604f0/
Changeset: 598139a604f0
User: acm
Date: 2017-05-07 09:03:21+00:00
Summary: CC Mode internal cache: Handle a cache pos being inside a two-char
construct.
Cache c-state-semi-nonlit-pos-cache was failing when a cache position was,
e.g., between the two characters of an opening comment "/*", and additionally
there were an odd number of quote marks (apostrophes) in the comment. This
happened in .../src/xdisp.c in the Emacs master branch around 2017-05-02 at
buffer position 615001.
* cc-defs.el (c-emacs-features): Repurpose symbol pps-extended-state to mean
that there are at least 11 elements in the parser state.
* cc-engine.el (c-cache-to-parse-ps-state, c-parse-ps-state-to-cache): Rewrite
these to use enhanced cache element list types which indicate potentially
being inside two-char constructs.
(c-parse-ps-state-below): Rewrite to use the new versions of the above two
functions.
Affected #: 2 files
diff -r 42d965b3e8913f32d004a9cb170cf27ade0fb08f -r
598139a604f056a434e8953313b25270717d013d cc-defs.el
--- a/cc-defs.el
+++ b/cc-defs.el
@@ -1937,14 +1937,18 @@
(setq list (cons 'add-hook-local list)))
- ;; See if `parse-partial-sexp' returns the eighth element.
- (if (c-safe (>= (length (save-excursion
- (parse-partial-sexp (point) (point))))
- 10))
- (setq list (cons 'pps-extended-state list))
- (error (concat
- "CC Mode is incompatible with this version of Emacs - "
- "`parse-partial-sexp' has to return at least 10 elements.")))
+ ;; Check how many elements `parse-partial-sexp' returns.
+ (let ((ppss-size (or (c-safe (length
+ (save-excursion
+ (parse-partial-sexp (point) (point)))))
+ 0)))
+ (cond
+ ((>= ppss-size 11) (setq list (cons 'pps-extended-state list)))
+ ((>= ppss-size 10))
+ (t (error
+ (concat
+ "CC Mode is incompatible with this version of Emacs - "
+ "`parse-partial-sexp' has to return at least 10 elements.")))))
;;(message "c-emacs-features: %S" list)
list)
@@ -1967,10 +1971,9 @@
(i.e. the syntax class `!').
'gen-string-delim Generic string delimiters work
(i.e. the syntax class `|').
-'pps-extended-state `parse-partial-sexp' returns a list with at least 10
- elements, i.e. it contains the position of the start of
- the last comment or string. It's always set - CC Mode
- no longer works in emacsen without this feature.
+'pps-extended-state `parse-partial-sexp' returns a list with at least 11
+ elements, i.e. it indicates having stopped after the
+ first character of a potential two-char construct.
'posix-char-classes The regexp engine understands POSIX character classes.
'col-0-paren It's possible to turn off the ad-hoc rule that a paren
in column zero is the start of a defun.
diff -r 42d965b3e8913f32d004a9cb170cf27ade0fb08f -r
598139a604f056a434e8953313b25270717d013d cc-engine.el
--- a/cc-engine.el
+++ b/cc-engine.el
@@ -2578,17 +2578,24 @@
(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)
+ ;; `parse-partial-sexp', out of ELT, a member of
+ ;; `c-state-semi-nonlit-pos-cache'. ELT is either just a number, or a list
+ ;; with 2, 3, or 4 members (See `c-parse-ps-state-to-cache'). That number
+ ;; or the car of the list is the "position element" of ELT, the position
+ ;; where ELT is valid.
+ ;;
+ ;; POINT is left at the postition for which the returned state is valid. It
+ ;; will be either the position element of ELT, or one character before
+ ;; that. (The latter happens in Emacs <= 25 and XEmacs, when ELT indicates
+ ;; its position element directly follows a potential first character of a
+ ;; two char construct (such as a comment opener or an escaped character).)
+ (if (and (consp elt) (>= (length elt) 3))
+ ;; Inside a string or comment
(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)
+ (char-1 (nth 3 elt)) ; first char of poss. 2-char construct
+ (pos (car elt))
(type (cadr elt)))
(setq com-str-start (car (cddr elt)))
(cond
@@ -2599,28 +2606,88 @@
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))))
+ (if (memq 'pps-extended-state c-emacs-features)
+ (progn
+ (goto-char pos)
+ (list depth containing last
+ in-string in-comment after-quote
+ min-depth com-style com-str-start
+ intermediate char-1))
+ (goto-char (if char-1
+ (1- pos)
+ pos))
+ (list depth containing last
+ in-string in-comment nil
+ min-depth com-style com-str-start
+ intermediate)))
+
+ ;; Not in a string or comment.
+ (if (memq 'pps-extended-state c-emacs-features)
+ (progn
+ (goto-char (if (consp elt) (car elt) elt))
+ (list 0 nil nil nil nil
+ (and (consp elt) (eq (nth 1 elt) 9)) ; 9 is syntax code for "escape".
+ 0 nil nil nil
+ (and (consp elt) (nth 1 elt))))
+ (goto-char (if (consp elt) (car elt) elt))
+ (if (and (consp elt) (cdr elt)) (backward-char))
+ (copy-tree '(0 nil nil nil nil
+ nil
+ 0 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)))
- ((and (nth 4 state) ; A comment
- (not (eq (nth 7 state) 'syntax-table))) ; but not a psuedo comment.
- (list (point)
- (if (eq (nth 7 state) 1) 'c++ 'c)
- (nth 8 state)))
- (t ; Neither string nor comment.
- (point))))
+ ;; for the `c-state-semi-nonlit-pos-cache' cache. This is one of
+ ;; o - POINT (when point is not in a literal);
+ ;; o - (POINT CHAR-1) (when the last character before point is potentially
+ ;; the first of a two-character construct
+ ;; o - (POINT TYPE STARTING-POS) (when in a literal);
+ ;; o - (POINT TYPE STARTING-POS CHAR-1) (Combination of the previous two),
+ ;; where TYPE is the type of the literal (either 'c, or 'c++, or the
+ ;; character which closes the string), STARTING-POS is the starting
+ ;; position of the comment or string. CHAR-1 is either the character
+ ;; potentially forming the first half of a two-char construct (in Emacs <=
+ ;; 25 and XEmacs) or the syntax of the character (in Emacs >= 26).
+ (if (memq 'pps-extended-state c-emacs-features)
+ ;; Emacs >= 26.
+ (let ((basic
+ (cond
+ ((nth 3 state) ; A string
+ (list (point) (nth 3 state) (nth 8 state)))
+ ((and (nth 4 state) ; A comment
+ (not (eq (nth 7 state) 'syntax-table))) ; but not a psuedo comment.
+ (list (point)
+ (if (eq (nth 7 state) 1) 'c++ 'c)
+ (nth 8 state)))
+ (t ; Neither string nor comment.
+ (point)))))
+ (if (nth 10 state)
+ (append (if (consp basic)
+ basic
+ (list basic))
+ (list (nth 10 state)))
+ basic))
+
+ ;; Emacs <= 25, XEmacs.
+ (cond
+ ((nth 3 state) ; A string
+ (if (eq (char-before) ?\\)
+ (list (point) (nth 3 state) (nth 8 state) ?\\)
+ (list (point) (nth 3 state) (nth 8 state))))
+ ((and (nth 4 state) ; comment
+ (not (eq (nth 7 state) 'syntax-table)))
+ (if (and (eq (char-before) ?*)
+ (> (- (point) (nth 8 state)) 2)) ; not "/*/".
+ (list (point)
+ (if (eq (nth 7 state) 1) 'c++ 'c)
+ (nth 8 state)
+ ?*)
+ (list (point)
+ (if (eq (nth 7 state) 1) 'c++ 'c)
+ (nth 8 state))))
+ (t (if (memq (char-before) '(?/ ?\\))
+ (list (point) (char-before))
+ (point))))))
(defsubst c-ps-state-cache-pos (elt)
;; Get the buffer position from ELT, an element from the cache
@@ -2640,7 +2707,7 @@
(save-restriction
(widen)
(let ((c c-state-semi-nonlit-pos-cache)
- elt state pos npos high-elt)
+ elt state npos high-elt)
;; Trim the cache to take account of buffer changes.
(while (and c (> (c-ps-state-cache-pos (car c))
c-state-semi-nonlit-pos-cache-limit))
@@ -2650,29 +2717,27 @@
(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))))
+ (goto-char (or (and c (c-ps-state-cache-pos (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))))
+
+ (when (not high-elt)
+ ;; We need to extend the cache. Add an element to
+ ;; `c-state-semi-nonlit-pos-cache' each iteration of the following.
(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 npos (+ (point) c-state-nonlit-pos-interval)) here)
+ (setq state (parse-partial-sexp (point) 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)))))
+ (cons elt c-state-semi-nonlit-pos-cache))))
+
+ (if (> (point) c-state-semi-nonlit-pos-cache-limit)
+ (setq c-state-semi-nonlit-pos-cache-limit (point)))
+
+ (cons (point) state)))))
(defun c-state-safe-place (here)
;; Return a buffer position before HERE which is "safe", i.e. outside any
Repository URL:
https://bitbucket.org/xemacs/cc-mode/
--
This is a commit notification from
bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.