]> git.eshelyaron.com Git - emacs.git/commitdiff
CC Mode: Fix multiline block comments in macros.
authorAlan Mackenzie <acm@muc.de>
Thu, 2 May 2019 14:30:29 +0000 (14:30 +0000)
committerAlan Mackenzie <acm@muc.de>
Thu, 2 May 2019 14:33:05 +0000 (14:33 +0000)
In particulr, handle multiline block comments whose newlines are not escaped.
There is an example of this in #define EXTRA_CONTEXT_FIELDS in editfns.c.

* lisp/progmodes/cc-engine.el (c-beginning-of-macro, c-end-of-macro): Enclose
the loops scanning escaped newlines with outer loops which check
heuristically for, respectively, a block comment ender and a block comment
starter on the lines we end up on.  (A rigorous syntactic check would be too
slow, here.)

* lisp/progmodes/cc-langs.el (c-last-c-comment-end-on-line-re)
(c-last-open-c-comment-start-on-line-re): New language constants/variables.

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

index a0459b9f2aeb9f9afe3934389b5023984708e74b..f9e570e9f3f4de75cc136b2d5a235799bef3b82f 100644 (file)
@@ -287,7 +287,8 @@ otherwise return nil and leave point unchanged.
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
-  (let ((here (point)))
+  (let ((here (point))
+       (pause (c-point 'eol)))
     (when c-opt-cpp-prefix
       (if (and (car c-macro-cache)
               (>= (point) (car c-macro-cache))
@@ -307,8 +308,23 @@ comment at the start of cc-engine.el for more info."
        (save-restriction
          (if lim (narrow-to-region lim (point-max)))
          (beginning-of-line)
-         (while (eq (char-before (1- (point))) ?\\)
-           (forward-line -1))
+         (when (or (null lim)
+                   (>= here lim))
+           (while
+               (progn
+                 (while (eq (char-before (1- (point))) ?\\)
+                   (forward-line -1))
+                 (when (and c-last-c-comment-end-on-line-re
+                            (re-search-forward
+                             c-last-c-comment-end-on-line-re pause t))
+                   (goto-char (match-end 1))
+                   (if (c-backward-single-comment)
+                       (progn
+                         (beginning-of-line)
+                         (setq pause (point)))
+                     (goto-char pause)
+                     nil)))))
+
          (back-to-indentation)
          (if (and (<= (point) here)
                   (save-match-data (looking-at c-opt-cpp-start))
@@ -345,12 +361,23 @@ comment at the start of cc-engine.el for more info."
              c-macro-cache-start-pos nil
              c-macro-cache-syntactic nil
              c-macro-cache-no-comment nil))
-      (while (progn
-              (end-of-line)
-              (when (and (eq (char-before) ?\\)
-                         (not (eobp)))
-                (forward-char)
-                t)))
+      (while
+         (progn
+           (while (progn
+                    (end-of-line)
+                    (when (and (eq (char-before) ?\\)
+                               (not (eobp)))
+                      (forward-char)
+                      t)))
+           (if (and c-last-open-c-comment-start-on-line-re
+                    (re-search-backward
+                     c-last-open-c-comment-start-on-line-re
+                     (c-point 'bol) t))
+               (progn
+                 (goto-char (match-beginning 1))
+                 (c-forward-single-comment))
+             nil)))
+
       (when (and (car c-macro-cache)
                 (bolp)
                 (not (eq (char-before (1- (point))) ?\\)))
@@ -2007,6 +2034,10 @@ comment at the start of cc-engine.el for more info."
            ;; Take elaborate precautions to detect an open block comment at
            ;; the end of a macro.  If we find one, we set `safe-start' to nil
            ;; and break off any further scanning of comments.
+           ;;
+           ;; (2019-05-02): `c-end-of-macro' now moves completely over block
+           ;; comments, even multiline ones lacking \s at their EOLs.  So a
+           ;; lot of the following is probably redundant now.
            (let ((com-begin (point)) com-end in-macro)
              (when (and (c-forward-single-comment)
                         (setq com-end (point))
index 50f8b8473be8b3dadf992e212d5ddacddac183f0..00c581a06a9e9be9ced7de1f16428eb4728a4120 100644 (file)
@@ -1589,6 +1589,26 @@ properly."
 (c-lang-defvar c-line-comment-start-regexp
               (c-lang-const c-line-comment-start-regexp))
 
+(c-lang-defconst c-last-c-comment-end-on-line-re
+  "Regexp which matches the last block comment ender on the
+current line, if any, or nil in those languages without block
+comments.  When a match is found, submatch 1 contains the comment
+ender."
+  t "\\(\\*/\\)\\([^*]\\|\\*[^/]\\)*$"
+  awk nil)
+(c-lang-defvar c-last-c-comment-end-on-line-re
+              (c-lang-const c-last-c-comment-end-on-line-re))
+
+(c-lang-defconst c-last-open-c-comment-start-on-line-re
+  "Regexp which matches the last block comment start on the
+current ine, if any, or nil in those languages without block
+comments.  When a match is found, submatch 1 contains the comment
+starter."
+  t "\\(/\\*\\)\\([^*]\\|\\*[^/]\\)*$"
+  awk nil)
+(c-lang-defvar c-last-open-c-comment-start-on-line-re
+              (c-lang-const c-last-open-c-comment-start-on-line-re))
+
 (c-lang-defconst c-literal-start-regexp
   ;; Regexp to match the start of comments and string literals.
   t (concat (c-lang-const c-comment-start-regexp)