aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2017-04-10 21:01:38 +0000
committerAlan Mackenzie2017-04-10 21:01:38 +0000
commit230e25fd67fd654f04b8c744db0e170353a7f3b3 (patch)
treeca4c9def3c497739dd48e5d8c708b5addf51f4de
parent3ccd0ff1064a2836c379b13c2d5f4b11c5da1f88 (diff)
downloademacs-230e25fd67fd654f04b8c744db0e170353a7f3b3.tar.gz
emacs-230e25fd67fd654f04b8c744db0e170353a7f3b3.zip
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. * lisp/progmodes/cc-engine.el (c-end-of-macro): Add a limit parameter, wherer 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.
-rw-r--r--lisp/progmodes/cc-engine.el105
1 files changed, 73 insertions, 32 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index de15d1d82fc..e7a8962ac2b 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -319,34 +319,41 @@ comment at the start of cc-engine.el for more info."
319 (goto-char here) 319 (goto-char here)
320 nil)))))) 320 nil))))))
321 321
322(defun c-end-of-macro () 322(defun c-end-of-macro (&optional lim)
323 "Go to the end of a preprocessor directive. 323 "Go to the end of a preprocessor directive.
324More accurately, move the point to the end of the closest following 324More accurately, move the point to the end of the closest following
325line that doesn't end with a line continuation backslash - no check is 325line that doesn't end with a line continuation backslash - no check is
326done that the point is inside a cpp directive to begin with. 326done that the point is inside a cpp directive to begin with.
327 327
328If LIM is provided, it is a limit position at which point is left
329if the end of the macro doesn't occur earlier.
330
328Note that this function might do hidden buffer changes. See the 331Note that this function might do hidden buffer changes. See the
329comment at the start of cc-engine.el for more info." 332comment at the start of cc-engine.el for more info."
330 (if (and (cdr c-macro-cache) 333 (save-restriction
331 (<= (point) (cdr c-macro-cache)) 334 (if lim (narrow-to-region (point-min) lim))
332 (>= (point) (car c-macro-cache))) 335 (if (and (cdr c-macro-cache)
333 (goto-char (cdr c-macro-cache)) 336 (<= (point) (cdr c-macro-cache))
334 (unless (and (car c-macro-cache) 337 (>= (point) (car c-macro-cache)))
335 (<= (point) c-macro-cache-start-pos) 338 (goto-char (cdr c-macro-cache))
336 (>= (point) (car c-macro-cache))) 339 (unless (and (car c-macro-cache)
337 (setq c-macro-cache nil 340 (<= (point) c-macro-cache-start-pos)
338 c-macro-cache-start-pos nil 341 (>= (point) (car c-macro-cache)))
339 c-macro-cache-syntactic nil 342 (setq c-macro-cache nil
340 c-macro-cache-no-comment nil)) 343 c-macro-cache-start-pos nil
341 (while (progn 344 c-macro-cache-syntactic nil
342 (end-of-line) 345 c-macro-cache-no-comment nil))
343 (when (and (eq (char-before) ?\\) 346 (while (progn
344 (not (eobp))) 347 (end-of-line)
345 (forward-char) 348 (when (and (eq (char-before) ?\\)
346 t))) 349 (not (eobp)))
347 (when (car c-macro-cache) 350 (forward-char)
348 (setcdr c-macro-cache (point)) 351 t)))
349 (setq c-macro-cache-syntactic nil)))) 352 (when (and (car c-macro-cache)
353 (bolp)
354 (not (eq (char-before (1- (point))) ?\\)))
355 (setcdr c-macro-cache (point))
356 (setq c-macro-cache-syntactic nil)))))
350 357
351(defun c-syntactic-end-of-macro () 358(defun c-syntactic-end-of-macro ()
352 ;; Go to the end of a CPP directive, or a "safe" pos just before. 359 ;; Go to the end of a CPP directive, or a "safe" pos just before.
@@ -1842,13 +1849,10 @@ comment at the start of cc-engine.el for more info."
1842 (let (;; `rung-pos' is set to a position as early as possible in the 1849 (let (;; `rung-pos' is set to a position as early as possible in the
1843 ;; unmarked part of the simple ws region. 1850 ;; unmarked part of the simple ws region.
1844 (rung-pos (point)) next-rung-pos rung-end-pos last-put-in-sws-pos 1851 (rung-pos (point)) next-rung-pos rung-end-pos last-put-in-sws-pos
1845 rung-is-marked next-rung-is-marked simple-ws-end 1852 rung-is-marked next-rung-is-marked simple-ws-end macro-start macro-end
1846 ;; `safe-start' is set when it's safe to cache the start position. 1853 ;; `safe-start' is set when it's safe to cache the start position.
1847 ;; It's not set if we've initially skipped over comments and line 1854 ;; This is the case except when we have an unterminated block comment
1848 ;; continuations since we might have gone out through the end of a 1855 ;; within a macro.
1849 ;; macro then. This provision makes `c-forward-sws' not populate the
1850 ;; cache in the majority of cases, but otoh is `c-backward-sws' by far
1851 ;; more common.
1852 safe-start) 1856 safe-start)
1853 1857
1854 ;; Skip simple ws and do a quick check on the following character to see 1858 ;; Skip simple ws and do a quick check on the following character to see
@@ -1925,7 +1929,33 @@ comment at the start of cc-engine.el for more info."
1925 1929
1926 ;; Now move over any comments (x)or a CPP construct. 1930 ;; Now move over any comments (x)or a CPP construct.
1927 (setq simple-ws-end (point)) 1931 (setq simple-ws-end (point))
1928 (c-forward-comments) 1932 (setq safe-start t)
1933 ;; Take elaborate precautions to detect an open block comment at
1934 ;; the end of a macro. If we find one, we set `safe-start' to nil
1935 ;; and break off any further scanning of comments.
1936 (let ((com-begin (point)) com-end in-macro)
1937 (when (and (c-forward-single-comment)
1938 (setq com-end (point))
1939 (save-excursion
1940 (goto-char com-begin)
1941 (c-beginning-of-macro)))
1942 (setq in-macro t)
1943 (goto-char com-begin)
1944 (if (progn (c-end-of-macro com-end)
1945 (< (point) com-end))
1946 (setq safe-start nil)))
1947 (if in-macro
1948 (while (and safe-start
1949 com-end (> com-end com-begin)
1950 (setq com-begin (point))
1951 (when (and (c-forward-single-comment)
1952 (setq com-end (point)))
1953 (goto-char com-begin)
1954 (if (progn (c-end-of-macro com-end)
1955 (< (point) com-end))
1956 (setq safe-start nil))
1957 safe-start)))
1958 (c-forward-comments)))
1929 1959
1930 (cond 1960 (cond
1931 ((/= (point) simple-ws-end) 1961 ((/= (point) simple-ws-end)
@@ -1936,6 +1966,7 @@ comment at the start of cc-engine.el for more info."
1936 ((save-excursion 1966 ((save-excursion
1937 (and c-opt-cpp-prefix 1967 (and c-opt-cpp-prefix
1938 (looking-at c-opt-cpp-start) 1968 (looking-at c-opt-cpp-start)
1969 (setq macro-start (point))
1939 (progn (skip-chars-backward " \t") 1970 (progn (skip-chars-backward " \t")
1940 (bolp)) 1971 (bolp))
1941 (or (bobp) 1972 (or (bobp)
@@ -1946,8 +1977,20 @@ comment at the start of cc-engine.el for more info."
1946 (while (and (eq (char-before) ?\\) 1977 (while (and (eq (char-before) ?\\)
1947 (= (forward-line 1) 0)) 1978 (= (forward-line 1) 0))
1948 (end-of-line)) 1979 (end-of-line))
1980 (setq macro-end (point))
1981 ;; Check for an open block comment at the end of the macro.
1982 (goto-char macro-start)
1983 (let (s in-block-comment)
1984 (while
1985 (progn
1986 (setq s (parse-partial-sexp (point) macro-end
1987 nil nil s 'syntax-table))
1988 (< (point) macro-end))
1989 (setq in-block-comment
1990 (and (elt s 4) ; in a comment
1991 (null (elt s 7))))) ; a block comment
1992 (if in-block-comment (setq safe-start nil)))
1949 (forward-line 1) 1993 (forward-line 1)
1950 (setq safe-start t)
1951 ;; Don't cache at eob in case the buffer is narrowed. 1994 ;; Don't cache at eob in case the buffer is narrowed.
1952 (not (eobp))) 1995 (not (eobp)))
1953 1996
@@ -1955,7 +1998,6 @@ comment at the start of cc-engine.el for more info."
1955 (looking-at c-noise-macro-name-re)) 1998 (looking-at c-noise-macro-name-re))
1956 ;; Skip over a noise macro. 1999 ;; Skip over a noise macro.
1957 (goto-char (match-end 1)) 2000 (goto-char (match-end 1))
1958 (setq safe-start t)
1959 (not (eobp))))) 2001 (not (eobp)))))
1960 2002
1961 ;; We've searched over a piece of non-white syntactic ws. See if this 2003 ;; We've searched over a piece of non-white syntactic ws. See if this
@@ -2018,8 +2060,7 @@ comment at the start of cc-engine.el for more info."
2018 (if (setq rung-is-marked next-rung-is-marked) 2060 (if (setq rung-is-marked next-rung-is-marked)
2019 (setq rung-pos (1- (c-next-single-property-change 2061 (setq rung-pos (1- (c-next-single-property-change
2020 rung-is-marked 'c-is-sws nil rung-end-pos))) 2062 rung-is-marked 'c-is-sws nil rung-end-pos)))
2021 (setq rung-pos next-rung-pos)) 2063 (setq rung-pos next-rung-pos))))
2022 (setq safe-start t)))
2023 2064
2024 ;; Make sure that the newly marked `c-in-sws' region doesn't connect to 2065 ;; Make sure that the newly marked `c-in-sws' region doesn't connect to
2025 ;; another one after the point (which might occur when editing inside a 2066 ;; another one after the point (which might occur when editing inside a