Commit 757e66af authored by Alan Mackenzie's avatar Alan Mackenzie

CC Mode. Fix fontification bug with unterminated quotes on adjacent lines

In particular, with these unterminated quotes on each of two adjacent lines,
the following text was spuriously fontified with string face.

* lisp/progmodes/cc-defs.el
(c-search-backward-char-property-with-value-on-char): New macro.

* lisp/progmodes/cc-mode.el (c-clear-string-fences): Check whether there is an
unmatched quote at a lower buffer position which should match the current
quote, rather than wrongly assuming the latter is unmatched and marking it
with a punctuation syntax.
(c-font-lock-fontify-region): Ensure all pertinent parts of the buffer have
string fence properties applied before performing any syntactic operations on
it; in particular, this applies to a quote at an earlier buffer position which
"matches" one inside the region about to be fontified.
parent 3c278b49
Pipeline #4212 failed with stage
in 74 minutes and 55 seconds
......@@ -1340,6 +1340,29 @@ nil; point is then left undefined."
(search-forward-regexp "\\(\n\\|.\\)") ; to set the match-data.
(point))))
(defmacro c-search-backward-char-property-with-value-on-char
(property value char &optional limit)
"Search backward for a text-property PROPERTY having value VALUE on a
character with value CHAR.
LIMIT bounds the search. The value comparison is done with `equal'.
PROPERTY must be a constant.
Leave point just before the character, and set the match data on
this character, and return point. If the search fails, return
nil; point is then left undefined."
`(let ((char-skip (concat "^" (char-to-string ,char)))
(-limit- (or ,limit (point-min)))
(-value- ,value))
(while
(and
(progn (skip-chars-backward char-skip -limit-)
(> (point) -limit-))
(not (equal (c-get-char-property (1- (point)) ,property) -value-)))
(backward-char))
(when (> (point) -limit-)
(search-backward-regexp "\\(\n\\|.\\)") ; to set the match-data.
(point))))
(defmacro c-search-forward-char-property-without-value-on-char
(property value char &optional limit)
"Search forward for a character CHAR without text property PROPERTY having
......
......@@ -1233,6 +1233,15 @@ Note that the style variables are always made local to the buffer."
;; Check we haven't left any unbalanced "s.
(save-excursion
(setq pos beg)
;; Is there already an unbalanced " before BEG?
(setq pos (c-min-property-position pos end 'c-fl-syn-tab))
(when (< pos end) (goto-char pos))
(when (and (save-match-data
(c-search-backward-char-property-with-value-on-char
'c-fl-syn-tab '(15) ?\"
(max (- (point) 500) (point-min))))
(not (equal (c-get-char-property (point) 'syntax-table) '(1))))
(setq pos (1+ pos)))
(while (< pos end)
(setq pos
(c-min-property-position pos end 'c-fl-syn-tab))
......@@ -2234,44 +2243,69 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; line was fouled up by context fontification.
(save-restriction
(widen)
(let (new-beg new-end new-region case-fold-search)
(if (and c-in-after-change-fontification
(< beg c-new-END) (> end c-new-BEG))
;; Region and the latest after-change fontification region overlap.
;; Determine the upper and lower bounds of our adjusted region
;; separately.
(progn
(if (<= beg c-new-BEG)
(setq c-in-after-change-fontification nil))
(setq new-beg
(if (and (>= beg (c-point 'bol c-new-BEG))
(<= beg c-new-BEG))
;; Either jit-lock has accepted `c-new-BEG', or has
;; (probably) extended the change region spuriously to
;; BOL, which position likely has a syntactically
;; different position. To ensure correct fontification,
;; we start at `c-new-BEG', assuming any characters to the
;; left of `c-new-BEG' on the line do not require
;; fontification.
c-new-BEG
(setq new-region (c-before-context-fl-expand-region beg end)
new-end (cdr new-region))
(car new-region)))
(setq new-end
(if (and (>= end (c-point 'bol c-new-END))
(<= end c-new-END))
c-new-END
(or new-end
(cdr (c-before-context-fl-expand-region beg end))))))
;; Context (etc.) fontification.
(setq new-region (c-before-context-fl-expand-region beg end)
new-beg (car new-region) new-end (cdr new-region)))
(c-save-buffer-state nil
(unwind-protect
(progn (c-restore-string-fences new-beg new-end)
(funcall (default-value 'font-lock-fontify-region-function)
new-beg new-end verbose))
(c-clear-string-fences))))))
(let (new-beg new-end new-region case-fold-search string-fence-beg lim)
;; Check how far back we need to extend the region where we reapply the
;; string fence syntax-table properties. These must be in place for the
;; coming fontification operations.
(save-excursion
(goto-char (if c-in-after-change-fontification
(min beg c-new-BEG)
beg))
(setq lim (max (- (point) 500) (point-min)))
(while
(progn
(skip-chars-backward "^\"" lim)
(or (bobp) (backward-char))
(save-excursion
(eq (logand (skip-chars-backward "\\\\") 1) 1))))
(setq string-fence-beg
(cond ((c-get-char-property (point) 'c-fl-syn-tab)
(point))
(c-in-after-change-fontification
c-new-BEG)
(t beg)))
(c-save-buffer-state nil
;; Temporarily reapply the string fence syntax-table properties.
(c-with-extended-string-fences
string-fence-beg (if c-in-after-change-fontification
(max end c-new-END)
end)
(if (and c-in-after-change-fontification
(< beg c-new-END) (> end c-new-BEG))
;; Region and the latest after-change fontification region overlap.
;; Determine the upper and lower bounds of our adjusted region
;; separately.
(progn
(if (<= beg c-new-BEG)
(setq c-in-after-change-fontification nil))
(setq new-beg
(if (and (>= beg (c-point 'bol c-new-BEG))
(<= beg c-new-BEG))
;; Either jit-lock has accepted `c-new-BEG', or has
;; (probably) extended the change region spuriously
;; to BOL, which position likely has a
;; syntactically different position. To ensure
;; correct fontification, we start at `c-new-BEG',
;; assuming any characters to the left of
;; `c-new-BEG' on the line do not require
;; fontification.
c-new-BEG
(setq new-region (c-before-context-fl-expand-region beg end)
new-end (cdr new-region))
(car new-region)))
(setq new-end
(if (and (>= end (c-point 'bol c-new-END))
(<= end c-new-END))
c-new-END
(or new-end
(cdr (c-before-context-fl-expand-region beg end))))))
;; Context (etc.) fontification.
(setq new-region (c-before-context-fl-expand-region beg end)
new-beg (car new-region) new-end (cdr new-region)))
;; Finally invoke font lock's functionality.
(funcall (default-value 'font-lock-fontify-region-function)
new-beg new-end verbose)))))))
(defun c-after-font-lock-init ()
;; Put on `font-lock-mode-hook'. This function ensures our after-change
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment