CC Mode: Optimize font-locking stanzas for long raw strings.

Also replace some regexp searches which had caused regexp engine stack
overflows with simple end-of-line calls.

* lisp/progmodes/cc-fonts.el (c-make-syntactic-matcher)
(c-make-font-lock-search-form): Start the generated functions with a skipping
of comments and strings.
(c-make-font-lock-BO-decl-search-function): Start the generated function with
a (fast) movement to the start of any literal.

* lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings)
(c-after-change-mark-abnormal-strings): Replace complicated regexp searches
for end of logical line with basic Lisp functions.
This commit is contained in:
Alan Mackenzie 2022-08-06 21:11:18 +00:00
parent b459e275c3
commit e43fa98a71
2 changed files with 49 additions and 39 deletions

View file

@ -285,6 +285,7 @@
(byte-compile
`(lambda (limit)
(let (res)
(c-skip-comments-and-strings limit)
(while (and (setq res (re-search-forward ,regexp limit t))
(progn
(goto-char (match-beginning 0))
@ -300,43 +301,45 @@
;; with HIGHLIGHTS, a list of highlighters as specified on page
;; "Search-based Fontification" in the elisp manual. If CHECK-POINT
;; is non-nil, we will check (< (point) limit) in the main loop.
`(while
,(if check-point
`(and (< (point) limit)
(re-search-forward ,regexp limit t))
`(re-search-forward ,regexp limit t))
(unless (progn
(goto-char (match-beginning 0))
(c-skip-comments-and-strings limit))
(goto-char (match-end 0))
,@(mapcar
(lambda (highlight)
(if (integerp (car highlight))
;; e.g. highlight is (1 font-lock-type-face t)
(progn
(unless (eq (nth 2 highlight) t)
(error
"The override flag must currently be t in %s"
highlight))
(when (nth 3 highlight)
(error
"The laxmatch flag may currently not be set in %s"
highlight))
`(save-match-data
(c-put-font-lock-face
(match-beginning ,(car highlight))
(match-end ,(car highlight))
,(elt highlight 1))))
;; highlight is an "ANCHORED HIGHLIGHTER" of the form
;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...)
(when (nth 3 highlight)
(error "Match highlights currently not supported in %s"
`(progn
(c-skip-comments-and-strings limit)
(while
,(if check-point
`(and (< (point) limit)
(re-search-forward ,regexp limit t))
`(re-search-forward ,regexp limit t))
(unless (progn
(goto-char (match-beginning 0))
(c-skip-comments-and-strings limit))
(goto-char (match-end 0))
,@(mapcar
(lambda (highlight)
(if (integerp (car highlight))
;; e.g. highlight is (1 font-lock-type-face t)
(progn
(unless (eq (nth 2 highlight) t)
(error
"The override flag must currently be t in %s"
highlight))
`(progn
,(nth 1 highlight)
(save-match-data ,(car highlight))
,(nth 2 highlight))))
highlights))))
(when (nth 3 highlight)
(error
"The laxmatch flag may currently not be set in %s"
highlight))
`(save-match-data
(c-put-font-lock-face
(match-beginning ,(car highlight))
(match-end ,(car highlight))
,(elt highlight 1))))
;; highlight is an "ANCHORED HIGHLIGHTER" of the form
;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...)
(when (nth 3 highlight)
(error "Match highlights currently not supported in %s"
highlight))
`(progn
,(nth 1 highlight)
(save-match-data ,(car highlight))
,(nth 2 highlight))))
highlights)))))
(defun c-make-font-lock-search-function (regexp &rest highlights)
;; This function makes a byte compiled function that works much like
@ -416,6 +419,8 @@
;; lambda more easily.
(byte-compile
`(lambda (limit)
(let ((lit-start (c-literal-start)))
(when lit-start (goto-char lit-start)))
(let ( ;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties

View file

@ -1518,7 +1518,10 @@ 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)
(while
(progn (end-of-line)
(eq (char-before) ?\\))
(forward-line))
;; We're at an EOLL or point-max.
(if (equal (c-get-char-property (point) 'syntax-table) '(15))
(if (memq (char-after) '(?\n ?\r))
@ -1636,8 +1639,10 @@ Note that the style variables are always made local to the buffer."
(min (1+ end) ; 1+, if we're inside an escaped NL.
(point-max))
end))
(re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*"
nil t)
(while
(progn (end-of-line)
(eq (char-before) ?\\))
(forward-line))
(point))
c-new-END))
s)