aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2020-05-15 19:24:29 +0000
committerAlan Mackenzie2020-05-15 19:24:29 +0000
commit66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6 (patch)
treec829c22997d507dec9142eadad25967a8362db3f
parentafca37343d0637386e4dfc4fb04d8700f3c6bf0d (diff)
downloademacs-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.el23
-rw-r--r--lisp/progmodes/cc-mode.el8
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.
1647Return 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.
1647Return t if a comment was found, nil otherwise. In either case, the 1662Return 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)