diff options
| author | Alan Mackenzie | 2017-04-10 21:01:38 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2017-04-10 21:01:38 +0000 |
| commit | 230e25fd67fd654f04b8c744db0e170353a7f3b3 (patch) | |
| tree | ca4c9def3c497739dd48e5d8c708b5addf51f4de /lisp | |
| parent | 3ccd0ff1064a2836c379b13c2d5f4b11c5da1f88 (diff) | |
| download | emacs-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.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 105 |
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. |
| 324 | More accurately, move the point to the end of the closest following | 324 | More accurately, move the point to the end of the closest following |
| 325 | line that doesn't end with a line continuation backslash - no check is | 325 | line that doesn't end with a line continuation backslash - no check is |
| 326 | done that the point is inside a cpp directive to begin with. | 326 | done that the point is inside a cpp directive to begin with. |
| 327 | 327 | ||
| 328 | If LIM is provided, it is a limit position at which point is left | ||
| 329 | if the end of the macro doesn't occur earlier. | ||
| 330 | |||
| 328 | Note that this function might do hidden buffer changes. See the | 331 | Note that this function might do hidden buffer changes. See the |
| 329 | comment at the start of cc-engine.el for more info." | 332 | comment 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 |