2 # Copyright (c) 2006 The Regents of The University of Michigan
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met: redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer;
9 # redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution;
12 # neither the name of the copyright holders nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 # Authors: Nathan Binkert
30 from getopt
import getopt
, GetoptError
37 lead
= re
.compile(r
'^([ \t])+')
38 trail
= re
.compile(r
'[ \t]+$')
39 any_control
= re
.compile(r
'\b(if|while|for)[ \t]*[(]')
40 good_control
= re
.compile(r
'\b(if|while|for) [(]')
43 tabs
= line
.count('\t')
50 count
+= tabsize
- count
% tabsize
63 def validate(filename
, verbose
, code
):
64 global toolong
, toolong80
, leadtabs
, trailwhite
, badcontrol
, cret
66 def msg(lineno
, line
, message
):
67 print '%s:%d>' % (filename
, lineno
+ 1), message
75 cpp
= filename
.endswith('.cc') or filename
.endswith('.hh')
76 py
= filename
.endswith('.py')
79 raise AttributeError, \
80 "I don't know how to deal with the file %s" % filename
83 f
= file(filename
, 'r')
86 print 'could not open file %s' % filename
90 for i
,line
in enumerate(f
):
91 line
= line
.rstrip('\n')
94 if line
.find('\r') != -1:
97 msg(i
, line
, 'carriage return found')
100 # lines max out at 79 chars
107 msg(i
, line
, 'line too long (%d chars)' % llen
)
110 # no tabs used to indent
111 match
= lead
.search(line
)
112 if match
and match
.group(1).find('\t') != -1:
115 msg(i
, line
, 'using tabs to indent')
118 # no trailing whitespace
119 if trail
.search(line
):
122 msg(i
, line
, 'trailing whitespace')
125 # for c++, exactly one space betwen if/while/for and (
127 match
= any_control
.search(line
)
128 if match
and not good_control
.search(line
):
131 msg(i
, line
, 'improper spacing after %s' % match
.group(1))
134 if __name__
== '__main__':
135 progname
= sys
.argv
[0]
137 def usage(code
=None):
138 print >>sys
.stderr
, '''%s [-n] [-q] [-v] <filenames>''' % progname
143 opts
, args
= getopt(sys
.argv
[1:], '-nv')
157 for filename
in args
:
158 validate(filename
, verbose
=verbose
, code
=code
)
162 %d violations of lines over 79 chars. %d of which are 80 chars exactly.
163 %d cases of whitespace at the end of a line.
164 %d cases of tabs to indent.
165 %d bad parens after if/while/for.
166 %d carriage returns found.
167 ''' % (toolong
, toolong80
, trailwhite
, leadtabs
, badcontrol
, cret
)