comparison contrib/check-code.py @ 10719:3be9ae49b628

code-code: Add a logfunc argument to checkfile This helps external tool customisation. The logfunc argument must be a function called to report errors. A new logger class is also added to keep the old behaviour by default.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Tue, 16 Mar 2010 19:53:00 +0100
parents f18c37fd624f
children fbcccf9ec58f
comparison
equal deleted inserted replaced
10718:f18c37fd624f 10719:3be9ae49b628
131 checks = [ 131 checks = [
132 ('python', r'.*\.(py|cgi)$', pyfilters, pypats), 132 ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
133 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats), 133 ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
134 ('c', r'.*\.c$', cfilters, cpats), 134 ('c', r'.*\.c$', cfilters, cpats),
135 ] 135 ]
136 def checkfile(f, maxerr=None): 136
137 """checks style and portability of a given file""" 137 class norepeatlogger(object):
138 def __init__(self):
139 self._lastseen = None
140
141 def log(self, fname, lineno, line, msg):
142 """print error related a to given line of a given file.
143
144 The faulty line will also be printed but only once in the case
145 of multiple errors.
146
147 :fname: filename
148 :lineno: line number
149 :line: actual content of the line
150 :msg: error message
151 """
152 msgid = fname, lineno, line
153 if msgid != self._lastseen:
154 print "%s:%d:" % (fname, lineno)
155 print " > %s" % line
156 self._lastseen = msgid
157 print " " + msg
158
159 _defaultlogger = norepeatlogger()
160
161 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None):
162 """checks style and portability of a given file
163
164 :f: filepath
165 :logfunc: function used to report error
166 logfunc(filename, linenumber, linecontent, errormessage)
167 :maxerr: number of error to display before arborting.
168 Set to None (default) to report all errors
169 """
138 for name, match, filters, pats in checks: 170 for name, match, filters, pats in checks:
139 fc = 0 171 fc = 0
140 if not re.match(match, f): 172 if not re.match(match, f):
141 continue 173 continue
142 pre = post = open(f).read() 174 pre = post = open(f).read()
147 # print post # uncomment to show filtered version 179 # print post # uncomment to show filtered version
148 z = enumerate(zip(pre.splitlines(), post.splitlines(True))) 180 z = enumerate(zip(pre.splitlines(), post.splitlines(True)))
149 for n, l in z: 181 for n, l in z:
150 if "check-code" + "-ignore" in l[0]: 182 if "check-code" + "-ignore" in l[0]:
151 continue 183 continue
152 lc = 0
153 for p, msg in pats: 184 for p, msg in pats:
154 if re.search(p, l[1]): 185 if re.search(p, l[1]):
155 if not lc: 186 logfunc(f, n+1, l[0], msg)
156 print "%s:%d:" % (f, n + 1)
157 print " > %s" % l[0]
158 print " %s" % msg
159 lc += 1
160 fc += 1 187 fc += 1
161 if maxerr is not None and fc >= maxerr: 188 if maxerr is not None and fc >= maxerr:
162 print " (too many errors, giving up)" 189 print " (too many errors, giving up)"
163 break 190 break
164 break 191 break