style.py (7807:15553b536bd6) style.py (7827:49b7d40ee88a)
1#! /usr/bin/env python
2# Copyright (c) 2006 The Regents of The University of Michigan
3# Copyright (c) 2007 The Hewlett-Packard Development Company
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer;
10# redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution;
13# neither the name of the copyright holders nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29# Authors: Nathan Binkert
30
31import re
32import os
33import sys
34
35sys.path.insert(0, os.path.dirname(__file__))
36
37from file_types import lang_type
38
1#! /usr/bin/env python
2# Copyright (c) 2006 The Regents of The University of Michigan
3# Copyright (c) 2007 The Hewlett-Packard Development Company
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer;
10# redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution;
13# neither the name of the copyright holders nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29# Authors: Nathan Binkert
30
31import re
32import os
33import sys
34
35sys.path.insert(0, os.path.dirname(__file__))
36
37from file_types import lang_type
38
39tabsize = 8
39lead = re.compile(r'^([ \t]+)')
40trail = re.compile(r'([ \t]+)$')
41any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
42good_control = re.compile(r'\b(if|while|for) [(]')
43
44whitespace_types = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons'))
45format_types = set(('C', 'C++'))
46
47def checkwhite_line(line):
48 match = lead.search(line)
49 if match and match.group(1).find('\t') != -1:
50 return False
51
52 match = trail.search(line)
53 if match:
54 return False
55
56 return True
57
58def checkwhite(filename):
59 if lang_type(filename) not in whitespace_types:
60 return
61
62 try:
63 f = file(filename, 'r+')
64 except OSError, msg:
65 print 'could not open file %s: %s' % (filename, msg)
66 return
67
68 for num,line in enumerate(f):
69 if not checkwhite_line(line):
70 yield line,num + 1
71
40lead = re.compile(r'^([ \t]+)')
41trail = re.compile(r'([ \t]+)$')
42any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
43good_control = re.compile(r'\b(if|while|for) [(]')
44
45whitespace_types = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons'))
46format_types = set(('C', 'C++'))
47
48def checkwhite_line(line):
49 match = lead.search(line)
50 if match and match.group(1).find('\t') != -1:
51 return False
52
53 match = trail.search(line)
54 if match:
55 return False
56
57 return True
58
59def checkwhite(filename):
60 if lang_type(filename) not in whitespace_types:
61 return
62
63 try:
64 f = file(filename, 'r+')
65 except OSError, msg:
66 print 'could not open file %s: %s' % (filename, msg)
67 return
68
69 for num,line in enumerate(f):
70 if not checkwhite_line(line):
71 yield line,num + 1
72
72def fixwhite_line(line, tabsize):
73def fixwhite_line(line):
73 if lead.search(line):
74 newline = ''
75 for i,c in enumerate(line):
76 if c == ' ':
77 newline += ' '
78 elif c == '\t':
79 newline += ' ' * (tabsize - len(newline) % tabsize)
80 else:
81 newline += line[i:]
82 break
83
84 line = newline
85
86 return line.rstrip() + '\n'
87
74 if lead.search(line):
75 newline = ''
76 for i,c in enumerate(line):
77 if c == ' ':
78 newline += ' '
79 elif c == '\t':
80 newline += ' ' * (tabsize - len(newline) % tabsize)
81 else:
82 newline += line[i:]
83 break
84
85 line = newline
86
87 return line.rstrip() + '\n'
88
88def fixwhite(filename, tabsize, fixonly=None):
89def fixwhite(filename, fixonly=None):
89 if lang_type(filename) not in whitespace_types:
90 return
91
92 try:
93 f = file(filename, 'r+')
94 except OSError, msg:
95 print 'could not open file %s: %s' % (filename, msg)
96 return
97
98 lines = list(f)
99
100 f.seek(0)
101 f.truncate()
102
103 for i,line in enumerate(lines):
104 if fixonly is None or i in fixonly:
105 line = fixwhite_line(line, tabsize)
106
107 print >>f, line,
108
109def linelen(line):
110 tabs = line.count('\t')
111 if not tabs:
112 return len(line)
113
114 count = 0
115 for c in line:
116 if c == '\t':
117 count += tabsize - count % tabsize
118 else:
119 count += 1
120
121 return count
122
123class ValidationStats(object):
124 def __init__(self):
125 self.toolong = 0
126 self.toolong80 = 0
127 self.leadtabs = 0
128 self.trailwhite = 0
129 self.badcontrol = 0
130 self.cret = 0
131
132 def dump(self):
133 print '''\
134%d violations of lines over 79 chars. %d of which are 80 chars exactly.
135%d cases of whitespace at the end of a line.
136%d cases of tabs to indent.
137%d bad parens after if/while/for.
138%d carriage returns found.
139''' % (self.toolong, self.toolong80, self.trailwhite, self.leadtabs,
140 self.badcontrol, self.cret)
141
142 def __nonzero__(self):
143 return self.toolong or self.toolong80 or self.leadtabs or \
144 self.trailwhite or self.badcontrol or self.cret
145
146def validate(filename, stats, verbose, exit_code):
147 if lang_type(filename) not in format_types:
148 return
149
150 def msg(lineno, line, message):
151 print '%s:%d>' % (filename, lineno + 1), message
152 if verbose > 2:
153 print line
154
155 def bad():
156 if exit_code is not None:
157 sys.exit(exit_code)
158
159 try:
160 f = file(filename, 'r')
161 except OSError:
162 if verbose > 0:
163 print 'could not open file %s' % filename
164 bad()
165 return
166
167 for i,line in enumerate(f):
168 line = line.rstrip('\n')
169
170 # no carriage returns
171 if line.find('\r') != -1:
172 self.cret += 1
173 if verbose > 1:
174 msg(i, line, 'carriage return found')
175 bad()
176
177 # lines max out at 79 chars
178 llen = linelen(line)
179 if llen > 79:
180 stats.toolong += 1
181 if llen == 80:
182 stats.toolong80 += 1
183 if verbose > 1:
184 msg(i, line, 'line too long (%d chars)' % llen)
185 bad()
186
187 # no tabs used to indent
188 match = lead.search(line)
189 if match and match.group(1).find('\t') != -1:
190 stats.leadtabs += 1
191 if verbose > 1:
192 msg(i, line, 'using tabs to indent')
193 bad()
194
195 # no trailing whitespace
196 if trail.search(line):
197 stats.trailwhite +=1
198 if verbose > 1:
199 msg(i, line, 'trailing whitespace')
200 bad()
201
202 # for c++, exactly one space betwen if/while/for and (
203 if cpp:
204 match = any_control.search(line)
205 if match and not good_control.search(line):
206 stats.badcontrol += 1
207 if verbose > 1:
208 msg(i, line, 'improper spacing after %s' % match.group(1))
209 bad()
210
211def modified_lines(old_data, new_data, max_lines):
212 from itertools import count
213 from mercurial import bdiff, mdiff
214
215 modified = set()
216 counter = count()
217 for pbeg, pend, fbeg, fend in bdiff.blocks(old_data, new_data):
218 for i in counter:
219 if i < fbeg:
220 modified.add(i)
221 elif i + 1 >= fend:
222 break
223 elif i > max_lines:
224 break
225 return modified
226
90 if lang_type(filename) not in whitespace_types:
91 return
92
93 try:
94 f = file(filename, 'r+')
95 except OSError, msg:
96 print 'could not open file %s: %s' % (filename, msg)
97 return
98
99 lines = list(f)
100
101 f.seek(0)
102 f.truncate()
103
104 for i,line in enumerate(lines):
105 if fixonly is None or i in fixonly:
106 line = fixwhite_line(line, tabsize)
107
108 print >>f, line,
109
110def linelen(line):
111 tabs = line.count('\t')
112 if not tabs:
113 return len(line)
114
115 count = 0
116 for c in line:
117 if c == '\t':
118 count += tabsize - count % tabsize
119 else:
120 count += 1
121
122 return count
123
124class ValidationStats(object):
125 def __init__(self):
126 self.toolong = 0
127 self.toolong80 = 0
128 self.leadtabs = 0
129 self.trailwhite = 0
130 self.badcontrol = 0
131 self.cret = 0
132
133 def dump(self):
134 print '''\
135%d violations of lines over 79 chars. %d of which are 80 chars exactly.
136%d cases of whitespace at the end of a line.
137%d cases of tabs to indent.
138%d bad parens after if/while/for.
139%d carriage returns found.
140''' % (self.toolong, self.toolong80, self.trailwhite, self.leadtabs,
141 self.badcontrol, self.cret)
142
143 def __nonzero__(self):
144 return self.toolong or self.toolong80 or self.leadtabs or \
145 self.trailwhite or self.badcontrol or self.cret
146
147def validate(filename, stats, verbose, exit_code):
148 if lang_type(filename) not in format_types:
149 return
150
151 def msg(lineno, line, message):
152 print '%s:%d>' % (filename, lineno + 1), message
153 if verbose > 2:
154 print line
155
156 def bad():
157 if exit_code is not None:
158 sys.exit(exit_code)
159
160 try:
161 f = file(filename, 'r')
162 except OSError:
163 if verbose > 0:
164 print 'could not open file %s' % filename
165 bad()
166 return
167
168 for i,line in enumerate(f):
169 line = line.rstrip('\n')
170
171 # no carriage returns
172 if line.find('\r') != -1:
173 self.cret += 1
174 if verbose > 1:
175 msg(i, line, 'carriage return found')
176 bad()
177
178 # lines max out at 79 chars
179 llen = linelen(line)
180 if llen > 79:
181 stats.toolong += 1
182 if llen == 80:
183 stats.toolong80 += 1
184 if verbose > 1:
185 msg(i, line, 'line too long (%d chars)' % llen)
186 bad()
187
188 # no tabs used to indent
189 match = lead.search(line)
190 if match and match.group(1).find('\t') != -1:
191 stats.leadtabs += 1
192 if verbose > 1:
193 msg(i, line, 'using tabs to indent')
194 bad()
195
196 # no trailing whitespace
197 if trail.search(line):
198 stats.trailwhite +=1
199 if verbose > 1:
200 msg(i, line, 'trailing whitespace')
201 bad()
202
203 # for c++, exactly one space betwen if/while/for and (
204 if cpp:
205 match = any_control.search(line)
206 if match and not good_control.search(line):
207 stats.badcontrol += 1
208 if verbose > 1:
209 msg(i, line, 'improper spacing after %s' % match.group(1))
210 bad()
211
212def modified_lines(old_data, new_data, max_lines):
213 from itertools import count
214 from mercurial import bdiff, mdiff
215
216 modified = set()
217 counter = count()
218 for pbeg, pend, fbeg, fend in bdiff.blocks(old_data, new_data):
219 for i in counter:
220 if i < fbeg:
221 modified.add(i)
222 elif i + 1 >= fend:
223 break
224 elif i > max_lines:
225 break
226 return modified
227
227def do_check_whitespace(ui, repo, *files, **args):
228def do_check_style(ui, repo, *files, **args):
228 """check files for proper m5 style guidelines"""
229 from mercurial import mdiff, util
230
231 if files:
232 files = frozenset(files)
233
234 def skip(name):
235 return files and name in files
236
229 """check files for proper m5 style guidelines"""
230 from mercurial import mdiff, util
231
232 if files:
233 files = frozenset(files)
234
235 def skip(name):
236 return files and name in files
237
237 def prompt(name, fixonly=None):
238 def prompt(name, func, fixonly=None):
238 if args.get('auto', False):
239 result = 'f'
240 else:
241 while True:
242 result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", default='a')
243 if result in 'aif':
244 break
245
246 if result == 'a':
247 return True
248 elif result == 'f':
239 if args.get('auto', False):
240 result = 'f'
241 else:
242 while True:
243 result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", default='a')
244 if result in 'aif':
245 break
246
247 if result == 'a':
248 return True
249 elif result == 'f':
249 fixwhite(repo.wjoin(name), args['tabsize'], fixonly)
250 func(repo.wjoin(name), fixonly)
250
251 return False
252
253 modified, added, removed, deleted, unknown, ignore, clean = repo.status()
254
255 for fname in added:
256 if skip(fname):
257 continue
258
259 ok = True
260 for line,num in checkwhite(repo.wjoin(fname)):
261 ui.write("invalid whitespace in %s:%d\n" % (fname, num))
262 if ui.verbose:
263 ui.write(">>%s<<\n" % line[-1])
264 ok = False
265
266 if not ok:
251
252 return False
253
254 modified, added, removed, deleted, unknown, ignore, clean = repo.status()
255
256 for fname in added:
257 if skip(fname):
258 continue
259
260 ok = True
261 for line,num in checkwhite(repo.wjoin(fname)):
262 ui.write("invalid whitespace in %s:%d\n" % (fname, num))
263 if ui.verbose:
264 ui.write(">>%s<<\n" % line[-1])
265 ok = False
266
267 if not ok:
267 if prompt(fname):
268 if prompt(fname, fixwhite):
268 return True
269
270 try:
271 wctx = repo.workingctx()
272 except:
273 from mercurial import context
274 wctx = context.workingctx(repo)
275
276 for fname in modified:
277 if skip(fname):
278 continue
279
280 if lang_type(fname) not in whitespace_types:
281 continue
282
283 fctx = wctx.filectx(fname)
284 pctx = fctx.parents()
285
286 file_data = fctx.data()
287 lines = mdiff.splitnewlines(file_data)
288 if len(pctx) in (1, 2):
289 mod_lines = modified_lines(pctx[0].data(), file_data, len(lines))
290 if len(pctx) == 2:
291 m2 = modified_lines(pctx[1].data(), file_data, len(lines))
292 # only the lines that are new in both
293 mod_lines = mod_lines & m2
294 else:
295 mod_lines = xrange(0, len(lines))
296
297 fixonly = set()
298 for i,line in enumerate(lines):
299 if i not in mod_lines:
300 continue
301
302 if checkwhite_line(line):
303 continue
304
305 ui.write("invalid whitespace: %s:%d\n" % (fname, i+1))
306 if ui.verbose:
307 ui.write(">>%s<<\n" % line[:-1])
308 fixonly.add(i)
309
310 if fixonly:
311 if prompt(fname, fixonly):
312 return True
313
314def do_check_format(ui, repo, **args):
315 modified, added, removed, deleted, unknown, ignore, clean = repo.status()
316
317 verbose = 0
318 stats = ValidationStats()
319 for f in modified + added:
320 validate(f, stats, verbose, None)
321
322 if stats:
323 stats.dump()
324 result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?",
325 "^[ia]$", "a")
326 if result.startswith('i'):
327 pass
328 elif result.startswith('a'):
329 return True
330 else:
331 raise util.Abort(_("Invalid response: '%s'") % result)
332
333 return False
334
335def check_hook(hooktype):
336 if hooktype not in ('pretxncommit', 'pre-qrefresh'):
337 raise AttributeError, \
338 "This hook is not meant for %s" % hooktype
339
269 return True
270
271 try:
272 wctx = repo.workingctx()
273 except:
274 from mercurial import context
275 wctx = context.workingctx(repo)
276
277 for fname in modified:
278 if skip(fname):
279 continue
280
281 if lang_type(fname) not in whitespace_types:
282 continue
283
284 fctx = wctx.filectx(fname)
285 pctx = fctx.parents()
286
287 file_data = fctx.data()
288 lines = mdiff.splitnewlines(file_data)
289 if len(pctx) in (1, 2):
290 mod_lines = modified_lines(pctx[0].data(), file_data, len(lines))
291 if len(pctx) == 2:
292 m2 = modified_lines(pctx[1].data(), file_data, len(lines))
293 # only the lines that are new in both
294 mod_lines = mod_lines & m2
295 else:
296 mod_lines = xrange(0, len(lines))
297
298 fixonly = set()
299 for i,line in enumerate(lines):
300 if i not in mod_lines:
301 continue
302
303 if checkwhite_line(line):
304 continue
305
306 ui.write("invalid whitespace: %s:%d\n" % (fname, i+1))
307 if ui.verbose:
308 ui.write(">>%s<<\n" % line[:-1])
309 fixonly.add(i)
310
311 if fixonly:
312 if prompt(fname, fixonly):
313 return True
314
315def do_check_format(ui, repo, **args):
316 modified, added, removed, deleted, unknown, ignore, clean = repo.status()
317
318 verbose = 0
319 stats = ValidationStats()
320 for f in modified + added:
321 validate(f, stats, verbose, None)
322
323 if stats:
324 stats.dump()
325 result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?",
326 "^[ia]$", "a")
327 if result.startswith('i'):
328 pass
329 elif result.startswith('a'):
330 return True
331 else:
332 raise util.Abort(_("Invalid response: '%s'") % result)
333
334 return False
335
336def check_hook(hooktype):
337 if hooktype not in ('pretxncommit', 'pre-qrefresh'):
338 raise AttributeError, \
339 "This hook is not meant for %s" % hooktype
340
340def check_whitespace(ui, repo, hooktype, **kwargs):
341def check_style(ui, repo, hooktype, **kwargs):
341 check_hook(hooktype)
342 check_hook(hooktype)
342 args = { 'tabsize' : 8 }
343 return do_check_whitespace(ui, repo, **args)
343 args = {}
344 return do_check_style(ui, repo, **args)
344
345def check_format(ui, repo, hooktype, **kwargs):
346 check_hook(hooktype)
347 args = {}
348 return do_check_format(ui, repo, **args)
349
350try:
351 from mercurial.i18n import _
352except ImportError:
353 def _(arg):
354 return arg
355
356cmdtable = {
357 '^m5style' :
345
346def check_format(ui, repo, hooktype, **kwargs):
347 check_hook(hooktype)
348 args = {}
349 return do_check_format(ui, repo, **args)
350
351try:
352 from mercurial.i18n import _
353except ImportError:
354 def _(arg):
355 return arg
356
357cmdtable = {
358 '^m5style' :
358 ( do_check_whitespace,
359 [ ('a', 'auto', False, _("automatically fix whitespace")),
360 ('t', 'tabsize', 8, _("Number of spaces TAB indents")) ],
361 _('hg m5style [-a] [-t <tabsize>] [FILE]...')),
359 ( do_check_style,
360 [ ('a', 'auto', False, _("automatically fix whitespace")) ],
361 _('hg m5style [-a] [FILE]...')),
362 '^m5format' :
363 ( do_check_format,
364 [ ],
365 _('hg m5format [FILE]...')),
366}
367
368if __name__ == '__main__':
369 import getopt
370
371 progname = sys.argv[0]
372 if len(sys.argv) < 2:
373 sys.exit('usage: %s <command> [<command args>]' % progname)
374
375 fixwhite_usage = '%s fixwhite [-t <tabsize> ] <path> [...] \n' % progname
376 chkformat_usage = '%s chkformat <path> [...] \n' % progname
377 chkwhite_usage = '%s chkwhite <path> [...] \n' % progname
378
379 command = sys.argv[1]
380 if command == 'fixwhite':
381 flags = 't:'
382 usage = fixwhite_usage
383 elif command == 'chkwhite':
384 flags = 'nv'
385 usage = chkwhite_usage
386 elif command == 'chkformat':
387 flags = 'nv'
388 usage = chkformat_usage
389 else:
390 sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage)
391
392 opts, args = getopt.getopt(sys.argv[2:], flags)
393
394 code = 1
395 verbose = 1
362 '^m5format' :
363 ( do_check_format,
364 [ ],
365 _('hg m5format [FILE]...')),
366}
367
368if __name__ == '__main__':
369 import getopt
370
371 progname = sys.argv[0]
372 if len(sys.argv) < 2:
373 sys.exit('usage: %s <command> [<command args>]' % progname)
374
375 fixwhite_usage = '%s fixwhite [-t <tabsize> ] <path> [...] \n' % progname
376 chkformat_usage = '%s chkformat <path> [...] \n' % progname
377 chkwhite_usage = '%s chkwhite <path> [...] \n' % progname
378
379 command = sys.argv[1]
380 if command == 'fixwhite':
381 flags = 't:'
382 usage = fixwhite_usage
383 elif command == 'chkwhite':
384 flags = 'nv'
385 usage = chkwhite_usage
386 elif command == 'chkformat':
387 flags = 'nv'
388 usage = chkformat_usage
389 else:
390 sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage)
391
392 opts, args = getopt.getopt(sys.argv[2:], flags)
393
394 code = 1
395 verbose = 1
396 tabsize = 8
397 for opt,arg in opts:
398 if opt == '-n':
399 code = None
400 if opt == '-t':
401 tabsize = int(arg)
402 if opt == '-v':
403 verbose += 1
404
405 if command == 'fixwhite':
406 for filename in args:
407 fixwhite(filename, tabsize)
408 elif command == 'chkwhite':
409 for filename in args:
410 for line,num in checkwhite(filename):
411 print 'invalid whitespace: %s:%d' % (filename, num)
412 if verbose:
413 print '>>%s<<' % line[:-1]
414 elif command == 'chkformat':
415 stats = ValidationStats()
416 for filename in args:
417 validate(filename, stats=stats, verbose=verbose, exit_code=code)
418
419 if verbose > 0:
420 stats.dump()
421 else:
422 sys.exit("command '%s' not found" % command)
396 for opt,arg in opts:
397 if opt == '-n':
398 code = None
399 if opt == '-t':
400 tabsize = int(arg)
401 if opt == '-v':
402 verbose += 1
403
404 if command == 'fixwhite':
405 for filename in args:
406 fixwhite(filename, tabsize)
407 elif command == 'chkwhite':
408 for filename in args:
409 for line,num in checkwhite(filename):
410 print 'invalid whitespace: %s:%d' % (filename, num)
411 if verbose:
412 print '>>%s<<' % line[:-1]
413 elif command == 'chkformat':
414 stats = ValidationStats()
415 for filename in args:
416 validate(filename, stats=stats, verbose=verbose, exit_code=code)
417
418 if verbose > 0:
419 stats.dump()
420 else:
421 sys.exit("command '%s' not found" % command)