1 new commit in cc-mode:
https://bitbucket.org/xemacs/cc-mode/commits/3aaa2fcb2d5b/
Changeset: 3aaa2fcb2d5b
User: acm
Date: 2017-04-10 20:32:56+00:00
Summary: Fix a loop in C Mode caused by inadequate analysis of comments.
After M-;, and the insertion of the opening "/*", the CC Mode after-change
function got confused, since the new comment opener matched the end of a
subsequent comment, but moving back over that comment did not come back to the
starting point. Fix this.
* cc-engine.el (c-end-of-macro): Add a limit parameter, where point is left if
no end-of-macro is found before it.
(c-forward-sws): Change the `safe-start' mechanism. Now `safe-start' is
non-nil except where we have an unclosed block comment at the end of a macro.
This enables us to populate the cache more fully, at the cost of some run
time.
Affected #: 1 file
diff -r 715fefb0bc0a5083da72adb687f97289371cb017 -r
3aaa2fcb2d5bac9e1008403bc12a2366a85cf576 cc-engine.el
--- a/cc-engine.el
+++ b/cc-engine.el
@@ -324,34 +324,41 @@
(goto-char here)
nil))))))
-(defun c-end-of-macro ()
+(defun c-end-of-macro (&optional lim)
"Go to the end of a preprocessor directive.
More accurately, move the point to the end of the closest following
line that doesn't end with a line continuation backslash - no check is
done that the point is inside a cpp directive to begin with.
+If LIM is provided, it is a limit position at which point is left
+if the end of the macro doesn't occur earlier.
+
Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
- (if (and (cdr c-macro-cache)
- (<= (point) (cdr c-macro-cache))
- (>= (point) (car c-macro-cache)))
- (goto-char (cdr c-macro-cache))
- (unless (and (car c-macro-cache)
- (<= (point) c-macro-cache-start-pos)
- (>= (point) (car c-macro-cache)))
- (setq c-macro-cache nil
- c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil
- c-macro-cache-no-comment nil))
- (while (progn
- (end-of-line)
- (when (and (eq (char-before) ?\\)
- (not (eobp)))
- (forward-char)
- t)))
- (when (car c-macro-cache)
- (setcdr c-macro-cache (point))
- (setq c-macro-cache-syntactic nil))))
+ (save-restriction
+ (if lim (narrow-to-region (point-min) lim))
+ (if (and (cdr c-macro-cache)
+ (<= (point) (cdr c-macro-cache))
+ (>= (point) (car c-macro-cache)))
+ (goto-char (cdr c-macro-cache))
+ (unless (and (car c-macro-cache)
+ (<= (point) c-macro-cache-start-pos)
+ (>= (point) (car c-macro-cache)))
+ (setq c-macro-cache nil
+ c-macro-cache-start-pos nil
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
+ (while (progn
+ (end-of-line)
+ (when (and (eq (char-before) ?\\)
+ (not (eobp)))
+ (forward-char)
+ t)))
+ (when (and (car c-macro-cache)
+ (bolp)
+ (not (eq (char-before (1- (point))) ?\\)))
+ (setcdr c-macro-cache (point))
+ (setq c-macro-cache-syntactic nil)))))
(defun c-syntactic-end-of-macro ()
;; Go to the end of a CPP directive, or a "safe" pos just before.
@@ -1846,13 +1853,10 @@
(let (;; `rung-pos' is set to a position as early as possible in the
;; unmarked part of the simple ws region.
(rung-pos (point)) next-rung-pos rung-end-pos last-put-in-sws-pos
- rung-is-marked next-rung-is-marked simple-ws-end
+ rung-is-marked next-rung-is-marked simple-ws-end macro-start macro-end
;; `safe-start' is set when it's safe to cache the start position.
- ;; It's not set if we've initially skipped over comments and line
- ;; continuations since we might have gone out through the end of a
- ;; macro then. This provision makes `c-forward-sws' not populate the
- ;; cache in the majority of cases, but otoh is `c-backward-sws' by far
- ;; more common.
+ ;; This is the case except when we have an unterminated block comment
+ ;; within a macro.
safe-start)
;; Skip simple ws and do a quick check on the following character to see
@@ -1928,7 +1932,33 @@
;; Now move over any comments (x)or a CPP construct.
(setq simple-ws-end (point))
- (c-forward-comments)
+ (setq safe-start t)
+ ;; Take elaborate precautions to detect an open block comment at
+ ;; the end of a macro. If we find one, we set `safe-start' to nil
+ ;; and break off any further scanning of comments.
+ (let ((com-begin (point)) com-end in-macro)
+ (when (and (c-forward-single-comment)
+ (setq com-end (point))
+ (save-excursion
+ (goto-char com-begin)
+ (c-beginning-of-macro)))
+ (setq in-macro t)
+ (goto-char com-begin)
+ (if (progn (c-end-of-macro com-end)
+ (< (point) com-end))
+ (setq safe-start nil)))
+ (if in-macro
+ (while (and safe-start
+ com-end (> com-end com-begin)
+ (setq com-begin (point))
+ (when (and (c-forward-single-comment)
+ (setq com-end (point)))
+ (goto-char com-begin)
+ (if (progn (c-end-of-macro com-end)
+ (< (point) com-end))
+ (setq safe-start nil))
+ safe-start)))
+ (c-forward-comments)))
(cond
((/= (point) simple-ws-end)
@@ -1939,6 +1969,7 @@
((save-excursion
(and c-opt-cpp-prefix
(looking-at c-opt-cpp-start)
+ (setq macro-start (point))
(progn (skip-chars-backward " \t")
(bolp))
(or (bobp)
@@ -1949,8 +1980,20 @@
(while (and (eq (char-before) ?\\)
(= (forward-line 1) 0))
(end-of-line))
+ (setq macro-end (point))
+ ;; Check for an open block comment at the end of the macro.
+ (goto-char macro-start)
+ (let (s in-block-comment)
+ (while
+ (progn
+ (setq s (parse-partial-sexp (point) macro-end
+ nil nil s 'syntax-table))
+ (< (point) macro-end))
+ (setq in-block-comment
+ (and (elt s 4) ; in a comment
+ (null (elt s 7))))) ; a block comment
+ (if in-block-comment (setq safe-start nil)))
(forward-line 1)
- (setq safe-start t)
;; Don't cache at eob in case the buffer is narrowed.
(not (eobp)))
@@ -1958,7 +2001,6 @@
(looking-at c-noise-macro-name-re))
;; Skip over a noise macro.
(goto-char (match-end 1))
- (setq safe-start t)
(not (eobp)))))
;; We've searched over a piece of non-white syntactic ws. See if this
@@ -2021,8 +2063,7 @@
(if (setq rung-is-marked next-rung-is-marked)
(setq rung-pos (1- (c-next-single-property-change
rung-is-marked 'c-is-sws nil rung-end-pos)))
- (setq rung-pos next-rung-pos))
- (setq safe-start t)))
+ (setq rung-pos next-rung-pos))))
;; Make sure that the newly marked `c-in-sws' region doesn't connect to
;; another one after the point (which might occur when editing inside a
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.