summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2019-05-02 14:30:29 +0000
committerAlan Mackenzie <acm@muc.de>2019-05-02 14:33:05 +0000
commit39acaff574140b67ef5311c5764a6b3b29491991 (patch)
tree3189f1fe8afe8bd4985a021eb3e271dc523bda8a
parent3fa9c9f774277530f4dac6c4f5de157cb4cdc536 (diff)
downloademacs-39acaff574140b67ef5311c5764a6b3b29491991.tar.gz
CC Mode: Fix multiline block comments in macros.
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.
-rw-r--r--lisp/progmodes/cc-engine.el49
-rw-r--r--lisp/progmodes/cc-langs.el20
2 files changed, 60 insertions, 9 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index a0459b9f2ae..f9e570e9f3f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -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))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 50f8b8473be..00c581a06a9 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -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)