Add 2011 to FSF/AIST copyright years.
[bpt/emacs.git] / lisp / progmodes / flymake.el
index 6de464b..da28a2e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; flymake.el -- a universal on-the-fly syntax checker
 
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 ;;   Free Software Foundation, Inc.
 
 ;; Author:  Pavel Kobyakov <pk_at_work@yahoo.com>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,9 +21,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 ;;
@@ -81,7 +79,7 @@
       'float-time
     (if (featurep 'xemacs)
        (lambda ()
-         (multiple-value-bind (s0 s1 s2) (current-time)
+         (multiple-value-bind (s0 s1 s2) (values-list (current-time))
            (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2)))))))
 
 (defalias 'flymake-replace-regexp-in-string
@@ -265,13 +263,18 @@ are the string substitutions (see `format')."
 
 (make-variable-buffer-local 'flymake-output-residual)
 
+(defgroup flymake nil
+  "A universal on-the-fly syntax checker."
+  :version "23.1"
+  :group 'tools)
+
 (defcustom flymake-allowed-file-name-masks
-  '(("\\.c\\'" flymake-simple-make-init)
-    ("\\.cpp\\'" flymake-simple-make-init)
+  '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'" flymake-simple-make-init)
     ("\\.xml\\'" flymake-xml-init)
     ("\\.html?\\'" flymake-xml-init)
     ("\\.cs\\'" flymake-simple-make-init)
-    ("\\.pl\\'" flymake-perl-init)
+    ("\\.p[ml]\\'" flymake-perl-init)
+    ("\\.php[345]?\\'" flymake-php-init)
     ("\\.h\\'" flymake-master-make-header-init flymake-master-cleanup)
     ("\\.java\\'" flymake-simple-make-java-init flymake-simple-java-cleanup)
     ("[0-9]+\\.tex\\'" flymake-master-tex-init flymake-master-cleanup)
@@ -287,7 +290,7 @@ are the string substitutions (see `format')."
     ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 ))
     ;; ("\\.tex\\'" 1)
     )
-  "*Files syntax checking is allowed for."
+  "Files syntax checking is allowed for."
   :group 'flymake
   :type '(repeat (string symbol symbol symbol)))
 
@@ -341,13 +344,10 @@ Return nil if we cannot, non-nil if we can."
 Buildfile includes Makefile, build.xml etc.
 Return its file name if found, or nil if not found."
   (or (flymake-get-buildfile-from-cache source-dir-name)
-      (let* ((file (locate-dominating-file
-                    source-dir-name
-                    (concat "\\`" (regexp-quote buildfile-name) "\\'"))))
+      (let* ((file (locate-dominating-file source-dir-name buildfile-name)))
         (if file
             (progn
               (flymake-log 3 "found buildfile at %s" file)
-              (setq file (file-name-directory file))
               (flymake-add-buildfile-to-cache source-dir-name file)
               file)
           (progn
@@ -383,7 +383,7 @@ Return t if so, nil if not."
 
 (defun flymake-find-possible-master-files (file-name master-file-dirs masks)
   "Find (by name and location) all possible master files.
-Master files are .cpp and .c for and .h.  Files are searched for
+Master files include .cpp and .c for .h.  Files are searched for
 starting from the .h directory and max max-level parent dirs.
 File contents are not checked."
   (let* ((dirs master-file-dirs)
@@ -433,9 +433,11 @@ to the beginning of the list (File.h -> File.cpp moved to top)."
         source-file-name patched-source-file-name
         include-dirs regexp)
   "Check if MASTER-FILE-NAME is a master file for SOURCE-FILE-NAME.
-For .cpp master file this means it includes SOURCE-FILE-NAME (.h).
 If yes, patch a copy of MASTER-FILE-NAME to include PATCHED-SOURCE-FILE-NAME
 instead of SOURCE-FILE-NAME.
+
+For example, foo.cpp is a master file if it includes foo.h.
+
 Whether a buffer for MATER-FILE-NAME exists, use it as a source
 instead of reading master file from disk."
   (let* ((source-file-nondir (file-name-nondirectory source-file-name))
@@ -563,10 +565,8 @@ Find master file, patch and save it."
        nil))))
 
 (defun flymake-save-buffer-in-file (file-name)
-  (save-restriction
-    (widen)
-    (make-directory (file-name-directory file-name) 1)
-    (write-region (point-min) (point-max) file-name nil 566))
+  (make-directory (file-name-directory file-name) 1)
+  (write-region nil nil file-name nil 566)
   (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name))
 
 (defun flymake-save-string-to-file (file-name data)
@@ -586,7 +586,7 @@ It's flymake process filter."
 
     (flymake-log 3 "received %d byte(s) of output from process %d"
                  (length output) (process-id process))
-    (when source-buffer
+    (when (buffer-live-p source-buffer)
       (with-current-buffer source-buffer
         (flymake-parse-output-and-residual output)))))
 
@@ -644,7 +644,7 @@ It's flymake process filter."
            (flymake-report-status "" "")       ; PASSED
          (if (not flymake-check-was-interrupted)
              (flymake-report-fatal-status "CFGERR"
-                                          (format "Configuration error has occured while running %s" command))
+                                          (format "Configuration error has occurred while running %s" command))
            (flymake-report-status nil ""))) ; "STOPPED"
       (flymake-report-status (format "%d/%d" err-count warn-count) ""))))
 
