diff options
| author | Alan Mackenzie | 2020-05-15 19:24:29 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2020-05-15 19:24:29 +0000 |
| commit | 66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6 (patch) | |
| tree | c829c22997d507dec9142eadad25967a8362db3f | |
| parent | afca37343d0637386e4dfc4fb04d8700f3c6bf0d (diff) | |
| download | emacs-66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6.tar.gz emacs-66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6.zip | |
CC Mode: Fix bug #40052, where a very large macro was too slow in scrolling
* lisp/progmodes/cc-engine.el (c-end-of-macro): Fix faulty cache handling,
where the upper bound of c-macro-cache was never being set.
(c-forward-comment-minus-1): New macro which terminates unwanted indefinite
backward searching with lots of escaped newlines in c-backward-single-comment.
(c-backward-single-comment, c-backward-comments): Use the new macro above.
* lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings)
(c-after-change-mark-abnormal-strings, c-after-change-escape-NL-in-string):
Optimize three regexps by using shy groups, thus preventing regexp stack
overflow while handling the large C Macro.
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 23 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 8 |
2 files changed, 23 insertions, 8 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index aa3f7d399e9..8c8296fd6da 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -405,7 +405,7 @@ comment at the start of cc-engine.el for more info." | |||
| 405 | (when (and (car c-macro-cache) | 405 | (when (and (car c-macro-cache) |
| 406 | (> (point) (car c-macro-cache)) ; in case we have a | 406 | (> (point) (car c-macro-cache)) ; in case we have a |
| 407 | ; zero-sized region. | 407 | ; zero-sized region. |
| 408 | (not (eq (char-before (1- (point))) ?\\))) | 408 | (not lim)) |
| 409 | (setcdr c-macro-cache (point)) | 409 | (setcdr c-macro-cache (point)) |
| 410 | (setq c-macro-cache-syntactic nil))))))) | 410 | (setq c-macro-cache-syntactic nil))))))) |
| 411 | 411 | ||
| @@ -1642,6 +1642,21 @@ comment at the start of cc-engine.el for more info." | |||
| 1642 | (forward-char 2) | 1642 | (forward-char 2) |
| 1643 | t)))) | 1643 | t)))) |
| 1644 | 1644 | ||
| 1645 | (defmacro c-forward-comment-minus-1 () | ||
| 1646 | "Call (forward-comment -1), taking care of escaped newlines. | ||
| 1647 | Return the result of `forward-comment' if it gets called, nil otherwise." | ||
| 1648 | `(if (not comment-end-can-be-escaped) | ||
| 1649 | (forward-comment -1) | ||
| 1650 | (when (and (< (skip-syntax-backward " >") 0) | ||
| 1651 | (eq (char-after) ?\n)) | ||
| 1652 | (forward-char)) | ||
| 1653 | (cond | ||
| 1654 | ((and (eq (char-before) ?\n) | ||
| 1655 | (eq (char-before (1- (point))) ?\\)) | ||
| 1656 | (backward-char) | ||
| 1657 | nil) | ||
| 1658 | (t (forward-comment -1))))) | ||
| 1659 | |||
| 1645 | (defun c-backward-single-comment () | 1660 | (defun c-backward-single-comment () |
| 1646 | "Move backward past whitespace and the closest preceding comment, if any. | 1661 | "Move backward past whitespace and the closest preceding comment, if any. |
| 1647 | Return t if a comment was found, nil otherwise. In either case, the | 1662 | Return t if a comment was found, nil otherwise. In either case, the |
| @@ -1675,12 +1690,12 @@ This function does not do any hidden buffer changes." | |||
| 1675 | ;; same line. | 1690 | ;; same line. |
| 1676 | (re-search-forward "\\=\\s *[\n\r]" start t) | 1691 | (re-search-forward "\\=\\s *[\n\r]" start t) |
| 1677 | 1692 | ||
| 1678 | (if (if (forward-comment -1) | 1693 | (if (if (c-forward-comment-minus-1) |
| 1679 | (if (eolp) | 1694 | (if (eolp) |
| 1680 | ;; If forward-comment above succeeded and we're at eol | 1695 | ;; If forward-comment above succeeded and we're at eol |
| 1681 | ;; then the newline we moved over above didn't end a | 1696 | ;; then the newline we moved over above didn't end a |
| 1682 | ;; line comment, so we give it another go. | 1697 | ;; line comment, so we give it another go. |
| 1683 | (forward-comment -1) | 1698 | (c-forward-comment-minus-1) |
| 1684 | t)) | 1699 | t)) |
| 1685 | 1700 | ||
| 1686 | ;; Emacs <= 20 and XEmacs move back over the closer of a | 1701 | ;; Emacs <= 20 and XEmacs move back over the closer of a |
| @@ -1709,7 +1724,7 @@ comment at the start of cc-engine.el for more info." | |||
| 1709 | 1724 | ||
| 1710 | (if (let (moved-comment) | 1725 | (if (let (moved-comment) |
| 1711 | (while | 1726 | (while |
| 1712 | (and (not (setq moved-comment (forward-comment -1))) | 1727 | (and (not (setq moved-comment (c-forward-comment-minus-1))) |
| 1713 | ;; Cope specifically with ^M^J here - | 1728 | ;; Cope specifically with ^M^J here - |
| 1714 | ;; forward-comment sometimes gets stuck after ^Ms, | 1729 | ;; forward-comment sometimes gets stuck after ^Ms, |
| 1715 | ;; sometimes after ^M^J. | 1730 | ;; sometimes after ^M^J. |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index e3a924efb06..d822788bee2 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -1431,7 +1431,7 @@ Note that the style variables are always made local to the buffer." | |||
| 1431 | 1431 | ||
| 1432 | ;; Move to end of logical line (as it will be after the change, or as it | 1432 | ;; Move to end of logical line (as it will be after the change, or as it |
| 1433 | ;; was before unescaping a NL.) | 1433 | ;; was before unescaping a NL.) |
| 1434 | (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" nil t) | 1434 | (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*" nil t) |
| 1435 | ;; We're at an EOLL or point-max. | 1435 | ;; We're at an EOLL or point-max. |
| 1436 | (if (equal (c-get-char-property (point) 'syntax-table) '(15)) | 1436 | (if (equal (c-get-char-property (point) 'syntax-table) '(15)) |
| 1437 | (if (memq (char-after) '(?\n ?\r)) | 1437 | (if (memq (char-after) '(?\n ?\r)) |
| @@ -1539,7 +1539,7 @@ Note that the style variables are always made local to the buffer." | |||
| 1539 | (progn | 1539 | (progn |
| 1540 | (goto-char (min (1+ end) ; 1+, in case a NL has become escaped. | 1540 | (goto-char (min (1+ end) ; 1+, in case a NL has become escaped. |
| 1541 | (point-max))) | 1541 | (point-max))) |
| 1542 | (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" | 1542 | (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*" |
| 1543 | nil t) | 1543 | nil t) |
| 1544 | (point)) | 1544 | (point)) |
| 1545 | c-new-END)) | 1545 | c-new-END)) |
| @@ -1620,8 +1620,8 @@ Note that the style variables are always made local to the buffer." | |||
| 1620 | (c-beginning-of-macro)))) | 1620 | (c-beginning-of-macro)))) |
| 1621 | (goto-char (1+ end)) ; After the \ | 1621 | (goto-char (1+ end)) ; After the \ |
| 1622 | ;; Search forward for EOLL | 1622 | ;; Search forward for EOLL |
| 1623 | (setq lim (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" | 1623 | (setq lim (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*" |
| 1624 | nil t)) | 1624 | nil t)) |
| 1625 | (goto-char (1+ end)) | 1625 | (goto-char (1+ end)) |
| 1626 | (when (c-search-forward-char-property-with-value-on-char | 1626 | (when (c-search-forward-char-property-with-value-on-char |
| 1627 | 'syntax-table '(15) ?\" lim) | 1627 | 'syntax-table '(15) ?\" lim) |