From b054393dd1b9146522d8aeb21cb9b1ad52210a33 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 11 Sep 2020 14:18:43 +0000 Subject: [PATCH] CC Mode: Fix minor bugs in the string handling functions These sometimes gave rise to the tail of a buffer being "stringed out". * lixp/progmodes/cc-defs.el (c-will-be-unescaped): New macro. * lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings) (c-after-change-mark-abnormal-strings): Fix bugs in the handling of string fence syntax-table text properties. --- lisp/progmodes/cc-defs.el | 9 +++++++++ lisp/progmodes/cc-mode.el | 25 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 9a3d7adf61d..77e263f1aad 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -434,6 +434,15 @@ to it is returned. This function does not modify the point or the mark." (setq count (+ count (skip-chars-backward "\\\\")))) (not (zerop (logand count 1)))))) +(defmacro c-will-be-unescaped (beg end) + ;; Would the character after END be unescaped after the removal of (BEG END)? + ;; This is regardless of its current status. It is assumed that (>= POS END). + `(save-excursion + (let (count) + (goto-char ,beg) + (setq count (skip-chars-backward "\\\\")) + (zerop (logand count 1))))) + (defvar c-use-extents) (defmacro c-next-single-property-change (position prop &optional object limit) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 2ffbde99aa4..73275cfa621 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1478,9 +1478,11 @@ Note that the style variables are always made local to the buffer." (c-will-be-escaped end beg end)) (c-remove-string-fences end) (goto-char (1+ end))) - ;; Are we unescaping a newline by inserting stuff between \ and \n? - ((and (eq end beg) - (c-is-escaped end)) + ;; Are we unescaping a newline ... + ((and + (c-is-escaped end) + (or (eq beg end) ; .... by inserting stuff between \ and \n? + (c-will-be-unescaped beg end))) ; ... by removing an odd number of \s? (goto-char (1+ end))) ; To after the NL which is being unescaped. (t (goto-char end))) @@ -1518,10 +1520,11 @@ Note that the style variables are always made local to the buffer." (not (c-characterp c-multiline-string-start-char)))) (when (and (eq end-literal-type 'string) (not (eq (char-before (cdr end-limits)) ?\()) - (memq (char-after (car end-limits)) c-string-delims) - (equal (c-get-char-property (car end-limits) 'syntax-table) - '(15))) - (c-remove-string-fences (car end-limits)) + (memq (char-after (car end-limits)) c-string-delims)) + (setq c-new-END (max c-new-END (cdr end-limits))) + (when (equal (c-get-char-property (car end-limits) 'syntax-table) + '(15)) + (c-remove-string-fences (car end-limits))) (setq c-new-END (max c-new-END (cdr end-limits)))) (when (and (eq beg-literal-type 'string) @@ -1594,8 +1597,12 @@ Note that the style variables are always made local to the buffer." ; insertion/deletion of string delimiters. (max (progn - (goto-char (min (1+ end) ; 1+, in case a NL has become escaped. - (point-max))) + (goto-char + (if (and (memq (char-after end) '(?\n ?\r)) + (c-is-escaped end)) + (min (1+ end) ; 1+, if we're inside an escaped NL. + (point-max)) + end)) (re-search-forward "\\(?:\\\\\\(?:.\\|\n\\)\\|[^\\\n\r]\\)*" nil t) (point)) -- 2.39.2