]> git.eshelyaron.com Git - emacs.git/commitdiff
CC Mode: Fix bug #40052, where a very large macro was too slow in scrolling
authorAlan Mackenzie <acm@muc.de>
Fri, 15 May 2020 19:24:29 +0000 (19:24 +0000)
committerAlan Mackenzie <acm@muc.de>
Fri, 15 May 2020 19:24:29 +0000 (19:24 +0000)
* 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.

lisp/progmodes/cc-engine.el
lisp/progmodes/cc-mode.el

index aa3f7d399e9abb5cc097f0db219d6bcacee21af9..8c8296fd6da2bb2d2a3b2903a8d1bde352690e28 100644 (file)
@@ -405,7 +405,7 @@ comment at the start of cc-engine.el for more info."
          (when (and (car c-macro-cache)
                     (> (point) (car c-macro-cache)) ; in case we have a
                                        ; zero-sized region.
-                    (not (eq (char-before (1- (point))) ?\\)))
+                    (not lim))
            (setcdr c-macro-cache (point))
            (setq c-macro-cache-syntactic nil)))))))
 
@@ -1642,6 +1642,21 @@ comment at the start of cc-engine.el for more info."
            (forward-char 2)
            t))))
 
+(defmacro c-forward-comment-minus-1 ()
+  "Call (forward-comment -1), taking care of escaped newlines.
+Return the result of `forward-comment' if it gets called, nil otherwise."
+  `(if (not comment-end-can-be-escaped)
+       (forward-comment -1)
+     (when (and (< (skip-syntax-backward " >") 0)
+               (eq (char-after) ?\n))
+       (forward-char))
+     (cond
+      ((and (eq (char-before) ?\n)
+           (eq (char-before (1- (point))) ?\\))
+       (backward-char)
+       nil)
+      (t (forward-comment -1)))))
+
 (defun c-backward-single-comment ()
   "Move backward past whitespace and the closest preceding comment, if any.
 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."
       ;; same line.
       (re-search-forward "\\=\\s *[\n\r]" start t)
 
-      (if (if (forward-comment -1)
+      (if (if (c-forward-comment-minus-1)
              (if (eolp)
                  ;; If forward-comment above succeeded and we're at eol
                  ;; then the newline we moved over above didn't end a
                  ;; line comment, so we give it another go.
-                 (forward-comment -1)
+                 (c-forward-comment-minus-1)
                t))
 
          ;; 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."
 
            (if (let (moved-comment)
                  (while
-                     (and (not (setq moved-comment (forward-comment -1)))
+                     (and (not (setq moved-comment (c-forward-comment-minus-1)))
                      ;; Cope specifically with ^M^J here -
                      ;; forward-comment sometimes gets stuck after ^Ms,
                      ;; sometimes after ^M^J.
index e3a924efb06e8ca8d69941adced5faf476a703ab..d822788bee27d20c9bc355dce40177d3bac89449 100644 (file)
@@ -1431,7 +1431,7 @@ Note that the style variables are always made local to the buffer."
 
       ;; Move to end of logical line (as it will be after the change, or as it
       ;; was before unescaping a NL.)
-      (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" nil t)
+      (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*" nil t)
       ;; We're at an EOLL or point-max.
       (if (equal (c-get-char-property (point) 'syntax-table) '(15))
          (if (memq (char-after) '(?\n ?\r))
@@ -1539,7 +1539,7 @@ Note that the style variables are always made local to the buffer."
           (progn
             (goto-char (min (1+ end)   ; 1+, in case a NL has become escaped.
                             (point-max)))
-            (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*"
+            (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*"
                                nil t)
             (point))
           c-new-END))
@@ -1620,8 +1620,8 @@ Note that the style variables are always made local to the buffer."
                   (c-beginning-of-macro))))
       (goto-char (1+ end))             ; After the \
       ;; Search forward for EOLL
-      (setq lim (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*"
-                                  nil t))
+      (setq lim (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*"
+                                          nil t))
       (goto-char (1+ end))
       (when (c-search-forward-char-property-with-value-on-char
             'syntax-table '(15) ?\" lim)