emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c601148ded7: CC Mode (some languages): handle string lines ending


From: Alan Mackenzie
Subject: master c601148ded7: CC Mode (some languages): handle string lines ending in \\
Date: Thu, 20 Jul 2023 15:36:41 -0400 (EDT)

branch: master
commit c601148ded734be2920044f943c44886d144cd97
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>

    CC Mode (some languages): handle string lines ending in \\
    
    In C, C++, Objective C, and Pike modes, regard \\ in a string
    at EOL as a backslash followed by an escaped newline.  In the
    other languages, this remains regarded as an escaped backslash
    followed by an invalid string terminator.
    
    * lisp/progmodes/cc-defs.el (c-is-escaped, c-will-be-escaped):
    Amend to observe the changed notion of escaped newlines.
    
    * lisp/progmodes/cc-langs.el (c-string-escaped-newlines):
    Unused, removed.
    (c-escaped-newline-takes-precedence): New lang const and var.
    (c-string-innards-re-alist): Amend, using the above new lang
    var.
---
 lisp/progmodes/cc-defs.el  | 29 +++++++++++++++++++++--------
 lisp/progmodes/cc-langs.el | 29 ++++++++++++++++++-----------
 2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 1d7f90ed428..2cbe9ca7e92 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -425,11 +425,14 @@ to it is returned.  This function does not modify the 
point or the mark."
 (defvar lookup-syntax-properties)       ;XEmacs.
 
 (defmacro c-is-escaped (pos)
-  ;; Are there an odd number of backslashes before POS?
+  ;; Is the character following POS escaped?
   (declare (debug t))
   `(save-excursion
      (goto-char ,pos)
-     (not (zerop (logand (skip-chars-backward "\\\\") 1)))))
+     (if (and c-escaped-newline-takes-precedence
+             (memq (char-after) '(?\n ?\r)))
+        (eq (char-before) ?\\)
+       (not (zerop (logand (skip-chars-backward "\\\\") 1))))))
 
 (defmacro c-will-be-escaped (pos beg end)
   ;; Will the character after POS be escaped after the removal of (BEG END)?
@@ -437,13 +440,23 @@ to it is returned.  This function does not modify the 
point or the mark."
   (declare (debug t))
   `(save-excursion
      (let ((-end- ,end)
+          (-pos- ,pos)
           count)
-       (goto-char ,pos)
-       (setq count (skip-chars-backward "\\\\" -end-))
-       (when (eq (point) -end-)
-        (goto-char ,beg)
-        (setq count (+ count (skip-chars-backward "\\\\"))))
-       (not (zerop (logand count 1))))))
+       (if (and c-escaped-newline-takes-precedence
+               (memq (char-after -pos-) '(?\n ?\r)))
+          (eq (char-before (if (eq -pos- -end-)
+                               ,beg
+                             -pos-))
+              ?\\)
+        (goto-char -pos-)
+        (setq count
+              (if (> -pos- -end-)
+                  (skip-chars-backward "\\\\" -end-)
+                0))
+        (when (eq (point) -end-)
+          (goto-char ,beg)
+          (setq count (+ count (skip-chars-backward "\\\\"))))
+        (not (zerop (logand count 1)))))))
 
 (defmacro c-will-be-unescaped (beg)
   ;; Would the character after BEG be unescaped?
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 3d0ad9984fa..ef7f27dc435 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1071,14 +1071,6 @@ Currently (2022-09) just C++ Mode uses this."
   ;; matched.
   t nil)
 
-(c-lang-defconst c-string-escaped-newlines
-  "Set if the language support backslash escaped newlines inside string
-literals."
-  t nil
-  (c c++ objc pike) t)
-(c-lang-defvar c-string-escaped-newlines
-  (c-lang-const c-string-escaped-newlines))
-
 (c-lang-defconst c-multiline-string-start-char
   "Set if the language supports multiline string literals without escaped
 newlines.  If t, all string literals are multiline.  If a character,
@@ -1095,6 +1087,18 @@ further directions."
 (c-lang-defvar c-multiline-string-start-char
   (c-lang-const c-multiline-string-start-char))
 
+(c-lang-defconst c-escaped-newline-takes-precedence
+  "Set if the language resolves escaped newlines first.
+This makes a difference in a string like \"...\\\\\n\".  When
+this variable is nil, the first backslash escapes the second,
+leaving an unterminated string.  When it's non-nil, the string is
+continued onto the next line, and the first backslash escapes
+whatever begins that next line."
+  t nil
+  (c c++ objc pike) t)
+(c-lang-defvar c-escaped-newline-takes-precedence
+  (c-lang-const c-escaped-newline-takes-precedence))
+
 (c-lang-defconst c-string-innards-re-alist
   ;; An alist of regexps matching the innards of a string, the key being the
   ;; string's delimiter.
@@ -1105,9 +1109,12 @@ further directions."
   t (mapcar (lambda (delim)
              (cons
               delim
-              (concat "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r"
-                      (string delim)
-                      "]\\)*")))
+              (concat
+               (if (c-lang-const c-escaped-newline-takes-precedence)
+                   "\\(\\\\\\(\\\\?\n\\|.\\)\\|[^\\\n\r"
+                 "\\(\\\\\\(\n\\|.\\)\\|[^\\\n\r")
+               (string delim)
+               "]\\)*")))
            (and
             (or (null (c-lang-const c-multiline-string-start-char))
                 (c-characterp (c-lang-const c-multiline-string-start-char)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]