/[emacs]/emacs/lisp/progmodes/flymake.el
ViewVC logotype

Diff of /emacs/lisp/progmodes/flymake.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by rms, Thu Nov 25 16:33:53 2004 UTC revision 1.6 by rms, Thu Nov 25 16:43:32 2004 UTC
# Line 43  Line 43 
43    
44  ;;;; [[ cross-emacs compatibility routines  ;;;; [[ cross-emacs compatibility routines
45  (defvar flymake-emacs  (defvar flymake-emacs
46      (cond    (cond
47          ((string-match "XEmacs" emacs-version)  'xemacs)     ((string-match "XEmacs" emacs-version)  'xemacs)
48          (t                                      'emacs)     (t                                      'emacs))
49          )    "Currently used Emacs flavor")
50      "Currently used emacs flavor"  
51  )  (defun flymake-makehash (&optional test)
52      (cond
53  (defun flymake-makehash(&optional test)     ((equal flymake-emacs 'xemacs)  (if test (make-hash-table :test test) (make-hash-table)))
54      (cond     (t                              (makehash test))))
55          ((equal flymake-emacs 'xemacs)  (if test (make-hash-table :test test) (make-hash-table)))  
56          (t                              (makehash test))          (defun flymake-time-to-float (&optional tm)
57      )    "Convert `current-time` to a float number of seconds."
58  )    (multiple-value-bind (s0 s1 s2) (or tm (current-time))
59        (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2))))
60  (defun flymake-time-to-float(&optional tm)  
61          "Convert `current-time` to a float number of seconds."  (defun flymake-float-time ()
62          (multiple-value-bind (s0 s1 s2) (or tm (current-time))    (cond
63            (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2)))     ((equal flymake-emacs 'xemacs)  (flymake-time-to-float (current-time)))
64  )     (t                              (float-time))))
65  (defun flymake-float-time()  
66      (cond  (defun flymake-replace-regexp-in-string (regexp rep str)
67          ((equal flymake-emacs 'xemacs)  (flymake-time-to-float (current-time)))    (cond
68          (t                              (float-time))     ((equal flymake-emacs 'xemacs)  (replace-in-string str regexp rep))
69      )     (t                              (replace-regexp-in-string regexp rep str))))
70  )  
71    (defun flymake-split-string-remove-empty-edges (str pattern)
72  (defun flymake-replace-regexp-in-string(regexp rep str)    "Split, then remove first and/or last in case it's empty."
73      (cond    (let* ((splitted (split-string str pattern)))
74          ((equal flymake-emacs 'xemacs)  (replace-in-string str regexp rep))      (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0))))
75          (t                              (replace-regexp-in-string regexp rep str))          (setq splitted (cdr splitted)))
76          )      (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted))))))
77  )          (setq splitted (reverse (cdr (reverse splitted)))))
78        splitted))
 (defun flymake-split-string-remove-empty-edges(str pattern)  
     "split, then remove first and/or last in case it's empty"  
         (let* ((splitted (split-string str pattern)))  
             (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0))))  
                         (setq splitted (cdr splitted))  
                 )  
             (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted))))))  
                         (setq splitted (reverse (cdr (reverse splitted))))  
                 )  
                 splitted  
     )  
 )  
