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