@@ -790,15 +790,15 @@ Return t if it has at least one flymake overlay, nil if no overlay."
     has-flymake-overlays))
 
 (defface flymake-errline
-  ;;+   '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
-  ;;+   '((((class color)) (:underline "OrangeRed"))
-  '((((class color)) (:background "LightPink"))
+  '((((class color) (background dark)) (:background "Firebrick4"))
+    (((class color) (background light)) (:background "LightPink"))
     (t (:bold t)))
   "Face used for marking error lines."
   :group 'flymake)
 
 (defface flymake-warnline
-  '((((class color)) (:background "LightBlue2"))
+  '((((class color) (background dark)) (:background "DarkBlue"))
+    (((class color) (background light)) (:background "LightBlue2"))
     (t (:bold t)))
   "Face used for marking warning lines."
   :group 'flymake)
@@ -806,7 +806,8 @@ Return t if it has at least one flymake overlay, nil if no overlay."
 (defun flymake-highlight-line (line-no line-err-info-list)
   "Highlight line LINE-NO in current buffer.
 Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
-  (goto-line line-no)
+  (goto-char (point-min))
+  (forward-line (1- line-no))
   (let* ((line-beg (flymake-line-beginning-position))
         (line-end (flymake-line-end-position))
         (beg      line-beg)
@@ -857,11 +858,9 @@ Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
                                       (flymake-ler-file line-err-info)))
        (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name))
 
-       (if (flymake-same-files real-file-name source-file-name)
-           (setq line-err-info (flymake-ler-set-file line-err-info nil))
-         (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))))
-
-       (setq err-info-list (flymake-add-err-info err-info-list line-err-info)))
+       (when (flymake-same-files real-file-name source-file-name)
+         (setq line-err-info (flymake-ler-set-file line-err-info nil))
+         (setq err-info-list (flymake-add-err-info err-info-list line-err-info))))
       (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no"))
       (setq idx (1+ idx)))
     err-info-list))
@@ -916,6 +915,8 @@ Convert it to flymake internal format."
       1 3 nil 4)
      ;; perl
      ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1)
+     ;; PHP
+     ("\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" 2 3 nil 1)
      ;; LaTeX warnings (fileless) ("\\(LaTeX \\(Warning\\|Error\\): .*\\) on input line \\([0-9]+\\)" 20 3 nil 1)
      ;; ant/javac
      (" *\\(\\[javac\\] *\\)?\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)"
@@ -1151,7 +1152,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
          (when dir
            (let ((default-directory dir))
              (flymake-log 3 "starting process on dir %s" default-directory)))
-         (setq process (apply 'start-process "flymake-proc" (current-buffer) cmd args))
+         (setq process (apply 'start-file-process
+                              "flymake-proc" (current-buffer) cmd args))
          (set-process-sentinel process 'flymake-process-sentinel)
          (set-process-filter process 'flymake-process-filter)
           (push process flymake-processes)
@@ -1270,7 +1272,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
   (if (not (file-exists-p file))
       (flymake-log 1 "File %s does not exist" file)
     (find-file file)
-    (goto-line line)))
+    (goto-char (point-min))
+    (forward-line (1- line))))
 
 ;; flymake minor mode declarations
 (defvar flymake-mode-line nil)
@@ -1444,7 +1447,8 @@ With arg, turn Flymake mode on if and only if arg is positive."
 
 (defun flymake-goto-line (line-no)
   "Go to line LINE-NO, then skip whitespace."
-  (goto-line line-no)
+  (goto-char (point-min))
+  (forward-line (1- line-no))
   (flymake-skip-whitespace))
 
 (defun flymake-goto-next-error ()
@@ -1698,9 +1702,10 @@ Use CREATE-TEMP-F for creating temp copy."
 
 ;;;; .h/make specific
 (defun flymake-master-make-header-init ()
-  (flymake-master-make-init 'flymake-get-include-dirs
-                           '("\\.cpp\\'" "\\.c\\'")
-                           "[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
+  (flymake-master-make-init
+   'flymake-get-include-dirs
+   '("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'")
+   "[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
 
 ;;;; .java/make specific
 (defun flymake-simple-make-java-init ()
@@ -1725,6 +1730,15 @@ Use CREATE-TEMP-F for creating temp copy."
                        (file-name-directory buffer-file-name))))
     (list "perl" (list "-wc " local-file))))
 
+;;;; php-specific init-cleanup routines
+(defun flymake-php-init ()
+  (let* ((temp-file   (flymake-init-create-temp-buffer-copy
+                       'flymake-create-temp-inplace))
+        (local-file  (file-relative-name
+                       temp-file
+                       (file-name-directory buffer-file-name))))
+    (list "php" (list "-f" local-file "-l"))))
+
 ;;;; tex-specific init-cleanup routines
 (defun flymake-get-tex-args (file-name)
   ;;(list "latex" (list "-c-style-errors" file-name))