[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] scratch/flymake-refactor 7d3d3d3 38/52: Fix flymake proble
From: |
João Távora |
Subject: |
[Emacs-diffs] scratch/flymake-refactor 7d3d3d3 38/52: Fix flymake problems when checking C header files |
Date: |
Sun, 1 Oct 2017 12:40:50 -0400 (EDT) |
branch: scratch/flymake-refactor
commit 7d3d3d3e40eeb241cdd66f2df8bd55615a34c0b3
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Fix flymake problems when checking C header files
The first of these problems is longstanding: if an error-less B.h is
included from error-ridden A.h, flymake's legacy parser will panic
(and disable itself) since it sees a non-zero exit for a clean file.
To fix this, recommend returning 'true' in the documentation for the
check-syntax target.
Another problem was introduced by the parser rewrite. For error
patterns spanning more than one line, point may be left in the middle
of a line and thus render other patterns useless. Those patterns were
written for the old line-by-line parser. To make them useful again,
move to the beginning of line in those situations.
The third problem was also longstanding and happened on newer GCC's:
The "In file included from" prefix confused
flymake-proc-get-real-file-name. Fix this.
Also updated flymake--diag-region to fallback to highlighting a full
line less often.
Add automatic tests to check this.
* lisp/progmodes/flymake-proc.el
(flymake-proc--diagnostics-for-pattern): Fix bug when patterns
accidentally spans more than one line. Don't create
diagnostics without error messages.
(flymake-proc-real-file-name-considering-includes): New
helper.
(flymake-proc-allowed-file-name-masks): Use it.
* lisp/progmodes/flymake-ui.el (flymake-diag-region): Make COL
argument explicitly optional. Only fall back to full line in extreme
cases. (flymake-error): Fix silly error.
* test/lisp/progmodes/flymake-tests.el
(included-c-header-files): New test.
(different-diagnostic-types): Update.
* test/lisp/progmodes/flymake-resources/Makefile
(check-syntax): Always return success (0) error code.
(CC_OPTS): Add -Wextra
* test/lisp/progmodes/flymake-resources/errors-and-warnings.c
(main): Rewrite comments.
* test/lisp/progmodes/flymake-resources/errors-and-warnings.c:
Include some dummy header files.
* test/lisp/progmodes/flymake-resources/no-problems.h: New file.
* test/lisp/progmodes/flymake-resources/some-problems.h: New file.
* doc/misc/flymake.texi (Example---Configuring a tool called
via make): Recommend adding "|| true" to the check-syntax target.
---
doc/misc/flymake.texi | 4 +--
lisp/progmodes/flymake-proc.el | 32 ++++++++++++++++++----
lisp/progmodes/flymake-ui.el | 27 ++++++++++--------
test/lisp/progmodes/flymake-resources/Makefile | 4 +--
.../flymake-resources/errors-and-warnings.c | 15 ++++++----
.../lisp/progmodes/flymake-resources/no-problems.h | 1 +
.../progmodes/flymake-resources/some-problems.h | 5 ++++
test/lisp/progmodes/flymake-tests.el | 20 ++++++++++++++
8 files changed, 82 insertions(+), 26 deletions(-)
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi
index a1abf04..61133a0 100644
--- a/doc/misc/flymake.texi
+++ b/doc/misc/flymake.texi
@@ -488,7 +488,7 @@ our case this target might look like this:
@verbatim
check-syntax:
- gcc -o /dev/null -S ${CHK_SOURCES}
+ gcc -o /dev/null -S ${CHK_SOURCES} || true
@end verbatim
@noindent
@@ -500,7 +500,7 @@ Automake variable @code{COMPILE}:
@verbatim
check-syntax:
- $(COMPILE) -o /dev/null -S ${CHK_SOURCES}
+ $(COMPILE) -o /dev/null -S ${CHK_SOURCES} || true
@end verbatim
@node Flymake Implementation
diff --git a/lisp/progmodes/flymake-proc.el b/lisp/progmodes/flymake-proc.el
index bbba180..ff12f47 100644
--- a/lisp/progmodes/flymake-proc.el
+++ b/lisp/progmodes/flymake-proc.el
@@ -66,7 +66,10 @@
:type 'integer)
(defcustom flymake-proc-allowed-file-name-masks
- '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'"
flymake-proc-simple-make-init)
+ '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'"
+ flymake-proc-simple-make-init
+ nil
+ flymake-proc-real-file-name-considering-includes)
("\\.xml\\'" flymake-proc-xml-init)
("\\.html?\\'" flymake-proc-xml-init)
("\\.cs\\'" flymake-proc-simple-make-init)
@@ -419,12 +422,25 @@ Create parent directories as needed."
(condition-case-unless-debug err
(cl-loop
with (regexp file-idx line-idx col-idx message-idx) = pattern
- while (search-forward-regexp regexp nil t)
+ while (and
+ (search-forward-regexp regexp nil t)
+ ;; If the preceding search spanned more than one line,
+ ;; move to the start of the line we ended up in. This
+ ;; preserves the usefulness of the patterns in
+ ;; `flymake-proc-err-line-patterns', which were
+ ;; written primarily for flymake's original
+ ;; line-by-line parsing and thus never spanned
+ ;; multiple lines.
+ (if (/= (line-number-at-pos (match-beginning 0))
+ (line-number-at-pos))
+ (goto-char (line-beginning-position))
+ t))
for fname = (and file-idx (match-string file-idx))
for message = (and message-idx (match-string message-idx))
for line-string = (and line-idx (match-string line-idx))
- for line-number = (and line-string
- (string-to-number line-string))
+ for line-number = (or (and line-string
+ (string-to-number line-string))
+ 1)
for col-string = (and col-idx (match-string col-idx))
for col-number = (and col-string
(string-to-number col-string))
@@ -436,7 +452,7 @@ Create parent directories as needed."
fname)))
for buffer = (and full-file
(find-buffer-visiting full-file))
- if (eq buffer (process-buffer proc))
+ if (and (eq buffer (process-buffer proc)) message)
collect (with-current-buffer buffer
(pcase-let ((`(,beg . ,end)
(flymake-diag-region line-number col-number)))
@@ -1030,6 +1046,12 @@ Use CREATE-TEMP-F for creating temp copy."
'("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'")
"[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
+(defun flymake-proc-real-file-name-considering-includes (scraped)
+ (flymake-proc-get-real-file-name
+ (replace-regexp-in-string "^in file included from[ \t*]"
+ ""
+ scraped)))
+
;;;; .java/make specific
(defun flymake-proc-simple-make-java-init ()
(flymake-proc-simple-make-init-impl
'flymake-proc-create-temp-with-folder-structure nil nil "Makefile"
'flymake-proc-get-make-cmdline))
diff --git a/lisp/progmodes/flymake-ui.el b/lisp/progmodes/flymake-ui.el
index 4ac9e0a..96711f8 100644
--- a/lisp/progmodes/flymake-ui.el
+++ b/lisp/progmodes/flymake-ui.el
@@ -148,10 +148,9 @@ are the string substitutions (see the function `format')."
(defun flymake-error (text &rest args)
"Signal an error for flymake."
- (let ((msg (format-message text args)))
+ (let ((msg (apply #'format-message text args)))
(flymake-log :error msg)
- (error (concat "[flymake] "
- (format text args)))))
+ (error (concat "[flymake] " msg))))
(cl-defstruct (flymake--diag
(:constructor flymake--diag-make))
@@ -235,9 +234,10 @@ verify FILTER, sort them by COMPARE (using KEY)."
(define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1")
(define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1")
-(defun flymake-diag-region (line col)
+(defun flymake-diag-region (line &optional col)
"Compute region (BEG . END) corresponding to LINE and COL.
-Or nil if the region is invalid."
+If COL is nil, return a region just for LINE.
+Return nil if the region is invalid."
(condition-case-unless-debug _err
(let ((line (min (max line 1)
(line-number-at-pos (point-max) 'absolute))))
@@ -254,13 +254,18 @@ Or nil if the region is invalid."
(if (eq (point) beg)
(line-beginning-position 2)
(point)))))
- (if col
- (let* ((beg (progn (forward-char (1- col)) (point)))
+ (if (and col (cl-plusp col))
+ (let* ((beg (progn (forward-char (1- col))
+ (point)))
(sexp-end (ignore-errors (end-of-thing 'sexp)))
- (end (or sexp-end
- (fallback-eol beg))))
- (cons (if sexp-end beg (fallback-bol))
- end))
+ (end (or (and sexp-end
+ (not (= sexp-end beg))
+ sexp-end)
+ (ignore-errors (goto-char (1+ beg)))))
+ (safe-end (or end
+ (fallback-eol beg))))
+ (cons (if end beg (fallback-bol))
+ safe-end))
(let* ((beg (fallback-bol))
(end (fallback-eol beg)))
(cons beg end))))))
diff --git a/test/lisp/progmodes/flymake-resources/Makefile
b/test/lisp/progmodes/flymake-resources/Makefile
index 0f3f397..4944075 100644
--- a/test/lisp/progmodes/flymake-resources/Makefile
+++ b/test/lisp/progmodes/flymake-resources/Makefile
@@ -1,6 +1,6 @@
# Makefile for flymake tests
-CC_OPTS = -Wall
+CC_OPTS = -Wall -Wextra
## Recent gcc (e.g. 4.8.2 on RHEL7) can automatically colorize their output,
## which can confuse flymake. Set GCC_COLORS to disable that.
@@ -8,6 +8,6 @@ CC_OPTS = -Wall
## normally use flymake, so it seems like just avoiding the issue
## in this test is fine. Set flymake-log-level to 3 to investigate.
check-syntax:
- GCC_COLORS= $(CC) $(CC_OPTS) ${CHK_SOURCES}
+ GCC_COLORS= $(CC) $(CC_OPTS) ${CHK_SOURCES} || true
# eof
diff --git a/test/lisp/progmodes/flymake-resources/errors-and-warnings.c
b/test/lisp/progmodes/flymake-resources/errors-and-warnings.c
index 6454dd2..1d38bd6 100644
--- a/test/lisp/progmodes/flymake-resources/errors-and-warnings.c
+++ b/test/lisp/progmodes/flymake-resources/errors-and-warnings.c
@@ -1,10 +1,13 @@
- int main()
+/* Flymake should notice an error on the next line, since
+ that file has at least one warning.*/
+#include "some-problems.h"
+/* But not this one */
+#include "no-problems.h"
+
+int main()
{
- char c = 1000;
+ char c = 1000; /* a note and a warning */
int bla;
- /* The following line should have one warning and one error. The
- warning spans the full line because gcc (at least 6.3.0) points
- places the error at the =, which isn't a sexp.*/
- char c; if (bla == (void*)3);
+ char c; if (bla == (void*)3); /* an error, and two warnings */
return c;
}
diff --git a/test/lisp/progmodes/flymake-resources/no-problems.h
b/test/lisp/progmodes/flymake-resources/no-problems.h
new file mode 100644
index 0000000..19ddc61
--- /dev/null
+++ b/test/lisp/progmodes/flymake-resources/no-problems.h
@@ -0,0 +1 @@
+typedef int no_problems;
diff --git a/test/lisp/progmodes/flymake-resources/some-problems.h
b/test/lisp/progmodes/flymake-resources/some-problems.h
new file mode 100644
index 0000000..165d8dd
--- /dev/null
+++ b/test/lisp/progmodes/flymake-resources/some-problems.h
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+strange;
+
+sint main();
diff --git a/test/lisp/progmodes/flymake-tests.el
b/test/lisp/progmodes/flymake-tests.el
index e313846..515aa08 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -121,14 +121,34 @@ SEVERITY-PREDICATE is used to setup
(flymake-tests--with-flymake
("errors-and-warnings.c")
(flymake-goto-next-error)
+ (should (eq 'flymake-error (face-at-point)))
+ (flymake-goto-next-error)
(should (eq 'flymake-note (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)
+ (should (eq 'flymake-error (face-at-point)))
+ (flymake-goto-next-error)
+ (should (eq 'flymake-warning (face-at-point)))
+ (flymake-goto-next-error)
+ (should (eq 'flymake-warning (face-at-point)))
+ (let ((flymake-wrap-around nil))
+ (should-error (flymake-goto-next-error nil nil t))) ))
+
+(ert-deftest included-c-header-files ()
+ "Test inclusion of .h header files."
+ (skip-unless (and (executable-find "gcc") (executable-find "make")))
+ (flymake-tests--with-flymake
+ ("some-problems.h")
+ (flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point)))
(let ((flymake-wrap-around nil))
+ (should-error (flymake-goto-next-error nil nil t))) )
+ (flymake-tests--with-flymake
+ ("no-problems.h")
+ (let ((flymake-wrap-around nil))
(should-error (flymake-goto-next-error nil nil t))) ))
(defmacro flymake-tests--assert-set (set
- [Emacs-diffs] scratch/flymake-refactor 3dfe11c 28/52: Simplify flymake logging and erroring., (continued)
- [Emacs-diffs] scratch/flymake-refactor 3dfe11c 28/52: Simplify flymake logging and erroring., João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 9329265 40/52: Treat flymake errors as just another type of diagnostic, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 38c7d4f 41/52: Remove old flymake-display-err-menu-for-current-line, it's useless, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 7a22358 34/52: A couple of new flymake backends for emacs-lisp-mode, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 9d93d46 42/52: New flymake fringe bitmaps, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 4e2cbaa 32/52: Fancy mode-line construct for flymake-mode, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 54ec5eb 47/52: Improve use of flymake-no-changes-timeout, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 95c126c 46/52: flymake-diagnostic-types-alist now uses flymake-category, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 1d58e32 39/52: Fix flymake-wrap-around for buffers with no errors, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 1116aa7 43/52: * lisp/progmodes/flymake-ui.el (flymake-mode-map): Bind "M-n" and "M-p", João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 7d3d3d3 38/52: Fix flymake problems when checking C header files,
João Távora <=
- [Emacs-diffs] scratch/flymake-refactor 87191ab 51/52: Hook Flymake onto proper checkdoc and byte-compile interfaces, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 3b6c736 37/52: Start rewriting flymake manual, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 51533c3 49/52: Capitalize "Flymake" in docstrings and comments, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor fea31e2 07/52: Rename many flymake-proc.el symbols with internal "--" prefixes, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 0b46ab8 45/52: Make flymake-diagnostic-functions a special hook, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 51a2b7b 52/52: Integrate elisp checkers into elisp-mode.el directly, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 26f1e0c 27/52: Replace flymake-backends with flymake-diagnostic-functions, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 6bf3a42 06/52: Move symbols in flymake-proc.el to separate namespace, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor 22c4b9b 44/52: First batch of minor flymake cleanup agreed to with Stefan, João Távora, 2017/10/01
- [Emacs-diffs] scratch/flymake-refactor b327de6 48/52: Flymake backends can report multiple times per check, João Távora, 2017/10/01