From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: joaotavora@gmail.com (=?utf-8?B?Sm/Do28gVMOhdm9yYQ==?=) Newsgroups: gmane.emacs.devel Subject: Re: New Flymake rewrite in emacs-26 Date: Wed, 11 Oct 2017 14:41:46 +0100 Message-ID: <87k2017qed.fsf@gmail.com> References: <8760bwz5qf.fsf@gmail.com> <83infw1dkz.fsf@gnu.org> <87efqbb35x.fsf@gmail.com> <831smbqe70.fsf@gnu.org> <87tvz79h0s.fsf@gmail.com> <83wp43ov7s.fsf@gnu.org> <87bmlf9dh3.fsf@gmail.com> <83tvz7ot1o.fsf@gnu.org> <87y3oj7x60.fsf@gmail.com> <87a80y8s3s.fsf@gmail.com> <831smaoubw.fsf@gnu.org> <87y3oh7v16.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1507729355 22806 195.159.176.226 (11 Oct 2017 13:42:35 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 11 Oct 2017 13:42:35 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.60 (gnu/linux) Cc: npostavs@users.sourceforge.net, lele@metapensiero.it, mvoteiza@udel.edu, monnier@iro.umontreal.ca, Eli Zaretskii , sdl.web@gmail.com To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 11 15:42:29 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2HH7-00044r-T4 for ged-emacs-devel@m.gmane.org; Wed, 11 Oct 2017 15:42:18 +0200 Original-Received: from localhost ([::1]:41131 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2HHF-00087g-5A for ged-emacs-devel@m.gmane.org; Wed, 11 Oct 2017 09:42:25 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33505) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2HGn-0007wb-Eh for emacs-devel@gnu.org; Wed, 11 Oct 2017 09:41:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2HGm-0005eW-CJ for emacs-devel@gnu.org; Wed, 11 Oct 2017 09:41:57 -0400 Original-Received: from mail-wm0-x229.google.com ([2a00:1450:400c:c09::229]:51626) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2HGi-0005cd-Cg; Wed, 11 Oct 2017 09:41:52 -0400 Original-Received: by mail-wm0-x229.google.com with SMTP id f4so4974632wme.0; Wed, 11 Oct 2017 06:41:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:in-reply-to:references:user-agent:date :message-id:mime-version:content-transfer-encoding; bh=AAsSkDxPyz/7MFsBMAnb1wL61XvNLJ05Kc0Ni0O+VJA=; b=np5sl3GtXTih/7iQ4/P60oR1jbRvQin3sCuebhZjYO8xdbq7mDyPZnecy2pg5HjEDF eG08ZW3QNBN6QuRO9mReY4VFBzWKVYJDhJu/mdW63tYyGIm+exmyI67NDBwfPUMrAXOy DzoRFdTc9HJ5dp5LtUFZNkPfQOZjcU7gBY4mqUWXGYNRCkP5Y9POVdU2l1pryxcYYlPL HIiSkly3JBZdHcY23mPrCbP+2imTsArd96KXy/sCSfcEcb4SE4gDzQIPntRiIG6GBCz4 N1rGokhxClDUIF1quZvGg+1xblQOcxEEx4r4PwAuXd+c1VAC+Vc2DAlS5OjgEyBs5GDX tIww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references :user-agent:date:message-id:mime-version:content-transfer-encoding; bh=AAsSkDxPyz/7MFsBMAnb1wL61XvNLJ05Kc0Ni0O+VJA=; b=re4j6xeAmCTklSm/1qXjBrlrMZ9rWutQ+frqTgC6J63BiOsQF9yFsKFBnMCzXQFch8 N2BdklHv7y5OhY7HaA1d6jvrZFUGoA1ZRhpCa59vDmQYpgsUBQMWAzV4whmQIIlSoGK1 YPcR0o5HjbaWuojnPsCNr18t0wuPN2HKyVlrSy6ezYacx/T0fX/e6zrORKhmGhArIpaq PuoOCF7xCce+4v2SXfipHHk0HyLXgZL9nMTzmnJ2vCabv6hF1oxtnmCVRTe7WYKmGzbw /0NVMwOICA1BoPOgxRn/CiYLoyMusaK4YYBNKKuCMRV6hY8pjs5TnHUR781/TPE41eV0 NWZg== X-Gm-Message-State: AMCzsaWb5M7KBGEKv3tSl92U5SpNUE7yZiOQWiy8a95kPsj0jIa+ZTQG 411JWYS2n7d/7WaF9Dyv6cg= X-Google-Smtp-Source: AOwi7QCCbSqeWZYw7dBFmXLE4jfPKqX2FmgJlbMBF7p8x+Yq5gVkhAV7je2vKOqoWiLgI9LgiTmYPA== X-Received: by 10.223.161.74 with SMTP id r10mr14609116wrr.8.1507729309990; Wed, 11 Oct 2017 06:41:49 -0700 (PDT) Original-Received: from lolita.yourcompany.com (188.139.62.94.rev.vodafone.pt. [94.62.139.188]) by smtp.gmail.com with ESMTPSA id l19sm10113430wre.26.2017.10.11.06.41.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 11 Oct 2017 06:41:49 -0700 (PDT) In-Reply-To: <87y3oh7v16.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Wed, 11 Oct 2017 13:01:41 +0100") X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::229 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:219376 Archived-At: joaotavora@gmail.com (Jo=C3=A3o T=C3=A1vora) writes: > No, I was aiming for something more generic that includes at least Emacs > and perhaps other GNU projects. FWIW, here's what I hacked up so far. Seems to work OK in two GNU projects: Emacs and Hello (after ./configure, of course). Probably flawed, but it's a start. Feedback welcome. To test, just load this file and M-x flymake-mode in a C file. Another option, as suggested previously, is to have a special Makefile target (that'll need reconfiguring for each project, though). Jo=C3=A3o ;;; flymake-gcc.el --- naive gcc Flymake backend -*- lexical-binding: t; -*- (defvar flymake-gcc-program "gcc" "GCC program") (defun flymake--gcc-heroic-unescape (string) (with-temp-buffer (let ((error-buffer (current-buffer))) (with-temp-buffer (cond ((zerop ;; I suspect "shell-command" makes windows even when called ;; from lisp. (save-window-excursion (shell-command (format "%s -Q --batch --eval \"%s\" -- %s" (expand-file-name invocation-name invocation-directory) "(mapc 'print (nthcdr 4 command-line-args))" string) (current-buffer) error-buffer))) (goto-char (point-min)) (cl-loop with eof =3D (make-symbol "eof") for form =3D (condition-case _err (read (current-buffer)) (error eof)) while (not (eq form eof)) collect form)) (t (with-current-buffer error-buffer (error (buffer-string))))))))) (defvar flymake-gcc-flags 'flymake-gcc-guess-flags "A list of flags passed to GCC. Alternatively, a symbol naming a function called with no arguments that should produce this list of flags, or error if it cannot do so.") (defvar flymake-gcc-extra-flags '("-Wextra" "-Wall") "A list of extra flags passed to GCC.") (defvar-local flymake--gcc-cached-flags nil "Internal variable for `flymake-gcc-guess-flags'") (defun flymake-gcc-guess-flags (&optional trash-cache) "Guess GCC flags for compiling current buffer " (interactive "P") (unless (executable-find "make") (error "Cannot find a suitable make")) (when trash-cache (setq flymake--gcc-cached-flags nil)) (catch 'retval (unless (buffer-file-name) ;; don't error and don't cache, so that when the buffer is saved ;; we get another chance. (throw 'retval nil)) (when-let* ((makefile-dir (locate-dominating-file default-directory "Makefile")) (makefile (expand-file-name "Makefile" makefile-dir)) (mtime (file-attribute-modification-time (file-attributes makefile)))) (cond ((equal (list makefile mtime) (cdr flymake--gcc-cached-flags)) (when (called-interactively-p 'interactive) (message "cached hit for flags for this buffer: %s" (car flymake--gcc-cached-flags))) (throw 'retval (car flymake--gcc-cached-flags))) (t (let* ((sans-nothing (file-name-nondirectory (file-name-sans-extension (buffer-file-name)))) (blob (shell-command-to-string (format "make -C %s -f %s --just-print %s.o" makefile-dir makefile sans-nothing))) (match (string-match (format "gcc[[:space:]]+\\(\\(?:-.*\\)*\\)%s" sans-nothing) blob)) (flag-string (and match (match-string 1 blob))) (flags (and flag-string (flymake--gcc-heroic-unescape flag-string)))) (when (or flags (string=3D "" flag-string)) (setq flymake--gcc-cached-flags (list flags makefile mtime)) (when (called-interactively-p 'interactive) (message "cached miss for flags for this buffer: %s" flags)) (throw 'retval flags)))))) (error "Could not guess gcc flags"))) (defvar-local flymake--gcc-proc nil "Internal variable for `flymake-gcc'") (defun flymake-gcc (report-fn &rest _args) "Flymake backend for GCC" (unless (executable-find flymake-gcc-program) (error "Cannot find a suitable gcc")) (when (process-live-p flymake--gcc-proc) (kill-process flymake--gcc-proc)) (let ((source (current-buffer))) (save-restriction (widen) (setq flymake--gcc-proc (make-process :name "gcc-flymake" :buffer (generate-new-buffer "*gcc-flymake*") :command `(,flymake-gcc-program "-fsyntax-only" ,@flymake-gcc-extra-flags ,@(if (symbolp flymake-gcc-flags) (funcall flymake-gcc-flags) flymake-gcc-flags) "-x" "c" "-") :noquery t :connection-type 'pipe :sentinel (lambda (p _ev) (when (eq 'exit (process-status p)) (unwind-protect (when (eq p flymake--gcc-proc) (with-current-buffer (process-buffer p) (goto-char (point-min)) (cl-loop while (search-forward-regexp "^:\\([0-9]+\\):\\([0-9]+\\): \\(.*= \\): \\(.*\\)$" nil t) for msg =3D (match-string 4) for (beg . end) =3D (flymake-diag-region source (string-to-number (match-string 1)) (string-to-number (match-string 2))) for type =3D (assoc-default (match-string 3) '(("error" . :error) ("note" . :note) ("warning" . :warning)) #'string-match) collect (flymake-make-diagnostic source beg end t= ype msg) into diags finally (funcall report-fn diags)))) ;; (display-buffer (process-buffer p)) ; use this instea= d of the next one for debug (kill-buffer (process-buffer p)) )) ))) (process-send-region flymake--gcc-proc (point-min) (point-max)) (process-send-eof flymake--gcc-proc)))) (defun flymake--setup-gcc-flymake () (add-hook 'flymake-diagnostic-functions 'flymake-gcc nil t)) (add-hook 'c-mode-hook 'flymake--setup-gcc-flymake) ;;; flymake-gcc.el ends here