Switch to recommended form of GPLv3 permissions notice.
[bpt/emacs.git] / lisp / progmodes / flymake.el
index b37be18..5412e2b 100644 (file)
@@ -1,18 +1,19 @@
 ;;; flymake.el -- a universal on-the-fly syntax checker
 
-;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+;;   Free Software Foundation, Inc.
 
-;; Author:  Pavel Kobiakov <pk_at_work@yahoo.com>
-;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com>
+;; Author:  Pavel Kobyakov <pk_at_work@yahoo.com>
+;; Maintainer: Pavel Kobyakov <pk_at_work@yahoo.com>
 ;; Version: 0.3
 ;; Keywords: c languages tools
 
 ;; 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 2, 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
@@ -20,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:
 ;;
@@ -117,6 +116,30 @@ Zero-length substrings at the beginning and end of the list are omitted."
       'line-end-position
     (lambda (&optional arg) (save-excursion (end-of-line arg) (point)))))
 
+(defun flymake-posn-at-point-as-event (&optional position window dx dy)
+  "Return pixel position of top left corner of glyph at POSITION,
+relative to top left corner of WINDOW, as a mouse-1 click
+event (identical to the event that would be triggered by clicking
+mouse button 1 at the top left corner of the glyph).
+
+POSITION and WINDOW default to the position of point in the
+selected window.
+
+DX and DY specify optional offsets from the top left of the glyph."
+  (unless window (setq window (selected-window)))
+  (unless position (setq position (window-point window)))
+  (unless dx (setq dx 0))
+  (unless dy (setq dy 0))
+
+  (let* ((pos (posn-at-point position window))
+         (x-y (posn-x-y pos))
+         (edges (window-inside-pixel-edges window))
+         (win-x-y (window-pixel-edges window)))
+    ;; adjust for window edges
+    (setcar (nthcdr 2 pos)
+            (cons (+ (car x-y) (car  edges) (- (car win-x-y))  dx)
+                  (+ (cdr x-y) (cadr edges) (- (cadr win-x-y)) dy)))
+    (list 'mouse-1 pos)))
 
 (defun flymake-popup-menu (menu-data)
   "Pop up the flymake menu at point, using the data MENU-DATA.
@@ -134,7 +157,7 @@ MENU-DATA is a list of error and warning messages returned by
        (popup-menu (flymake-make-xemacs-menu menu-data)
                     (make-event 'button-press fake-event-props)))
     (x-popup-menu (if (eval-when-compile (fboundp 'posn-at-point))
-                      (posn-at-point)
+                      (flymake-posn-at-point-as-event)
                     (list (flymake-get-point-pixel-pos) (selected-window)))
                   (flymake-make-emacs-menu menu-data))))
 
@@ -246,7 +269,8 @@ are the string substitutions (see `format')."
     ("\\.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)
@@ -300,11 +324,6 @@ Return nil if we cannot, non-nil if we can."
   (or (nth 2 (flymake-get-file-name-mode-and-masks file-name))
       'flymake-get-real-file-name))
 
-(defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..")
-  "Dirs to look for buildfile."
-  :group 'flymake
-  :type '(repeat (string)))
-
 (defvar flymake-find-buildfile-cache (flymake-makehash 'equal))
 
 (defun flymake-get-buildfile-from-cache (dir-name)
@@ -321,19 +340,15 @@ 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* ((dirs flymake-buildfile-dirs)
-             (buildfile-dir          nil)
-             (found                  nil))
-        (while (and (not found) dirs)
-          (setq buildfile-dir (concat source-dir-name (car dirs)))
-          (when (file-exists-p (expand-file-name buildfile-name buildfile-dir))
-            (setq found t))
-          (setq dirs (cdr dirs)))
-        (if found
+      (let* ((file (locate-dominating-file
+                    source-dir-name
+                    (concat "\\`" (regexp-quote buildfile-name) "\\'"))))
+        (if file
             (progn
-              (flymake-log 3 "found buildfile at %s/%s" buildfile-dir buildfile-name)
-              (flymake-add-buildfile-to-cache source-dir-name buildfile-dir)
-              buildfile-dir)
+              (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
             (flymake-log 3 "buildfile for %s not found" source-dir-name)
             nil)))))
@@ -900,14 +915,16 @@ 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]*\\(.+\\)"
+     (" *\\(\\[javac\\] *\\)?\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)"
       2 4 nil 5))
    ;; compilation-error-regexp-alist)
    (flymake-reformat-err-line-patterns-from-compile-el compilation-error-regexp-alist-alist))
-  "Patterns for matching error/warning lines.
-\(REGEXP FILE-IDX LINE-IDX ERR-TEXT-IDX).
+  "Patterns for matching error/warning lines.  Each pattern has the form
+\(REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX).
 Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns
 from compile.el")
 
@@ -1252,10 +1269,9 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
 (defun flymake-goto-file-and-line (file line)
   "Try to get buffer for FILE and goto line LINE in it."
   (if (not (file-exists-p file))
-      (flymake-log 1 "file %s does not exists" file)
-    (progn
-      (find-file file)
-      (goto-line line))))
+      (flymake-log 1 "File %s does not exist" file)
+    (find-file file)
+    (goto-line line)))
 
 ;; flymake minor mode declarations
 (defvar flymake-mode-line nil)
@@ -1601,7 +1617,7 @@ Return full-name.  Names are real, not patched."
                       buildfile-name source-file-name)))))
 
 (defun flymake-init-create-temp-source-and-master-buffer-copy (get-incl-dirs-f create-temp-f master-file-masks include-regexp)
-  "Find master file (or buffer), create it's copy along with a copy of the source file."
+  "Find master file (or buffer), create its copy along with a copy of the source file."
   (let* ((source-file-name       buffer-file-name)
         (temp-source-file-name  (flymake-init-create-temp-buffer-copy create-temp-f))
         (master-and-temp-master (flymake-create-master-file
@@ -1710,6 +1726,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))