79    
80  (defun flymake-split-string(str pattern)  (defalias 'flymake-split-string 'flymake-split-string-remove-empty-edges)
     (cond  
         ((equal flymake-emacs 'xemacs)  (flymake-split-string-remove-empty-edges str pattern))  
         (t                              (flymake-split-string-remove-empty-edges str pattern))  
     )  
 )  
81    
82  (defun flymake-get-temp-dir()  (defun flymake-get-temp-dir()
83      (cond    (cond
84          ((equal flymake-emacs 'xemacs)  (temp-directory))     ((equal flymake-emacs 'xemacs)  (temp-directory))
85          (t                              temporary-file-directory)))     (t                              temporary-file-directory)))
86    
87  (defun flymake-line-beginning-position ()  (defun flymake-line-beginning-position ()
88      (save-excursion    (save-excursion
89          (beginning-of-line)      (beginning-of-line)
90          (point)))      (point)))
91    
92  (defun flymake-line-end-position ()  (defun flymake-line-end-position ()
93      (save-excursion    (save-excursion
94          (end-of-line)      (end-of-line)
95          (point)))      (point)))
96    
97  (defun flymake-popup-menu(pos menu-data)  (defun flymake-popup-menu (pos menu-data)
98      (cond    (cond
99         ((equal flymake-emacs 'xemacs)     ((equal flymake-emacs 'xemacs)
100              (let* ((x-pos       (nth 0 (nth 0 pos)))      (let* ((x-pos       (nth 0 (nth 0 pos)))
101                     (y-pos       (nth 1 (nth 0 pos)))             (y-pos       (nth 1 (nth 0 pos)))
102                     (fake-event-props  '(button 1 x 1 y 1)))             (fake-event-props  '(button 1 x 1 y 1)))
103                  (setq fake-event-props (plist-put fake-event-props 'x x-pos))        (setq fake-event-props (plist-put fake-event-props 'x x-pos))
104                  (setq fake-event-props (plist-put fake-event-props 'y y-pos))        (setq fake-event-props (plist-put fake-event-props 'y y-pos))
105                  (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props))        (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props))
106              )        )
107         )      )
108         (t (x-popup-menu pos (flymake-make-emacs-menu menu-data)))))     (t (x-popup-menu pos (flymake-make-emacs-menu menu-data)))))
109    
110  (defun flymake-make-emacs-menu(menu-data)  (defun flymake-make-emacs-menu (menu-data)
111      (let* ((menu-title     (nth 0 menu-data))    (let* ((menu-title     (nth 0 menu-data))
112                     (menu-items     (nth 1 menu-data))           (menu-items     (nth 1 menu-data))
113                     (menu-commands  nil))           (menu-commands  nil))
114    
115          (setq menu-commands (mapcar (lambda (foo)      (setq menu-commands (mapcar (lambda (foo)
116                                        (cons (nth 0 foo) (nth 1 foo)))                                    (cons (nth 0 foo) (nth 1 foo)))
117                                      menu-items))                                  menu-items))
118                  (list menu-title (cons "" menu-commands))))      (list menu-title (cons "" menu-commands))))
119    
120  (defun flymake-nop ())  (defun flymake-nop ())
121    
122  (defun flymake-make-xemacs-menu (menu-data)  (defun flymake-make-xemacs-menu (menu-data)
123      (let* ((menu-title     (nth 0 menu-data))    (let* ((menu-title     (nth 0 menu-data))
124             (menu-items     (nth 1 menu-data))           (menu-items     (nth 1 menu-data))
125             (menu-commands  nil))           (menu-commands  nil))
126          (setq menu-commands (mapcar (lambda (foo)      (setq menu-commands (mapcar (lambda (foo)
127                                        (vector (nth 0 foo) (or (nth 1 foo) '(flymake-nop)) t))                                    (vector (nth 0 foo) (or (nth 1 foo) '(flymake-nop)) t))
128                                      menu-items))                                  menu-items))
129          (cons menu-title menu-commands)))      (cons menu-title menu-commands)))
130    
131  (defun flymake-xemacs-window-edges(&optional window)  (defun flymake-xemacs-window-edges (&optional window)
132      (let ((edges  (window-pixel-edges window))    (let ((edges  (window-pixel-edges window))
133            tmp)          tmp)
134          (setq tmp edges)      (setq tmp edges)
135          (setcar tmp (/ (car tmp) (face-width 'default)))      (setcar tmp (/ (car tmp) (face-width 'default)))
136          (setq tmp (cdr tmp))      (setq tmp (cdr tmp))
137          (setcar tmp (/ (car tmp) (face-height 'default)))      (setcar tmp (/ (car tmp) (face-height 'default)))
138          (setq tmp (cdr tmp))      (setq tmp (cdr tmp))
139          (setcar tmp (/ (car tmp) (face-width 'default)))      (setcar tmp (/ (car tmp) (face-width 'default)))
140          (setq tmp (cdr tmp))      (setq tmp (cdr tmp))
141          (setcar tmp (/ (car tmp) (face-height 'default)))      (setcar tmp (/ (car tmp) (face-height 'default)))
142          edges      edges))
143      )  
144  )  (defun flymake-current-row ()
145      "Return current row number in current frame."
146  (defun flymake-current-row()    (cond
147      "return current row in current frame"     ((equal flymake-emacs 'xemacs)  (count-lines (window-start) (point)))
148      (cond     (t                              (+ (car (cdr (window-edges))) (count-lines (window-start) (point))))
149         ((equal flymake-emacs 'xemacs)  (count-lines (window-start) (point)))     )
150         (t                              (+ (car (cdr (window-edges))) (count-lines (window-start) (point))))    )
151      )  
152  )  (defun flymake-selected-frame ()
153      (cond
154  (defun flymake-selected-frame()     ((equal flymake-emacs 'xemacs)  (selected-window))
155      (cond     (t                              (selected-frame))
156         ((equal flymake-emacs 'xemacs)  (selected-window))     )
157         (t                              (selected-frame))    )
     )  
 )  
158    
159  ;;;; ]]  ;;;; ]]
160    
161  (defcustom flymake-log-level -1  (defcustom flymake-log-level -1
162      "Logging level, only messages with level > flymake-log-level will not be logged    "Logging level, only messages with level > flymake-log-level will not be logged
163  -1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG"  -1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG"
164      :group 'flymake    :group 'flymake
165      :type 'integer)    :type 'integer)
166    
167  (defun flymake-log (level text &rest args)  (defun flymake-log (level text &rest args)
168      "Log a message with optional arguments."    "Log a message with optional arguments."
169      (if (<= level flymake-log-level)    (if (<= level flymake-log-level)
170          (let* ((msg (apply 'format text args)))        (let* ((msg (apply 'format text args)))
171              (message msg)          (message msg)
172              ;(with-temp-buffer          ;;(with-temp-buffer
173              ;    (insert msg)          ;;    (insert msg)
174              ;   (insert "\n")          ;;   (insert "\n")
175              ;   (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t)  ; make log file name customizable          ;;   (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t)  ; make log file name customizable
176              ;)          ;;)
177          )))          )))
178    
179  (defun flymake-ins-after (list pos val)  (defun flymake-ins-after (list pos val)
180      "Insert VAL into LIST after position POS."    "Insert VAL into LIST after position POS."
181      (let ((tmp (copy-sequence list))) ; (???)    (let ((tmp (copy-sequence list)))     ; (???)
182          (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp)))      (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp)))
183          tmp))      tmp))
184    
185  (defun flymake-set-at (list pos val)  (defun flymake-set-at (list pos val)
186      "Set VAL at position POS in LIST"    "Set VAL at position POS in LIST"
187      (let ((tmp (copy-sequence list))) ; (???)    (let ((tmp (copy-sequence list)))     ; (???)
188          (setcar (nthcdr pos tmp) val)      (setcar (nthcdr pos tmp) val)
189          tmp))      tmp))
190    
191  (defvar flymake-pid-to-names (flymake-makehash)  (defvar flymake-pid-to-names (flymake-makehash)
192    "pid -> source buffer name, output file name mapping.")    "pid -> source buffer name, output file name mapping.")
193    
194  (defun flymake-reg-names (pid source-buffer-name)  (defun flymake-reg-names (pid source-buffer-name)
195      "Save into in PID map."    "Save into in PID map."
196      (unless (stringp source-buffer-name)    (unless (stringp source-buffer-name)
197          (error "Invalid buffer name"))      (error "Invalid buffer name"))
198      (puthash pid (list source-buffer-name) flymake-pid-to-names))    (puthash pid (list source-buffer-name) flymake-pid-to-names))
199    
200  (defun flymake-get-source-buffer-name (pid)  (defun flymake-get-source-buffer-name (pid)
201      "Return buffer name stored in PID map."    "Return buffer name stored in PID map."
202      (nth 0 (gethash pid flymake-pid-to-names)))    (nth 0 (gethash pid flymake-pid-to-names)))
203    
204  (defun flymake-unreg-names (pid)  (defun flymake-unreg-names (pid)
205      "Delete PID->buffer name mapping."    "Delete PID->buffer name mapping."
206      (remhash pid flymake-pid-to-names))    (remhash pid flymake-pid-to-names))
207    
208  (defun flymake-get-buffer-var (buffer var-name)  (defun flymake-get-buffer-var (buffer var-name)
209      "Switch to BUFFER if necessary and return local variable VAR-NAME."    "Switch to BUFFER if necessary and return local variable VAR-NAME."
210      (unless (bufferp buffer)    (unless (bufferp buffer)
211          (error "Invalid buffer"))      (error "Invalid buffer"))
212    
213      (if (eq buffer (current-buffer))    (if (eq buffer (current-buffer))
214          (symbol-value var-name)        (symbol-value var-name)
215          (save-excursion      (save-excursion
216              (set-buffer buffer)        (set-buffer buffer)
217              (symbol-value var-name))))        (symbol-value var-name))))
218    
219  (defun flymake-set-buffer-var (buffer var-name var-value)  (defun flymake-set-buffer-var (buffer var-name var-value)
220      "Switch to BUFFER if necessary and set local variable VAR-NAME to VAR-VALUE."    "Switch to BUFFER if necessary and set local variable VAR-NAME to VAR-VALUE."
221      (unless (bufferp buffer)    (unless (bufferp buffer)
222          (error "Invalid buffer"))      (error "Invalid buffer"))
223    
224      (if (eq buffer (current-buffer))    (if (eq buffer (current-buffer))
225          (set var-name var-value)        (set var-name var-value)
226          (save-excursion      (save-excursion
227              (set-buffer buffer)        (set-buffer buffer)
228              (set var-name var-value))))        (set var-name var-value))))
229    
230  (defvar flymake-buffer-data (flymake-makehash)  (defvar flymake-buffer-data (flymake-makehash)
231    "Data specific to syntax check tool, in name-value pairs.")    "Data specific to syntax check tool, in name-value pairs.")
# Line 252  Line 233 
233  (make-variable-buffer-local 'flymake-buffer-data)  (make-variable-buffer-local 'flymake-buffer-data)
234    
235  (defun flymake-get-buffer-data (buffer)  (defun flymake-get-buffer-data (buffer)
236      (flymake-get-buffer-var buffer 'flymake-buffer-data))    (flymake-get-buffer-var buffer 'flymake-buffer-data))
237    
238  (defun flymake-set-buffer-data (buffer data)  (defun flymake-set-buffer-data (buffer data)
239      (flymake-set-buffer-var buffer 'flymake-buffer-data data))    (flymake-set-buffer-var buffer 'flymake-buffer-data data))
240    
241  (defun flymake-get-buffer-value (buffer name)  (defun flymake-get-buffer-value (buffer name)
242      (gethash name (flymake-get-buffer-data buffer)))    (gethash name (flymake-get-buffer-data buffer)))
243    
244  (defun flymake-set-buffer-value (buffer name value)  (defun flymake-set-buffer-value (buffer name value)
245      (puthash name value (flymake-get-buffer-data buffer)))    (puthash name value (flymake-get-buffer-data buffer)))
246    
247  (defvar flymake-output-residual nil "")  (defvar flymake-output-residual nil "")
248    
249  (make-variable-buffer-local 'flymake-output-residual)  (make-variable-buffer-local 'flymake-output-residual)
250    
251  (defun flymake-get-buffer-output-residual (buffer)  (defun flymake-get-buffer-output-residual (buffer)
252      (flymake-get-buffer-var buffer 'flymake-output-residual))    (flymake-get-buffer-var buffer 'flymake-output-residual))
253    
254  (defun flymake-set-buffer-output-residual (buffer residual)  (defun flymake-set-buffer-output-residual (buffer residual)
255      (flymake-set-buffer-var buffer 'flymake-output-residual residual))    (flymake-set-buffer-var buffer 'flymake-output-residual residual))
256    
257  (defcustom flymake-allowed-file-name-masks '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)  (defcustom flymake-allowed-file-name-masks
258                                               (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)    '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)
259                                               (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name)      (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)
260                                               (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name)      (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name)
261                                               (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)      (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name)
262                                               (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name)      (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)
263                                               (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name)      (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name)
264                                               (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name)      (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name)
265                                               (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name)      (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name)
266                                               (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name)      (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name)
267                                               (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)      (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name)
268  ;                                            (".+\\.cpp$" 1)      (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name)
269  ;                                            (".+\\.java$" 3)                                          ;                                            (".+\\.cpp$" 1)
270  ;                                            (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$")                                          ;                                            (".+\\.java$" 3)
271  ;                                                ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2))                                          ;                                            (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$")
272  ;                                            (".+\\.idl$" 1)                                          ;                                                ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2))
273  ;                                            (".+\\.odl$" 1)                                          ;                                            (".+\\.idl$" 1)
274  ;                                            (".+[0-9]+\\.tex$" 2 (".+\\.tex$")                                          ;                                            (".+\\.odl$" 1)
275  ;                                                ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 ))                                          ;                                            (".+[0-9]+\\.tex$" 2 (".+\\.tex$")
276  ;                                            (".+\\.tex$" 1)                                          ;                                                ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 ))
277                                               )                                          ;                                            (".+\\.tex$" 1)
278      "*Files syntax checking is allowed for."      )
279      :group 'flymake    "*Files syntax checking is allowed for."
280      :type '(repeat (string symbol symbol symbol)))    :group 'flymake
281      :type '(repeat (string symbol symbol symbol)))
282    
283  (defun flymake-get-file-name-mode-and-masks (file-name)  (defun flymake-get-file-name-mode-and-masks (file-name)
284      "Return the corresponding entry from 'flymake-allowed-file-name-masks'."    "Return the corresponding entry from 'flymake-allowed-file-name-masks'."
285      (unless (stringp file-name)    (unless (stringp file-name)
286          (error "Invalid file-name"))      (error "Invalid file-name"))
287      (let ((count           (length flymake-allowed-file-name-masks))    (let ((count           (length flymake-allowed-file-name-masks))
288            (idx             0)          (idx             0)
289            (mode-and-masks  nil))          (mode-and-masks  nil))
290          (while (and (not mode-and-masks) (< idx count))      (while (and (not mode-and-masks) (< idx count))
291              (if (string-match (nth 0 (nth idx flymake-allowed-file-name-masks)) file-name)        (if (string-match (nth 0 (nth idx flymake-allowed-file-name-masks)) file-name)
292                  (setq mode-and-masks (cdr (nth idx flymake-allowed-file-name-masks))))            (setq mode-and-masks (cdr (nth idx flymake-allowed-file-name-masks))))
293              (setq idx (1+ idx)))        (setq idx (1+ idx)))
294          (flymake-log 3 "file %s, init=%s" file-name (car mode-and-masks))      (flymake-log 3 "file %s, init=%s" file-name (car mode-and-masks))
295          mode-and-masks))      mode-and-masks))
296    
297  (defun flymake-can-syntax-check-file (file-name)  (defun flymake-can-syntax-check-file (file-name)
298      "Determine whether we can syntax check FILE-NAME.    "Determine whether we can syntax check FILE-NAME.
299  Return nil if we cannot, non-nil if we can."  Return nil if we cannot, non-nil if we can."
300      (if (flymake-get-init-function file-name) t nil))    (if (flymake-get-init-function file-name) t nil))
301    
302  (defun flymake-get-init-function (file-name)  (defun flymake-get-init-function (file-name)
303      "Return init function to be used for the file."    "Return init function to be used for the file."
304      (let* ((init-f  (nth 0 (flymake-get-file-name-mode-and-masks file-name))))    (let* ((init-f  (nth 0 (flymake-get-file-name-mode-and-masks file-name))))
305          ;(flymake-log 0 "calling %s" init-f)                                          ;(flymake-log 0 "calling %s" init-f)
306          ;(funcall init-f (current-buffer))                                          ;(funcall init-f (current-buffer))
307            init-f))      init-f))
308    
309  (defun flymake-get-cleanup-function (file-name)  (defun flymake-get-cleanup-function (file-name)
310      "Return cleanup function to be used for the file."    "Return cleanup function to be used for the file."
311      (nth 1 (flymake-get-file-name-mode-and-masks file-name)))    (nth 1 (flymake-get-file-name-mode-and-masks file-name)))
312    
313  (defun flymake-get-real-file-name-function (file-name)  (defun flymake-get-real-file-name-function (file-name)
314      (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name))    (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name))
315    
316  (defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..")  (defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..")
317      "Dirs to look for buildfile."    "Dirs to look for buildfile."
318      :group 'flymake    :group 'flymake
319      :type '(repeat (string)))    :type '(repeat (string)))
320    
321  (defvar flymake-find-buildfile-cache (flymake-makehash 'equal))  (defvar flymake-find-buildfile-cache (flymake-makehash 'equal))
322    
323  (defun flymake-get-buildfile-from-cache (dir-name)  (defun flymake-get-buildfile-from-cache (dir-name)
324      (gethash dir-name flymake-find-buildfile-cache))    (gethash dir-name flymake-find-buildfile-cache))
325    
326  (defun flymake-add-buildfile-to-cache (dir-name buildfile)  (defun flymake-add-buildfile-to-cache (dir-name buildfile)
327      (puthash dir-name buildfile flymake-find-buildfile-cache))    (puthash dir-name buildfile flymake-find-buildfile-cache))
328    
329  (defun flymake-clear-buildfile-cache ()  (defun flymake-clear-buildfile-cache ()
330      (clrhash flymake-find-buildfile-cache))    (clrhash flymake-find-buildfile-cache))
331    
332  (defun flymake-find-buildfile (buildfile-name source-dir-name dirs)  (defun flymake-find-buildfile (buildfile-name source-dir-name dirs)
333      "Find buildfile starting from current directory.    "Find buildfile starting from current directory.
334  Buildfile includes Makefile, build.xml etc.  Buildfile includes Makefile, build.xml etc.
335  Return its path if found, or nil if not found."  Return its file name if found, or nil if not found."
336      (if (flymake-get-buildfile-from-cache source-dir-name)    (if (flymake-get-buildfile-from-cache source-dir-name)
337          (progn
338            (flymake-get-buildfile-from-cache source-dir-name))
339        (let* ((buildfile-dir          nil)
340               (buildfile              nil)
341               (dir-count              (length dirs))
342               (dir-idx                0)
343               (found                  nil))
344          (while (and (not found) (< dir-idx dir-count))
345            (setq buildfile-dir (concat source-dir-name (nth dir-idx dirs)))
346            (setq buildfile (concat buildfile-dir "/" buildfile-name))
347            (when (file-exists-p buildfile)
348              (setq found t))
349            (setq dir-idx (1+ dir-idx)))
350          (if found
351              (progn
352                (flymake-log 3 "found buildfile at %s/%s" buildfile-dir buildfile-name)
353                (flymake-add-buildfile-to-cache source-dir-name buildfile-dir)
354                buildfile-dir)
355          (progn          (progn
356              (flymake-get-buildfile-from-cache source-dir-name))            (flymake-log 3 "buildfile for %s not found" source-dir-name)
357          (let* ((buildfile-dir          nil)            nil)))))
358                 (buildfile              nil)  
359                 (dir-count              (length dirs))  (defun flymake-fix-file-name (name)
360                 (dir-idx                0)    "Replace all occurences of '\' with '/'."
361                 (found                  nil))    (when name
362              (while (and (not found) (< dir-idx dir-count))      (let* ((new-name (flymake-replace-regexp-in-string "[\\]" "/" (expand-file-name name)))
363                  (setq buildfile-dir (concat source-dir-name (nth dir-idx dirs)))             (last-char (elt new-name (1- (length new-name)))))
364                  (setq buildfile (concat buildfile-dir "/" buildfile-name))        (setq new-name (flymake-replace-regexp-in-string "\\./" "" new-name))
365                  (when (file-exists-p buildfile)        (if (equal "/" (char-to-string last-char))
366                      (setq found t))            (setq new-name (substring new-name 0 (1- (length new-name)))))
367                  (setq dir-idx (1+ dir-idx)))        new-name)))
             (if found  
                 (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)  
                 (progn  
                     (flymake-log 3 "buildfile for %s not found" source-dir-name)  
                     nil)))))  
   
 (defun flymake-fix-path-name (name)  
     "Replace all occurences of '\' with '/'."  
     (when name  
         (let* ((new-name (flymake-replace-regexp-in-string "[\\]" "/" (expand-file-name name)))  
                (last-char (elt new-name (1- (length new-name)))))  
             (setq new-name (flymake-replace-regexp-in-string "\\./" "" new-name))  
             (if (equal "/" (char-to-string last-char))  
                 (setq new-name (substring new-name 0 (1- (length new-name)))))  
             new-name)))  
368    
369  (defun flymake-same-files (file-name-one file-name-two)  (defun flymake-same-files (file-name-one file-name-two)
370      "Check if FILE-NAME-ONE and FILE-NAME-TWO point to same file.    "Check if FILE-NAME-ONE and FILE-NAME-TWO point to same file.
371  Return t if so, nil if not."  Return t if so, nil if not."
372      (equal (flymake-fix-path-name file-name-one) (flymake-fix-path-name file-name-two)))    (equal (flymake-fix-file-name file-name-one)
373             (flymake-fix-file-name file-name-two)))
374    
375  (defun flymake-ensure-ends-with-slash (path)  (defun flymake-ensure-ends-with-slash (filename)
376      (if (not (= (elt path (1- (length path))) (string-to-char "/")))    ;; Should this really be file-name-as-directory?
377          (concat path "/")    (if (not (= (elt filename (1- (length filename))) (string-to-char "/")))
378          path))        (concat filename "/")
379        filename))
380  (defun flymake-get-common-path-prefix (string-one string-two)  
381      "Return common prefix for two paths STRING-ONE and STRING-TWO."  (defun flymake-get-common-file-prefix (string-one string-two)
382      (when (and string-one string-two)    "Return common prefix for two file names STRING-ONE and STRING-TWO."
383          (let* ((slash-pos-one  -1)    (when (and string-one string-two)
384                 (slash-pos-two  -1)      (let* ((slash-pos-one  -1)
385                 (done           nil)             (slash-pos-two  -1)
386                 (prefix         nil))             (done           nil)
387              (setq string-one (flymake-ensure-ends-with-slash string-one))             (prefix         nil))
388              (setq string-two (flymake-ensure-ends-with-slash string-two))        (setq string-one (flymake-ensure-ends-with-slash string-one))
389              (while (not done)        (setq string-two (flymake-ensure-ends-with-slash string-two))
390                  (setq slash-pos-one (string-match "/" string-one (1+ slash-pos-one)))        (while (not done)
391                  (setq slash-pos-two (string-match "/" string-two (1+ slash-pos-two)))          (setq slash-pos-one (string-match "/" string-one (1+ slash-pos-one)))
392                  (if (and slash-pos-one slash-pos-two          (setq slash-pos-two (string-match "/" string-two (1+ slash-pos-two)))
393                           (= slash-pos-one slash-pos-two)          (if (and slash-pos-one slash-pos-two
394                           (string= (substring string-one 0 slash-pos-one) (substring string-two 0 slash-pos-two)))                   (= slash-pos-one slash-pos-two)
395                      (progn                   (string= (substring string-one 0 slash-pos-one) (substring string-two 0 slash-pos-two)))
396                          (setq prefix (substring string-one 0 (1+ slash-pos-one))))              (progn
397                      (setq done t)))                (setq prefix (substring string-one 0 (1+ slash-pos-one))))
398              prefix)))            (setq done t)))
399          prefix)))
400  (defun flymake-build-relative-path (from-dir to-dir)  
401      "Return rel: FROM-DIR/rel == TO-DIR."  (defun flymake-build-relative-filename (from-dir to-dir)
402      (if (not (equal (elt from-dir 0) (elt to-dir 0)))    "Return rel: FROM-DIR/rel == TO-DIR."
403          (error "First chars in paths %s, %s must be equal (same drive)" from-dir to-dir)    (if (not (equal (elt from-dir 0) (elt to-dir 0)))
404      ;else        (error "First chars in file names %s, %s must be equal (same drive)"
405          (let* ((from        (flymake-ensure-ends-with-slash (flymake-fix-path-name from-dir)))               from-dir to-dir)
406                 (to          (flymake-ensure-ends-with-slash (flymake-fix-path-name to-dir)))      (let* ((from (flymake-ensure-ends-with-slash (flymake-fix-file-name from-dir)))
407                 (prefix      (flymake-get-common-path-prefix from to))             (to   (flymake-ensure-ends-with-slash (flymake-fix-file-name to-dir)))
408                 (from-suffix (substring from (length prefix)))             (prefix      (flymake-get-common-file-prefix from to))
409                 (up-count    (length (flymake-split-string from-suffix "[/]")))             (from-suffix (substring from (length prefix)))
410                 (to-suffix   (substring to   (length prefix)))             (up-count    (length (flymake-split-string from-suffix "[/]")))
411                 (idx         0)             (to-suffix   (substring to   (length prefix)))
412                 (rel         nil))             (idx         0)
413              (if (and (> (length to-suffix) 0) (equal "/" (char-to-string (elt to-suffix 0))))             (rel         nil))
414                  (setq to-suffix (substring to-suffix 1)))        (if (and (> (length to-suffix) 0) (equal "/" (char-to-string (elt to-suffix 0))))
415              (setq to-suffix (substring to-suffix 1)))
416              (while (< idx up-count)  
417                  (if (> (length rel) 0)        (while (< idx up-count)
418                      (setq rel (concat rel "/")))          (if (> (length rel) 0)
419                  (setq rel (concat rel ".."))              (setq rel (concat rel "/")))
420                  (setq idx (1+ idx)))          (setq rel (concat rel ".."))
421              (if (> (length rel) 0)          (setq idx (1+ idx)))
422                  (setq rel (concat rel "/")))        (if (> (length rel) 0)
423              (if (> (length to-suffix) 0)            (setq rel (concat rel "/")))
424                 (setq rel (concat rel to-suffix)))        (if (> (length to-suffix) 0)
425              (or rel "./"))))            (setq rel (concat rel to-suffix)))
426          (or rel "./"))))
427    
428  (defcustom flymake-master-file-dirs '("." "./src" "./UnitTest")  (defcustom flymake-master-file-dirs '("." "./src" "./UnitTest")
429      "Dirs where to llok for master files."    "Dirs where to llok for master files."
430      :group 'flymake    :group 'flymake
431      :type '(repeat (string)))    :type '(repeat (string)))
432    
433  (defcustom flymake-master-file-count-limit 32  (defcustom flymake-master-file-count-limit 32
434      "Max number of master files to check."    "Max number of master files to check."
435      :group 'flymake    :group 'flymake
436      :type 'integer)    :type 'integer)
437    
438  (defvar flymake-included-file-name nil " ") ; this is used to pass a parameter to a sort predicate below  (defvar flymake-included-file-name nil " ") ; this is used to pass a parameter to a sort predicate below
439    
440  (defun flymake-find-possible-master-files (file-name master-file-dirs masks)  (defun flymake-find-possible-master-files (file-name master-file-dirs masks)
441      "Find (by name and location) all posible master files.    "Find (by name and location) all posible master files.
442  Mater files are .cpp and .c for and .h. Files are searched for  Mater files are .cpp and .c for and .h. Files are searched for
443  starting from the .h directory and max max-level parent dirs.  starting from the .h directory and max max-level parent dirs.
444  File contents are not checked."  File contents are not checked."
445      (let* ((dir-idx    0)    (let* ((dir-idx    0)
446            (dir-count  (length master-file-dirs))           (dir-count  (length master-file-dirs))
447            (files  nil)           (files  nil)
448            (done   nil)           (done   nil)
449            (masks-count (length masks)))           (masks-count (length masks)))
450    
451          (while (and (not done) (< dir-idx dir-count))      (while (and (not done) (< dir-idx dir-count))
452              (let* ((dir (concat (flymake-fix-path-name (file-name-directory file-name)) "/" (nth dir-idx master-file-dirs)))        (let* ((dir (concat (flymake-fix-file-name (file-name-directory file-name)) "/" (nth dir-idx master-file-dirs)))
453                     (masks-idx 0))               (masks-idx 0))
454                  (while (and (file-exists-p dir) (not done) (< masks-idx masks-count))          (while (and (file-exists-p dir) (not done) (< masks-idx masks-count))
455                      (let* ((mask        (nth masks-idx masks))            (let* ((mask        (nth masks-idx masks))
456                             (dir-files   (directory-files dir t mask))                   (dir-files   (directory-files dir t mask))
457                             (file-count  (length dir-files))                   (file-count  (length dir-files))
458                             (file-idx    0))                   (file-idx    0))
459    
460                          (flymake-log 3 "dir %s, %d file(s) for mask %s" dir file-count mask)              (flymake-log 3 "dir %s, %d file(s) for mask %s" dir file-count mask)
461                          (while (and (not done) (< file-idx file-count))              (while (and (not done) (< file-idx file-count))
462                              (when (not (file-directory-p (nth file-idx dir-files)))                (when (not (file-directory-p (nth file-idx dir-files)))
463                                  (setq files (cons (nth file-idx dir-files) files))                  (setq files (cons (nth file-idx dir-files) files))
464                                  (when (>= (length files) flymake-master-file-count-limit)                  (when (>= (length files) flymake-master-file-count-limit)
465                                      (flymake-log 3 "master file count limit (%d) reached" flymake-master-file-count-limit)                    (flymake-log 3 "master file count limit (%d) reached" flymake-master-file-count-limit)
466                                      (setq done t)))                    (setq done t)))
467                              (setq file-idx (1+ file-idx))))                (setq file-idx (1+ file-idx))))
468                      (setq masks-idx (1+ masks-idx))))            (setq masks-idx (1+ masks-idx))))
469              (setq dir-idx (1+ dir-idx)))        (setq dir-idx (1+ dir-idx)))
470          (when files      (when files
471              (setq flymake-included-file-name (file-name-nondirectory file-name))        (setq flymake-included-file-name (file-name-nondirectory file-name))
472              (setq files (sort files 'flymake-master-file-compare))        (setq files (sort files 'flymake-master-file-compare))
473              (setq flymake-included-file-name nil))        (setq flymake-included-file-name nil))
474          (flymake-log 3 "found %d possible master file(s)" (length files))      (flymake-log 3 "found %d possible master file(s)" (length files))
475          files))      files))
476    
477  (defun flymake-master-file-compare (file-one file-two)  (defun flymake-master-file-compare (file-one file-two)
478      "Compare two files speccified by FILE-ONE and FILE-TWO.    "Compare two files speccified by FILE-ONE and FILE-TWO.
479  This function is used in sort to move most possible file names  This function is used in sort to move most possible file names
480  to the beginning of the list (File.h -> File.cpp moved to top."  to the beginning of the list (File.h -> File.cpp moved to top."
481      (and (equal (file-name-sans-extension flymake-included-file-name)    (and (equal (file-name-sans-extension flymake-included-file-name)
482                  (file-name-sans-extension (file-name-nondirectory file-one)))                (file-name-sans-extension (file-name-nondirectory file-one)))
483           (not (equal file-one file-two))))         (not (equal file-one file-two))))
484    
485  (defcustom flymake-check-file-limit 8192  (defcustom flymake-check-file-limit 8192
486      "Max number of chars to look at when checking possible master file."    "Max number of chars to look at when checking possible master file."
487      :group 'flymake    :group 'flymake
488      :type 'integer)    :type 'integer)
489    
490  (defun flymake-check-patch-master-file-buffer (master-file-temp-buffer  (defun flymake-check-patch-master-file-buffer (master-file-temp-buffer
491                                              master-file-name patched-master-file-name                                                 master-file-name patched-master-file-name
492                                              source-file-name patched-source-file-name                                                 source-file-name patched-source-file-name
493                                              include-dirs regexp-list)                                                 include-dirs regexp-list)
494      "Check if MASTER-FILE-NAME is a master file for SOURCE-FILE-NAME.    "Check if MASTER-FILE-NAME is a master file for SOURCE-FILE-NAME.
495  For .cpp master file this means it includes SOURCE-FILE-NAME (.h).  For .cpp master file this means it includes SOURCE-FILE-NAME (.h).
496  If yes, patch a copy of MASTER-FILE-NAME to include PATCHED-SOURCE-FILE-NAME  If yes, patch a copy of MASTER-FILE-NAME to include PATCHED-SOURCE-FILE-NAME
497  instead of SOURCE-FILE-NAME.  instead of SOURCE-FILE-NAME.
498  Whether a buffer for MATER-FILE-NAME exists, use it as a source  Whether a buffer for MATER-FILE-NAME exists, use it as a source
499  instead of reading master file from disk."  instead of reading master file from disk."
500      (let* ((found                     nil)    (let* ((found                     nil)
501             (regexp                    (format (nth 0 regexp-list) ; "[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\""           (regexp                    (format (nth 0 regexp-list) ; "[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\""
502                                                (file-name-nondirectory source-file-name)))                                              (file-name-nondirectory source-file-name)))
503             (path-idx                  (nth 1 regexp-list))           (path-idx                  (nth 1 regexp-list))
504             (name-idx                  (nth 2 regexp-list))           (name-idx                  (nth 2 regexp-list))
505             (inc-path                  nil)           (inc-path                  nil)
506             (inc-name                  nil)           (inc-name                  nil)
507             (search-limit              flymake-check-file-limit))           (search-limit              flymake-check-file-limit))
508          (save-excursion      (save-excursion
509              (unwind-protect        (unwind-protect
510                  (progn            (progn
511                      (set-buffer master-file-temp-buffer)              (set-buffer master-file-temp-buffer)
512                      (when (> search-limit (point-max))              (when (> search-limit (point-max))
513                          (setq search-limit (point-max)))                (setq search-limit (point-max)))
514                      (flymake-log 3 "checking %s against regexp %s" master-file-name regexp)              (flymake-log 3 "checking %s against regexp %s" master-file-name regexp)
515                      (goto-char (point-min))              (goto-char (point-min))
516                      (while (and (< (point) search-limit) (re-search-forward regexp search-limit t))              (while (and (< (point) search-limit) (re-search-forward regexp search-limit t))
517                                                  (let* ((match-beg   (match-beginning name-idx))                (let* ((match-beg   (match-beginning name-idx))
518                                                             (match-end   (match-end name-idx)))                       (match-end   (match-end name-idx)))
519    
520                                                          (flymake-log 3 "found possible match for %s" (file-name-nondirectory source-file-name))                  (flymake-log 3 "found possible match for %s" (file-name-nondirectory source-file-name))
521                                                          (setq inc-path (match-string path-idx))                  (setq inc-path (match-string path-idx))
522                                                          (setq inc-name (match-string name-idx))                  (setq inc-name (match-string name-idx))
523                                                          (when (string= inc-name (file-name-nondirectory source-file-name))                  (when (string= inc-name (file-name-nondirectory source-file-name))
524                                                                  (flymake-log 3 "inc-path=%s inc-name=%s" inc-path inc-name)                    (flymake-log 3 "inc-path=%s inc-name=%s" inc-path inc-name)
525                                                                  (when (flymake-check-include source-file-name inc-path inc-name include-dirs)                    (when (flymake-check-include source-file-name inc-path inc-name include-dirs)
526                                                                          (setq found t)                      (setq found t)
527                                                                          ; replace-match is not used here as it fails in xemacs with                      ;;  replace-match is not used here as it fails in
528                                                                          ; 'last match not a buffer' error as check-includes calls replace-in-string                      ;; xemacs with 'last match not a buffer' error as
529                                                                          (flymake-replace-region (current-buffer) match-beg match-end                      ;; check-includes calls replace-in-string
530                                                                                                                          (file-name-nondirectory patched-source-file-name))))                      (flymake-replace-region (current-buffer) match-beg match-end
531                                                          (forward-line 1)))                                              (file-name-nondirectory patched-source-file-name))))
532                      (when found                  (forward-line 1)))
533                          (flymake-save-buffer-in-file (current-buffer) patched-master-file-name)))              (when found
534                  ;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer))                (flymake-save-buffer-in-file (current-buffer) patched-master-file-name)))
535                  (kill-buffer master-file-temp-buffer)))                                          ;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer))
536          ;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found)          (kill-buffer master-file-temp-buffer)))
537          (when found                                          ;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found)
538              (flymake-log 2 "found master file %s" master-file-name))      (when found
539          found))        (flymake-log 2 "found master file %s" master-file-name))
540        found))
541    
542  (defun flymake-replace-region (buffer beg end rep)  (defun flymake-replace-region (buffer beg end rep)
543      "Replace text in BUFFER in region (BEG END) with REP."    "Replace text in BUFFER in region (BEG END) with REP."
544      (save-excursion    (save-excursion
545          (delete-region beg end)      (delete-region beg end)
546              (goto-char beg)      (goto-char beg)
547          (insert rep)))      (insert rep)))
548    
549  (defun flymake-read-file-to-temp-buffer (file-name)  (defun flymake-read-file-to-temp-buffer (file-name)
550      "Insert contents of FILE-NAME into newly created temp buffer."    "Insert contents of FILE-NAME into newly created temp buffer."
551      (let* ((temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (file-name-nondirectory file-name))))))    (let* ((temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (file-name-nondirectory file-name))))))
552          (save-excursion      (save-excursion
553              (set-buffer temp-buffer)        (set-buffer temp-buffer)
554              (insert-file-contents file-name))        (insert-file-contents file-name))
555          temp-buffer))      temp-buffer))
556    
557  (defun flymake-copy-buffer-to-temp-buffer (buffer)  (defun flymake-copy-buffer-to-temp-buffer (buffer)
558      "Copy contents of BUFFER into newly created temp buffer."    "Copy contents of BUFFER into newly created temp buffer."
559      (let ((contents     nil)    (let ((contents     nil)
560            (temp-buffer  nil))          (temp-buffer  nil))
561          (save-excursion      (save-excursion
562              (set-buffer buffer)        (set-buffer buffer)
563              (setq contents (buffer-string))        (setq contents (buffer-string))
564    
565              (setq temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (buffer-name buffer)))))        (setq temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (buffer-name buffer)))))
566              (set-buffer temp-buffer)        (set-buffer temp-buffer)
567              (insert contents))        (insert contents))
568          temp-buffer))      temp-buffer))
569    
570  (defun flymake-check-include (source-file-name inc-path inc-name include-dirs)  (defun flymake-check-include (source-file-name inc-path inc-name include-dirs)
571      "Check if SOURCE-FILE-NAME can be found in include path.    "Check if SOURCE-FILE-NAME can be found in include path.
572  Return t if it can be found via include path using INC-PATH and INC-NAME."  Return t if it can be found via include path using INC-PATH and INC-NAME."
573      (if (file-name-absolute-p inc-path)    (if (file-name-absolute-p inc-path)
574          (flymake-same-files source-file-name (concat inc-path "/" inc-name))        (flymake-same-files source-file-name (concat inc-path "/" inc-name))
575          (let* ((count      (length include-dirs))      (let* ((count      (length include-dirs))
576                 (idx        0)             (idx        0)
577                 (file-name  nil)             (file-name  nil)
578                 (found      nil))             (found      nil))
579              (while (and (not found) (< idx count))        (while (and (not found) (< idx count))
580                  (setq file-name (concat (file-name-directory source-file-name) "/" (nth idx include-dirs)))          (setq file-name (concat (file-name-directory source-file-name) "/" (nth idx include-dirs)))
581                  (if (> (length inc-path) 0)          (if (> (length inc-path) 0)
582                      (setq file-name (concat file-name "/" inc-path)))              (setq file-name (concat file-name "/" inc-path)))
583                  (setq file-name (concat file-name "/" inc-name))          (setq file-name (concat file-name "/" inc-name))
584                  (when (flymake-same-files source-file-name file-name)          (when (flymake-same-files source-file-name file-name)
585                      (setq found t))            (setq found t))
586                  (setq idx (1+ idx)))          (setq idx (1+ idx)))
587              found)))        found)))
588    
589  (defun flymake-find-buffer-for-file (file-name)  (defun flymake-find-buffer-for-file (file-name)
590      "Check if there exists a buffer visiting FILE-NAME.    "Check if there exists a buffer visiting FILE-NAME.
591  Return t if so, nil if not."  Return t if so, nil if not."
592      (let ((buffer-name (get-file-buffer file-name)))    (let ((buffer-name (get-file-buffer file-name)))
593          (if buffer-name      (if buffer-name
594              (get-buffer buffer-name))))          (get-buffer buffer-name))))
595    
596  (defun flymake-create-master-file (source-file-name patched-source-file-name get-incl-dirs-f create-temp-f masks include-regexp-list)  (defun flymake-create-master-file (source-file-name patched-source-file-name get-incl-dirs-f create-temp-f masks include-regexp-list)
597      "Save SOURCE-FILE-NAME with a different name.    "Save SOURCE-FILE-NAME with a different name.
598  Find master file, patch and save it."  Find master file, patch and save it."
599      (let* ((possible-master-files     (flymake-find-possible-master-files source-file-name flymake-master-file-dirs masks))    (let* ((possible-master-files     (flymake-find-possible-master-files source-file-name flymake-master-file-dirs masks))
600             (master-file-count         (length possible-master-files))           (master-file-count         (length possible-master-files))
601             (idx                       0)           (idx                       0)
602             (temp-buffer               nil)           (temp-buffer               nil)
603             (master-file-name          nil)           (master-file-name          nil)
604             (patched-master-file-name  nil)           (patched-master-file-name  nil)
605             (found                     nil))           (found                     nil))
606    
607          (while (and (not found) (< idx master-file-count))      (while (and (not found) (< idx master-file-count))
608              (setq master-file-name (nth idx possible-master-files))        (setq master-file-name (nth idx possible-master-files))
609              (setq patched-master-file-name (funcall create-temp-f master-file-name "flymake_master"))        (setq patched-master-file-name (funcall create-temp-f master-file-name "flymake_master"))
610              (if (flymake-find-buffer-for-file master-file-name)        (if (flymake-find-buffer-for-file master-file-name)
611                  (setq temp-buffer (flymake-copy-buffer-to-temp-buffer (flymake-find-buffer-for-file master-file-name)))            (setq temp-buffer (flymake-copy-buffer-to-temp-buffer (flymake-find-buffer-for-file master-file-name)))
612                  (setq temp-buffer (flymake-read-file-to-temp-buffer master-file-name)))          (setq temp-buffer (flymake-read-file-to-temp-buffer master-file-name)))
613              (setq found        (setq found
614                    (flymake-check-patch-master-file-buffer              (flymake-check-patch-master-file-buffer
615                         temp-buffer               temp-buffer
616                         master-file-name               master-file-name
617                         patched-master-file-name               patched-master-file-name
618                         source-file-name               source-file-name
619                         patched-source-file-name               patched-source-file-name
620                         (funcall get-incl-dirs-f (file-name-directory master-file-name))               (funcall get-incl-dirs-f (file-name-directory master-file-name))
621                         include-regexp-list))               include-regexp-list))
622              (setq idx (1+ idx)))        (setq idx (1+ idx)))
623          (if found      (if found
624              (list master-file-name patched-master-file-name)          (list master-file-name patched-master-file-name)
625              (progn        (progn
626                  (flymake-log 3 "none of %d master file(s) checked includes %s" master-file-count          (flymake-log 3 "none of %d master file(s) checked includes %s" master-file-count
627                             (file-name-nondirectory source-file-name))                       (file-name-nondirectory source-file-name))
628                  nil))))          nil))))
629    
630  (defun flymake-save-buffer-in-file (buffer file-name)  (defun flymake-save-buffer-in-file (buffer file-name)
631      (or buffer    (or buffer
632          (error "Invalid buffer"))        (error "Invalid buffer"))
633      (save-excursion    (save-excursion
634          (save-restriction      (save-restriction
635              (set-buffer buffer)        (set-buffer buffer)
636              (widen)        (widen)
637              (make-directory (file-name-directory file-name) 1)        (make-directory (file-name-directory file-name) 1)
638              (write-region (point-min) (point-max) file-name nil 566)))        (write-region (point-min) (point-max) file-name nil 566)))
639      (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name))    (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name))
640    
641  (defun flymake-save-string-to-file (file-name data)  (defun flymake-save-string-to-file (file-name data)
642      "Save string DATA to file FILE-NAME."    "Save string DATA to file FILE-NAME."
643      (write-region data nil file-name nil 566))    (write-region data nil file-name nil 566))
644    
645  (defun flymake-read-file-to-string (file-name)  (defun flymake-read-file-to-string (file-name)
646      "Read contents of file FILE-NAME and return as a string."    "Read contents of file FILE-NAME and return as a string."
647      (with-temp-buffer    (with-temp-buffer
648          (insert-file-contents file-name)      (insert-file-contents file-name)
649          (buffer-substring (point-min) (point-max))))      (buffer-substring (point-min) (point-max))))
650    
651  (defun flymake-process-filter (process output)  (defun flymake-process-filter (process output)
652      "Parse OUTPUT and highlight error lines.    "Parse OUTPUT and highlight error lines.
653  It's flymake process filter."  It's flymake process filter."
654      (let* ((pid               (process-id process))    (let* ((pid               (process-id process))
655             (source-buffer     (get-buffer (flymake-get-source-buffer-name pid))))           (source-buffer     (get-buffer (flymake-get-source-buffer-name pid))))
656    
657          (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid)      (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid)
658          (when source-buffer      (when source-buffer
659              (flymake-parse-output-and-residual source-buffer output))))        (flymake-parse-output-and-residual source-buffer output))))
660    
661  (defun flymake-process-sentinel (process event)  (defun flymake-process-sentinel (process event)
662     "Sentinel for syntax check buffers."    "Sentinel for syntax check buffers."
663     (if (memq (process-status process) '(signal exit))    (if (memq (process-status process) '(signal exit))
664         (let*((exit-status       (process-exit-status process))        (let*((exit-status       (process-exit-status process))
665               (command           (process-command process))              (command           (process-command process))
666               (pid               (process-id process))              (pid               (process-id process))
667               (source-buffer     (get-buffer (flymake-get-source-buffer-name pid)))              (source-buffer     (get-buffer (flymake-get-source-buffer-name pid)))
668               (cleanup-f         (flymake-get-cleanup-function (buffer-file-name source-buffer))))              (cleanup-f         (flymake-get-cleanup-function (buffer-file-name source-buffer))))
669    
670           (flymake-log 2 "process %d exited with code %d" pid exit-status)          (flymake-log 2 "process %d exited with code %d" pid exit-status)
671           (condition-case err          (condition-case err
672               (progn              (progn
673                   (flymake-log 3 "cleaning up using %s" cleanup-f)                (flymake-log 3 "cleaning up using %s" cleanup-f)
674                   (funcall cleanup-f source-buffer)                (funcall cleanup-f source-buffer)
675    
676                   (flymake-unreg-names pid)                (flymake-unreg-names pid)
677                   (delete-process process)                (delete-process process)
678    
679                   (when source-buffer                (when source-buffer
680                       (save-excursion                  (save-excursion
681                           (set-buffer source-buffer)                    (set-buffer source-buffer)
682    
683                           (flymake-parse-residual source-buffer)                    (flymake-parse-residual source-buffer)
684                           (flymake-post-syntax-check source-buffer exit-status command)                    (flymake-post-syntax-check source-buffer exit-status command)
685                           (flymake-set-buffer-is-running source-buffer nil))))                    (flymake-set-buffer-is-running source-buffer nil))))
686             (error            (error
687                (let ((err-str (format "Error in process sentinel for buffer %s: %s"             (let ((err-str (format "Error in process sentinel for buffer %s: %s"
688                                      source-buffer (error-message-string err))))                                    source-buffer (error-message-string err))))
689                    (flymake-log 0 err-str)               (flymake-log 0 err-str)
690                    (flymake-set-buffer-is-running source-buffer nil)))))))               (flymake-set-buffer-is-running source-buffer nil)))))))
691    
692  (defun flymake-post-syntax-check (source-buffer exit-status command)  (defun flymake-post-syntax-check (source-buffer exit-status command)
693     (flymake-set-buffer-err-info source-buffer (flymake-get-buffer-new-err-info source-buffer))    (flymake-set-buffer-err-info source-buffer (flymake-get-buffer-new-err-info source-buffer))
694     (flymake-set-buffer-new-err-info source-buffer nil)    (flymake-set-buffer-new-err-info source-buffer nil)
695    
696     (flymake-set-buffer-err-info source-buffer (flymake-fix-line-numbers    (flymake-set-buffer-err-info source-buffer (flymake-fix-line-numbers
697                                               (flymake-get-buffer-err-info source-buffer)                                                (flymake-get-buffer-err-info source-buffer)
698                                               1                                                1
699                                               (flymake-count-lines source-buffer)))                                                (flymake-count-lines source-buffer)))
700     (flymake-delete-own-overlays source-buffer)    (flymake-delete-own-overlays source-buffer)
701     (flymake-highlight-err-lines source-buffer (flymake-get-buffer-err-info source-buffer))    (flymake-highlight-err-lines source-buffer (flymake-get-buffer-err-info source-buffer))
702    
703     (let ((err-count   (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "e"))    (let ((err-count   (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "e"))
704           (warn-count  (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "w")))          (warn-count  (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "w")))
705    
706         (flymake-log 2 "%s: %d error(s), %d warning(s) in %.2f second(s)"      (flymake-log 2 "%s: %d error(s), %d warning(s) in %.2f second(s)"
707                    (buffer-name source-buffer) err-count warn-count                   (buffer-name source-buffer) err-count warn-count
708                    (- (flymake-float-time) (flymake-get-buffer-check-start-time source-buffer)))                   (- (flymake-float-time) (flymake-get-buffer-check-start-time source-buffer)))
709         (flymake-set-buffer-check-start-time source-buffer nil)      (flymake-set-buffer-check-start-time source-buffer nil)
710         (if (and (equal 0 err-count) (equal 0 warn-count))      (if (and (equal 0 err-count) (equal 0 warn-count))
711             (if (equal 0 exit-status)          (if (equal 0 exit-status)
712                 (flymake-report-status source-buffer "" "") ; PASSED              (flymake-report-status source-buffer "" "") ; PASSED
713                 (if (not (flymake-get-buffer-check-was-interrupted source-buffer))            (if (not (flymake-get-buffer-check-was-interrupted source-buffer))
714                     (flymake-report-fatal-status (current-buffer) "CFGERR"                (flymake-report-fatal-status (current-buffer) "CFGERR"
715                         (format "Configuration error has occured while running %s" command))                                             (format "Configuration error has occured while running %s" command))
716                     (flymake-report-status source-buffer nil ""))) ; "STOPPED"              (flymake-report-status source-buffer nil ""))) ; "STOPPED"
717             (flymake-report-status source-buffer (format "%d/%d" err-count warn-count) ""))))        (flymake-report-status source-buffer (format "%d/%d" err-count warn-count) ""))))
718    
719  (defun flymake-parse-output-and-residual (source-buffer output)  (defun flymake-parse-output-and-residual (source-buffer output)
720      "Split OUTPUT into lines, merge in residual if necessary."    "Split OUTPUT into lines, merge in residual if necessary."
721      (save-excursion    (save-excursion
722          (set-buffer source-buffer)      (set-buffer source-buffer)
723          (let* ((buffer-residual     (flymake-get-buffer-output-residual source-buffer))      (let* ((buffer-residual     (flymake-get-buffer-output-residual source-buffer))
724                 (total-output        (if buffer-residual (concat buffer-residual output) output))             (total-output        (if buffer-residual (concat buffer-residual output) output))
725                 (lines-and-residual  (flymake-split-output total-output))             (lines-and-residual  (flymake-split-output total-output))
726                 (lines               (nth 0 lines-and-residual))             (lines               (nth 0 lines-and-residual))
727                 (new-residual        (nth 1 lines-and-residual)))             (new-residual        (nth 1 lines-and-residual)))
728    
729              (flymake-set-buffer-output-residual source-buffer new-residual)        (flymake-set-buffer-output-residual source-buffer new-residual)
730              (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines        (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines
731                                                              (flymake-get-buffer-new-err-info source-buffer)                                                        (flymake-get-buffer-new-err-info source-buffer)
732                                                              source-buffer lines)))))                                                        source-buffer lines)))))
733    
734  (defun flymake-parse-residual (source-buffer)  (defun flymake-parse-residual (source-buffer)
735      "Parse residual if it's non empty."    "Parse residual if it's non empty."
736      (save-excursion    (save-excursion
737          (set-buffer source-buffer)      (set-buffer source-buffer)
738          (when (flymake-get-buffer-output-residual source-buffer)      (when (flymake-get-buffer-output-residual source-buffer)
739              (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines        (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines
740                                                             (flymake-get-buffer-new-err-info source-buffer)                                                        (flymake-get-buffer-new-err-info source-buffer)
741                                                             source-buffer                                                        source-buffer
742                                                             (list (flymake-get-buffer-output-residual source-buffer))))                                                        (list (flymake-get-buffer-output-residual source-buffer))))
743              (flymake-set-buffer-output-residual source-buffer nil))))        (flymake-set-buffer-output-residual source-buffer nil))))
744    
745  (defvar flymake-err-info nil  (defvar flymake-err-info nil
746    "Sorted list of line numbers and lists of err info in the form (file, err-text).")    "Sorted list of line numbers and lists of err info in the form (file, err-text).")
# Line 763  It's flymake process filter." Line 748  It's flymake process filter."
748  (make-variable-buffer-local 'flymake-err-info)  (make-variable-buffer-local 'flymake-err-info)
749    
750  (defun flymake-get-buffer-err-info (buffer)  (defun flymake-get-buffer-err-info (buffer)
751      (flymake-get-buffer-var buffer 'flymake-err-info))    (flymake-get-buffer-var buffer 'flymake-err-info))
752    
753  (defun flymake-set-buffer-err-info (buffer err-info)  (defun flymake-set-buffer-err-info (buffer err-info)
754      (flymake-set-buffer-var buffer 'flymake-err-info err-info))    (flymake-set-buffer-var buffer 'flymake-err-info err-info))
755    
756  (defun flymake-er-make-er (line-no line-err-info-list)  (defun flymake-er-make-er (line-no line-err-info-list)
757      (list line-no line-err-info-list))    (list line-no line-err-info-list))
758    
759  (defun flymake-er-get-line (err-info)  (defun flymake-er-get-line (err-info)
760      (nth 0 err-info))    (nth 0 err-info))
761    
762  (defun flymake-er-get-line-err-info-list (err-info)  (defun flymake-er-get-line-err-info-list (err-info)
763      (nth 1 err-info))    (nth 1 err-info))
764    
765  (defvar flymake-new-err-info nil  (defvar flymake-new-err-info nil
766    "Same as 'flymake-err-info', effective when a syntax check is in progress.")    "Same as 'flymake-err-info', effective when a syntax check is in progress.")
# Line 783  It's flymake process filter." Line 768  It's flymake process filter."
768  (make-variable-buffer-local 'flymake-new-err-info)  (make-variable-buffer-local 'flymake-new-err-info)
769    
770  (defun flymake-get-buffer-new-err-info (buffer)  (defun flymake-get-buffer-new-err-info (buffer)
771      (flymake-get-buffer-var buffer 'flymake-new-err-info))    (flymake-get-buffer-var buffer 'flymake-new-err-info))
772    
773  (defun flymake-set-buffer-new-err-info (buffer new-err-info)  (defun flymake-set-buffer-new-err-info (buffer new-err-info)
774      (flymake-set-buffer-var buffer 'flymake-new-err-info new-err-info))    (flymake-set-buffer-var buffer 'flymake-new-err-info new-err-info))
775    
776  ;; getters/setters for line-err-info: (file, line, type, text).  ;; getters/setters for line-err-info: (file, line, type, text).
777  (defun flymake-ler-make-ler (file line type text &optional full-file)  (defun flymake-ler-make-ler (file line type text &optional full-file)
778      (list file line type text full-file))    (list file line type text full-file))
779    
780  (defun flymake-ler-get-file (line-err-info)  (defun flymake-ler-get-file (line-err-info)
781      (nth 0 line-err-info))    (nth 0 line-err-info))
782    
783  (defun flymake-ler-get-line (line-err-info)  (defun flymake-ler-get-line (line-err-info)
784      (nth 1 line-err-info))    (nth 1 line-err-info))
785    
786  (defun flymake-ler-get-type (line-err-info)  (defun flymake-ler-get-type (line-err-info)
787      (nth 2 line-err-info))    (nth 2 line-err-info))
788    
789  (defun flymake-ler-get-text (line-err-info)  (defun flymake-ler-get-text (line-err-info)
790      (nth 3 line-err-info))    (nth 3 line-err-info))
791    
792  (defun flymake-ler-get-full-file (line-err-info)  (defun flymake-ler-get-full-file (line-err-info)
793      (nth 4 line-err-info))    (nth 4 line-err-info))
794    
795  (defun flymake-ler-set-file (line-err-info file)  (defun flymake-ler-set-file (line-err-info file)
796      (flymake-ler-make-ler file    (flymake-ler-make-ler file
797                          (flymake-ler-get-line line-err-info)                          (flymake-ler-get-line line-err-info)
798                          (flymake-ler-get-type line-err-info)                          (flymake-ler-get-type line-err-info)
799                          (flymake-ler-get-text line-err-info)                          (flymake-ler-get-text line-err-info)
800                          (flymake-ler-get-full-file line-err-info)))                          (flymake-ler-get-full-file line-err-info)))
801    
802  (defun flymake-ler-set-full-file (line-err-info full-file)  (defun flymake-ler-set-full-file (line-err-info full-file)
803      (flymake-ler-make-ler (flymake-ler-get-file line-err-info)    (flymake-ler-make-ler (flymake-ler-get-file line-err-info)
804                          (flymake-ler-get-line line-err-info)                          (flymake-ler-get-line line-err-info)
805                          (flymake-ler-get-type line-err-info)                          (flymake-ler-get-type line-err-info)
806                          (flymake-ler-get-text line-err-info)                          (flymake-ler-get-text line-err-info)
807                          full-file))                          full-file))
808    
809  (defun flymake-ler-set-line (line-err-info line)  (defun flymake-ler-set-line (line-err-info line)
810      (flymake-ler-make-ler (flymake-ler-get-file line-err-info)    (flymake-ler-make-ler (flymake-ler-get-file line-err-info)
811                          line                          line
812                          (flymake-ler-get-type line-err-info)                          (flymake-ler-get-type line-err-info)
813                          (flymake-ler-get-text line-err-info)                          (flymake-ler-get-text line-err-info)
814                          (flymake-ler-get-full-file line-err-info)))                          (flymake-ler-get-full-file line-err-info)))
815    
816  (defun flymake-get-line-err-count (line-err-info-list type)  (defun flymake-get-line-err-count (line-err-info-list type)
817      "Return number of errors of specified TYPE.    "Return number of errors of specified TYPE.
818  Value of TYPE is eigher e or w."  Value of TYPE is eigher e or w."
819      (let* ((idx        0)    (let* ((idx        0)
820             (count      (length line-err-info-list))           (count      (length line-err-info-list))
821             (err-count  0))           (err-count  0))
822    
823          (while (< idx count)      (while (< idx count)
824              (when (equal type (flymake-ler-get-type (nth idx line-err-info-list)))        (when (equal type (flymake-ler-get-type (nth idx line-err-info-list)))
825                  (setq err-count (1+ err-count)))          (setq err-count (1+ err-count)))
826              (setq idx (1+ idx)))        (setq idx (1+ idx)))
827          err-count))      err-count))
828    
829  (defun flymake-get-err-count (err-info-list type)  (defun flymake-get-err-count (err-info-list type)
830      "Return number of errors of specified TYPE for ERR-INFO-LIST."    "Return number of errors of specified TYPE for ERR-INFO-LIST."
831      (let* ((idx        0)    (let* ((idx        0)
832             (count      (length err-info-list))           (count      (length err-info-list))
833             (err-count  0))           (err-count  0))
834          (while (< idx count)      (while (< idx count)
835              (setq err-count (+ err-count (flymake-get-line-err-count (nth 1 (nth idx err-info-list)) type)))        (setq err-count (+ err-count (flymake-get-line-err-count (nth 1 (nth idx err-info-list)) type)))
836              (setq idx (1+ idx)))        (setq idx (1+ idx)))
837          err-count))      err-count))
838    
839  (defun flymake-fix-line-numbers (err-info-list min-line max-line)  (defun flymake-fix-line-numbers (err-info-list min-line max-line)
840      "Replace line numbers with fixed value.    "Replace line numbers with fixed value.
841  If line-numbers is less than MIN-LINE, set line numbers to MIN-LINE.  If line-numbers is less than MIN-LINE, set line numbers to MIN-LINE.
842  If line numbers is greater than MAX-LINE, set line numbers to MAX-LINE.  If line numbers is greater than MAX-LINE, set line numbers to MAX-LINE.
843  The reason for this fix is because some compilers might report  The reason for this fix is because some compilers might report
844  line number outside the file being compiled."  line number outside the file being compiled."
845      (let* ((count     (length err-info-list))    (let* ((count     (length err-info-list))
846             (err-info  nil)           (err-info  nil)
847             (line      0))           (line      0))
848          (while (> count 0)      (while (> count 0)
849              (setq err-info (nth (1- count) err-info-list))        (setq err-info (nth (1- count) err-info-list))
850              (setq line (flymake-er-get-line err-info))        (setq line (flymake-er-get-line err-info))
851              (when (or (< line min-line) (> line max-line))        (when (or (< line min-line) (> line max-line))
852                  (setq line (if (< line min-line) min-line max-line))          (setq line (if (< line min-line) min-line max-line))
853                  (setq err-info-list (flymake-set-at err-info-list (1- count)          (setq err-info-list (flymake-set-at err-info-list (1- count)
854                      (flymake-er-make-er line                                              (flymake-er-make-er line
855                          (flymake-er-get-line-err-info-list err-info)))))                                                                  (flymake-er-get-line-err-info-list err-info)))))
856              (setq count (1- count))))        (setq count (1- count))))
857      err-info-list)    err-info-list)
858    
859  (defun flymake-highlight-err-lines (buffer err-info-list)  (defun flymake-highlight-err-lines (buffer err-info-list)
860      "Highlight error lines in BUFFER using info from ERR-INFO-LIST."    "Highlight error lines in BUFFER using info from ERR-INFO-LIST."
861      (save-excursion    (save-excursion
862          (set-buffer buffer)      (set-buffer buffer)
863          (let* ((idx    0)      (let* ((idx    0)
864                 (count  (length err-info-list)))             (count  (length err-info-list)))
865              (while (< idx count)        (while (< idx count)
866                  (flymake-highlight-line (car (nth idx err-info-list)) (nth 1 (nth idx err-info-list)))          (flymake-highlight-line (car (nth idx err-info-list)) (nth 1 (nth idx err-info-list)))
867                  (setq idx (1+ idx))))))          (setq idx (1+ idx))))))
868    
869  (defun flymake-overlay-p (ov)  (defun flymake-overlay-p (ov)
870       "Determine whether overlay OV was created by flymake."    "Determine whether overlay OV was created by flymake."
871       (and (overlayp ov) (overlay-get ov 'flymake-overlay)))    (and (overlayp ov) (overlay-get ov 'flymake-overlay)))
872    
873  (defun flymake-make-overlay (beg end tooltip-text face mouse-face)  (defun flymake-make-overlay (beg end tooltip-text face mouse-face)
874      "Allocate a flymake overlay in range BEG and END."    "Allocate a flymake overlay in range BEG and END."
875      (when (not (flymake-region-has-flymake-overlays beg end))    (when (not (flymake-region-has-flymake-overlays beg end))
876          (let ((ov (make-overlay beg end nil t t)))      (let ((ov (make-overlay beg end nil t t)))
877              (overlay-put ov 'face           face)        (overlay-put ov 'face           face)
878              (overlay-put ov 'mouse-face     mouse-face)        (overlay-put ov 'mouse-face     mouse-face)
879              (overlay-put ov 'help-echo      tooltip-text)        (overlay-put ov 'help-echo      tooltip-text)
880              (overlay-put ov 'flymake-overlay  t)        (overlay-put ov 'flymake-overlay  t)
881              (overlay-put ov 'priority 100)        (overlay-put ov 'priority 100)
882              ;+(flymake-log 3 "created overlay %s" ov)                                          ;+(flymake-log 3 "created overlay %s" ov)
883              ov)        ov)
884          (flymake-log 3 "created an overlay at (%d-%d)" beg end)))      (flymake-log 3 "created an overlay at (%d-%d)" beg end)))
885    
886  (defun flymake-delete-own-overlays (buffer)  (defun flymake-delete-own-overlays (buffer)
887      "Delete all flymake overlays in BUFFER."    "Delete all flymake overlays in BUFFER."
888      (save-excursion    (save-excursion
889          (set-buffer buffer)      (set-buffer buffer)
890          (let ((ov (overlays-in (point-min) (point-max))))      (let ((ov (overlays-in (point-min) (point-max))))
891              (while (consp ov)        (while (consp ov)
892                  (when (flymake-overlay-p (car ov))          (when (flymake-overlay-p (car ov))
893                      (delete-overlay (car ov))            (delete-overlay (car ov))
894                      ;+(flymake-log 3 "deleted overlay %s" ov)                                          ;+(flymake-log 3 "deleted overlay %s" ov)
895                  )            )
896                  (setq ov (cdr ov))))))          (setq ov (cdr ov))))))
897    
898  (defun flymake-region-has-flymake-overlays (beg end)  (defun flymake-region-has-flymake-overlays (beg end)
899      "Check if region specified by BEG and END has overlay.    "Check if region specified by BEG and END has overlay.
900  Return t if it has at least one flymake overlay, nil if no overlay."  Return t if it has at least one flymake overlay, nil if no overlay."
901      (let ((ov                  (overlays-in beg end))    (let ((ov                  (overlays-in beg end))
902            (has-flymake-overlays  nil))          (has-flymake-overlays  nil))
903          (while (consp ov)      (while (consp ov)
904              (when (flymake-overlay-p (car ov))        (when (flymake-overlay-p (car ov))
905                  (setq has-flymake-overlays t))          (setq has-flymake-overlays t))
906              (setq ov (cdr ov)))))        (setq ov (cdr ov)))))
907    
908  (defface flymake-errline-face  (defface flymake-errline-face
909  ;+   '((((class color)) (:foreground "OrangeRed" :bold t :underline t))                                          ;+   '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
910  ;+   '((((class color)) (:underline "OrangeRed"))                                          ;+   '((((class color)) (:underline "OrangeRed"))
911     '((((class color)) (:background "LightPink"))    '((((class color)) (:background "LightPink"))
912       (t (:bold t)))      (t (:bold t)))
913     "Face used for marking error lines."    "Face used for marking error lines."
914      :group 'flymake)    :group 'flymake)
915    
916  (defface flymake-warnline-face  (defface flymake-warnline-face
917     '((((class color)) (:background "LightBlue2"))    '((((class color)) (:background "LightBlue2"))
918       (t (:bold t)))      (t (:bold t)))
919     "Face used for marking warning lines."    "Face used for marking warning lines."
920      :group 'flymake)    :group 'flymake)
921    
922  (defun flymake-highlight-line (line-no line-err-info-list)  (defun flymake-highlight-line (line-no line-err-info-list)
923      "Highlight line LINE-NO in current buffer.    "Highlight line LINE-NO in current buffer.
924  Perhaps use text from LINE-ERR-INFO-ILST to enhance highlighting."  Perhaps use text from LINE-ERR-INFO-ILST to enhance highlighting."
925      (goto-line line-no)    (goto-line line-no)
926      (let* ((line-beg (flymake-line-beginning-position))    (let* ((line-beg (flymake-line-beginning-position))
927             (line-end (flymake-line-end-position))           (line-end (flymake-line-end-position))
928             (beg      line-beg)           (beg      line-beg)
929             (end      line-end)           (end      line-end)
930             (tooltip-text (flymake-ler-get-text (nth 0 line-err-info-list)))           (tooltip-text (flymake-ler-get-text (nth 0 line-err-info-list)))
931             (face     nil))           (face     nil))
932    
933          (goto-char line-beg)      (goto-char line-beg)
934          (while (looking-at "[ \t]")      (while (looking-at "[ \t]")
935              (forward-char))        (forward-char))
936    
937          (setq beg (point))      (setq beg (point))
938    
939          (goto-char line-end)      (goto-char line-end)
940          (while (and (looking-at "[ \t\r\n]") (> (point) 1))      (while (and (looking-at "[ \t\r\n]") (> (point) 1))
941              (backward-char))        (backward-char))
   
         (setq end (1+ (point)))  
   
         (when (<= end beg)  
             (setq beg line-beg)  
             (setq end line-end))  
   
         (when (= end beg)  
             (goto-char end)  
             (forward-line)  
             (setq end (point)))  
   
         (if (> (flymake-get-line-err-count line-err-info-list "e") 0)  
             (setq face 'flymake-errline-face)  
             (setq face 'flymake-warnline-face))  
942    
943          (flymake-make-overlay beg end tooltip-text face nil)))      (setq end (1+ (point)))
944    
945        (when (<= end beg)
946          (setq beg line-beg)
947          (setq end line-end))
948    
949        (when (= end beg)
950          (goto-char end)
951          (forward-line)
952          (setq end (point)))
953    
954        (if (> (flymake-get-line-err-count line-err-info-list "e") 0)
955            (setq face 'flymake-errline-face)
956          (setq face 'flymake-warnline-face))
957    
958        (flymake-make-overlay beg end tooltip-text face nil)))
959    
960  (defun flymake-parse-err-lines (err-info-list source-buffer lines)  (defun flymake-parse-err-lines (err-info-list source-buffer lines)
961      "Parse err LINES, store info in ERR-INFO-LIST."    "Parse err LINES, store info in ERR-INFO-LIST."
962      (let* ((count              (length lines))    (let* ((count              (length lines))
963             (idx                0)           (idx                0)
964             (line-err-info      nil)           (line-err-info      nil)
965             (real-file-name     nil)           (real-file-name     nil)
966             (source-file-name   (buffer-file-name source-buffer))           (source-file-name   (buffer-file-name source-buffer))
967             (get-real-file-name-f (flymake-get-real-file-name-function source-file-name)))           (get-real-file-name-f (flymake-get-real-file-name-function source-file-name)))
968    
969          (while (< idx count)      (while (< idx count)
970              (setq line-err-info (flymake-parse-line (nth idx lines)))        (setq line-err-info (flymake-parse-line (nth idx lines)))
971              (when line-err-info        (when line-err-info
972                  (setq real-file-name (funcall get-real-file-name-f source-buffer (flymake-ler-get-file line-err-info)))          (setq real-file-name (funcall get-real-file-name-f source-buffer (flymake-ler-get-file line-err-info)))
973                  (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name))          (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name))
974    
975                  (if (flymake-same-files real-file-name source-file-name)          (if (flymake-same-files real-file-name source-file-name)
976                      (setq line-err-info (flymake-ler-set-file line-err-info nil))              (setq line-err-info (flymake-ler-set-file line-err-info nil))
977                      (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))))            (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))))
978    
979                  (setq err-info-list (flymake-add-err-info err-info-list line-err-info)))          (setq err-info-list (flymake-add-err-info err-info-list line-err-info)))
980              (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no"))        (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no"))
981              (setq idx (1+ idx)))        (setq idx (1+ idx)))
982          err-info-list))      err-info-list))
983    
984  (defun flymake-split-output (output)  (defun flymake-split-output (output)
985      "Split OUTPUT into lines.    "Split OUTPUT into lines.
986  Return last one as residual if it does not end with newline char. Returns ((lines) residual)."  Return last one as residual if it does not end with newline char. Returns ((lines) residual)."
987      (when (and output (> (length output) 0))    (when (and output (> (length output) 0))
988          (let* ((lines (flymake-split-string output "[\n\r]+"))      (let* ((lines (flymake-split-string output "[\n\r]+"))
989                 (complete (equal "\n" (char-to-string (aref output (1- (length output))))))             (complete (equal "\n" (char-to-string (aref output (1- (length output))))))
990                 (residual nil))             (residual nil))
991              (when (not complete)        (when (not complete)
992                  (setq residual (car (last lines)))          (setq residual (car (last lines)))
993                  (setq lines (butlast lines)))          (setq lines (butlast lines)))
994              (list lines residual))))        (list lines residual))))
995    
996  (defun flymake-reformat-err-line-patterns-from-compile-el (original-list)  (defun flymake-reformat-err-line-patterns-from-compile-el (original-list)
997      "Grab error line patterns from ORIGINAL-LIST in compile.el format.    "Grab error line patterns from ORIGINAL-LIST in compile.el format.
998  Convert it to flymake internal format."  Convert it to flymake internal format."
999          (let* ((converted-list '()))    (let* ((converted-list '()))
1000          (mapcar      (mapcar
1001              (lambda (item)       (lambda (item)
1002                          (setq item (cdr item))         (setq item (cdr item))
1003                          (let ((regexp (nth 0 item))         (let ((regexp (nth 0 item))
1004                                    (file (nth 1 item))               (file (nth 1 item))
1005                                    (line (nth 2 item))               (line (nth 2 item))
1006                                    (col (nth 3 item))               (col (nth 3 item))
1007                                    end-line)               end-line)
1008                            (if (consp file)      (setq file (car file)))           (if (consp file)       (setq file (car file)))
1009                            (if (consp line)      (setq end-line (cdr line) line (car line)))           (if (consp line)       (setq end-line (cdr line) line (car line)))
1010                            (if (consp col)       (setq col (car col)))           (if (consp col)        (setq col (car col)))
1011    
1012                            (when (not (functionp line))           (when (not (functionp line))
1013                                    (setq converted-list (cons (list regexp file line col) converted-list)))))             (setq converted-list (cons (list regexp file line col) converted-list)))))
1014                  original-list)       original-list)
1015          converted-list))      converted-list))
1016    
1017  (eval-when-compile  (eval-when-compile
1018      (require 'compile))    (require 'compile))
1019    
1020  (defvar flymake-err-line-patterns  ; regexp file-idx line-idx col-idx (optional) text-idx(optional), match-end to end of string is error text  (defvar flymake-err-line-patterns ; regexp file-idx line-idx col-idx (optional) text-idx(optional), match-end to end of string is error text
1021      (append    (append
1022       '(     '(
1023      ; MS Visual C++ 6.0                                          ; MS Visual C++ 6.0
1024         ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)"       ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)"
1025          1 3 nil 4)        1 3 nil 4)
1026      ; jikes                                          ; jikes
1027         ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\|Semantic Error\\):[ \t\n]*\\(.+\\)\\)"       ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\|Semantic Error\\):[ \t\n]*\\(.+\\)\\)"
1028          1 3 nil 4)        1 3 nil 4)
1029      ; MS midl                                          ; MS midl
1030         ("midl[ ]*:[ ]*\\(command line error .*\\)"       ("midl[ ]*:[ ]*\\(command line error .*\\)"
1031          nil nil nil 1)        nil nil nil 1)
1032      ; MS C#                                          ; MS C#
1033         ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\),[0-9]+)\: \\(\\(error\\|warning\\|fatal error\\) \\(CS[0-9]+\\):[ \t\n]*\\(.+\\)\\)"       ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\),[0-9]+)\: \\(\\(error\\|warning\\|fatal error\\) \\(CS[0-9]+\\):[ \t\n]*\\(.+\\)\\)"
1034          1 3 nil 4)        1 3 nil 4)
1035      ; perl                                          ; perl
1036         ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1)       ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1)
1037      ; LaTeX warnings (fileless) ("\\(LaTeX \\(Warning\\|Error\\): .*\\) on input line \\([0-9]+\\)" 20 3 nil 1)                                          ; LaTeX warnings (fileless) ("\\(LaTeX \\(Warning\\|Error\\): .*\\) on input line \\([0-9]+\\)" 20 3 nil 1)
1038      ; ant/javac                                          ; ant/javac
1039             (" *\\(\\[javac\\]\\)? *\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)"       (" *\\(\\[javac\\]\\)? *\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)"
1040          2 4 nil 5))        2 4 nil 5))
1041           ;; compilation-error-regexp-alist)     ;; compilation-error-regexp-alist)
1042       (flymake-reformat-err-line-patterns-from-compile-el compilation-error-regexp-alist-alist))     (flymake-reformat-err-line-patterns-from-compile-el compilation-error-regexp-alist-alist))
1043      "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx). Use flymake-reformat-err-line-patterns-from-compile-el to add patterns from compile.el")    "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx). Use flymake-reformat-err-line-patterns-from-compile-el to add patterns from compile.el")
1044    
1045  ;(defcustom flymake-err-line-patterns                                          ;(defcustom flymake-err-line-patterns
1046  ;  '(                                          ;  '(
1047  ;    ; MS Visual C++ 6.0                                          ;    ; MS Visual C++ 6.0
1048  ;    ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)"                                          ;    ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)"
1049  ;       1 3 4)                                          ;       1 3 4)
1050  ;   ; jikes                                          ;   ; jikes
1051  ;   ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\):[ \t\n]*\\(.+\\)\\)"                                          ;   ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\):[ \t\n]*\\(.+\\)\\)"
1052  ;       1 3 4))                                          ;       1 3 4))
1053  ;    "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx)"                                          ;    "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx)"
1054  ;   :group 'flymake                                          ;   :group 'flymake
1055  ;   :type '(repeat (string number number number))                                          ;   :type '(repeat (string number number number))
1056  ;)                                          ;)
1057    
1058  (defun flymake-parse-line (line)  (defun flymake-parse-line (line)
1059      "Parse LINE to see if it is an error of warning.    "Parse LINE to see if it is an error of warning.
1060  Return its components if so, nil if no."  Return its components if so, nil if no."
1061      (let ((raw-file-name nil)    (let ((raw-file-name nil)
1062            (line-no 0)          (line-no 0)
1063            (err-type "e")          (err-type "e")
1064            (err-text nil)          (err-text nil)
1065            (count (length flymake-err-line-patterns))          (count (length flymake-err-line-patterns))
1066            (idx   0)          (idx   0)
1067            (matched nil))          (matched nil))
1068          (while (and (< idx count) (not matched))      (while (and (< idx count) (not matched))
1069              (when (string-match (car (nth idx flymake-err-line-patterns)) line)        (when (string-match (car (nth idx flymake-err-line-patterns)) line)
1070                  (let* ((file-idx (nth 1 (nth idx flymake-err-line-patterns)))          (let* ((file-idx (nth 1 (nth idx flymake-err-line-patterns)))
1071                         (line-idx (nth 2 (nth idx flymake-err-line-patterns))))                 (line-idx (nth 2 (nth idx flymake-err-line-patterns))))
1072    
1073                      (setq raw-file-name (if file-idx (match-string file-idx line) nil))            (setq raw-file-name (if file-idx (match-string file-idx line) nil))
1074                      (setq line-no       (if line-idx (string-to-int (match-string line-idx line)) 0))            (setq line-no       (if line-idx (string-to-int (match-string line-idx line)) 0))
1075                      (setq err-text      (if (> (length (nth idx flymake-err-line-patterns)) 4)            (setq err-text      (if (> (length (nth idx flymake-err-line-patterns)) 4)
1076                                              (match-string (nth 4 (nth idx flymake-err-line-patterns)) line)                                    (match-string (nth 4 (nth idx flymake-err-line-patterns)) line)
1077                                            (flymake-patch-err-text (substring line (match-end 0)))))                                  (flymake-patch-err-text (substring line (match-end 0)))))
1078                      (or err-text (setq err-text "<no error text>"))            (or err-text (setq err-text "<no error text>"))
1079                      (if (and err-text (string-match "^[wW]arning" err-text))            (if (and err-text (string-match "^[wW]arning" err-text))
1080                          (setq err-type "w")                (setq err-type "w")
1081                      )              )
1082                      (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx            (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx
1083                                   raw-file-name line-no err-text)                         raw-file-name line-no err-text)
1084                      (setq matched t)))            (setq matched t)))
1085              (setq idx (1+ idx)))        (setq idx (1+ idx)))
1086          (if matched      (if matched
1087             (flymake-ler-make-ler raw-file-name line-no err-type err-text)          (flymake-ler-make-ler raw-file-name line-no err-type err-text)
1088             ())))        ())))
1089    
1090  (defun flymake-find-err-info (err-info-list line-no)  (defun flymake-find-err-info (err-info-list line-no)
1091      "Find (line-err-info-list pos) for specified LINE-NO."    "Find (line-err-info-list pos) for specified LINE-NO."
1092      (if err-info-list    (if err-info-list
1093          (let* ((line-err-info-list  nil)        (let* ((line-err-info-list  nil)
1094                 (pos       0)               (pos       0)
1095                 (count     (length err-info-list)))               (count     (length err-info-list)))
1096    
1097              (while (and (< pos count) (< (car (nth pos err-info-list)) line-no))          (while (and (< pos count) (< (car (nth pos err-info-list)) line-no))
1098                  (setq pos (1+ pos)))            (setq pos (1+ pos)))
1099              (when (and (< pos count) (equal (car (nth pos err-info-list)) line-no))          (when (and (< pos count) (equal (car (nth pos err-info-list)) line-no))
1100                  (setq line-err-info-list (flymake-er-get-line-err-info-list (nth pos err-info-list))))            (setq line-err-info-list (flymake-er-get-line-err-info-list (nth pos err-info-list))))
1101              (list line-err-info-list pos))          (list line-err-info-list pos))
1102          '(nil 0)))      '(nil 0)))
1103    
1104  (defun flymake-line-err-info-is-less-or-equal (line-one line-two)  (defun flymake-line-err-info-is-less-or-equal (line-one line-two)
1105      (or (string< (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))    (or (string< (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))
1106          (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))        (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))
1107               (not (flymake-ler-get-file line-one)) (flymake-ler-get-file line-two))             (not (flymake-ler-get-file line-one)) (flymake-ler-get-file line-two))
1108          (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))        (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two))
1109               (or (and      (flymake-ler-get-file line-one)       (flymake-ler-get-file line-two))             (or (and      (flymake-ler-get-file line-one)       (flymake-ler-get-file line-two))
1110                   (and (not (flymake-ler-get-file line-one)) (not (flymake-ler-get-file line-two)))))))                 (and (not (flymake-ler-get-file line-one)) (not (flymake-ler-get-file line-two)))))))
1111    
1112  (defun flymake-add-line-err-info (line-err-info-list line-err-info)  (defun flymake-add-line-err-info (line-err-info-list line-err-info)
1113      "Insert new err info favoring sorting: err-type e/w, filename nil/non-nil."    "Insert new err info favoring sorting: err-type e/w, filename nil/non-nil."
1114      (if (not line-err-info-list)    (if (not line-err-info-list)
1115          (list line-err-info)        (list line-err-info)
1116          (let* ((count  (length line-err-info-list))      (let* ((count  (length line-err-info-list))
1117                 (idx    0))             (idx    0))
1118              (while (and (< idx count) (flymake-line-err-info-is-less-or-equal (nth idx line-err-info-list) line-err-info))        (while (and (< idx count) (flymake-line-err-info-is-less-or-equal (nth idx line-err-info-list) line-err-info))
1119                  (setq idx (1+ idx)))          (setq idx (1+ idx)))
1120              (cond ((equal 0     idx)    (setq line-err-info-list (cons line-err-info line-err-info-list)))        (cond ((equal 0     idx)    (setq line-err-info-list (cons line-err-info line-err-info-list)))
1121                    (t                    (setq line-err-info-list (flymake-ins-after line-err-info-list (1- idx) line-err-info))))              (t                    (setq line-err-info-list (flymake-ins-after line-err-info-list (1- idx) line-err-info))))
1122              line-err-info-list)))        line-err-info-list)))
1123    
1124  (defun flymake-add-err-info (err-info-list line-err-info)  (defun flymake-add-err-info (err-info-list line-err-info)
1125      "Add error info (file line type text) to err info list preserving sort order."    "Add error info (file line type text) to err info list preserving sort order."
1126      (let* ((count               (length err-info-list))    (let* ((count               (length err-info-list))
1127             (line-no             (if (flymake-ler-get-file line-err-info) 1 (flymake-ler-get-line line-err-info)))           (line-no             (if (flymake-ler-get-file line-err-info) 1 (flymake-ler-get-line line-err-info)))
1128             (info-and-pos        (flymake-find-err-info err-info-list line-no))           (info-and-pos        (flymake-find-err-info err-info-list line-no))
1129             (exists              (car info-and-pos))           (exists              (car info-and-pos))
1130             (pos                 (nth 1 info-and-pos))           (pos                 (nth 1 info-and-pos))
1131             (line-err-info-list  nil)           (line-err-info-list  nil)
1132             (err-info            nil))           (err-info            nil))
1133    
1134          (if exists      (if exists
1135              (setq line-err-info-list (flymake-er-get-line-err-info-list (car (nthcdr pos err-info-list)))))          (setq line-err-info-list (flymake-er-get-line-err-info-list (car (nthcdr pos err-info-list)))))
1136          (setq line-err-info-list (flymake-add-line-err-info line-err-info-list line-err-info))      (setq line-err-info-list (flymake-add-line-err-info line-err-info-list line-err-info))
1137    
1138          (setq err-info (flymake-er-make-er line-no line-err-info-list))      (setq err-info (flymake-er-make-er line-no line-err-info-list))
1139          (cond (exists             (setq err-info-list (flymake-set-at err-info-list pos err-info)))      (cond (exists             (setq err-info-list (flymake-set-at err-info-list pos err-info)))
1140                ((equal 0 pos)      (setq err-info-list (cons err-info err-info-list)))            ((equal 0 pos)      (setq err-info-list (cons err-info err-info-list)))
1141                (t                  (setq err-info-list (flymake-ins-after err-info-list (1- pos) err-info))))            (t                  (setq err-info-list (flymake-ins-after err-info-list (1- pos) err-info))))
1142          err-info-list))      err-info-list))
1143    
1144  (defun flymake-get-project-include-dirs-imp (basedir)  (defun flymake-get-project-include-dirs-imp (basedir)
1145      "Include dirs for the project current file belongs to."    "Include dirs for the project current file belongs to."
1146      (if (flymake-get-project-include-dirs-from-cache basedir)    (if (flymake-get-project-include-dirs-from-cache basedir)
1147          (progn        (progn
1148              (flymake-get-project-include-dirs-from-cache basedir))          (flymake-get-project-include-dirs-from-cache basedir))
1149      ;else                                          ;else
1150          (let* ((command-line  (concat "make -C\"" basedir "\" DUMPVARS=INCLUDE_DIRS dumpvars"))      (let* ((command-line  (concat "make -C\"" basedir "\" DUMPVARS=INCLUDE_DIRS dumpvars"))
1151                 (output        (shell-command-to-string command-line))             (output        (shell-command-to-string command-line))
1152                 (lines         (flymake-split-string output "\n"))             (lines         (flymake-split-string output "\n"))
1153                 (count         (length lines))             (count         (length lines))
1154                 (idx           0)             (idx           0)
1155                 (inc-dirs      nil))             (inc-dirs      nil))
1156              (while (and (< idx count) (not (string-match "^INCLUDE_DIRS=.*" (nth idx lines))))        (while (and (< idx count) (not (string-match "^INCLUDE_DIRS=.*" (nth idx lines))))
1157                 (setq idx (1+ idx)))          (setq idx (1+ idx)))
1158              (when (< idx count)        (when (< idx count)
1159                  (let* ((inc-lines  (flymake-split-string (nth idx lines) " *-I"))          (let* ((inc-lines  (flymake-split-string (nth idx lines) " *-I"))
1160                         (inc-count  (length inc-lines)))                 (inc-count  (length inc-lines)))
1161                      (while (> inc-count 0)            (while (> inc-count 0)
1162                          (when (not (string-match "^INCLUDE_DIRS=.*" (nth (1- inc-count) inc-lines)))              (when (not (string-match "^INCLUDE_DIRS=.*" (nth (1- inc-count) inc-lines)))
1163                              (setq inc-dirs (cons (flymake-replace-regexp-in-string "\"" "" (nth (1- inc-count) inc-lines)) inc-dirs)))                (setq inc-dirs (cons (flymake-replace-regexp-in-string "\"" "" (nth (1- inc-count) inc-lines)) inc-dirs)))
1164                          (setq inc-count (1- inc-count)))))              (setq inc-count (1- inc-count)))))
1165              (flymake-add-project-include-dirs-to-cache basedir inc-dirs)        (flymake-add-project-include-dirs-to-cache basedir inc-dirs)
1166              inc-dirs)))        inc-dirs)))
1167    
1168  (defcustom flymake-get-project-include-dirs-function 'flymake-get-project-include-dirs-imp  (defcustom flymake-get-project-include-dirs-function 'flymake-get-project-include-dirs-imp
1169      "Function used to get project inc dirs, one paramater: basedir name."    "Function used to get project inc dirs, one paramater: basedir name."
1170      :group 'flymake    :group 'flymake
1171      :type 'function)    :type 'function)
1172    
1173  (defun flymake-get-project-include-dirs (basedir)  (defun flymake-get-project-include-dirs (basedir)
1174      (funcall flymake-get-project-include-dirs-function basedir))    (funcall flymake-get-project-include-dirs-function basedir))
1175    
1176  (defun flymake-get-system-include-dirs ()  (defun flymake-get-system-include-dirs ()
1177      "System include dirs - from the 'INCLUDE' env setting."    "System include dirs - from the 'INCLUDE' env setting."
1178      (let* ((includes (getenv "INCLUDE")))    (let* ((includes (getenv "INCLUDE")))
1179          (if includes (flymake-split-string includes path-separator) nil)))      (if includes (flymake-split-string includes path-separator) nil)))
1180    
1181  (defvar flymake-project-include-dirs-cache (flymake-makehash 'equal))  (defvar flymake-project-include-dirs-cache (flymake-makehash 'equal))
1182    
1183  (defun flymake-get-project-include-dirs-from-cache (base-dir)  (defun flymake-get-project-include-dirs-from-cache (base-dir)
1184      (gethash base-dir flymake-project-include-dirs-cache))    (gethash base-dir flymake-project-include-dirs-cache))
1185    
1186  (defun flymake-add-project-include-dirs-to-cache (base-dir include-dirs)  (defun flymake-add-project-include-dirs-to-cache (base-dir include-dirs)
1187      (puthash base-dir include-dirs flymake-project-include-dirs-cache))    (puthash base-dir include-dirs flymake-project-include-dirs-cache))
1188    
1189  (defun flymake-clear-project-include-dirs-cache ()  (defun flymake-clear-project-include-dirs-cache ()
1190      (clrhash flymake-project-include-dirs-cache))    (clrhash flymake-project-include-dirs-cache))
1191    
1192  (defun flymake-get-include-dirs (base-dir)  (defun flymake-get-include-dirs (base-dir)
1193      "Get dirs to use when resolving local file names."    "Get dirs to use when resolving local file names."
1194      (let* ((include-dirs (append '(".") (flymake-get-project-include-dirs base-dir) (flymake-get-system-include-dirs))))    (let* ((include-dirs (append '(".") (flymake-get-project-include-dirs base-dir) (flymake-get-system-include-dirs))))
1195          include-dirs))      include-dirs))
1196    
1197  (defun flymake-find-file (rel-file-name include-dirs)  (defun flymake-find-file (rel-file-name include-dirs)
1198      "Iterate through include-dirs to find file REL-FILE-NAME.    "Iterate through include-dirs to find file REL-FILE-NAME.
1199  Return first 'INCLUDE-DIRS/REL-FILE-NAME' that exists,  or just REL-FILE-NAME if not."  Return first 'INCLUDE-DIRS/REL-FILE-NAME' that exists,  or just REL-FILE-NAME if not."
1200      (let* ((count          (length include-dirs))    (let* ((count          (length include-dirs))
1201             (idx            0)           (idx            0)
1202             (found          nil)           (found          nil)
1203             (full-file-name rel-file-name))           (full-file-name rel-file-name))
1204    
1205          (while (and (not found) (< idx count))      (while (and (not found) (< idx count))
1206              (let* ((dir (nth idx include-dirs)))        (let* ((dir (nth idx include-dirs)))
1207                  (setq full-file-name  (concat dir "/" rel-file-name))          (setq full-file-name  (concat dir "/" rel-file-name))
1208                  (when (file-exists-p full-file-name)          (when (file-exists-p full-file-name)
1209                      (setq found t)))            (setq found t)))
1210              (setq idx (1+ idx)))        (setq idx (1+ idx)))
1211          (if found      (if found
1212              full-file-name          full-file-name
1213              rel-file-name)))        rel-file-name)))
1214    
1215  (defun flymake-restore-formatting (source-buffer)  (defun flymake-restore-formatting (source-buffer)
1216      "Remove any formatting made by flymake."    "Remove any formatting made by flymake."
1217  )    )
1218    
1219  (defun flymake-get-program-dir (buffer)  (defun flymake-get-program-dir (buffer)
1220      "Get dir to start program in."    "Get dir to start program in."
1221      (unless (bufferp buffer)    (unless (bufferp buffer)
1222          (error "Invlid buffer"))      (error "Invlid buffer"))
1223      (save-excursion    (save-excursion
1224          (set-buffer buffer)      (set-buffer buffer)
1225          default-directory))      default-directory))
1226    
1227  (defun flymake-safe-delete-file (file-name)  (defun flymake-safe-delete-file (file-name)
1228      (when (and file-name (file-exists-p file-name))    (when (and file-name (file-exists-p file-name))
1229          (delete-file file-name)      (delete-file file-name)
1230          (flymake-log 1 "deleted file %s" file-name)))      (flymake-log 1 "deleted file %s" file-name)))
1231    
1232  (defun flymake-safe-delete-directory (dir-name)  (defun flymake-safe-delete-directory (dir-name)
1233      (condition-case err    (condition-case err
1234          (progn        (progn
1235              (delete-directory dir-name)          (delete-directory dir-name)
1236              (flymake-log 1 "deleted dir %s" dir-name))          (flymake-log 1 "deleted dir %s" dir-name))
1237          (error      (error
1238              (flymake-log 1 "Failed to delete dir %s, error ignored" dir-name))))       (flymake-log 1 "Failed to delete dir %s, error ignored" dir-name))))
1239    
1240  (defcustom flymake-compilation-prevents-syntax-check t  (defcustom flymake-compilation-prevents-syntax-check t
1241       "If non-nil, syntax check won't be started in case compilation is running."    "If non-nil, syntax check won't be started in case compilation is running."
1242      :group 'flymake    :group 'flymake
1243      :type 'boolean)    :type 'boolean)
1244    
1245  (defun flymake-start-syntax-check (buffer)  (defun flymake-start-syntax-check (buffer)
1246      "Start syntax checking for buffer BUFFER."    "Start syntax checking for buffer BUFFER."
1247      (unless (bufferp buffer)    (unless (bufferp buffer)
1248          (error "Expected a buffer"))      (error "Expected a buffer"))
1249      (save-excursion    (save-excursion
1250          (set-buffer buffer)      (set-buffer buffer)
1251          (flymake-log 3 "flymake is running: %s" (flymake-get-buffer-is-running buffer))      (flymake-log 3 "flymake is running: %s" (flymake-get-buffer-is-running buffer))
1252          (when (and (not (flymake-get-buffer-is-running buffer))      (when (and (not (flymake-get-buffer-is-running buffer))
1253                     (flymake-can-syntax-check-file (buffer-file-name buffer)))                 (flymake-can-syntax-check-file (buffer-file-name buffer)))
1254              (when (or (not flymake-compilation-prevents-syntax-check)        (when (or (not flymake-compilation-prevents-syntax-check)
1255                      (not (flymake-compilation-is-running))) ;+ (flymake-rep-ort-status buffer "COMP")                  (not (flymake-compilation-is-running))) ;+ (flymake-rep-ort-status buffer "COMP")
1256                  (flymake-clear-buildfile-cache)          (flymake-clear-buildfile-cache)
1257                  (flymake-clear-project-include-dirs-cache)          (flymake-clear-project-include-dirs-cache)
1258    
1259                  (flymake-set-buffer-check-was-interrupted buffer nil)          (flymake-set-buffer-check-was-interrupted buffer nil)
1260                  (flymake-set-buffer-data buffer (flymake-makehash 'equal))          (flymake-set-buffer-data buffer (flymake-makehash 'equal))
1261    
1262                  (let* ((source-file-name  (buffer-file-name buffer))          (let* ((source-file-name  (buffer-file-name buffer))
1263                         (init-f (flymake-get-init-function source-file-name))                 (init-f (flymake-get-init-function source-file-name))
1264                         (cleanup-f (flymake-get-cleanup-function source-file-name))                 (cleanup-f (flymake-get-cleanup-function source-file-name))
1265                         (cmd-and-args (funcall init-f buffer))                 (cmd-and-args (funcall init-f buffer))
1266                         (cmd          (nth 0 cmd-and-args))                 (cmd          (nth 0 cmd-and-args))
1267                         (args         (nth 1 cmd-and-args))                 (args         (nth 1 cmd-and-args))
1268                                             (dir          (nth 2 cmd-and-args)))                 (dir          (nth 2 cmd-and-args)))
1269                      (if (not cmd-and-args)            (if (not cmd-and-args)
1270                          (progn                (progn
1271                              (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name)                  (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name)
1272                              (funcall cleanup-f buffer))                  (funcall cleanup-f buffer))
1273                          (progn              (progn
1274                              (flymake-set-buffer-last-change-time buffer nil)                (flymake-set-buffer-last-change-time buffer nil)
1275                              (flymake-start-syntax-check-process buffer cmd args dir))))))))                (flymake-start-syntax-check-process buffer cmd args dir))))))))
1276    
1277  (defun flymake-start-syntax-check-process (buffer cmd args dir)  (defun flymake-start-syntax-check-process (buffer cmd args dir)
1278      "Start syntax check process."    "Start syntax check process."
1279      (let* ((process nil))    (let* ((process nil))
1280          (condition-case err      (condition-case err
1281              (progn          (progn
1282                  (when dir            (when dir
1283                      (let ((default-directory dir))              (let ((default-directory dir))
1284                            (flymake-log 3 "starting process on dir %s" default-directory)))                (flymake-log 3 "starting process on dir %s" default-directory)))
1285                  (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args)))            (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args)))
1286                  (set-process-sentinel process 'flymake-process-sentinel)            (set-process-sentinel process 'flymake-process-sentinel)
1287                  (set-process-filter process 'flymake-process-filter)            (set-process-filter process 'flymake-process-filter)
1288    
1289                  (flymake-reg-names (process-id process) (buffer-name buffer))            (flymake-reg-names (process-id process) (buffer-name buffer))
1290    
1291                  (flymake-set-buffer-is-running buffer t)            (flymake-set-buffer-is-running buffer t)
1292                  (flymake-set-buffer-last-change-time buffer nil)            (flymake-set-buffer-last-change-time buffer nil)
1293                  (flymake-set-buffer-check-start-time buffer (flymake-float-time))            (flymake-set-buffer-check-start-time buffer (flymake-float-time))
1294    
1295                  (flymake-report-status buffer nil "*")            (flymake-report-status buffer nil "*")
1296                  (flymake-log 2 "started process %d, command=%s, dir=%s"            (flymake-log 2 "started process %d, command=%s, dir=%s"
1297                             (process-id process) (process-command process) default-directory)                         (process-id process) (process-command process) default-directory)
1298                  process)            process)
1299              (error        (error
1300                  (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s"         (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s"
1301                               cmd args (error-message-string err)))                                 cmd args (error-message-string err)))
1302                        (source-file-name (buffer-file-name buffer))                (source-file-name (buffer-file-name buffer))
1303                        (cleanup-f        (flymake-get-cleanup-function source-file-name)))                (cleanup-f        (flymake-get-cleanup-function source-file-name)))
1304                      (flymake-log 0 err-str)           (flymake-log 0 err-str)
1305                      (funcall cleanup-f buffer)           (funcall cleanup-f buffer)
1306                      (flymake-report-fatal-status buffer "PROCERR" err-str))))))           (flymake-report-fatal-status buffer "PROCERR" err-str))))))
1307    
1308  (defun flymake-kill-process (pid &optional rest)  (defun flymake-kill-process (pid &optional rest)
1309      "Kill process PID."    "Kill process PID."
1310      (signal-process pid 9)    (signal-process pid 9)
1311      (let* ((buffer-name (flymake-get-source-buffer-name pid)))    (let* ((buffer-name (flymake-get-source-buffer-name pid)))
1312          (when (and buffer-name (get-buffer buffer-name))      (when (and buffer-name (get-buffer buffer-name))
1313              (flymake-set-buffer-check-was-interrupted (get-buffer buffer-name) t)))        (flymake-set-buffer-check-was-interrupted (get-buffer buffer-name) t)))
1314      (flymake-log 1 "killed process %d" pid))    (flymake-log 1 "killed process %d" pid))
1315    
1316  (defun flymake-stop-all-syntax-checks ()  (defun flymake-stop-all-syntax-checks ()
1317      "Kill all syntax check processes."    "Kill all syntax check processes."
1318      (interactive)    (interactive)
1319      (let ((pids  (copy-hash-table flymake-pid-to-names)))    (let ((pids  (copy-hash-table flymake-pid-to-names)))
1320          (maphash 'flymake-kill-process pids)))      (maphash 'flymake-kill-process pids)))
1321    
1322  (defun flymake-compilation-is-running ()  (defun flymake-compilation-is-running ()
1323     (and (boundp 'compilation-in-progress)    (and (boundp 'compilation-in-progress)
1324          compilation-in-progress))         compilation-in-progress))
1325    
1326  (defun flymake-compile ()  (defun flymake-compile ()
1327      "Kill all flymake syntax checks, start compilation."    "Kill all flymake syntax checks, start compilation."
1328      (interactive)    (interactive)
1329      (flymake-stop-all-syntax-checks)    (flymake-stop-all-syntax-checks)
1330      (call-interactively 'compile))    (call-interactively 'compile))
1331    
1332  (defvar flymake-is-running nil  (defvar flymake-is-running nil
1333    "If t, flymake syntax check process is running for the current buffer")    "If t, flymake syntax check process is running for the current buffer")
# Line 1350  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1335  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1335  (make-variable-buffer-local 'flymake-is-running)  (make-variable-buffer-local 'flymake-is-running)
1336    
1337  (defun flymake-get-buffer-is-running (buffer)  (defun flymake-get-buffer-is-running (buffer)
1338      (flymake-get-buffer-var buffer 'flymake-is-running))    (flymake-get-buffer-var buffer 'flymake-is-running))
1339    
1340  (defun flymake-set-buffer-is-running (buffer is-running)  (defun flymake-set-buffer-is-running (buffer is-running)
1341      (flymake-set-buffer-var buffer 'flymake-is-running is-running))    (flymake-set-buffer-var buffer 'flymake-is-running is-running))
1342    
1343  (defvar flymake-timer nil  (defvar flymake-timer nil
1344    "Timer for starting syntax check.")    "Timer for starting syntax check.")
# Line 1361  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1346  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1346  (make-variable-buffer-local 'flymake-timer)  (make-variable-buffer-local 'flymake-timer)
1347    
1348  (defun flymake-get-buffer-timer (buffer)  (defun flymake-get-buffer-timer (buffer)
1349      (flymake-get-buffer-var buffer 'flymake-timer))    (flymake-get-buffer-var buffer 'flymake-timer))
1350    
1351  (defun flymake-set-buffer-timer (buffer timer)  (defun flymake-set-buffer-timer (buffer timer)
1352      (flymake-set-buffer-var buffer 'flymake-timer timer))    (flymake-set-buffer-var buffer 'flymake-timer timer))
1353    
1354  (defvar flymake-last-change-time nil  (defvar flymake-last-change-time nil
1355    "Time of last buffer change.")    "Time of last buffer change.")
# Line 1372  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1357  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1357  (make-variable-buffer-local 'flymake-last-change-time)  (make-variable-buffer-local 'flymake-last-change-time)
1358    
1359  (defun flymake-get-buffer-last-change-time (buffer)  (defun flymake-get-buffer-last-change-time (buffer)
1360      (flymake-get-buffer-var buffer 'flymake-last-change-time))    (flymake-get-buffer-var buffer 'flymake-last-change-time))
1361    
1362  (defun flymake-set-buffer-last-change-time (buffer change-time)  (defun flymake-set-buffer-last-change-time (buffer change-time)
1363      (flymake-set-buffer-var buffer 'flymake-last-change-time change-time))    (flymake-set-buffer-var buffer 'flymake-last-change-time change-time))
1364    
1365  (defvar flymake-check-start-time nil  (defvar flymake-check-start-time nil
1366    "Time at which syntax check was started.")    "Time at which syntax check was started.")
# Line 1383  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1368  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1368  (make-variable-buffer-local 'flymake-check-start-time)  (make-variable-buffer-local 'flymake-check-start-time)
1369    
1370  (defun flymake-get-buffer-check-start-time (buffer)  (defun flymake-get-buffer-check-start-time (buffer)
1371      (flymake-get-buffer-var buffer 'flymake-check-start-time))    (flymake-get-buffer-var buffer 'flymake-check-start-time))
1372    
1373  (defun flymake-set-buffer-check-start-time (buffer check-start-time)  (defun flymake-set-buffer-check-start-time (buffer check-start-time)
1374      (flymake-set-buffer-var buffer 'flymake-check-start-time check-start-time))    (flymake-set-buffer-var buffer 'flymake-check-start-time check-start-time))
1375    
1376  (defvar flymake-check-was-interrupted nil  (defvar flymake-check-was-interrupted nil
1377    "t if syntax check was killed by flymake-compile")    "t if syntax check was killed by flymake-compile")
# Line 1394  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1379  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1379  (make-variable-buffer-local 'flymake-check-was-interrupted)  (make-variable-buffer-local 'flymake-check-was-interrupted)
1380    
1381  (defun flymake-get-buffer-check-was-interrupted (buffer)  (defun flymake-get-buffer-check-was-interrupted (buffer)
1382      (flymake-get-buffer-var buffer 'flymake-check-was-interrupted))    (flymake-get-buffer-var buffer 'flymake-check-was-interrupted))
1383    
1384  (defun flymake-set-buffer-check-was-interrupted (buffer interrupted)  (defun flymake-set-buffer-check-was-interrupted (buffer interrupted)
1385      (flymake-set-buffer-var buffer 'flymake-check-was-interrupted interrupted))    (flymake-set-buffer-var buffer 'flymake-check-was-interrupted interrupted))
1386    
1387  (defcustom flymake-no-changes-timeout 0.5  (defcustom flymake-no-changes-timeout 0.5
1388      "Time to wait after last change before starting compilation."    "Time to wait after last change before starting compilation."
1389      :group 'flymake    :group 'flymake
1390      :type 'number)    :type 'number)
1391    
1392  (defun flymake-on-timer-event (buffer)  (defun flymake-on-timer-event (buffer)
1393      "Start a syntax check for buffer BUFFER if necessary."    "Start a syntax check for buffer BUFFER if necessary."
1394      ;+(flymake-log 3 "timer: running=%s, time=%s, cur-time=%s" (flymake-get-buffer-is-running buffer) (flymake-get-buffer-last-change-time buffer) (flymake-float-time))                                          ;+(flymake-log 3 "timer: running=%s, time=%s, cur-time=%s" (flymake-get-buffer-is-running buffer) (flymake-get-buffer-last-change-time buffer) (flymake-float-time))
1395       (when (and (bufferp buffer) (not (flymake-get-buffer-is-running buffer)))    (when (and (bufferp buffer) (not (flymake-get-buffer-is-running buffer)))
1396          (save-excursion      (save-excursion
1397              (set-buffer buffer)        (set-buffer buffer)
1398              (when (and (flymake-get-buffer-last-change-time buffer)        (when (and (flymake-get-buffer-last-change-time buffer)
1399                         (> (flymake-float-time) (+ flymake-no-changes-timeout (flymake-get-buffer-last-change-time buffer))))                   (> (flymake-float-time) (+ flymake-no-changes-timeout (flymake-get-buffer-last-change-time buffer))))
1400                  (flymake-set-buffer-last-change-time buffer nil)          (flymake-set-buffer-last-change-time buffer nil)
1401                  (flymake-log 3 "starting syntax check as more than 1 second passed since last change")          (flymake-log 3 "starting syntax check as more than 1 second passed since last change")
1402                  (flymake-start-syntax-check buffer)))))          (flymake-start-syntax-check buffer)))))
1403    
1404  (defun flymake-start-syntax-check-for-current-buffer ()  (defun flymake-start-syntax-check-for-current-buffer ()
1405      "Run 'flymake-start-syntax-check' for current buffer if it isn't already running."    "Run 'flymake-start-syntax-check' for current buffer if it isn't already running."
1406      (interactive)    (interactive)
1407      (flymake-start-syntax-check (current-buffer)))    (flymake-start-syntax-check (current-buffer)))
1408    
1409  (defun flymake-current-line-no ()  (defun flymake-current-line-no ()
1410      "Return number of current line in current buffer."    "Return number of current line in current buffer."
1411      (interactive)    (interactive)
1412      (let ((beg  (point-min))    (let ((beg  (point-min))
1413            (end  (if (= (point) (point-max)) (point) (1+ (point)))))          (end  (if (= (point) (point-max)) (point) (1+ (point)))))
1414          (count-lines beg end)))      (count-lines beg end)))
1415    
1416  (defun flymake-get-line-count (buffer)  (defun flymake-get-line-count (buffer)
1417      "Return number of lines in buffer BUFFER."    "Return number of lines in buffer BUFFER."
1418      (unless (bufferp buffer)    (unless (bufferp buffer)
1419          (error "Invalid buffer"))      (error "Invalid buffer"))
1420      (save-excursion    (save-excursion
1421          (set-buffer buffer)      (set-buffer buffer)
1422          (count-lines (point-min) (point-max))))      (count-lines (point-min) (point-max))))
1423    
1424  (defun flymake-count-lines (buffer)  (defun flymake-count-lines (buffer)
1425      "Return number of lines in buffer BUFFER."    "Return number of lines in buffer BUFFER."
1426      (save-excursion    (save-excursion
1427          (set-buffer buffer)      (set-buffer buffer)
1428          (count-lines (point-min) (point-max))))      (count-lines (point-min) (point-max))))
1429    
1430  (defun flymake-get-point-pixel-pos ()  (defun flymake-get-point-pixel-pos ()
1431      "Return point position in pixels: (x, y)."    "Return point position in pixels: (x, y)."
1432      (let ((mouse-pos  (mouse-position))    (let ((mouse-pos  (mouse-position))
1433            (pixel-pos  nil)          (pixel-pos  nil)
1434            (ret        nil))          (ret        nil))
1435          (if (car (cdr mouse-pos))      (if (car (cdr mouse-pos))
1436              (progn          (progn
1437                  (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row))            (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row))
1438                  (setq pixel-pos (mouse-pixel-position))            (setq pixel-pos (mouse-pixel-position))
1439                  (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos)))            (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos)))
1440                  (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))))            (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))))
1441              (progn        (progn
1442                  (setq ret '(0 0))))          (setq ret '(0 0))))
1443          (flymake-log 3 "mouse pos is %s" ret)      (flymake-log 3 "mouse pos is %s" ret)
1444          ret))      ret))
1445    
1446  (defun flymake-display-err-menu-for-current-line ()  (defun flymake-display-err-menu-for-current-line ()
1447     "Display a menu with errors/warnings for current line if it has errors and/or warnings."    "Display a menu with errors/warnings for current line if it has errors and/or warnings."
1448     (interactive)    (interactive)
1449     (let* ((line-no             (flymake-current-line-no))    (let* ((line-no             (flymake-current-line-no))
1450            (line-err-info-list  (nth 0 (flymake-find-err-info (flymake-get-buffer-err-info (current-buffer)) line-no)))           (line-err-info-list  (nth 0 (flymake-find-err-info (flymake-get-buffer-err-info (current-buffer)) line-no)))
1451            (menu-data           (flymake-make-err-menu-data line-no line-err-info-list))           (menu-data           (flymake-make-err-menu-data line-no line-err-info-list))
1452            (choice              nil)           (choice              nil)
1453            (mouse-pos           (flymake-get-point-pixel-pos))           (mouse-pos           (flymake-get-point-pixel-pos))
1454            (moved-mouse-pos     (list (car mouse-pos) (+ 10 (car (cdr mouse-pos)))))           (moved-mouse-pos     (list (car mouse-pos) (+ 10 (car (cdr mouse-pos)))))
1455            (menu-pos            (list (flymake-get-point-pixel-pos) (selected-window))))           (menu-pos            (list (flymake-get-point-pixel-pos) (selected-window))))
1456         (if menu-data      (if menu-data
1457             (progn          (progn
1458                 (setq choice (flymake-popup-menu menu-pos menu-data))            (setq choice (flymake-popup-menu menu-pos menu-data))
1459                             (flymake-log 3 "choice=%s" choice)            (flymake-log 3 "choice=%s" choice)
1460                 (when choice            (when choice
1461                                 (eval choice)))              (eval choice)))
1462             (flymake-log 1 "no errors for line %d" line-no))))        (flymake-log 1 "no errors for line %d" line-no))))
1463    
1464  (defun flymake-make-err-menu-data (line-no line-err-info-list)  (defun flymake-make-err-menu-data (line-no line-err-info-list)
1465     "Make a (menu-title (item-title item-action)*) list with errors/warnings from line-err-info."    "Make a (menu-title (item-title item-action)*) list with errors/warnings from line-err-info."
1466     (let* ((menu-items  nil))    (let* ((menu-items  nil))
1467         (when line-err-info-list      (when line-err-info-list
1468             (let* ((count           (length line-err-info-list))        (let* ((count           (length line-err-info-list))
1469                    (menu-item-text  nil))               (menu-item-text  nil))
1470                 (while (> count 0)          (while (> count 0)
1471                      (setq menu-item-text (flymake-ler-get-text (nth (1- count) line-err-info-list)))            (setq menu-item-text (flymake-ler-get-text (nth (1- count) line-err-info-list)))
1472                      (let* ((file       (flymake-ler-get-file (nth (1- count) line-err-info-list)))            (let* ((file       (flymake-ler-get-file (nth (1- count) line-err-info-list)))
1473                             (full-file  (flymake-ler-get-full-file (nth (1- count) line-err-info-list)))                   (full-file  (flymake-ler-get-full-file (nth (1- count) line-err-info-list)))
1474                             (line       (flymake-ler-get-line (nth (1- count) line-err-info-list))))                   (line       (flymake-ler-get-line (nth (1- count) line-err-info-list))))
1475                          (if file              (if file
1476                              (setq menu-item-text (concat menu-item-text " - " file "(" (format "%d" line) ")")))                  (setq menu-item-text (concat menu-item-text " - " file "(" (format "%d" line) ")")))
1477                          (setq menu-items (cons (list menu-item-text              (setq menu-items (cons (list menu-item-text
1478                                                       (if file (list 'flymake-goto-file-and-line full-file line) nil))                                           (if file (list 'flymake-goto-file-and-line full-file line) nil))
1479                                                 menu-items)))                                     menu-items)))
1480                      (setq count (1- count)))            (setq count (1- count)))
1481                 (flymake-log 3 "created menu-items with %d item(s)" (length menu-items))))          (flymake-log 3 "created menu-items with %d item(s)" (length menu-items))))
1482         (if menu-items      (if menu-items
1483             (let* ((menu-title  (format "Line %d: %d error(s), %d warning(s)" line-no          (let* ((menu-title  (format "Line %d: %d error(s), %d warning(s)" line-no
1484                                        (flymake-get-line-err-count line-err-info-list "e")                                      (flymake-get-line-err-count line-err-info-list "e")
1485                                        (flymake-get-line-err-count line-err-info-list "w"))))                                      (flymake-get-line-err-count line-err-info-list "w"))))
1486                 (list menu-title menu-items))            (list menu-title menu-items))
1487             nil)))        nil)))
1488    
1489  (defun flymake-goto-file-and-line (file line)  (defun flymake-goto-file-and-line (file line)
1490      "Try to get buffer for file and goto line line in it"    "Try to get buffer for file and goto line line in it"
1491      (if (not (file-exists-p file))    (if (not (file-exists-p file))
1492          (flymake-log 1 "file %s does not exists" file)        (flymake-log 1 "file %s does not exists" file)
1493          (progn      (progn
1494              (find-file file)        (find-file file)
1495              (goto-line line))))        (goto-line line))))
1496    
1497  ;; flymake minor mode declarations  ;; flymake minor mode declarations
1498  (defvar flymake-mode nil)  (defvar flymake-mode nil)
# Line 1520  Return first 'INCLUDE-DIRS/REL-FILE-NAME Line 1505  Return first 'INCLUDE-DIRS/REL-FILE-NAME
1505  (make-variable-buffer-local 'flymake-mode-line)  (make-variable-buffer-local 'flymake-mode-line)
1506    
1507  (defun flymake-get-buffer-mode-line (buffer)  (defun flymake-get-buffer-mode-line (buffer)
1508      (flymake-get-buffer-var buffer 'flymake-mode-line))    (flymake-get-buffer-var buffer 'flymake-mode-line))
1509    
1510  (defun flymake-set-buffer-mode-line (buffer mode-line-string)  (defun flymake-set-buffer-mode-line (buffer mode-line-string)
1511      (flymake-set-buffer-var buffer 'flymake-mode-line mode-line-string))    (flymake-set-buffer-var buffer 'flymake-mode-line mode-line-string))
1512    
1513  (defvar flymake-mode-line-e-w nil)  (defvar flymake-mode-line-e-w nil)
1514    
1515  (make-variable-buffer-local 'flymake-mode-line-e-w)  (make-variable-buffer-local 'flymake-mode-line-e-w)
1516    
1517  (defun flymake-get-buffer-mode-line-e-w (buffer)  (defun flymake-get-buffer-mode-line-e-w (buffer)
1518      (flymake-get-buffer-var buffer 'flymake-mode-line-e-w))    (flymake-get-buffer-var buffer 'flymake-mode-line-e-w))
1519    
1520  (defun flymake-set-buffer-mode-line-e-w (buffer e-w)  (defun flymake-set-buffer-mode-line-e-w (buffer e-w)
1521      (flymake-set-buffer-var buffer 'flymake-mode-line-e-w e-w))    (flymake-set-buffer-var buffer 'flymake-mode-line-e-w e-w))
1522    
1523  (defvar flymake-mode-line-status nil)  (defvar flymake-mode-line-status nil)
1524    
1525  (make-variable-buffer-local 'flymake-mode-line-status)  (make-variable-buffer-local 'flymake-mode-line-status)
1526    
1527  (defun flymake-get-buffer-mode-line-status (buffer)  (defun flymake-get-buffer-mode-line-status (buffer)
1528      (flymake-get-buffer-var buffer 'flymake-mode-line-status))    (flymake-get-buffer-var buffer 'flymake-mode-line-status))
1529    
1530  (defun flymake-set-buffer-mode-line-status (buffer status)  (defun flymake-set-buffer-mode-line-status (buffer status)
1531      (flymake-set-buffer-var buffer 'flymake-mode-line-status status))    (flymake-set-buffer-var buffer 'flymake-mode-line-status status))
1532    
1533  (defun flymake-report-status (buffer e-w &optional status)  (defun flymake-report-status (buffer e-w &optional status)
1534      "Show status in mode line."    "Show status in mode line."
1535      (when (bufferp buffer)    (when (bufferp buffer)
1536          (save-excursion      (save-excursion
1537              (set-buffer buffer)        (set-buffer buffer)
1538              (when e-w        (when e-w
1539                  (flymake-set-buffer-mode-line-e-w buffer e-w)          (flymake-set-buffer-mode-line-e-w buffer e-w)
1540              )          )
1541              (when status        (when status
1542                  (flymake-set-buffer-mode-line-status buffer status))          (flymake-set-buffer-mode-line-status buffer status))
1543              (let* ((mode-line " Flymake"))        (let* ((mode-line " Flymake"))
1544                  (when (> (length (flymake-get-buffer-mode-line-e-w buffer)) 0)          (when (> (length (flymake-get-buffer-mode-line-e-w buffer)) 0)
1545                      (setq mode-line (concat mode-line ":"  (flymake-get-buffer-mode-line-e-w buffer))))            (setq mode-line (concat mode-line ":"  (flymake-get-buffer-mode-line-e-w buffer))))
1546                  (setq mode-line (concat mode-line (flymake-get-buffer-mode-line-status buffer)))          (setq mode-line (concat mode-line (flymake-get-buffer-mode-line-status buffer)))
1547                  (flymake-set-buffer-mode-line buffer mode-line)          (flymake-set-buffer-mode-line buffer mode-line)
1548                  (force-mode-line-update)))))          (force-mode-line-update)))))
1549    
1550  (defun flymake-display-warning (warning)  (defun flymake-display-warning (warning)
1551      "Display a warning to user."    "Display a warning to user."
1552      (message-box warning))    (message-box warning))
1553    
1554  (defcustom flymake-gui-warnings-enabled t  (defcustom flymake-gui-warnings-enabled t
1555      "Enables/disables gui warnings."    "Enables/disables gui warnings."
1556          :group 'flymake    :group 'flymake
1557          :type 'boolean)    :type 'boolean)
1558    
1559  (defun flymake-report-fatal-status (buffer status warning)  (defun flymake-report-fatal-status (buffer status warning)
1560      "Display a warning and switch flymake mode off."    "Display a warning and switch flymake mode off."
1561          (when flymake-gui-warnings-enabled    (when flymake-gui-warnings-enabled
1562          (flymake-display-warning (format "Flymake: %s. Flymake will be switched OFF" warning))      (flymake-display-warning (format "Flymake: %s. Flymake will be switched OFF" warning))
1563          )      )
1564      (save-excursion    (save-excursion
1565          (set-buffer buffer)      (set-buffer buffer)
1566          (flymake-mode 0)      (flymake-mode 0)
1567          (flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s"      (flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s"
1568                       (buffer-name buffer) status warning)))                   (buffer-name buffer) status warning)))
1569    
1570  (defun flymake-mode (&optional arg)  (defun flymake-mode (&optional arg)
1571      "Toggle flymake mode on/off."    "Toggle flymake mode on/off."
1572      (interactive)    (interactive)
1573      (let ((old-flymake-mode flymake-mode)    (let ((old-flymake-mode flymake-mode)
1574                    (turn-on nil))          (turn-on nil))
1575    
1576          (setq turn-on      (setq turn-on
1577              (if (null arg)            (if (null arg)
1578                  (not flymake-mode)                (not flymake-mode)
1579              ;else                                          ;else
1580                  (> (prefix-numeric-value arg) 0)))              (> (prefix-numeric-value arg) 0)))
1581    
1582          (if turn-on      (if turn-on
1583              (if (flymake-can-syntax-check-file (buffer-file-name))          (if (flymake-can-syntax-check-file (buffer-file-name))
1584                  (flymake-mode-on)              (flymake-mode-on)
1585                  (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)))            (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)))
1586              (flymake-mode-off))        (flymake-mode-off))
1587          (force-mode-line-update)))      (force-mode-line-update)))
1588    
1589  (defcustom flymake-start-syntax-check-on-find-file t  (defcustom flymake-start-syntax-check-on-find-file t
1590      "Start syntax check on find file."    "Start syntax check on find file."
1591      :group 'flymake    :group 'flymake
1592      :type 'boolean)    :type 'boolean)
1593    
1594  ;;;###autoload  ;;;###autoload
1595  (unless (assq 'flymake-mode minor-mode-alist)  (unless (assq 'flymake-mode minor-mode-alist)
1596      (setq minor-mode-alist (cons '(flymake-mode flymake-mode-line) minor-mode-alist)))    (setq minor-mode-alist (cons '(flymake-mode flymake-mode-line) minor-mode-alist)))
1597    
1598  ;;;###autoload  ;;;###autoload
1599  (defun flymake-mode-on ()  (defun flymake-mode-on ()
1600      "Turn flymake mode on."    "Turn flymake mode on."
1601      (when (not flymake-mode)    (when (not flymake-mode)
1602          (make-local-variable 'after-change-functions)      (make-local-variable 'after-change-functions)
1603          (setq after-change-functions (cons 'flymake-after-change-function after-change-functions))      (setq after-change-functions (cons 'flymake-after-change-function after-change-functions))
1604          (add-hook 'after-save-hook 'flymake-after-save-hook)      (add-hook 'after-save-hook 'flymake-after-save-hook)
1605          (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook)      (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook)
1606          ;+(add-hook 'find-file-hooks 'flymake-find-file-hook)                                          ;+(add-hook 'find-file-hooks 'flymake-find-file-hook)
1607    
1608          (flymake-report-status (current-buffer) "" "")      (flymake-report-status (current-buffer) "" "")
1609    
1610          (flymake-set-buffer-timer (current-buffer) (run-at-time nil 1 'flymake-on-timer-event (current-buffer)))      (flymake-set-buffer-timer (current-buffer) (run-at-time nil 1 'flymake-on-timer-event (current-buffer)))
1611    
1612          (setq flymake-mode t)      (setq flymake-mode t)
1613          (flymake-log 1 "flymake mode turned ON for buffer %s" (buffer-name (current-buffer)))      (flymake-log 1 "flymake mode turned ON for buffer %s" (buffer-name (current-buffer)))
1614          (when flymake-start-syntax-check-on-find-file      (when flymake-start-syntax-check-on-find-file
1615              (flymake-start-syntax-check-for-current-buffer)))) ; will be started by on-load hook        (flymake-start-syntax-check-for-current-buffer)))) ; will be started by on-load hook
1616    
1617  ;;;###autoload  ;;;###autoload
1618  (defun flymake-mode-off ()  (defun flymake-mode-off ()
1619      "Turn flymake mode off."    "Turn flymake mode off."
1620      (when flymake-mode    (when flymake-mode
1621          (setq after-change-functions (delq 'flymake-after-change-function  after-change-functions))      (setq after-change-functions (delq 'flymake-after-change-function  after-change-functions))
1622          (remove-hook 'after-save-hook (function flymake-after-save-hook) t)      (remove-hook 'after-save-hook (function flymake-after-save-hook) t)
1623          (remove-hook 'kill-buffer-hook (function flymake-kill-buffer-hook) t)      (remove-hook 'kill-buffer-hook (function flymake-kill-buffer-hook) t)
1624          ;+(remove-hook 'find-file-hooks (function flymake-find-file-hook) t)                                          ;+(remove-hook 'find-file-hooks (function flymake-find-file-hook) t)
   
         (flymake-delete-own-overlays (current-buffer))  
   
         (when (flymake-get-buffer-timer (current-buffer))  
             (cancel-timer (flymake-get-buffer-timer (current-buffer)))  
             (flymake-set-buffer-timer (current-buffer) nil))  
1625    
1626          (flymake-set-buffer-is-running (current-buffer) nil)      (flymake-delete-own-overlays (current-buffer))
1627    
1628          (setq flymake-mode nil)      (when (flymake-get-buffer-timer (current-buffer))
1629          (flymake-log 1 "flymake mode turned OFF for buffer %s" (buffer-name (current-buffer)))))        (cancel-timer (flymake-get-buffer-timer (current-buffer)))
1630          (flymake-set-buffer-timer (current-buffer) nil))
1631    
1632        (flymake-set-buffer-is-running (current-buffer) nil)
1633    
1634        (setq flymake-mode nil)
1635        (flymake-log 1 "flymake mode turned OFF for buffer %s" (buffer-name (current-buffer)))))
1636    
1637  (defcustom flymake-start-syntax-check-on-newline t  (defcustom flymake-start-syntax-check-on-newline t
1638      "Start syntax check if newline char was added/removed from the buffer."    "Start syntax check if newline char was added/removed from the buffer."
1639      :group 'flymake    :group 'flymake
1640      :type 'boolean)    :type 'boolean)
1641    
1642  (defun flymake-after-change-function (start stop len)  (defun flymake-after-change-function (start stop len)
1643      "Start syntax check for current buffer if it isn't already running"    "Start syntax check for current buffer if it isn't already running"
1644      ;+(flymake-log 0 "setting change time to %s" (flymake-float-time))                                          ;+(flymake-log 0 "setting change time to %s" (flymake-float-time))
1645      (let((new-text (buffer-substring start stop)))    (let((new-text (buffer-substring start stop)))
1646          (when (and flymake-start-syntax-check-on-newline (equal new-text "\n"))      (when (and flymake-start-syntax-check-on-newline (equal new-text "\n"))
1647              (flymake-log 3 "starting syntax check as new-line has been seen")        (flymake-log 3 "starting syntax check as new-line has been seen")
1648              (flymake-start-syntax-check-for-current-buffer))        (flymake-start-syntax-check-for-current-buffer))
1649          (flymake-set-buffer-last-change-time (current-buffer) (flymake-float-time))))      (flymake-set-buffer-last-change-time (current-buffer) (flymake-float-time))))
1650    
1651  (defun flymake-after-save-hook ()  (defun flymake-after-save-hook ()
1652      (if (local-variable-p 'flymake-mode (current-buffer)) ; (???) other way to determine whether flymake is active in buffer being saved?    (if (local-variable-p 'flymake-mode (current-buffer)) ; (???) other way to determine whether flymake is active in buffer being saved?
1653          (progn        (progn
1654              (flymake-log 3 "starting syntax check as buffer was saved")          (flymake-log 3 "starting syntax check as buffer was saved")
1655              (flymake-start-syntax-check-for-current-buffer)))) ; no more mode 3. cannot start check if mode 3 (to temp copies) is active - (???)          (flymake-start-syntax-check-for-current-buffer)))) ; no more mode 3. cannot start check if mode 3 (to temp copies) is active - (???)
1656    
1657  (defun flymake-kill-buffer-hook ()  (defun flymake-kill-buffer-hook ()
1658      (when (flymake-get-buffer-timer (current-buffer))    (when (flymake-get-buffer-timer (current-buffer))
1659          (cancel-timer (flymake-get-buffer-timer (current-buffer)))      (cancel-timer (flymake-get-buffer-timer (current-buffer)))
1660          (flymake-set-buffer-timer (current-buffer) nil)))      (flymake-set-buffer-timer (current-buffer) nil)))
1661    
1662  (defun flymake-find-file-hook ()  (defun flymake-find-file-hook ()
1663      ;+(when flymake-start-syntax-check-on-find-file                                          ;+(when flymake-start-syntax-check-on-find-file
1664      ;+    (flymake-log 3 "starting syntax check on file open")                                          ;+    (flymake-log 3 "starting syntax check on file open")
1665      ;+    (flymake-start-syntax-check-for-current-buffer)                                          ;+    (flymake-start-syntax-check-for-current-buffer)
1666      ;+)                                          ;+)
1667      (when (and (not (local-variable-p 'flymake-mode (current-buffer)))    (when (and (not (local-variable-p 'flymake-mode (current-buffer)))
1668             (flymake-can-syntax-check-file (buffer-file-name (current-buffer))))               (flymake-can-syntax-check-file (buffer-file-name (current-buffer))))
1669          (flymake-mode)      (flymake-mode)
1670          (flymake-log 3 "automatically turned ON flymake mode")))      (flymake-log 3 "automatically turned ON flymake mode")))
1671    
1672  (defun flymake-get-first-err-line-no (err-info-list)  (defun flymake-get-first-err-line-no (err-info-list)
1673      "Return first line with error."    "Return first line with error."
1674      (when err-info-list    (when err-info-list
1675          (flymake-er-get-line (car err-info-list))))      (flymake-er-get-line (car err-info-list))))
1676    
1677  (defun flymake-get-last-err-line-no (err-info-list)  (defun flymake-get-last-err-line-no (err-info-list)
1678      "Return last line with error."    "Return last line with error."
1679      (when err-info-list    (when err-info-list
1680          (flymake-er-get-line (nth (1- (length err-info-list)) err-info-list))))      (flymake-er-get-line (nth (1- (length err-info-list)) err-info-list))))
1681    
1682  (defun flymake-get-next-err-line-no (err-info-list line-no)  (defun flymake-get-next-err-line-no (err-info-list line-no)
1683      "Return next line with error."    "Return next line with error."
1684      (when err-info-list    (when err-info-list
1685          (let* ((count  (length err-info-list))      (let* ((count  (length err-info-list))
1686                 (idx    0))             (idx    0))
1687              (while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx err-info-list))))        (while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx err-info-list))))
1688                  (setq idx (1+ idx)))          (setq idx (1+ idx)))
1689              (if (< idx count)        (if (< idx count)
1690                  (flymake-er-get-line (nth idx err-info-list))))))            (flymake-er-get-line (nth idx err-info-list))))))
1691    
1692  (defun flymake-get-prev-err-line-no (err-info-list line-no)  (defun flymake-get-prev-err-line-no (err-info-list line-no)
1693      "Return prev line with error."    "Return prev line with error."
1694      (when err-info-list    (when err-info-list
1695          (let* ((count (length err-info-list)))      (let* ((count (length err-info-list)))
1696              (while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1- count) err-info-list))))        (while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1- count) err-info-list))))
1697                  (setq count (1- count)))          (setq count (1- count)))
1698              (if (> count 0)        (if (> count 0)
1699                  (flymake-er-get-line (nth (1- count) err-info-list))))))            (flymake-er-get-line (nth (1- count) err-info-list))))))
1700    
1701  (defun flymake-skip-whitespace ()  (defun flymake-skip-whitespace ()
1702      "Move forward until non-whitespace is reached."    "Move forward until non-whitespace is reached."
1703      (while (looking-at "[ \t]")    (while (looking-at "[ \t]")
1704          (forward-char)))      (forward-char)))
1705    
1706  (defun flymake-goto-line (line-no)  (defun flymake-goto-line (line-no)
1707      "goto-line, then skip whitespace"    "goto-line, then skip whitespace"
1708      (goto-line line-no)    (goto-line line-no)
1709      (flymake-skip-whitespace))    (flymake-skip-whitespace))
1710    
1711  (defun flymake-goto-next-error ()  (defun flymake-goto-next-error ()
1712      "go to next error in err ring"    "go to next error in err ring"
1713      (interactive)    (interactive)
1714      (let ((line-no (flymake-get-next-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no))))    (let ((line-no (flymake-get-next-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no))))
1715          (when (not line-no)      (when (not line-no)
1716              (setq line-no (flymake-get-first-err-line-no (flymake-get-buffer-err-info (current-buffer))))        (setq line-no (flymake-get-first-err-line-no (flymake-get-buffer-err-info (current-buffer))))
1717              (flymake-log 1 "passed end of file"))        (flymake-log 1 "passed end of file"))
1718          (if line-no      (if line-no
1719              (flymake-goto-line line-no)          (flymake-goto-line line-no)
1720              (flymake-log 1 "no errors in current buffer"))))        (flymake-log 1 "no errors in current buffer"))))
1721    
1722  (defun flymake-goto-prev-error ()  (defun flymake-goto-prev-error ()
1723      "go to prev error in err ring"    "go to prev error in err ring"
1724      (interactive)    (interactive)
1725      (let ((line-no (flymake-get-prev-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no))))    (let ((line-no (flymake-get-prev-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no))))
1726          (when (not line-no)      (when (not line-no)
1727              (setq line-no (flymake-get-last-err-line-no (flymake-get-buffer-err-info (current-buffer))))        (setq line-no (flymake-get-last-err-line-no (flymake-get-buffer-err-info (current-buffer))))
1728              (flymake-log 1 "passed beginning of file"))        (flymake-log 1 "passed beginning of file"))
1729          (if line-no      (if line-no
1730              (flymake-goto-line line-no)          (flymake-goto-line line-no)
1731              (flymake-log 1 "no errors in current buffer"))))        (flymake-log 1 "no errors in current buffer"))))
1732    
1733  (defun flymake-patch-err-text (string)  (defun flymake-patch-err-text (string)
1734      (if (string-match "^[\n\t :0-9]*\\(.*\\)$" string)    (if (string-match "^[\n\t :0-9]*\\(.*\\)$" string)
1735          (match-string 1 string)        (match-string 1 string)
1736          string))      string))
1737    
1738  ;;;; general init-cleanup and helper routines  ;;;; general init-cleanup and helper routines
1739  (defun flymake-create-temp-inplace (file-name prefix)  (defun flymake-create-temp-inplace (file-name prefix)
1740      (unless (stringp file-name)    (unless (stringp file-name)
1741          (error "Invalid file-name"))      (error "Invalid file-name"))
1742      (or prefix    (or prefix
1743          (setq prefix "flymake"))        (setq prefix "flymake"))
1744      (let* ((temp-name   (concat (file-name-sans-extension file-name)    (let* ((temp-name   (concat (file-name-sans-extension file-name)
1745                                  "_" prefix                                "_" prefix
1746                                  (and (file-name-extension file-name)                                (and (file-name-extension file-name)
1747                                       (concat "." (file-name-extension file-name))))))                                     (concat "." (file-name-extension file-name))))))
1748          (flymake-log 3 "create-temp-inplace: file=%s temp=%s" file-name temp-name)      (flymake-log 3 "create-temp-inplace: file=%s temp=%s" file-name temp-name)
1749          temp-name))      temp-name))
1750    
1751  (defun flymake-create-temp-with-folder-structure (file-name prefix)  (defun flymake-create-temp-with-folder-structure (file-name prefix)
1752      (unless (stringp file-name)    (unless (stringp file-name)
1753          (error "Invalid file-name"))      (error "Invalid file-name"))
1754    
1755      (let* ((dir       (file-name-directory file-name))    (let* ((dir       (file-name-directory file-name))
1756                     (slash-pos (string-match "/" dir))           (slash-pos (string-match "/" dir))
1757                     (temp-dir  (concat (flymake-ensure-ends-with-slash (flymake-get-temp-dir)) (substring dir (1+ slash-pos)))))           (temp-dir  (concat (flymake-ensure-ends-with-slash (flymake-get-temp-dir)) (substring dir (1+ slash-pos)))))
1758    
1759              (file-truename (concat (flymake-ensure-ends-with-slash temp-dir)      (file-truename (concat (flymake-ensure-ends-with-slash temp-dir)
1760                                  (file-name-nondirectory file-name)))))                             (file-name-nondirectory file-name)))))
1761    
1762  (defun flymake-strrchr (str ch)  (defun flymake-strrchr (str ch)
1763      (let* ((count  (length str))    (let* ((count  (length str))
1764             (pos    nil))           (pos    nil))
1765          (while (and (not pos) (> count 0))      (while (and (not pos) (> count 0))
1766              (if (= ch (elt str (1- count)))        (if (= ch (elt str (1- count)))
1767                  (setq pos (1- count)))            (setq pos (1- count)))
1768              (setq count (1- count)))        (setq count (1- count)))
1769          pos))      pos))
1770    
1771  (defun flymake-delete-temp-directory (dir-name)  (defun flymake-delete-temp-directory (dir-name)
1772      "attempt to delete temp dir created by flymake-create-temp-with-folder-structure, do not fail on error."    "attempt to delete temp dir created by flymake-create-temp-with-folder-structure, do not fail on error."
1773      (let* ((temp-dir    (flymake-get-temp-dir))    (let* ((temp-dir    (flymake-get-temp-dir))
1774             (suffix      (substring dir-name (1+ (length temp-dir))))           (suffix      (substring dir-name (1+ (length temp-dir))))
1775             (slash-pos   nil))           (slash-pos   nil))
1776    
1777          (while (> (length suffix) 0)      (while (> (length suffix) 0)
1778              ;+(flymake-log 0 "suffix=%s" suffix)                                          ;+(flymake-log 0 "suffix=%s" suffix)
1779                          (flymake-safe-delete-directory (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) suffix)))        (flymake-safe-delete-directory (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) suffix)))
1780              (setq slash-pos (flymake-strrchr suffix (string-to-char "/")))        (setq slash-pos (flymake-strrchr suffix (string-to-char "/")))
1781              (if slash-pos        (if slash-pos
1782                  (setq suffix (substring suffix 0 slash-pos))            (setq suffix (substring suffix 0 slash-pos))
1783                  (setq suffix "")))))          (setq suffix "")))))
1784    
1785  (defun flymake-init-create-temp-buffer-copy (buffer create-temp-f)  (defun flymake-init-create-temp-buffer-copy (buffer create-temp-f)
1786      "Make a temporary copy of the current buffer, save its name in buffer data and return the name."    "Make a temporary copy of the current buffer, save its name in buffer data and return the name."
1787      (let*  ((source-file-name       (buffer-file-name buffer))    (let*  ((source-file-name       (buffer-file-name buffer))
1788              (temp-source-file-name  (funcall create-temp-f source-file-name "flymake")))            (temp-source-file-name  (funcall create-temp-f source-file-name "flymake")))
1789    
1790          (flymake-save-buffer-in-file buffer temp-source-file-name)      (flymake-save-buffer-in-file buffer temp-source-file-name)
1791          (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name)      (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name)
1792          temp-source-file-name))      temp-source-file-name))
1793    
1794  (defun flymake-simple-cleanup (buffer)  (defun flymake-simple-cleanup (buffer)
1795      "Do cleanup after 'flymake-init-create-temp-buffer-copy'.    "Do cleanup after 'flymake-init-create-temp-buffer-copy'.
1796  Delete temp file."  Delete temp file."
1797      (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")))    (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")))
1798          (flymake-safe-delete-file temp-source-file-name)      (flymake-safe-delete-file temp-source-file-name)
1799          (flymake-set-buffer-last-change-time buffer nil)))      (flymake-set-buffer-last-change-time buffer nil)))
1800    
1801  (defun flymake-get-real-file-name (buffer file-name-from-err-msg)  (defun flymake-get-real-file-name (buffer file-name-from-err-msg)
1802      "Translate file name from error message to `real' file name.    "Translate file name from error message to `real' file name.
1803  Return full-name. Names are real, not patched."  Return full-name. Names are real, not patched."
1804      (let* ((real-name              nil)    (let* ((real-name              nil)
1805             (source-file-name       (buffer-file-name buffer))           (source-file-name       (buffer-file-name buffer))
1806             (master-file-name       (flymake-get-buffer-value buffer "master-file-name"))           (master-file-name       (flymake-get-buffer-value buffer "master-file-name"))
1807             (temp-source-file-name  (flymake-get-buffer-value buffer "temp-source-file-name"))           (temp-source-file-name  (flymake-get-buffer-value buffer "temp-source-file-name"))
1808             (temp-master-file-name  (flymake-get-buffer-value buffer "temp-master-file-name"))           (temp-master-file-name  (flymake-get-buffer-value buffer "temp-master-file-name"))
1809             (base-dirs              (list (flymake-get-buffer-value buffer "base-dir")           (base-dirs              (list (flymake-get-buffer-value buffer "base-dir")
1810                                           (file-name-directory source-file-name)                                         (file-name-directory source-file-name)
1811                                           (if master-file-name (file-name-directory master-file-name) nil)))                                         (if master-file-name (file-name-directory master-file-name) nil)))
1812             (files                  (list (list source-file-name       source-file-name)           (files                  (list (list source-file-name       source-file-name)
1813                                           (list temp-source-file-name  source-file-name)                                         (list temp-source-file-name  source-file-name)
1814                                           (list master-file-name       master-file-name)                                         (list master-file-name       master-file-name)
1815                                           (list temp-master-file-name  master-file-name))))                                         (list temp-master-file-name  master-file-name))))
1816    
1817          (when (equal 0 (length file-name-from-err-msg))      (when (equal 0 (length file-name-from-err-msg))
1818              (setq file-name-from-err-msg source-file-name))        (setq file-name-from-err-msg source-file-name))
1819    
1820          (setq real-name (flymake-get-full-patched-file-name file-name-from-err-msg base-dirs files))      (setq real-name (flymake-get-full-patched-file-name file-name-from-err-msg base-dirs files))
1821          ; if real-name is nil, than file name from err msg is none of the files we've patched                                          ; if real-name is nil, than file name from err msg is none of the files we've patched
1822          (if (not real-name)      (if (not real-name)
1823              (setq real-name (flymake-get-full-nonpatched-file-name file-name-from-err-msg base-dirs)))          (setq real-name (flymake-get-full-nonpatched-file-name file-name-from-err-msg base-dirs)))
1824          (if (not real-name)      (if (not real-name)
1825              (setq real-name file-name-from-err-msg))          (setq real-name file-name-from-err-msg))
1826          (setq real-name (flymake-fix-path-name real-name))      (setq real-name (flymake-fix-file-name real-name))
1827          (flymake-log 3 "get-real-file-name: file-name=%s real-name=%s" file-name-from-err-msg real-name)      (flymake-log 3 "get-real-file-name: file-name=%s real-name=%s" file-name-from-err-msg real-name)
1828          real-name))      real-name))
1829    
1830  (defun flymake-get-full-patched-file-name (file-name-from-err-msg base-dirs files)  (defun flymake-get-full-patched-file-name (file-name-from-err-msg base-dirs files)
1831      (let* ((base-dirs-count  (length base-dirs))    (let* ((base-dirs-count  (length base-dirs))
1832             (file-count       (length files))           (file-count       (length files))
1833             (real-name        nil))           (real-name        nil))
1834    
1835          (while (and (not real-name) (> base-dirs-count 0))      (while (and (not real-name) (> base-dirs-count 0))
1836              (setq file-count (length files))        (setq file-count (length files))
1837              (while (and (not real-name) (> file-count 0))        (while (and (not real-name) (> file-count 0))
1838                  (let* ((this-dir        (nth (1- base-dirs-count) base-dirs))          (let* ((this-dir        (nth (1- base-dirs-count) base-dirs))
1839                         (this-file       (nth 0 (nth (1- file-count) files)))                 (this-file       (nth 0 (nth (1- file-count) files)))
1840                         (this-real-name  (nth 1 (nth (1- file-count) files))))                 (this-real-name  (nth 1 (nth (1- file-count) files))))
1841                      ;+(flymake-log 0 "this-dir=%s this-file=%s this-real=%s msg-file=%s" this-dir this-file this-real-name file-name-from-err-msg)                                          ;+(flymake-log 0 "this-dir=%s this-file=%s this-real=%s msg-file=%s" this-dir this-file this-real-name file-name-from-err-msg)
1842                      (when (and this-dir this-file (flymake-same-files            (when (and this-dir this-file (flymake-same-files
1843                                                     (flymake-get-absolute-file-name-basedir file-name-from-err-msg this-dir)                                           (flymake-get-absolute-file-name-basedir file-name-from-err-msg this-dir)
1844                                                     this-file))                                           this-file))
1845                          (setq real-name this-real-name)))              (setq real-name this-real-name)))
1846                  (setq file-count (1- file-count)))          (setq file-count (1- file-count)))
1847              (setq base-dirs-count (1- base-dirs-count)))        (setq base-dirs-count (1- base-dirs-count)))
1848          real-name))      real-name))
1849    
1850  (defun flymake-get-full-nonpatched-file-name (file-name-from-err-msg base-dirs)  (defun flymake-get-full-nonpatched-file-name (file-name-from-err-msg base-dirs)
1851      (let* ((real-name  nil))    (let* ((real-name  nil))
1852          (if (file-name-absolute-p file-name-from-err-msg)      (if (file-name-absolute-p file-name-from-err-msg)
1853              (setq real-name file-name-from-err-msg)          (setq real-name file-name-from-err-msg)
1854              (let* ((base-dirs-count  (length base-dirs)))        (let* ((base-dirs-count  (length base-dirs)))
1855                  (while (and (not real-name) (> base-dirs-count 0))          (while (and (not real-name) (> base-dirs-count 0))
1856                      (let* ((full-name (flymake-get-absolute-file-name-basedir file-name-from-err-msg            (let* ((full-name (flymake-get-absolute-file-name-basedir file-name-from-err-msg
1857                                                                                (nth (1- base-dirs-count) base-dirs))))                                                                      (nth (1- base-dirs-count) base-dirs))))
1858                          (if (file-exists-p full-name)              (if (file-exists-p full-name)
1859                              (setq real-name full-name))                  (setq real-name full-name))
1860                          (setq base-dirs-count (1- base-dirs-count))))))              (setq base-dirs-count (1- base-dirs-count))))))
1861          real-name))      real-name))
1862    
1863  (defun flymake-get-absolute-file-name-basedir (file-name dir-name)  (defun flymake-get-absolute-file-name-basedir (file-name dir-name)
1864      (if (file-name-absolute-p file-name)    (if (file-name-absolute-p file-name)
1865          file-name        file-name
1866          (concat dir-name "/" file-name)))      (concat dir-name "/" file-name)))
1867    
1868  (defun flymake-init-find-buildfile-dir (buffer source-file-name buildfile-name)  (defun flymake-init-find-buildfile-dir (buffer source-file-name buildfile-name)
1869      "Find buildfile, store its dir in buffer data and return its dir, if found."    "Find buildfile, store its dir in buffer data and return its dir, if found."
1870      (let* ((buildfile-dir  (flymake-find-buildfile buildfile-name    (let* ((buildfile-dir  (flymake-find-buildfile buildfile-name
1871                                                     (file-name-directory source-file-name)                                                   (file-name-directory source-file-name)
1872                                                     flymake-buildfile-dirs)))                                                   flymake-buildfile-dirs)))
1873          (if (not buildfile-dir)      (if (not buildfile-dir)
1874              (progn          (progn
1875                  (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name)            (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name)
1876                  (flymake-report-fatal-status buffer "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name))            (flymake-report-fatal-status buffer "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name))
1877              )            )
1878              (progn        (progn
1879                  (flymake-set-buffer-value buffer "base-dir" buildfile-dir)))          (flymake-set-buffer-value buffer "base-dir" buildfile-dir)))
1880          buildfile-dir))      buildfile-dir))
1881    
1882  (defun flymake-init-create-temp-source-and-master-buffer-copy (buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list)  (defun flymake-init-create-temp-source-and-master-buffer-copy (buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list)
1883      "Find master file (or buffer), create it's copy along with a copy of the source file."    "Find master file (or buffer), create it's copy along with a copy of the source file."
1884      (let* ((source-file-name       (buffer-file-name buffer))    (let* ((source-file-name       (buffer-file-name buffer))
1885             (temp-source-file-name  (flymake-init-create-temp-buffer-copy buffer create-temp-f))           (temp-source-file-name  (flymake-init-create-temp-buffer-copy buffer create-temp-f))
1886             (master-file-name       nil)           (master-file-name       nil)
1887             (temp-master-file-name  nil)           (temp-master-file-name  nil)
1888             (master-and-temp-master (flymake-create-master-file           (master-and-temp-master (flymake-create-master-file
1889                                      source-file-name temp-source-file-name                                    source-file-name temp-source-file-name
1890                                      get-incl-dirs-f create-temp-f                                    get-incl-dirs-f create-temp-f
1891                                      master-file-masks include-regexp-list)))                                    master-file-masks include-regexp-list)))
1892    
1893          (if (not master-and-temp-master)      (if (not master-and-temp-master)
1894              (progn          (progn
1895                  (flymake-log 1 "cannot find master file for %s" source-file-name)            (flymake-log 1 "cannot find master file for %s" source-file-name)
1896                  (flymake-report-status buffer "!" "") ; NOMASTER            (flymake-report-status buffer "!" "") ; NOMASTER
1897              )            )
1898              (progn        (progn
1899                  (setq master-file-name       (nth 0 master-and-temp-master))          (setq master-file-name       (nth 0 master-and-temp-master))
1900                  (setq temp-master-file-name  (nth 1 master-and-temp-master))          (setq temp-master-file-name  (nth 1 master-and-temp-master))
1901                  (flymake-set-buffer-value buffer "master-file-name"      master-file-name)          (flymake-set-buffer-value buffer "master-file-name"      master-file-name)
1902                  (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name)          (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name)
1903              ))          ))
1904          temp-master-file-name))      temp-master-file-name))
1905    
1906  (defun flymake-master-cleanup (buffer)  (defun flymake-master-cleanup (buffer)
1907      (flymake-simple-cleanup buffer)    (flymake-simple-cleanup buffer)
1908      (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name")))    (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name")))
1909    
1910  ;;;; make-specific init-cleanup routines  ;;;; make-specific init-cleanup routines
1911  (defun flymake-get-syntax-check-program-args (source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f)  (defun flymake-get-syntax-check-program-args (source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f)
1912      "Create a command line for syntax check using GET-CMD-LINE-F."    "Create a command line for syntax check using GET-CMD-LINE-F."
1913      (let* ((my-base-dir  base-dir)    (let* ((my-base-dir  base-dir)
1914             (my-source    source-file-name))           (my-source    source-file-name))
1915    
1916          (when use-relative-base-dir      (when use-relative-base-dir
1917              (setq my-base-dir (flymake-build-relative-path (file-name-directory source-file-name) base-dir)))        (setq my-base-dir (flymake-build-relative-filename (file-name-directory source-file-name) base-dir)))
1918    
1919          (when use-relative-source      (when use-relative-source
1920              (setq my-source (concat (flymake-build-relative-path base-dir (file-name-directory source-file-name))        (setq my-source (concat (flymake-build-relative-filename base-dir (file-name-directory source-file-name))
1921                                      (file-name-nondirectory source-file-name))))                                (file-name-nondirectory source-file-name))))
1922          (funcall get-cmd-line-f my-source my-base-dir)))      (funcall get-cmd-line-f my-source my-base-dir)))
1923    
1924  (defun flymake-get-make-cmdline (source base-dir)  (defun flymake-get-make-cmdline (source base-dir)
1925      (list "make"    (list "make"
1926            (list "-s"          (list "-s"
1927                          "-C"                "-C"
1928                          base-dir                base-dir
1929                          (concat "CHK_SOURCES=" source)                (concat "CHK_SOURCES=" source)
1930                          "SYNTAX_CHECK_MODE=1"                "SYNTAX_CHECK_MODE=1"
1931                          "check-syntax")))                "check-syntax")))
1932    
1933  (defun flymake-get-ant-cmdline (source base-dir)  (defun flymake-get-ant-cmdline (source base-dir)
1934      (list "ant"    (list "ant"
1935            (list "-buildfile"          (list "-buildfile"
1936                  (concat base-dir "/" "build.xml")                (concat base-dir "/" "build.xml")
1937                  (concat "-DCHK_SOURCES=" source)                (concat "-DCHK_SOURCES=" source)
1938                  "check-syntax")))                "check-syntax")))
1939    
1940  (defun flymake-simple-make-init-impl (buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f)  (defun flymake-simple-make-init-impl (buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f)
1941      "Create syntax check command line for a directly checked source file.    "Create syntax check command line for a directly checked source file.
1942  Use CREATE-TEMP-F for creating temp copy."  Use CREATE-TEMP-F for creating temp copy."
1943      (let* ((args nil)    (let* ((args nil)
1944             (source-file-name   (buffer-file-name buffer))           (source-file-name   (buffer-file-name buffer))
1945             (buildfile-dir      (flymake-init-find-buildfile-dir buffer source-file-name build-file-name)))           (buildfile-dir      (flymake-init-find-buildfile-dir buffer source-file-name build-file-name)))
1946          (if buildfile-dir      (if buildfile-dir
1947              (let* ((temp-source-file-name  (flymake-init-create-temp-buffer-copy buffer create-temp-f)))          (let* ((temp-source-file-name  (flymake-init-create-temp-buffer-copy buffer create-temp-f)))
1948                  (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir            (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir
1949                                                                 use-relative-base-dir use-relative-source                                                              use-relative-base-dir use-relative-source
1950                                                                 get-cmdline-f))))                                                              get-cmdline-f))))
1951          args))      args))
1952    
1953  (defun flymake-simple-make-init (buffer)  (defun flymake-simple-make-init (buffer)
1954      (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline))    (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline))
1955    
1956  (defun flymake-master-make-init (buffer get-incl-dirs-f master-file-masks include-regexp-list)  (defun flymake-master-make-init (buffer get-incl-dirs-f master-file-masks include-regexp-list)
1957      "create make command line for a source file checked via master file compilation"    "create make command line for a source file checked via master file compilation"
1958      (let* ((make-args nil)    (let* ((make-args nil)
1959             (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy           (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy
1960                                     buffer get-incl-dirs-f 'flymake-create-temp-inplace                                   buffer get-incl-dirs-f 'flymake-create-temp-inplace
1961                                     master-file-masks include-regexp-list)))                                   master-file-masks include-regexp-list)))
1962          (when temp-master-file-name      (when temp-master-file-name
1963              (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile")))        (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile")))
1964                  (if  buildfile-dir          (if  buildfile-dir
1965                                      (setq make-args (flymake-get-syntax-check-program-args              (setq make-args (flymake-get-syntax-check-program-args
1966                                                                           temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline)))))                               temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline)))))
1967                  make-args))      make-args))
1968    
1969  (defun flymake-find-make-buildfile (source-dir)  (defun flymake-find-make-buildfile (source-dir)
1970      (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs))    (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs))
1971    
1972  ;;;; .h/make specific  ;;;; .h/make specific
1973  (defun flymake-master-make-header-init (buffer)  (defun flymake-master-make-header-init (buffer)
1974      (flymake-master-make-init buffer    (flymake-master-make-init buffer
1975                                'flymake-get-include-dirs                              'flymake-get-include-dirs
1976                                '(".+\\.cpp$" ".+\\.c$")                              '(".+\\.cpp$" ".+\\.c$")
1977                                '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)))                              '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)))
1978    
1979  ;;;; .java/make specific  ;;;; .java/make specific
1980  (defun flymake-simple-make-java-init (buffer)  (defun flymake-simple-make-java-init (buffer)
1981      (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline))    (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline))
1982    
1983  (defun flymake-simple-ant-java-init (buffer)  (defun flymake-simple-ant-java-init (buffer)
1984      (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline))    (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline))
1985    
1986  (defun flymake-simple-java-cleanup (buffer)  (defun flymake-simple-java-cleanup (buffer)
1987      "cleanup after flymake-simple-make-java-init -- delete temp file and dirs"    "cleanup after flymake-simple-make-java-init -- delete temp file and dirs"
1988      (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")))    (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")))
1989          (flymake-safe-delete-file temp-source-file-name)      (flymake-safe-delete-file temp-source-file-name)
1990          (when temp-source-file-name      (when temp-source-file-name
1991              (flymake-delete-temp-directory (file-name-directory temp-source-file-name)))))        (flymake-delete-temp-directory (file-name-directory temp-source-file-name)))))
1992    
1993  ;;;; perl-specific init-cleanup routines  ;;;; perl-specific init-cleanup routines
1994  (defun flymake-perl-init (buffer)  (defun flymake-perl-init (buffer)
1995      (let* ((temp-file   (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))    (let* ((temp-file   (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))
1996                     (local-file  (concat (flymake-build-relative-path (file-name-directory (buffer-file-name (current-buffer)))           (local-file  (concat (flymake-build-relative-filename (file-name-directory (buffer-file-name (current-buffer)))
1997                                                                                                                           (file-name-directory temp-file))                                                             (file-name-directory temp-file))
1998                                                                  (file-name-nondirectory temp-file))))                                (file-name-nondirectory temp-file))))
1999          (list "perl" (list "-wc " local-file))))      (list "perl" (list "-wc " local-file))))
2000    
2001  ;;;; tex-specific init-cleanup routines  ;;;; tex-specific init-cleanup routines
2002  (defun flymake-get-tex-args (file-name)  (defun flymake-get-tex-args (file-name)
2003      ;(list "latex" (list "-c-style-errors" file-name))                                          ;(list "latex" (list "-c-style-errors" file-name))
2004      (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name)))    (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name)))
2005    
2006  (defun flymake-simple-tex-init (buffer)  (defun flymake-simple-tex-init (buffer)
2007      (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)))    (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)))
2008    
2009  (defun flymake-master-tex-init (buffer)  (defun flymake-master-tex-init (buffer)
2010      (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy    (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy
2011                                     buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace                                   buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace
2012                                     '(".+\\.tex$")                                   '(".+\\.tex$")
2013                                     '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2))))                                   '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2))))
2014          (when temp-master-file-name      (when temp-master-file-name
2015              (flymake-get-tex-args temp-master-file-name))))        (flymake-get-tex-args temp-master-file-name))))
2016    
2017  (defun flymake-get-include-dirs-dot (base-dir)  (defun flymake-get-include-dirs-dot (base-dir)
2018      '("."))    '("."))
2019    
2020  ;;;; xml-specific init-cleanup routines  ;;;; xml-specific init-cleanup routines
2021  (defun flymake-xml-init(buffer)  (defun flymake-xml-init(buffer)
2022      (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))))    (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))))
2023    
2024  (provide 'flymake)  (provide 'flymake)
2025    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26